diff --git a/README.md b/README.md index 536152c..a6754d8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -# multi Version: 1.7.5 (Typos and improved module creation supprt, examples to come soon) +# multi Version: 1.7.6 (Examples and more module creation support, small tweaks to cut down the amount of code needed to get things to work) View Changes: https://github.com/rayaman/multi#changes +**Note: The changes section has information on how to use the new features as they come out. Why put the infomation twice on the readme?**
My multitasking library for lua
To install copy the multi folder into your enviroment and you are good to go
@@ -14,14 +15,22 @@ Also I will eventually add an example folder with a lot of examples for how you For real-time assistance with my libraries! A place where you can ask questions and get help with any of my libraries
https://discord.gg/U8UspuA
-# Planned feature -- [x] Add system threads for love2d that work like the lanesManager (loveManager). +# Planned features/TODO +- [x] Add system threads for love2d that works like the lanesManager (loveManager, slight differences). - [ ] Improve performance of the library - [ ] Add more features to support module creators - +- [ ] Make a framework for eaiser thread task distributing +- [ ] Fix Error handling on multi objects +- [ ] Add Remote Proxies **May or may not be completed** +- [ ] sThread.wrapper(obj) **May or may not be completed** +- [ ] SystemThreaded Actors +- [ ] LoadBalancing for system threads (Once SystemThreaded Actors are done) +- [ ] Add more intergrations +- [ ] Finish the wiki stuff. (11% done)
+- [ ] Test for unknown bugs
Usage:
```lua ---Basic usage Alarms: Have been moved to the core of the library require("multi") would work as well +-- Basic usage Alarms: Have been moved to the core of the library require("multi") would work as well require("multi") -- gets the entire library alarm=multi:newAlarm(3) -- in seconds can go to .001 uses the built in os.clock() alarm:OnRing(function(a) @@ -753,13 +762,25 @@ Looping...
We did it! 1 2 3
# Changes -Updated from 1.7.4 to 1.7.5
-Fixed some typos in the readme... (I am sure there are more there are always more) -Added more features for module support -TODO: -Work on performance of the library... I see 3 places where I can make this thing run quicker +Updated from 1.7.5 to 1.7.6
+Fixed: +Typos like always +Added:
+multi:getPlatform() -- returns "love2d" if using the love2d platform or returns "lanes" if using lanes for threading
+examples files
+In Events added method setTask(func)
+The old way still works and is more convient to be honest, but I felt a method to do this was ok.
-I'll show case some old versions of the multitasking library eventually so you can see its changes in days past! +Updated: +some example files to reflect changes to the core. Changes allow for less typing
+loveManager to require the compat if used so you don't need 2 require line to retrieve the library
+Updated from 1.7.4 to 1.7.5
+Fixed some typos in the readme... (I am sure there are more there are always more)
+Added more features for module support
+TODO:
+Work on performance of the library... I see 3 places where I can make this thing run quicker
+ +I'll show case some old versions of the multitasking library eventually so you can see its changes in days past!
Updated from 1.7.3 to 1.7.4
Added: the example folder which will be populated with more examples in the near future!
@@ -943,7 +964,4 @@ Added: 1.4.1 - First Public release of the library IMPORTANT:
-Every update I make aims to make things simpler more efficent and just better, but a lot of old code, which can be really big, uses a lot of older features. I know the pain of having to rewrite everything. My promise to my library users is that I will always have backwards support for older features! New ways may exist that are quicker and eaiser, but the old features/methods will be supported.
-# TODO (In order of importance) -- [ ] Finish the wiki stuff. (10% done)
-- [ ] Test for unknown bugs
+Every update I make aims to make things simpler more efficent and just better, but a lot of old code, which can be really big, uses a lot of older features. I know the pain of having to rewrite everything. My promise to my library users is that I will always have backwards support for older features! New ways may exist that are quicker and eaiser, but the old features/methods will be supported.
\ No newline at end of file diff --git a/examples/lanes resource loading/proAudioRt.dll b/examples/lanes resource loading/proAudioRt.dll new file mode 100644 index 0000000..f24fcb9 Binary files /dev/null and b/examples/lanes resource loading/proAudioRt.dll differ diff --git a/examples/lanes resource loading/proAudioRt.so b/examples/lanes resource loading/proAudioRt.so new file mode 100644 index 0000000..e1ce5c7 Binary files /dev/null and b/examples/lanes resource loading/proAudioRt.so differ diff --git a/examples/lanes resource loading/resourceloading.lua b/examples/lanes resource loading/resourceloading.lua new file mode 100644 index 0000000..309dc1e --- /dev/null +++ b/examples/lanes resource loading/resourceloading.lua @@ -0,0 +1,32 @@ +local GLOBAL,sThread=require("multi.intergration.lanesManager").init() +require("proAudioRt") -- an audio library +-- The hosting site with precompiled binaries is down, but here is a link to a archive +-- https://web.archive.org/web/20160907180559/http://viremo.eludi.net:80/proteaAudio/proteaaudiolua.html documentation and downloads are availiable... I also have saved copies just in case :D +-- Music by: myuuji +-- His youtube channel can be found here: https://www.youtube.com/channel/UCiSKnkKCKAQVxMUWpZQobuQ +proAudio.create() +multi:newThread("test",function() + -- simple playlist + sThread.waitFor("song") + print("Playing song 1!") + proAudio.soundPlay(GLOBAL["song"]) + sThread.waitFor("song2") + thread.hold(function() sThread.sleep(.001) return proAudio.soundActive()==0 end) + print("Playing song 2!") + proAudio.soundPlay(GLOBAL["song2"]) + sThread.waitFor("song3") + thread.hold(function() sThread.sleep(.001) return proAudio.soundActive()==0 end) + print("Playing song 3!") + proAudio.soundPlay(GLOBAL["song3"]) +end) +-- loading the audio in another thread is way faster! So lets do that +multi:newSystemThread("test1",function() -- spawns a thread in another lua process + require("proAudioRt") + GLOBAL["song"]=proAudio.sampleFromFile("test.ogg",1,1) + print("Loaded song 1!") + GLOBAL["song2"]=proAudio.sampleFromFile("test2.ogg",1,1) + print("Loaded song 2!") + GLOBAL["song3"]=proAudio.sampleFromFile("test3.ogg",1,1) + print("Loaded song 3!") +end) +multi:mainloop() diff --git a/examples/lanes resource loading/test.ogg b/examples/lanes resource loading/test.ogg new file mode 100644 index 0000000..3e95504 Binary files /dev/null and b/examples/lanes resource loading/test.ogg differ diff --git a/examples/lanes resource loading/test2.ogg b/examples/lanes resource loading/test2.ogg new file mode 100644 index 0000000..818f791 Binary files /dev/null and b/examples/lanes resource loading/test2.ogg differ diff --git a/examples/lanes resource loading/test3.ogg b/examples/lanes resource loading/test3.ogg new file mode 100644 index 0000000..b1b1a76 Binary files /dev/null and b/examples/lanes resource loading/test3.ogg differ diff --git a/examples/lanesintergratetest.lua b/examples/lanesintergratetest.lua index 33bbb30..d8f2a37 100644 --- a/examples/lanesintergratetest.lua +++ b/examples/lanesintergratetest.lua @@ -1,6 +1,5 @@ package.path="?/init.lua;?.lua;"..package.path local GLOBAL,sThread=require("multi.intergration.lanesManager").init() -require("multi.threading") multi:newAlarm(2):OnRing(function(self) GLOBAL["NumOfCores"]=sThread.getCores() end) diff --git a/examples/lanesintergratetest2.lua b/examples/lanesintergratetest2.lua index 7ae5ee0..095a7cd 100644 --- a/examples/lanesintergratetest2.lua +++ b/examples/lanesintergratetest2.lua @@ -1,6 +1,5 @@ package.path="?/init.lua;?.lua;"..package.path -local GLOBAL,sThread=require("multi.intergration.lanesManager").init() -require("multi.threading") -- obvious copy/paste below with no attempt to clean it up :P +local GLOBAL,sThread=require("multi.intergration.lanesManager").init() -- loads the lanesManager and includes the entire multi library local function comma_value(amount) local formatted = amount while true do @@ -40,8 +39,6 @@ multi:newSystemThread("test6",function() -- spawns a thread in another lua proce require("multi.all") -- now you can do all of your coding with the multi library! You could even spawn more threads from here with the intergration. You would need to require the interaction again though multi:benchMark(sThread.waitFor("Bench"),nil,"Thread 6"):OnBench(function(self,c) GLOBAL["T6"]=c multi:Stop() end) multi:mainloop() -end) -multi:newSystemThread("Combiner",function() -- spawns a thread in another lua process print("Bench: ",comma_value(tostring(sThread.waitFor("T1")+sThread.waitFor("T2")+sThread.waitFor("T3")+sThread.waitFor("T4")+sThread.waitFor("T5")+sThread.waitFor("T6")))) GLOBAL["DONE"]=true end) @@ -58,5 +55,5 @@ multi:newThread("test0",function() end end end) -GLOBAL["Bench"]=10 +GLOBAL["Bench"]=60 multi:mainloop() diff --git a/examples/lanesintergratetest3.lua b/examples/lanesintergratetest3.lua new file mode 100644 index 0000000..bf1f585 --- /dev/null +++ b/examples/lanesintergratetest3.lua @@ -0,0 +1,48 @@ +package.path="?/init.lua;?.lua;"..package.path -- Spawing threads using 1 method and the sThread.getCores() function! +local GLOBAL,sThread=require("multi.intergration.lanesManager").init() -- loads the lanesManager and includes the entire multi library +local function comma_value(amount) + local formatted = amount + while true do + formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') + if (k==0) then + break + end + end + return formatted +end +GLOBAL["BENCHCOUNT"],GLOBAL["CNUM"],GLOBAL["DONE"]=0,0,0 +cores=sThread.getCores() +function benchmark() -- our single function that will be used across a bunch of threads + require("multi.all") -- get the library + local n=GLOBAL["CNUM"]; GLOBAL["CNUM"]=n+1 -- do some math so we can identify which thread is which + multi:benchMark(sThread.waitFor("BENCH"),nil,"Thread "..n+1):OnBench(function(self,c) GLOBAL["BENCHCOUNT"]=GLOBAL["BENCHCOUNT"]+c; GLOBAL["DONE"]=GLOBAL["DONE"]+1; multi:Stop() end) + -- ^ do the bench mark and add to the BENCHCOUNT GLOBAL value, then increment the DONE Value + multi:mainloop() +end +for i=1,cores do -- loop based on the number of cores you have + multi:newSystemThread("test"..i,benchmark) -- create a system thread based on the benchmark +end +multi:newThread("test0",function() + while true do + thread.skip(1) + sThread.sleep(.001) + if GLOBAL["DONE"]==cores then + print(comma_value(tostring(GLOBAL["BENCHCOUNT"]))) + os.exit() + end + end +end) +GLOBAL["BENCH"]=10 +print("Platform is: ",multi:getPlatform()) -- returns love2d or lanes depending on which platform you are using... If I add more intergrations then this method will be updated! corona sdk may see this library in the future... +multi:mainloop() +--[[ Output on my machine! I am using luajit and have 6 cores on my computer. Your numbers will vary, but it should look something like this +Intergrated Lanes! +Platform is: lanes +Thread 1 62442125 Steps in 10 second(s)! +Thread 2 61379095 Steps in 10 second(s)! +Thread 3 62772502 Steps in 10 second(s)! +Thread 4 62740684 Steps in 10 second(s)! +Thread 5 60926715 Steps in 10 second(s)! +Thread 6 61793175 Steps in 10 second(s)! +372,054,296 +]] diff --git a/examples/love2d Threading Example/main.lua b/examples/love2d Threading Example/main.lua index a7d7899..57c210d 100644 --- a/examples/love2d Threading Example/main.lua +++ b/examples/love2d Threading Example/main.lua @@ -1,6 +1,5 @@ require("core.Library") -require("multi.compat.love2d") -- allows for multitasking and binds my libraies to the love2d engine that i am using -GLOBAL,sThread=require("multi.intergration.loveManager").init() -- load the love2d version of the lanesManager +GLOBAL,sThread=require("multi.intergration.loveManager").init() -- load the love2d version of the lanesManager and requires the entire multi library --IMPORTANT -- Do not make the above local, this is the one difference that the lanesManager does not have -- If these are local the functions will have the upvalues put into them that do not exist on the threaded side diff --git a/examples/love2d Threading Example/multi/init.lua b/examples/love2d Threading Example/multi/init.lua index 5df3b84..66d82ba 100644 --- a/examples/love2d Threading Example/multi/init.lua +++ b/examples/love2d Threading Example/multi/init.lua @@ -45,7 +45,7 @@ function print(...) end end multi = {} -multi.Version={1,7,5} +multi.Version={1,7,6} multi.stage='stable' multi.__index = multi multi.Mainloop={} @@ -67,7 +67,7 @@ multi.jobUS=2 multi.clock=os.clock multi.time=os.time multi.LinkedPath=multi -mulit.isRunning=false +multi.isRunning=false multi.queuefinal=function(self) self:Destroy() if self.Parent.Mainloop[#self.Parent.Mainloop] then @@ -239,6 +239,15 @@ end function multi:getVersion() return multi.Version[1].."."..multi.Version[2].."."..multi.Version[3] end +function multi:getPlatform() + if love then + if love.thread then + return "love2d" + end + else + return "lanes" + end +end --Processor function multi:getError() if self.error then @@ -953,8 +962,8 @@ function multi:newCondition(func) end multi.NewCondition=multi.newCondition function multi:mainloop() - if not mulit.isRunning then - mulit.isRunning=true + if not multi.isRunning then + multi.isRunning=true for i=1,#self.Tasks do self.Tasks[i](self) end @@ -1020,6 +1029,9 @@ function multi:newEvent(task) end end end + function c:SetTask(func) + self.Task=func + end function c:OnEvent(func) table.insert(self.func,func) end diff --git a/examples/love2d Threading Example/multi/intergration/lanesManager.lua b/examples/love2d Threading Example/multi/intergration/lanesManager.lua index 235cbbf..150fd00 100644 --- a/examples/love2d Threading Example/multi/intergration/lanesManager.lua +++ b/examples/love2d Threading Example/multi/intergration/lanesManager.lua @@ -31,7 +31,7 @@ end -- Step 1 get lanes lanes=require("lanes").configure() package.path="lua/?/init.lua;lua/?.lua;"..package.path -require("multi.updater") -- get it all and have it on all lanes +require("multi.all") -- get it all and have it on all lanes local multi=multi -- Step 2 set up the linda objects local __GlobalLinda = lanes.linda() -- handles global stuff diff --git a/examples/love2d Threading Example/multi/intergration/loveManager.lua b/examples/love2d Threading Example/multi/intergration/loveManager.lua index 9fa3986..e8304d9 100644 --- a/examples/love2d Threading Example/multi/intergration/loveManager.lua +++ b/examples/love2d Threading Example/multi/intergration/loveManager.lua @@ -1,3 +1,4 @@ +require("multi.compat.love2d") multi.intergration={} multi.intergration.love2d={} multi.intergration.love2d.ThreadBase=[[ @@ -326,6 +327,7 @@ updater:OnUpdate(function(self) data=multi.intergration.love2d.mainChannel:pop() end end) +print("Intergrated Love2d!") return { init=function(t) if t then diff --git a/multi/init.lua b/multi/init.lua index b498f87..66d82ba 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -45,7 +45,7 @@ function print(...) end end multi = {} -multi.Version={1,7,5} +multi.Version={1,7,6} multi.stage='stable' multi.__index = multi multi.Mainloop={} @@ -239,6 +239,15 @@ end function multi:getVersion() return multi.Version[1].."."..multi.Version[2].."."..multi.Version[3] end +function multi:getPlatform() + if love then + if love.thread then + return "love2d" + end + else + return "lanes" + end +end --Processor function multi:getError() if self.error then @@ -1020,6 +1029,9 @@ function multi:newEvent(task) end end end + function c:SetTask(func) + self.Task=func + end function c:OnEvent(func) table.insert(self.func,func) end diff --git a/multi/intergration/loveManager.lua b/multi/intergration/loveManager.lua index 9fa3986..e8304d9 100644 --- a/multi/intergration/loveManager.lua +++ b/multi/intergration/loveManager.lua @@ -1,3 +1,4 @@ +require("multi.compat.love2d") multi.intergration={} multi.intergration.love2d={} multi.intergration.love2d.ThreadBase=[[ @@ -326,6 +327,7 @@ updater:OnUpdate(function(self) data=multi.intergration.love2d.mainChannel:pop() end end) +print("Intergrated Love2d!") return { init=function(t) if t then