Version 15.0.0
This commit is contained in:
parent
d2ce7e070b
commit
ed924a3d9d
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
test2.lua
|
test2.lua
|
||||||
*.mp3
|
*.mp3
|
||||||
*.exe
|
*.exe
|
||||||
|
*.dll
|
||||||
lanestestclient.lua
|
lanestestclient.lua
|
||||||
lanestest.lua
|
lanestest.lua
|
||||||
sample-node.lua
|
sample-node.lua
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
Current Multi Version: 14.2.0
|
Current Multi Version: 15.0.0
|
||||||
|
|
||||||
# Multi static variables
|
# Multi static variables
|
||||||
`multi.Version` — The current version of the library
|
`multi.Version` — The current version of the library
|
||||||
@ -153,7 +153,7 @@ The connect feature has some syntax sugar to it as seen below
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
-- Let’s create the events
|
-- Let’s create the events
|
||||||
yawn={}
|
yawn={}
|
||||||
OnCustomSafeEvent=multi:newConnection(true) -- lets pcall the calls in case something goes wrong default
|
OnCustomSafeEvent=multi:newConnection(true) -- lets pcall the calls in case something goes wrong default
|
||||||
@ -201,7 +201,7 @@ Timeouts are a collection of methods that allow you to handle timeouts. These on
|
|||||||
|
|
||||||
```lua
|
```lua
|
||||||
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
||||||
multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
|
|
||||||
loop = multi:newLoop(function()
|
loop = multi:newLoop(function()
|
||||||
-- do stuff
|
-- do stuff
|
||||||
@ -224,7 +224,7 @@ loop:OnTimerResolved(function(self,...)
|
|||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
As mentioned above this is made much easier using threads
|
As mentioned above this is made much easier using threads
|
||||||
```lua
|
```lua
|
||||||
@ -255,14 +255,14 @@ print(func(0))
|
|||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
||||||
multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
multi:scheduleJob({min = 30},function() -- Every hour at minute 30 this event will be triggered! You can mix and match as well!
|
multi:scheduleJob({min = 30},function() -- Every hour at minute 30 this event will be triggered! You can mix and match as well!
|
||||||
print("Hi")
|
print("Hi")
|
||||||
end)
|
end)
|
||||||
multi:scheduleJob({min = 30,hour = 0},function() -- Every day at 12:30AM this event will be triggered
|
multi:scheduleJob({min = 30,hour = 0},function() -- Every day at 12:30AM this event will be triggered
|
||||||
print("Hi")
|
print("Hi")
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Universal Actor methods
|
# Universal Actor methods
|
||||||
@ -287,7 +287,7 @@ All of these functions are found on actors
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
count=0
|
count=0
|
||||||
-- A loop object is used to demostrate how one could use an event object.
|
-- A loop object is used to demostrate how one could use an event object.
|
||||||
loop=multi:newLoop(function(self,dt)
|
loop=multi:newLoop(function(self,dt)
|
||||||
@ -298,7 +298,7 @@ event:OnEvent(function(self) -- connect to the event object
|
|||||||
loop:Destroy() -- destroys the loop from running!
|
loop:Destroy() -- destroys the loop from running!
|
||||||
print("Stopped that loop!",count)
|
print("Stopped that loop!",count)
|
||||||
end) -- events like alarms need to be reset the Reset() command works here as well
|
end) -- events like alarms need to be reset the Reset() command works here as well
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Actor: Updaters
|
# Actor: Updaters
|
||||||
@ -311,12 +311,12 @@ Updaters are a mix between both loops and steps. They were a way to add basic pr
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
updater=multi:newUpdater(5000) -- simple, think of a loop with the skip feature of a step
|
updater=multi:newUpdater(5000) -- simple, think of a loop with the skip feature of a step
|
||||||
updater:OnUpdate(function(self)
|
updater:OnUpdate(function(self)
|
||||||
print("updating...")
|
print("updating...")
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Actor: Alarms
|
# Actor: Alarms
|
||||||
@ -328,13 +328,13 @@ Alarms ring after a certain amount of time, but you need to reset the alarm ever
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
alarm=multi:newAlarm(3) -- in seconds can go to .001 uses the built in os.clock()
|
alarm=multi:newAlarm(3) -- in seconds can go to .001 uses the built in os.clock()
|
||||||
alarm:OnRing(function(a)
|
alarm:OnRing(function(a)
|
||||||
print("3 Seconds have passed!")
|
print("3 Seconds have passed!")
|
||||||
a:Reset(n) -- if n were nil it will reset back to 3, or it would reset to n seconds
|
a:Reset(n) -- if n were nil it will reset back to 3, or it would reset to n seconds
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Actor: Loops
|
# Actor: Loops
|
||||||
@ -346,7 +346,7 @@ Loops are events that happen over and over until paused. They act like a while l
|
|||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
package.path="?/init.lua;?.lua;"..package.path
|
package.path="?/init.lua;?.lua;"..package.path
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
local a = 0
|
local a = 0
|
||||||
loop = multi:newLoop(function()
|
loop = multi:newLoop(function()
|
||||||
a = a + 1
|
a = a + 1
|
||||||
@ -355,7 +355,7 @@ loop = multi:newLoop(function()
|
|||||||
loop:Pause()
|
loop:Pause()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Actor: TLoops
|
# Actor: TLoops
|
||||||
@ -366,7 +366,7 @@ multi:lightloop()
|
|||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
package.path="?/init.lua;?.lua;"..package.path
|
package.path="?/init.lua;?.lua;"..package.path
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
local a = 0
|
local a = 0
|
||||||
loop = multi:newTLoop(function()
|
loop = multi:newTLoop(function()
|
||||||
a = a + 1
|
a = a + 1
|
||||||
@ -375,7 +375,7 @@ loop = multi:newTLoop(function()
|
|||||||
loop:Pause()
|
loop:Pause()
|
||||||
end
|
end
|
||||||
end,1)
|
end,1)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Actor: Steps
|
# Actor: Steps
|
||||||
@ -390,13 +390,13 @@ multi:lightloop()
|
|||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
package.path="?/init.lua;?.lua;"..package.path
|
package.path="?/init.lua;?.lua;"..package.path
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
multi:newStep(1,10,1,0):OnStep(function(step,pos)
|
multi:newStep(1,10,1,0):OnStep(function(step,pos)
|
||||||
print(step,pos)
|
print(step,pos)
|
||||||
end):OnEnd(fucntion(step)
|
end):OnEnd(fucntion(step)
|
||||||
step:Destroy()
|
step:Destroy()
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Actor: TSteps
|
# Actor: TSteps
|
||||||
@ -411,13 +411,13 @@ multi:lightloop()
|
|||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
package.path="?/init.lua;?.lua;"..package.path
|
package.path="?/init.lua;?.lua;"..package.path
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
multi:newTStep(1,10,1,1):OnStep(function(step,pos)
|
multi:newTStep(1,10,1,1):OnStep(function(step,pos)
|
||||||
print(step,pos)
|
print(step,pos)
|
||||||
end):OnEnd(fucntion(step)
|
end):OnEnd(fucntion(step)
|
||||||
step:Destroy()
|
step:Destroy()
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# Coroutine based Threading (CBT)
|
# Coroutine based Threading (CBT)
|
||||||
@ -474,7 +474,7 @@ Example:
|
|||||||
-- Jobs are not natively part of the multi library. I planned on adding them, but decided against it. Below is the code that would have been used.
|
-- Jobs are not natively part of the multi library. I planned on adding them, but decided against it. Below is the code that would have been used.
|
||||||
-- Implementing a job manager using services
|
-- Implementing a job manager using services
|
||||||
package.path="?/init.lua;?.lua;"..package.path
|
package.path="?/init.lua;?.lua;"..package.path
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
multi.Jobs = multi:newService(function(self,jobs)
|
multi.Jobs = multi:newService(function(self,jobs)
|
||||||
local job = table.remove(jobs,1)
|
local job = table.remove(jobs,1)
|
||||||
if job and job.removed==nil then
|
if job and job.removed==nil then
|
||||||
@ -532,6 +532,7 @@ jobsn[1]:removeJob() -- Select a job and remove it
|
|||||||
multi.Jobs:removeJobs("test2") -- Remove all jobs names 'test2'
|
multi.Jobs:removeJobs("test2") -- Remove all jobs names 'test2'
|
||||||
multi.Jobs.SetScheme(1) -- Jobs are internally a service, so setting scheme and priority
|
multi.Jobs.SetScheme(1) -- Jobs are internally a service, so setting scheme and priority
|
||||||
multi.Jobs.SetPriority(multi.Priority_Core)
|
multi.Jobs.SetPriority(multi.Priority_Core)
|
||||||
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# CBT: newThread()
|
# CBT: newThread()
|
||||||
@ -556,21 +557,21 @@ Constants
|
|||||||
Examples:
|
Examples:
|
||||||
```lua
|
```lua
|
||||||
package.path="?/init.lua;?.lua;"..package.path
|
package.path="?/init.lua;?.lua;"..package.path
|
||||||
local multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
multi:newThread("Example of basic usage",function()
|
multi:newThread("Example of basic usage",function()
|
||||||
while true do
|
while true do
|
||||||
thread.sleep(1)
|
thread.sleep(1)
|
||||||
print("We just made an alarm!")
|
print("We just made an alarm!")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# System Threads (ST) - Multi-Integration Getting Started
|
# System Threads (ST) - Multi-Integration Getting Started
|
||||||
The system threads need to be required seperatly.
|
The system threads need to be required seperatly.
|
||||||
```lua
|
```lua
|
||||||
-- I recommend keeping these as globals. When using lanes you can use local and things will work, but if you use love2d and locals, upvalues are not transfered over threads and this can be an issue
|
-- I recommend keeping these as globals. When using lanes you can use local and things will work, but if you use love2d and locals, upvalues are not transfered over threads and this can be an issue
|
||||||
GLOBAL, THREAD = require("multi.integration.lanesManager"):init() -- We will talk about the global and thread interface that is returned
|
GLOBAL, THREAD = require("multi.integration.threading"):init() -- We will talk about the global and thread interface that is returned
|
||||||
GLOBAL, THREAD = require("multi.integration.loveManager"):init()
|
GLOBAL, THREAD = require("multi.integration.loveManager"):init()
|
||||||
GLOBAL, THREAD = require("luvitManager") --*
|
GLOBAL, THREAD = require("luvitManager") --*
|
||||||
```
|
```
|
||||||
@ -609,8 +610,8 @@ ST - System Threads
|
|||||||
System Threads are the feature that allows a user to interact with systen threads. It differs from regular coroutine based thread in how it can interact with variables. When using system threads the GLOBAL table is the "only way"* to send data. Spawning a System thread is really simple once all the required libraries are in place. See example below:
|
System Threads are the feature that allows a user to interact with systen threads. It differs from regular coroutine based thread in how it can interact with variables. When using system threads the GLOBAL table is the "only way"* to send data. Spawning a System thread is really simple once all the required libraries are in place. See example below:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local multi = require("multi") -- keep this global when using lanes or implicitly define multi within the spawned thread
|
multi,thread = require("multi"):init() -- keep this global when using lanes or implicitly define multi within the spawned thread
|
||||||
local GLOBAL, THREAD = require("multi.integration.lanesManager").init()
|
local GLOBAL, THREAD = require("multi.integration.threading").init()
|
||||||
multi:newSystemThread("Example thread",function()
|
multi:newSystemThread("Example thread",function()
|
||||||
local multi = require("multi") -- we are in a thread so lets not refer to that upvalue!
|
local multi = require("multi") -- we are in a thread so lets not refer to that upvalue!
|
||||||
print("We have spawned a thread!")
|
print("We have spawned a thread!")
|
||||||
@ -624,7 +625,7 @@ end,"A message that we are passing") -- There are restrictions on what can be pa
|
|||||||
tloop = multi:newTLoop(function()
|
tloop = multi:newTLoop(function()
|
||||||
print("I'm still kicking!")
|
print("I'm still kicking!")
|
||||||
end,1)
|
end,1)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>*</b>This isn't entirely true, as of right now the compatiablity with the lanes library and love2d engine have their own methods to share data, but if you would like to have your code work in both enviroments then using the GLOBAL table and the data structures provided by the multi library will ensure this happens. If you do not plan on having support for both platforms then feel free to use linda's in lanes and channels in love2d.
|
<b>*</b>This isn't entirely true, as of right now the compatiablity with the lanes library and love2d engine have their own methods to share data, but if you would like to have your code work in both enviroments then using the GLOBAL table and the data structures provided by the multi library will ensure this happens. If you do not plan on having support for both platforms then feel free to use linda's in lanes and channels in love2d.
|
||||||
@ -638,8 +639,8 @@ When creating objects with a name they are automatically exposed to the GLOBAL t
|
|||||||
|
|
||||||
```lua
|
```lua
|
||||||
-- Exposing a queue
|
-- Exposing a queue
|
||||||
multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
local GLOBAL, THREAD = require("multi.integration.lanesManager").init() -- The standard setup above
|
local GLOBAL, THREAD = require("multi.integration.threading").init() -- The standard setup above
|
||||||
queue = multi:newSystemThreadedQueue("myQueue"):init() -- We create and initiate the queue for the main thread
|
queue = multi:newSystemThreadedQueue("myQueue"):init() -- We create and initiate the queue for the main thread
|
||||||
queue:push("This is a test!") -- We push some data onto the queue that other threads can consume and do stuff with
|
queue:push("This is a test!") -- We push some data onto the queue that other threads can consume and do stuff with
|
||||||
multi:newSystemThread("Example thread",function() -- Create a system thread
|
multi:newSystemThread("Example thread",function() -- Create a system thread
|
||||||
@ -647,7 +648,7 @@ multi:newSystemThread("Example thread",function() -- Create a system thread
|
|||||||
local data = queue:pop() -- Get the data
|
local data = queue:pop() -- Get the data
|
||||||
print(data) -- print the data
|
print(data) -- print the data
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
# ST - SystemThreadedQueue
|
# ST - SystemThreadedQueue
|
||||||
@ -659,9 +660,9 @@ multi:lightloop()
|
|||||||
|
|
||||||
Let's get into some examples:
|
Let's get into some examples:
|
||||||
```lua
|
```lua
|
||||||
multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
thread_names = {"Thread_A","Thread_B","Thread_C","Thread_D"}
|
thread_names = {"Thread_A","Thread_B","Thread_C","Thread_D"}
|
||||||
local GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
|
local GLOBAL, THREAD = require("multi.integration.threading"):init()
|
||||||
queue = multi:newSystemThreadedQueue("myQueue"):init()
|
queue = multi:newSystemThreadedQueue("myQueue"):init()
|
||||||
for _,n in pairs(thread_names) do
|
for _,n in pairs(thread_names) do
|
||||||
multi:newSystemThread(n,function()
|
multi:newSystemThread(n,function()
|
||||||
@ -683,11 +684,13 @@ end):OnEvent(function()
|
|||||||
print("No more data within the queue!")
|
print("No more data within the queue!")
|
||||||
os.exit()
|
os.exit()
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
|
||||||
You have probable noticed that the output from this is a total mess! Well I though so too, and created the system threaded console!
|
You have probable noticed that the output from this is a total mess! Well I though so too, and created the system threaded console!
|
||||||
|
|
||||||
|
# ST - Using the Console
|
||||||
|
|
||||||
# ST - SystemThreadedJobQueue
|
# ST - SystemThreadedJobQueue
|
||||||
`jq = multi:newSystemThreadedJobQueue([NUMBER: threads])` — Creates a system threaded job queue with an optional number of threads
|
`jq = multi:newSystemThreadedJobQueue([NUMBER: threads])` — Creates a system threaded job queue with an optional number of threads
|
||||||
- `jq.cores = (supplied number) or (the number of cores on your system*2)`
|
- `jq.cores = (supplied number) or (the number of cores on your system*2)`
|
||||||
@ -703,8 +706,8 @@ You have probable noticed that the output from this is a total mess! Well I thou
|
|||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
||||||
multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
|
GLOBAL, THREAD = require("multi.integration.threading"):init()
|
||||||
local jq = multi:newSystemThreadedJobQueue(4) -- job queue using 4 cores
|
local jq = multi:newSystemThreadedJobQueue(4) -- job queue using 4 cores
|
||||||
jq:doToAll(function()
|
jq:doToAll(function()
|
||||||
Important = 15
|
Important = 15
|
||||||
@ -727,7 +730,7 @@ func(5,5).connect(function(ret)
|
|||||||
print("Connected",ret)
|
print("Connected",ret)
|
||||||
os.exit()
|
os.exit()
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
# ST - SystemThreadedTable
|
# ST - SystemThreadedTable
|
||||||
`stt = multi:newSystemThreadedTable(STRING: name)`
|
`stt = multi:newSystemThreadedTable(STRING: name)`
|
||||||
@ -738,15 +741,15 @@ multi:lightloop()
|
|||||||
Example:
|
Example:
|
||||||
```lua
|
```lua
|
||||||
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
||||||
multi = require("multi")
|
multi,thread = require("multi"):init()
|
||||||
GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
|
GLOBAL, THREAD = require("multi.integration.threading"):init()
|
||||||
local stt = multi:newSystemThreadedTable("stt")
|
local stt = multi:newSystemThreadedTable("stt")
|
||||||
stt["hello"] = "world"
|
stt["hello"] = "world"
|
||||||
multi:newSystemThread("test thread",function()
|
multi:newSystemThread("test thread",function()
|
||||||
local stt = GLOBAL["stt"]:init()
|
local stt = GLOBAL["stt"]:init()
|
||||||
print(stt["hello"])
|
print(stt["hello"])
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
# Network Threads - Multi-Integration WIP Being Reworked
|
# Network Threads - Multi-Integration WIP Being Reworked
|
||||||
More of a fun project of mine then anything core to to the library it will be released and documented when it is ready. I do not have a timeframe for this
|
More of a fun project of mine then anything core to to the library it will be released and documented when it is ready. I do not have a timeframe for this
|
||||||
|
|||||||
23
README.md
23
README.md
@ -1,6 +1,7 @@
|
|||||||
# Multi Version: 15.0.0 Fake it, until you make it
|
# Multi Version: 15.0.0 Fake it till you make it
|
||||||
**Key Changes**
|
**Key Changes**
|
||||||
- Emulating system threading on a single thread
|
- Emulating system threading on a single thread
|
||||||
|
- Purpose to allow consistant code that can scale when threading is available. Check out the changelog for more details
|
||||||
|
|
||||||
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and I'll look into it!
|
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and I'll look into it!
|
||||||
|
|
||||||
@ -26,20 +27,28 @@ https://discord.gg/U8UspuA</br>
|
|||||||
Planned features/TODO
|
Planned features/TODO
|
||||||
---------------------
|
---------------------
|
||||||
- [x] ~~Finish Documentation~~ Finished
|
- [x] ~~Finish Documentation~~ Finished
|
||||||
|
- [ ] Create test suite
|
||||||
- [ ] Network Parallelism rework
|
- [ ] Network Parallelism rework
|
||||||
|
|
||||||
Usage: [Check out the documentation for more info](https://github.com/rayaman/multi/blob/master/Documentation.md)</br>
|
Usage: [Check out the documentation for more info](https://github.com/rayaman/multi/blob/master/Documentation.md)</br>
|
||||||
-----
|
-----
|
||||||
```lua
|
```lua
|
||||||
local multi, thread = require("multi").init()
|
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
||||||
mutli:newThread("Example",function()
|
local multi, thread = require("multi"):init()
|
||||||
|
GLOBAL, THREAD = require("multi.integration.threading"):init()
|
||||||
|
multi:newSystemThread("System Thread",function()
|
||||||
while true do
|
while true do
|
||||||
thread.sleep(1)
|
THREAD.sleep(1)
|
||||||
print("Hello!")
|
print("World!")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
multi:lightloop()
|
multi:newThread("Coroutine Based Thread",function()
|
||||||
--multi:mainloop()
|
while true do
|
||||||
|
print("Hello")
|
||||||
|
thread.sleep(1)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
multi:mainloop()
|
||||||
--[[
|
--[[
|
||||||
while true do
|
while true do
|
||||||
multi:uManager()
|
multi:uManager()
|
||||||
|
|||||||
58
changes.md
58
changes.md
@ -12,65 +12,67 @@ package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
|||||||
multi,thread = require("multi"):init()
|
multi,thread = require("multi"):init()
|
||||||
GLOBAL,THREAD = require("multi.integration.threading"):init() -- Auto detects your enviroment and uses what's available
|
GLOBAL,THREAD = require("multi.integration.threading"):init() -- Auto detects your enviroment and uses what's available
|
||||||
|
|
||||||
jq = multi:newSystemThreadedJobQueue(100) -- Job queue with 4 worker threads
|
jq = multi:newSystemThreadedJobQueue(4) -- Job queue with 4 worker threads
|
||||||
func = jq:newFunction("test",function(a,b)
|
func = jq:newFunction("test",function(a,b)
|
||||||
THREAD.sleep(2)
|
THREAD.sleep(2)
|
||||||
return a+b
|
return a+b
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for i = 1,100 do
|
for i = 1,10 do
|
||||||
func(i,i*3).connect(function(data)
|
func(i,i*3).connect(function(data)
|
||||||
print(data)
|
print(data)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
test = true
|
|
||||||
local haha = true
|
|
||||||
multi:newThread("Standard Thread 1",function()
|
multi:newThread("Standard Thread 1",function()
|
||||||
print(self.Name,haha)
|
|
||||||
while true do
|
while true do
|
||||||
thread.sleep(1)
|
thread.sleep(1)
|
||||||
print("Testing "..self.Name..":",test)
|
print("Testing 1 ...")
|
||||||
thread.sleep(.1)
|
|
||||||
prient("...")
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
multi:newThread("Standard Thread 2",function()
|
|
||||||
print(self.Name)
|
|
||||||
while true do
|
|
||||||
thread.sleep(1)
|
|
||||||
print("Testing "..self.Name..":",test)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
multi:newISOThread("Isolated Thread",function()
|
|
||||||
while true do
|
|
||||||
thread.sleep(1)
|
|
||||||
print("Testing Isolated:",test)
|
|
||||||
--errhor("huh")
|
|
||||||
end
|
|
||||||
end).OnError(function(...)
|
|
||||||
print(...)
|
|
||||||
end)
|
|
||||||
|
|
||||||
multi:lightloop()
|
multi:newISOThread("ISO Thread 2",{test=true},function()
|
||||||
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
print("Testing 2 ...")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
multi:mainloop()
|
||||||
```
|
```
|
||||||
|
Note:
|
||||||
|
---
|
||||||
|
This was supposed to be released over a year ago, but work and other things got in my way. Pesudo Threading now works. The goal of this is so you can write modules that can be scaled up to utlize threading features when available.
|
||||||
Added:
|
Added:
|
||||||
---
|
---
|
||||||
- multi:newISOThread(name,func)
|
- multi:newISOThread(name,func,env)
|
||||||
- Creates an isolated thread that prevents both locals and globals from being accessed.
|
- Creates an isolated thread that prevents both locals and globals from being accessed.
|
||||||
|
- Was designed for the pesudoManager so it can emulate threads. You can use it as a super sandbox, but remember upvalues are also stripped which was intened for what I wanted them to do!
|
||||||
- Added new integration: pesudoManager, functions just like lanesManager and loveManager, but it's actually single threaded
|
- Added new integration: pesudoManager, functions just like lanesManager and loveManager, but it's actually single threaded
|
||||||
- This was implemented because, you may want to build your code around being multi threaded, but some systems/implemetations of lua may not permit this. Since we now have a "single threaded" implementation of multi threading. We can actually create scalable code where things automatcally are threaded if built correctly. I am planning on adding more threadedOjbects.
|
- This was implemented because, you may want to build your code around being multi threaded, but some systems/implemetations of lua may not permit this. Since we now have a "single threaded" implementation of multi threading. We can actually create scalable code where things automatcally are threaded if built correctly. I am planning on adding more threadedOjbects.
|
||||||
- In addition to adding pesudo Threading `multi.integration.threading` can now be used to autodetect which enviroment you are on and use the threading features.
|
- In addition to adding pesudo Threading `multi.integration.threading` can now be used to autodetect which enviroment you are on and use the threading features.
|
||||||
```
|
```
|
||||||
GLOBAL,THREAD = require("multi.integration.threading"):init()
|
GLOBAL,THREAD = require("multi.integration.threading"):init()
|
||||||
```
|
```
|
||||||
If you are using love2d it will use that, if you have lanes avaialble then it will use lanes. Otherwise it will use pesudo threading. This allows module creators to implement scalable features without having to worry about which enviroment they are in.
|
If you are using love2d it will use that, if you have lanes avaialble then it will use lanes. Otherwise it will use pesudo threading. This allows module creators to implement scalable features without having to worry about which enviroment they are in. Can now require a consistant module: `require("multi.integration.threading"):init()`
|
||||||
|
|
||||||
|
Changed:
|
||||||
|
---
|
||||||
|
- Documentation to reflect the changes made
|
||||||
|
|
||||||
|
Removed:
|
||||||
|
---
|
||||||
|
- CBT (Coroutine Based threading) has lost a feature, one that hasn't been used much, but broke compatiblity with anything above lua 5.1. My goal is to make my library work with all versions of lua above 5.1, including 5.4. Lua 5.2+ changed how enviroments worked which means that you can no longer modify an enviroment of function without using the debug library. This isn't ideal for how things in my library worked, but it is what it is. The feature lost is the one that converted all functions within a threaded enviroment into a threadedfunction. This in hindsight wasn't the best pratice and if it is the desired state you as the user can manually do that anyway. This shouldn't affect anyones code in a massive way.
|
||||||
|
|
||||||
Fixed:
|
Fixed:
|
||||||
---
|
---
|
||||||
- pseudoThreading and threads had an issue where they weren't executing properly
|
- pseudoThreading and threads had an issue where they weren't executing properly
|
||||||
- lanesManager THREAD:get(STRING: name) not returning the value
|
- lanesManager THREAD:get(STRING: name) not returning the value
|
||||||
|
|
||||||
|
Todo:
|
||||||
|
---
|
||||||
|
- Add more details to the documentation
|
||||||
|
|
||||||
# Update 14.2.0 - Bloatware Removed
|
# Update 14.2.0 - Bloatware Removed
|
||||||
Full Update Showcase
|
Full Update Showcase
|
||||||
---
|
---
|
||||||
@ -131,7 +133,7 @@ Quality Of Life:
|
|||||||
Added:
|
Added:
|
||||||
---
|
---
|
||||||
- Type: destroyed
|
- Type: destroyed
|
||||||
- A special state of an object that causes that object to become immutable and callable. The object Type is always "destroyed" it cannot be changed. The object can be indexed to infinity without issue. Every part of the object can be called as if it were a function including the indexed parts. This is done incase you destroy an object and still use it somewhere. However, if you are expecting something from the object then you may still encounter an error, though the returned type is an instance of the destroyed object which can be indexed and called like normal. This object can be used in any way and no errors will come about with it.
|
- A special state of an object that causes that object to become immutable and callable. The object Type is always "destroyed" it cannot be changed. The object can be indexed to infinity without issue. Every part of the object can be called as if it were a function including the indexed parts. This is done incase you destroy an object and still "use" it somewhere. However, if you are expecting something from the object then you may still encounter an error, though the returned type is an instance of the destroyed object which can be indexed and called like normal. This object can be used in any way and no errors will come about with it.
|
||||||
|
|
||||||
Fixed:
|
Fixed:
|
||||||
---
|
---
|
||||||
|
|||||||
156
multi/init.lua
156
multi/init.lua
@ -163,6 +163,20 @@ function multi:getTasksDetails(t)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--Helpers
|
--Helpers
|
||||||
|
|
||||||
|
-- Used with ISO Threads
|
||||||
|
local function isolateFunction(func,env)
|
||||||
|
local dmp = string.dump(func)
|
||||||
|
local env = env or {}
|
||||||
|
if setfenv then
|
||||||
|
local f = loadstring(dmp,"IsolatedThread_PesudoThreading")
|
||||||
|
setfenv(f,env)
|
||||||
|
return f
|
||||||
|
else
|
||||||
|
return load(dmp,"IsolatedThread_PesudoThreading","bt",env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function multi:Break()
|
function multi:Break()
|
||||||
self:Pause()
|
self:Pause()
|
||||||
self.Active=nil
|
self.Active=nil
|
||||||
@ -963,7 +977,12 @@ function thread.yield()
|
|||||||
return thread.sleep(0)
|
return thread.sleep(0)
|
||||||
end
|
end
|
||||||
function thread.isThread()
|
function thread.isThread()
|
||||||
|
if _VERSION~="Lua 5.1" then
|
||||||
|
local a,b = coroutine.running()
|
||||||
|
return not(b)
|
||||||
|
else
|
||||||
return coroutine.running()~=nil
|
return coroutine.running()~=nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
function thread.getCores()
|
function thread.getCores()
|
||||||
return thread.__CORES
|
return thread.__CORES
|
||||||
@ -1087,17 +1106,6 @@ function multi:newThread(name,func,...)
|
|||||||
end
|
end
|
||||||
local c={}
|
local c={}
|
||||||
local env = {self=c}
|
local env = {self=c}
|
||||||
setmetatable(env,{
|
|
||||||
__index = Gref,
|
|
||||||
__newindex = function(t,k,v)
|
|
||||||
if type(v)=="function" then
|
|
||||||
rawset(t,k,thread:newFunction(v))
|
|
||||||
else
|
|
||||||
Gref[k]=v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
setfenv(func,env)
|
|
||||||
c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
||||||
c.startArgs = {...}
|
c.startArgs = {...}
|
||||||
c.ref={}
|
c.ref={}
|
||||||
@ -1110,6 +1118,7 @@ function multi:newThread(name,func,...)
|
|||||||
c.timer=multi:newTimer()
|
c.timer=multi:newTimer()
|
||||||
c._isPaused = false
|
c._isPaused = false
|
||||||
c.returns = {}
|
c.returns = {}
|
||||||
|
c.isError = false
|
||||||
c.OnError = multi:newConnection(true,nil,true)
|
c.OnError = multi:newConnection(true,nil,true)
|
||||||
c.OnDeath = multi:newConnection(true,nil,true)
|
c.OnDeath = multi:newConnection(true,nil,true)
|
||||||
function c:isPaused()
|
function c:isPaused()
|
||||||
@ -1173,126 +1182,21 @@ function multi:newThread(name,func,...)
|
|||||||
self:create(c)
|
self:create(c)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
function multi:newISOThread(name,func,...)
|
function multi:newISOThread(name,func,_env,...)
|
||||||
multi.OnLoad:Fire()
|
multi.OnLoad:Fire()
|
||||||
local func = func or name
|
local func = func or name
|
||||||
|
local env = _env or {}
|
||||||
|
if not env.thread then
|
||||||
|
env.thread = thread
|
||||||
|
end
|
||||||
|
if not env.multi then
|
||||||
|
env.multi = multi
|
||||||
|
end
|
||||||
if type(name) == "function" then
|
if type(name) == "function" then
|
||||||
name = "Thread#"..threadCount
|
name = "Thread#"..threadCount
|
||||||
end
|
end
|
||||||
local Gref = {}
|
local func = isolateFunction(func,env)
|
||||||
local env = {
|
return self:newThread(name,func)
|
||||||
THREAD_NAME = name,
|
|
||||||
thread = thread,
|
|
||||||
multi = multi,
|
|
||||||
coroutine = coroutine,
|
|
||||||
debug = debug,
|
|
||||||
io = io,
|
|
||||||
math = math,
|
|
||||||
os = os,
|
|
||||||
package = package,
|
|
||||||
string = string,
|
|
||||||
table = table,
|
|
||||||
utf8 = utf8
|
|
||||||
}
|
|
||||||
for i,v in pairs(_G) do
|
|
||||||
if tostring(v):match("builtin") then
|
|
||||||
env[i]=v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local c={}
|
|
||||||
function c:inject(tab)
|
|
||||||
for i,v in pairs(tab) do
|
|
||||||
Gref[i] = v
|
|
||||||
env[i] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function c:start()
|
|
||||||
setmetatable(env,{
|
|
||||||
__index = Gref,
|
|
||||||
__newindex = function(t,k,v)
|
|
||||||
if type(v)=="function" then
|
|
||||||
rawset(t,k,thread:newFunction(v))
|
|
||||||
else
|
|
||||||
Gref[k]=v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
self.thread=coroutine.create(multi.setEnv(func,env))
|
|
||||||
end
|
|
||||||
env.self = c
|
|
||||||
c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
|
|
||||||
c.startArgs = {...}
|
|
||||||
c.ref={}
|
|
||||||
c.Name=name
|
|
||||||
c.sleep=1
|
|
||||||
c.Type="thread"
|
|
||||||
c.TID = threadid
|
|
||||||
c.firstRunDone=false
|
|
||||||
c.timer=multi:newTimer()
|
|
||||||
c._isPaused = false
|
|
||||||
c.returns = {}
|
|
||||||
c.OnError = multi:newConnection(true,nil,true)
|
|
||||||
c.OnDeath = multi:newConnection(true,nil,true)
|
|
||||||
function c:isPaused()
|
|
||||||
return self._isPaused
|
|
||||||
end
|
|
||||||
local resumed = false
|
|
||||||
function c:Pause()
|
|
||||||
if not self._isPaused then
|
|
||||||
thread.request(self,"exec",function()
|
|
||||||
thread.hold(function()
|
|
||||||
return resumed
|
|
||||||
end)
|
|
||||||
resumed = false
|
|
||||||
self._isPaused = false
|
|
||||||
end)
|
|
||||||
self._isPaused = true
|
|
||||||
end
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
function c:Resume()
|
|
||||||
resumed = true
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
function c:Kill()
|
|
||||||
thread.request(self,"kill")
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
c.Destroy = c.Kill
|
|
||||||
function c.ref:send(name,val)
|
|
||||||
ret=coroutine.yield({Name=name,Value=val})
|
|
||||||
end
|
|
||||||
function c.ref:get(name)
|
|
||||||
return self.Globals[name]
|
|
||||||
end
|
|
||||||
function c.ref:kill()
|
|
||||||
dRef[1] = "_kill_"
|
|
||||||
dRef[2] = "I Was killed by You!"
|
|
||||||
err = coroutine.yield(dRef)
|
|
||||||
if err then
|
|
||||||
error("Failed to kill a thread! Exiting...")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function c.ref:sleep(n)
|
|
||||||
if type(n)=="function" then
|
|
||||||
ret=thread.hold(n)
|
|
||||||
elseif type(n)=="number" then
|
|
||||||
ret=thread.sleep(tonumber(n) or 0)
|
|
||||||
else
|
|
||||||
error("Invalid Type for sleep!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function c.ref:syncGlobals(v)
|
|
||||||
self.Globals=v
|
|
||||||
end
|
|
||||||
table.insert(threads,c)
|
|
||||||
if initT==false then
|
|
||||||
multi.initThreads()
|
|
||||||
end
|
|
||||||
c.creationTime = os.clock()
|
|
||||||
threadid = threadid + 1
|
|
||||||
self:create(c)
|
|
||||||
return c
|
|
||||||
end
|
end
|
||||||
function multi.initThreads(justThreads)
|
function multi.initThreads(justThreads)
|
||||||
initT = true
|
initT = true
|
||||||
|
|||||||
@ -23,6 +23,16 @@ SOFTWARE.
|
|||||||
]]
|
]]
|
||||||
local multi, thread = require("multi"):init()
|
local multi, thread = require("multi"):init()
|
||||||
local GLOBAL, THREAD = multi.integration.GLOBAL,multi.integration.THREAD
|
local GLOBAL, THREAD = multi.integration.GLOBAL,multi.integration.THREAD
|
||||||
|
|
||||||
|
local function stripUpValues(func)
|
||||||
|
local dmp = string.dump(func)
|
||||||
|
if setfenv then
|
||||||
|
return loadstring(dmp,"IsolatedThread_PesudoThreading")
|
||||||
|
else
|
||||||
|
return load(dmp,"IsolatedThread_PesudoThreading","bt")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function multi:newSystemThreadedQueue(name)
|
function multi:newSystemThreadedQueue(name)
|
||||||
local c = {}
|
local c = {}
|
||||||
function c:push(v)
|
function c:push(v)
|
||||||
@ -85,6 +95,7 @@ function multi:newSystemThreadedJobQueue(n)
|
|||||||
end
|
end
|
||||||
local nFunc = 0
|
local nFunc = 0
|
||||||
function c:newFunction(name,func,holup) -- This registers with the queue
|
function c:newFunction(name,func,holup) -- This registers with the queue
|
||||||
|
local func = stripUpValues(func)
|
||||||
if type(name)=="function" then
|
if type(name)=="function" then
|
||||||
holup = func
|
holup = func
|
||||||
func = name
|
func = name
|
||||||
|
|||||||
@ -41,18 +41,39 @@ end
|
|||||||
function multi:getPlatform()
|
function multi:getPlatform()
|
||||||
return "pesudo"
|
return "pesudo"
|
||||||
end
|
end
|
||||||
|
local function split(str)
|
||||||
|
local tab = {}
|
||||||
|
for word in string.gmatch(str, '([^,]+)') do
|
||||||
|
table.insert(tab,word)
|
||||||
|
end
|
||||||
|
return tab
|
||||||
|
end
|
||||||
THREAD.newFunction=thread.newFunction
|
THREAD.newFunction=thread.newFunction
|
||||||
local id = 0
|
local id = 0
|
||||||
function multi:newSystemThread(name,func,...)
|
function multi:newSystemThread(name,func,...)
|
||||||
local t = multi:newISOThread(name,func,...)
|
GLOBAL["$THREAD_NAME"] = name
|
||||||
t:inject{
|
GLOBAL["$__THREADNAME__"] = name
|
||||||
|
GLOBAL["$THREAD_ID"] = id
|
||||||
|
--GLOBAL["$thread"] = thread
|
||||||
|
local env = {
|
||||||
GLOBAL = GLOBAL,
|
GLOBAL = GLOBAL,
|
||||||
THREAD = THREAD,
|
THREAD = THREAD,
|
||||||
THREAD_ID = id
|
THREAD_NAME = name,
|
||||||
|
__THREADNAME__ = name,
|
||||||
|
THREAD_ID = id,
|
||||||
|
thread = thread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local tab = [[_VERSION,io,os,require,load,debug,assert,collectgarbage,error,getfenv,getmetatable,ipairs,loadstring,module,next,pairs,pcall,print,rawequal,rawget,rawset,select,setfenv,setmetatable,tonumber,tostring,type,unpack,xpcall,math,coroutine,string,table]]
|
||||||
|
tab = split(tab)
|
||||||
|
for i = 1,#tab do
|
||||||
|
env[tab[i]] = _G[tab[i]]
|
||||||
|
end
|
||||||
|
--setmetatable(env,{__index=env})
|
||||||
|
multi:newISOThread(name,func,env,...).OnError(function(self,msg)
|
||||||
|
print("ERROR:",msg)
|
||||||
|
end)
|
||||||
id = id + 1
|
id = id + 1
|
||||||
t:start()
|
|
||||||
end
|
end
|
||||||
-- System threads as implemented here cannot share memory, but use a message passing system.
|
-- System threads as implemented here cannot share memory, but use a message passing system.
|
||||||
-- An isolated thread allows us to mimic that behavior so if access data from the "main" thread happens things will not work. This behavior is in line with how the system threading works
|
-- An isolated thread allows us to mimic that behavior so if access data from the "main" thread happens things will not work. This behavior is in line with how the system threading works
|
||||||
|
|||||||
@ -28,7 +28,7 @@ local function getOS()
|
|||||||
return "unix"
|
return "unix"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function INIT()
|
local function INIT(env)
|
||||||
local THREAD = {}
|
local THREAD = {}
|
||||||
local GLOBAL = {}
|
local GLOBAL = {}
|
||||||
THREAD.Priority_Core = 3
|
THREAD.Priority_Core = 3
|
||||||
@ -45,6 +45,7 @@ local function INIT()
|
|||||||
return GLOBAL[name]
|
return GLOBAL[name]
|
||||||
end
|
end
|
||||||
function THREAD.waitFor(name)
|
function THREAD.waitFor(name)
|
||||||
|
print("Waiting",thread)
|
||||||
return thread.hold(function() return GLOBAL[name] end)
|
return thread.hold(function() return GLOBAL[name] end)
|
||||||
end
|
end
|
||||||
if getOS() == "windows" then
|
if getOS() == "windows" then
|
||||||
@ -61,7 +62,7 @@ local function INIT()
|
|||||||
print(...)
|
print(...)
|
||||||
end
|
end
|
||||||
function c.error(err)
|
function c.error(err)
|
||||||
error("ERROR in <"..__THREADNAME__..">: "..err)
|
error("ERROR in <"..GLOBAL["$__THREADNAME__"]..">: "..err)
|
||||||
end
|
end
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
@ -77,10 +78,10 @@ local function INIT()
|
|||||||
error("Thread was killed!")
|
error("Thread was killed!")
|
||||||
end
|
end
|
||||||
function THREAD.getName()
|
function THREAD.getName()
|
||||||
return THREAD_NAME
|
return GLOBAL["$THREAD_NAME"]
|
||||||
end
|
end
|
||||||
function THREAD.getID()
|
function THREAD.getID()
|
||||||
return THREAD_ID
|
return GLOBAL["$THREAD_ID"]
|
||||||
end
|
end
|
||||||
function THREAD.sleep(n)
|
function THREAD.sleep(n)
|
||||||
thread.sleep(n)
|
thread.sleep(n)
|
||||||
|
|||||||
51
test.lua
51
test.lua
@ -1,22 +1,41 @@
|
|||||||
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
|
||||||
multi,thread = require("multi"):init()
|
multi,thread = require("multi"):init()
|
||||||
GLOBAL,THREAD = require("multi.integration.pesudoManager"):init()
|
GLOBAL,THREAD = require("multi.integration.threading"):init() -- Auto detects your enviroment and uses what's available
|
||||||
test = true
|
|
||||||
local haha = true
|
jq = multi:newSystemThreadedJobQueue(5) -- Job queue with 4 worker threads
|
||||||
local test = multi:newSystemThreadedTable("test"):init()
|
func = jq:newFunction("test",function(a,b)
|
||||||
test['hi'] = "Hello World!!!"
|
THREAD.sleep(2)
|
||||||
test['bye'] = "Bye World!!!"
|
return a+b
|
||||||
multi:newSystemThread("test_1",function()
|
|
||||||
print(THREAD_NAME,THREAD_ID,THREAD.getName())
|
|
||||||
print("thread",GLOBAL,THREAD,test,haha)
|
|
||||||
tab = THREAD.waitFor("test"):init()
|
|
||||||
print(tab["hi"])
|
|
||||||
end)
|
end)
|
||||||
multi:newSystemThread("test_2",function()
|
|
||||||
print(THREAD_NAME,THREAD_ID,THREAD.getName())
|
for i = 1,10 do
|
||||||
print("thread",GLOBAL,THREAD,test,haha)
|
func(i,i*3).connect(function(data)
|
||||||
tab = THREAD.waitFor("test"):init()
|
print(data)
|
||||||
print(tab["bye"])
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local a = true
|
||||||
|
b = false
|
||||||
|
|
||||||
|
multi:newThread("Standard Thread 1",function()
|
||||||
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
print("Testing 1 ...",a,b,test)
|
||||||
|
end
|
||||||
|
end).OnError(function(self,msg)
|
||||||
|
print(msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- All upvalues are stripped! no access to the global, multi and thread are exposed however
|
||||||
|
multi:newISOThread("ISO Thread 2",function()
|
||||||
|
while true do
|
||||||
|
thread.sleep(1)
|
||||||
|
print("Testing 2 ...",a,b,test) -- a and b are nil, but test is true
|
||||||
|
end
|
||||||
|
end,{test=true,print=print})
|
||||||
|
|
||||||
|
.OnError(function(self,msg)
|
||||||
|
print(msg)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
multi:mainloop()
|
multi:mainloop()
|
||||||
17
tests/runtests.lua
Normal file
17
tests/runtests.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package.path="../?.lua;../?/init.lua;../?.lua;../?/?/init.lua;"..package.path
|
||||||
|
--[[
|
||||||
|
This file runs all tests.
|
||||||
|
Format:
|
||||||
|
Expected:
|
||||||
|
...
|
||||||
|
...
|
||||||
|
...
|
||||||
|
Actual:
|
||||||
|
...
|
||||||
|
...
|
||||||
|
...
|
||||||
|
|
||||||
|
Each test that is ran should have a 5 second pause after the test is complete
|
||||||
|
The expected and actual should "match" (Might be impossible when playing with threads)
|
||||||
|
This will be pushed directly to the master as tests start existing.
|
||||||
|
]]
|
||||||
Loading…
x
Reference in New Issue
Block a user