mirror of
https://github.com/rayaman/multi.git
synced 2026-09-05 07:27:35 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b5d10cbb6 | ||
|
|
0796788fcb | ||
|
|
ee5e3bde7f | ||
|
|
c86413351c | ||
|
|
4a52cd5e14 | ||
|
|
14beeb686a | ||
|
|
60783fdb16 | ||
|
|
b1a7e61c03 | ||
|
|
9fa0e7c2cb | ||
|
|
ef243f87d4 | ||
|
|
178283e0b4 | ||
|
|
7f35265a8e | ||
|
|
0501f068e4 | ||
|
|
ffd7ac15f6 | ||
|
|
869368af56 | ||
|
|
eeb75490dc | ||
|
|
2fec5b39b8 | ||
|
|
0a92890290 | ||
|
|
40de9a8d22 | ||
|
|
f8265fbb3b | ||
|
|
b995b1c0a7 | ||
|
|
66e922a971 | ||
|
|
92659c7eaf | ||
|
|
011ed53337 | ||
|
|
474ad6438f | ||
|
|
45095191f4 | ||
|
|
e44a3cd98b | ||
|
|
fff3601041 | ||
|
|
1639de5d0f | ||
|
|
59462df9a6 | ||
|
|
72733394ac | ||
|
|
dc9cee5a3e | ||
|
|
71ab702a75 | ||
|
|
1bb7410210 | ||
|
|
ec5bf74009 | ||
|
|
7ea6873c1f | ||
|
|
8c3d66a7b1 | ||
|
|
f5e95b8c9f | ||
|
|
2f11a80a28 | ||
|
|
8b6b56164a | ||
|
|
bbc83acc0f | ||
|
|
0d6a9f92ad | ||
|
|
4cf80517eb | ||
|
|
35a86a6cda | ||
|
|
019855d81f | ||
|
|
2a47de9fd8 | ||
|
|
0d3de6e31d | ||
|
|
d6d4934a7e | ||
|
|
6369450d2f | ||
|
|
a90b1d09b1 | ||
|
|
92090f0a0a | ||
|
|
5cfd155241 | ||
|
|
0b2b2f9613 | ||
|
|
a5b59ee601 | ||
|
|
f240588edd | ||
|
|
6abfb9c3d9 | ||
|
|
e5ac4d3d9e | ||
|
|
7353fde799 | ||
|
|
4c088b9080 | ||
|
|
b727fb15b5 | ||
|
|
57b4871a85 | ||
|
|
3ae2acbd78 | ||
|
|
df429b617e | ||
|
|
0d3a7b9393 | ||
|
|
6de93c10af | ||
|
|
a14cbb45d3 | ||
|
|
827d3d8c45 | ||
|
|
7bbb217018 | ||
|
|
62e05788d2 | ||
|
|
772095431f | ||
|
|
bb7fab0857 | ||
|
|
1546076c80 | ||
|
|
8f3eb6d9a3 | ||
|
|
ccc4a15121 | ||
|
|
9050e65d93 | ||
|
|
8f7183f998 | ||
|
|
3d07e774a0 | ||
|
|
99ba411781 | ||
|
|
23eaf42cad | ||
|
|
5bca4e3383 | ||
|
|
e2bb964423 | ||
|
|
0e2119a87d | ||
|
|
7dfbf16bc1 | ||
|
|
bac91574a2 | ||
|
|
bf2f495812 | ||
|
|
beddecc742 | ||
|
|
86f31bbe52 | ||
|
|
d8f3db6972 | ||
|
|
494baf1e32 | ||
|
|
e14fa83681 | ||
|
|
278b982aff | ||
|
|
89e76ce31d | ||
|
|
831abeaccf | ||
|
|
f74f85759b | ||
|
|
7b70838567 | ||
|
|
fcc0717115 | ||
|
|
47d8ac30c4 | ||
|
|
3646a1a074 | ||
|
|
b0ab40d410 | ||
|
|
440995b1c8 | ||
|
|
8da4c4c1de | ||
|
|
2cc2a57a46 | ||
|
|
6527dc1aaa | ||
|
|
bd49805c25 | ||
|
|
40dd293bf8 | ||
|
|
568c95fa73 | ||
|
|
d30ee3788e | ||
|
|
79f58a79f9 | ||
|
|
d8aeefd202 | ||
|
|
c0fb94ddbb | ||
|
|
e8a3cd731d | ||
|
|
03ffb6bc0a | ||
|
|
4240737e00 | ||
|
|
5172dcdf01 | ||
|
|
fc18a303dd | ||
|
|
04d5500374 | ||
|
|
72e24e8a9b | ||
|
|
48bba84c08 | ||
|
|
e9a0e7bbf7 | ||
|
|
264867a0da | ||
|
|
3f046afaa1 | ||
|
|
2acce5001d | ||
|
|
78cd15681a | ||
|
|
3401a8ac61 | ||
|
|
19ac257204 | ||
|
|
c14a469069 | ||
|
|
03cea2d71a | ||
|
|
593bfd0d8c | ||
|
|
bf60a354d4 | ||
|
|
6c73220a52 | ||
|
|
c3a9ddfdbd | ||
|
|
e05f2ea400 | ||
|
|
a60aae02c6 | ||
|
|
207c5b8d69 | ||
|
|
a9111f2fa3 | ||
|
|
b572bf218d | ||
|
|
49c0bd3930 | ||
|
|
cdb4bfda11 | ||
|
|
3fbead60d9 | ||
|
|
2b122f5c77 | ||
|
|
472d1748ee | ||
|
|
47178dd3b3 | ||
|
|
3fcba8825b | ||
|
|
e194a06427 | ||
|
|
32f7b4492b | ||
|
|
913745a1bc | ||
|
|
889dc6ca68 | ||
|
|
2805137648 | ||
|
|
f7167cf972 | ||
|
|
9e1ecb3583 | ||
|
|
b9b9b51d12 | ||
|
|
a708fb3f83 | ||
|
|
4335f3ed14 | ||
|
|
8580d92c9c | ||
|
|
f1f6e30a98 | ||
|
|
6c1e9f26f0 | ||
|
|
d98f353936 | ||
|
|
14c8665910 | ||
|
|
f7452db3ec | ||
|
|
588923e1b7 | ||
|
|
4877f64ca1 | ||
|
|
b8b31253d4 | ||
|
|
af4672245e | ||
|
|
609613dbe9 | ||
|
|
b16593425b | ||
|
|
997ea48b54 | ||
|
|
537dcf0db1 | ||
|
|
b74a6c006e | ||
|
|
b3453d028c | ||
|
|
6842147522 | ||
|
|
de34b9dc59 | ||
|
|
dff19d865f | ||
|
|
544aa78d70 | ||
|
|
91d0b5f7be | ||
|
|
27e03a2546 | ||
|
|
7dbcd01c33 | ||
|
|
cc20914391 | ||
|
|
c2aa449a65 | ||
|
|
57563688ae | ||
|
|
317dacd0de | ||
|
|
a7ba146a64 | ||
|
|
efa30e30cc | ||
|
|
197b418fc5 | ||
|
|
d3d53599f7 | ||
|
|
bf517facd1 | ||
|
|
9cff2735ba | ||
|
|
ea77b934b6 | ||
|
|
74bfd571a5 | ||
|
|
06132fc1dd | ||
|
|
ade5172f26 | ||
|
|
bdc657771d | ||
|
|
8c24bcbbb0 | ||
|
|
804a117ed0 | ||
|
|
37afd37f9e | ||
|
|
4399fb6424 | ||
|
|
02a54e13ea | ||
|
|
bb2c7d6440 | ||
|
|
d1b8ed1922 | ||
|
|
9992a2c091 | ||
|
|
155466dc71 | ||
|
|
cea6508d68 | ||
|
|
726707eb8a | ||
|
|
9a9d28f62f | ||
|
|
ed924a3d9d | ||
|
|
2d239c65ea | ||
|
|
fd8e77555a | ||
|
|
b60aab9602 | ||
|
|
180176e2cf | ||
|
|
952b592b97 | ||
|
|
d2ce7e070b | ||
|
|
300827b7bd | ||
|
|
9d97eac146 | ||
|
|
61dcb9da01 | ||
|
|
b597fbdf9b | ||
|
|
8fbaa76fe9 | ||
|
|
abb3da416f | ||
|
|
8ba489dc58 |
@@ -0,0 +1,32 @@
|
||||
name: Lua Unit Tests (Matrix)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
luaVersion: ["5.1", "5.2", "5.3", "5.4"]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Lua
|
||||
uses: leafo/gh-actions-lua@v10
|
||||
with:
|
||||
luaVersion: ${{ matrix.luaVersion }}
|
||||
|
||||
- name: Verify Lua version
|
||||
run: lua -v
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Replace with your actual test file
|
||||
lua tests/multi_test.lua
|
||||
+3
-14
@@ -1,14 +1,3 @@
|
||||
|
||||
test2.lua
|
||||
*.mp3
|
||||
*.exe
|
||||
lanestestclient.lua
|
||||
lanestest.lua
|
||||
sample-node.lua
|
||||
sample-master.lua
|
||||
Ayn Rand - The Virtue of Selfishness-Mg4QJheclsQ.m4a
|
||||
Atlas Shrugged by Ayn Rand Audiobook-9s2qrEau63E.webm
|
||||
test.lua
|
||||
test.lua
|
||||
*.code-workspace
|
||||
*.dat
|
||||
*.code-workspace
|
||||
lua5.4/*
|
||||
test.lua
|
||||
Vendored
-50
@@ -1,50 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "launch-lua",
|
||||
"type": "lua",
|
||||
"request": "launch",
|
||||
"workingDirectory": "${workspaceRoot}",
|
||||
"sourceBasePath": "${workspaceRoot}",
|
||||
"executable": "C:\\Program Files (x86)\\Lua\\5.1\\lua.exe",
|
||||
"arguments": "main.lua",
|
||||
"listenPublicly": false,
|
||||
"listenPort": 56789,
|
||||
"encoding": "UTF-8",
|
||||
"env": {}
|
||||
},
|
||||
{
|
||||
"name": "launch-gideros",
|
||||
"type": "lua",
|
||||
"request": "launch",
|
||||
"workingDirectory": "${workspaceRoot}",
|
||||
"giderosPath": "C:/Program Files (x86)/Gideros",
|
||||
"gprojPath": "${workspaceRoot}/GPROJ.gproj",
|
||||
"jumpToGiderosErrorPosition": false,
|
||||
"stopGiderosWhenDebuggerStops": true,
|
||||
"listenPublicly": false,
|
||||
"listenPort": 56789,
|
||||
"encoding": "UTF-8"
|
||||
},
|
||||
{
|
||||
"name": "wait",
|
||||
"type": "lua",
|
||||
"request": "attach",
|
||||
"workingDirectory": "${workspaceRoot}",
|
||||
"sourceBasePath": "${workspaceRoot}",
|
||||
"listenPublicly": false,
|
||||
"listenPort": 56789,
|
||||
"encoding": "UTF-8"
|
||||
},
|
||||
{
|
||||
"type": "lua",
|
||||
"request": "launch",
|
||||
"name": "Launch",
|
||||
"program": "${workspaceFolder}/test.lua"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# NTHREAD Namespace
|
||||
- [ ] NTHREAD.set(name, val)
|
||||
- [ ] NTHREAD.get(name, val)
|
||||
- [ ] NTHREAD.waitFor(name)
|
||||
- [ ] NTHREAD.getCores()*
|
||||
- [ ] NTHREAD.getConsole()
|
||||
- [ ] NTHREAD.getThreads()
|
||||
- [ ] NTHREAD.kill()
|
||||
- [ ] NTHREAD.getName()
|
||||
- [ ] NTHREAD.getID()
|
||||
- [ ] NTHREAD.pushStatus(...)
|
||||
- [ ] NTHREAD.sleep(n)
|
||||
- [ ] NTHREAD.hold(n)
|
||||
- [ ] NTHREAD.setENV(env)
|
||||
- [ ] NTHREAD.getENV()
|
||||
|
||||
# Extensions
|
||||
- [ ] multi:newNetworkThreadedQueue(name)
|
||||
- [ ] multi:newNetworkThreadedTable(name)
|
||||
- [ ] multi:newNetworkThreadedJobQueue(n)
|
||||
- [ ] multi:newNetworkThreadedConnection(name)
|
||||
|
||||
# Core
|
||||
- [ ] NTHREAD:newFunction(func, holdme)
|
||||
- [ ] NTHREAD:newNetworkThread(name, func, ...)
|
||||
- [ ] mulit:newNetworkThread(name, func, ...)
|
||||
@@ -1,50 +1,100 @@
|
||||
# Multi Version: 14.2.0 Documentation Complete, Bloat removed!
|
||||
|
||||
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and I'll look into it!
|
||||
|
||||
My multitasking library for lua. It is a pure lua binding, with exceptions of the integrations and the love2d compat. If you find any bugs or have any issues, please [let me know](https://github.com/rayaman/multi/issues) and I'll look into it!.
|
||||
|
||||
INSTALLING
|
||||
----------
|
||||
Links to dependicies:
|
||||
[lanes](https://github.com/LuaLanes/lanes)
|
||||
|
||||
To install copy the multi folder into your environment and you are good to go</br>
|
||||
If you want to use the system threads, then you'll need to install lanes!
|
||||
**or** use luarocks `luarocks install multi`
|
||||
|
||||
Going forward I will include a Release zip for love2d.
|
||||
**The Network Manager rework is currently being worked on and the old version is not included in this version.**
|
||||
|
||||
Discord
|
||||
-------
|
||||
Have a question that you need asking? Or need realtime assistance? Feel free to join the discord!</br>
|
||||
https://discord.gg/U8UspuA</br>
|
||||
|
||||
Planned features/TODO
|
||||
---------------------
|
||||
- [x] ~~Finish Documentation~~ Finished
|
||||
- [ ] Network Parallelism rework
|
||||
|
||||
Usage: [Check out the documentation for more info](https://github.com/rayaman/multi/blob/master/Documentation.md)</br>
|
||||
-----
|
||||
```lua
|
||||
local multi, thread = require("multi").init()
|
||||
mutli:newThread("Example",function()
|
||||
while true do
|
||||
thread.sleep(1)
|
||||
print("Hello!")
|
||||
end
|
||||
end)
|
||||
multi:lightloop()
|
||||
--multi:mainloop()
|
||||
--[[
|
||||
while true do
|
||||
multi:uManager()
|
||||
end
|
||||
]]
|
||||
```
|
||||
|
||||
Known Bugs/Issues
|
||||
-----------------
|
||||
Check the [Issues tab](https://github.com/rayaman/multi/issues) for issues
|
||||
# Multi Version: 16.3.0 -
|
||||
**Key Changes**
|
||||
- Fixed connection multiplying
|
||||
- Optimizing the library
|
||||
- Updated task management support
|
||||
|
||||
Refer to the [Change Log](https://github.com/rayaman/multi/blob/master/docs/changes.md) for more infromation
|
||||
|
||||
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and someone will look into it!
|
||||
|
||||
My multitasking library for lua. It is a pure lua binding, with exceptions of the integrations.
|
||||
|
||||
</br>
|
||||
|
||||
Progress is being made in [v16.3.0](https://github.com/rayaman/multi/tree/v16.3.0)
|
||||
---
|
||||
|
||||
</br>
|
||||
|
||||
INSTALLING
|
||||
----------
|
||||
Link to optional dependencies:
|
||||
- [lanes](https://github.com/LuaLanes/lanes) `luarocks install lanes`
|
||||
|
||||
- [chronos](https://github.com/ldrumm/chronos) `luarocks install chronos`
|
||||
|
||||
- [love2d](https://love2d.org/)
|
||||
|
||||
When using love2d add multi:uManager() or any processor to love.update()
|
||||
|
||||
```lua
|
||||
function love.update(dt)
|
||||
multi:uManager()
|
||||
end
|
||||
```
|
||||
|
||||
To install copy the multi folder into your environment and you are good to go</br>
|
||||
If you want to use the system threads, then you'll need to install lanes or love2d game engine!
|
||||
|
||||
```
|
||||
luarocks install multi
|
||||
```
|
||||
|
||||
Discord
|
||||
-------
|
||||
Have a question or need realtime assistance? Feel free to join the discord!</br>
|
||||
https://discord.gg/U8UspuA
|
||||
|
||||
Planned features/TODO
|
||||
---------------------
|
||||
- [x] ~~Create test suite (In progress, mostly done)~~
|
||||
- [ ] Network Parallelism rework
|
||||
|
||||
Usage: [Check out the documentation for more info](https://github.com/rayaman/multi/blob/master/docs/Documentation.md)
|
||||
-----
|
||||
|
||||
You can run tests in 2 ways:
|
||||
```
|
||||
lua tests/runtests.lua (Runs all tests, attempts to use lanes)
|
||||
love tests (Runs all tests in love2d env)
|
||||
```
|
||||
|
||||
```lua
|
||||
local multi, thread = require("multi"):init()
|
||||
GLOBAL, THREAD = require("multi.integration.threading"):init()
|
||||
|
||||
multi:newSystemThread("System Thread",function()
|
||||
while true do
|
||||
THREAD.sleep(.1)
|
||||
io.write(" World")
|
||||
THREAD.kill()
|
||||
end
|
||||
end)
|
||||
|
||||
multi:newThread("Coroutine Based Thread",function()
|
||||
while true do
|
||||
io.write("Hello")
|
||||
thread.sleep(.1)
|
||||
thread.kill()
|
||||
end
|
||||
end)
|
||||
|
||||
multi:newTLoop(function(loop)
|
||||
print("!")
|
||||
loop:Destroy()
|
||||
os.exit()
|
||||
end,.3)
|
||||
|
||||
multi:mainloop()
|
||||
|
||||
--[[
|
||||
while true do
|
||||
multi:uManager()
|
||||
end
|
||||
]]
|
||||
```
|
||||
|
||||
Known Bugs/Issues
|
||||
-----------------
|
||||
Check the [Issues tab](https://github.com/rayaman/multi/issues) for issues
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+3697
-2039
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,106 @@
|
||||
local multi, thread = require("multi"):init()
|
||||
|
||||
multi.defaultSettings.debugging = true
|
||||
|
||||
local dbg = {}
|
||||
dbg.__index = dbg
|
||||
dbg.processors = {}
|
||||
|
||||
-- Hooks to all on object created events!
|
||||
local c_cache = {}
|
||||
local d_cache = {}
|
||||
|
||||
local proc = multi:newProcessor("Debug_Processor").Start()
|
||||
|
||||
dbg.OnObjectCreated = function(obj, process)
|
||||
if c_cache[obj] then
|
||||
return false
|
||||
else
|
||||
c_cache[obj] = true
|
||||
proc:newTask(function()
|
||||
c_cache[obj] = false
|
||||
end)
|
||||
return true
|
||||
end
|
||||
end .. multi:newConnection()
|
||||
|
||||
dbg.OnObjectDestroyed = function(obj, process)
|
||||
if d_cache[obj] then
|
||||
return false
|
||||
else
|
||||
d_cache[obj] = true
|
||||
proc:newTask(function()
|
||||
d_cache[obj] = false
|
||||
end)
|
||||
return true
|
||||
end
|
||||
end .. multi:newConnection()
|
||||
|
||||
local creation_hook, destruction_hook
|
||||
local types
|
||||
local objects = {}
|
||||
|
||||
creation_hook = function(obj, process)
|
||||
types = multi:getTypes()
|
||||
if obj.Type == multi.PROCESS and not dbg.processors[obj] then
|
||||
obj.OnObjectCreated(creation_hook)
|
||||
obj.OnObjectDestroyed(destruction_hook)
|
||||
end
|
||||
|
||||
table.insert(objects, obj)
|
||||
|
||||
dbg.OnObjectCreated:Fire(obj, process)
|
||||
end
|
||||
|
||||
destruction_hook = function(obj, process)
|
||||
for i = 1, #objects do
|
||||
if objects[i] == obj then
|
||||
table.remove(objects, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
dbg.OnObjectDestroyed:Fire(obj, process)
|
||||
end
|
||||
|
||||
function dbg:getObjects(typ)
|
||||
if type(typ) == "string" then
|
||||
local objs = {}
|
||||
for i = 1, #objects do
|
||||
if objects[i].Type == typ then
|
||||
objs[#objs+1] = objects[i]
|
||||
end
|
||||
end
|
||||
return objs
|
||||
elseif type(typ) == "table" then -- Process
|
||||
local objs = {}
|
||||
for i = 1, #objects do
|
||||
if objects[i].Parent == typ then
|
||||
objs[#objs+1] = objects[i]
|
||||
end
|
||||
end
|
||||
return objs
|
||||
elseif type(typ) == "function" then
|
||||
local objs = {}
|
||||
-- Keep objects local/private, return true to add to list, false to reject, "break" to break loop
|
||||
for i = 1, #objects do
|
||||
local ret = typ(objects[i])
|
||||
if ret then
|
||||
objs[#objs+1] = objects[i]
|
||||
elseif ret == "break" then
|
||||
break
|
||||
end
|
||||
end
|
||||
return objs
|
||||
end
|
||||
end
|
||||
|
||||
local debug_stats = {}
|
||||
|
||||
local tmulti = multi:getThreadManagerProcess()
|
||||
multi.OnObjectCreated(creation_hook)
|
||||
tmulti.OnObjectCreated(creation_hook)
|
||||
multi.OnObjectDestroyed(destroction_hook)
|
||||
tmulti.OnObjectDestroyed(destroction_hook)
|
||||
|
||||
-- We write to a debug interface in the multi namespace
|
||||
multi.debugging = dbg
|
||||
@@ -0,0 +1,46 @@
|
||||
local multi, thread = require("multi"):init{error=true}
|
||||
multi.error("Currntly not supported!")
|
||||
os.exit(1)
|
||||
local effil = require("effil")
|
||||
|
||||
-- I like some of the things that this library offers.
|
||||
-- Current limitations prevent me from being able to use effil,
|
||||
-- but I might fork and work on it myself.
|
||||
|
||||
-- Configs
|
||||
effil.allow_table_upvalues(false)
|
||||
|
||||
local GLOBAL,THREAD = require("multi.integration.effilManager.threads").init()
|
||||
local count = 1
|
||||
local started = false
|
||||
local livingThreads = {}
|
||||
|
||||
function multi:newSystemThread(name, func, ...)
|
||||
local name = name or multi.randomString(16)
|
||||
local rand = math.random(1, 10000000)
|
||||
c = {}
|
||||
c.name = name
|
||||
c.Name = name
|
||||
c.Id = count
|
||||
end
|
||||
|
||||
function THREAD:newFunction(func, holdme)
|
||||
return thread:newFunctionBase(function(...)
|
||||
return multi:newSystemThread("TempSystemThread",func,...)
|
||||
end, holdme, multi.SFUNCTION)()
|
||||
end
|
||||
|
||||
THREAD.newSystemThread = function(...)
|
||||
multi:newSystemThread(...)
|
||||
end
|
||||
|
||||
multi.print("Integrated Effil Threading!")
|
||||
multi.integration = {} -- for module creators
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.effilManager.extensions")
|
||||
return {
|
||||
init = function()
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
|
||||
if not (GLOBAL and THREAD) then
|
||||
GLOBAL, THREAD = multi.integration.GLOBAL, multi.integration.THREAD
|
||||
else
|
||||
lanes = require("lanes")
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedQueue(name)
|
||||
local name = name or multi.randomString(16)
|
||||
local c = {}
|
||||
c.Name = name
|
||||
c.linda = lanes.linda()
|
||||
c.Type = multi.registerType("s_queue")
|
||||
|
||||
function c:push(v)
|
||||
self.linda:send("Q", v)
|
||||
end
|
||||
|
||||
function c:pop()
|
||||
return ({self.linda:receive(0, "Q")})[2]
|
||||
end
|
||||
|
||||
function c:peek()
|
||||
return self.linda:get("Q")
|
||||
end
|
||||
|
||||
function c:init()
|
||||
return self
|
||||
end
|
||||
|
||||
if multi.isMainThread then
|
||||
multi.integration.GLOBAL[name] = c
|
||||
else
|
||||
GLOBAL[name] = c
|
||||
end
|
||||
|
||||
local peek = function()
|
||||
return c:peek()
|
||||
end
|
||||
|
||||
local pop = function()
|
||||
return c:pop()
|
||||
end
|
||||
|
||||
function c:Hold(opt)
|
||||
local multi, thread = require("multi"):init()
|
||||
if opt.peek then
|
||||
return thread.hold(peek)
|
||||
else
|
||||
return thread.hold(pop)
|
||||
end
|
||||
end
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedTable(name)
|
||||
local name = name or multi.randomString(16)
|
||||
local c = {}
|
||||
c.link = lanes.linda()
|
||||
c.Name = name
|
||||
c.Type = multi.registerType("s_table")
|
||||
|
||||
function c:init()
|
||||
return self
|
||||
end
|
||||
|
||||
setmetatable(c,{
|
||||
__index = function(t,k)
|
||||
return c.link:get(k)
|
||||
end,
|
||||
__newindex = function(t,k,v)
|
||||
c.link:set(k, v)
|
||||
end
|
||||
})
|
||||
|
||||
if multi.isMainThread then
|
||||
multi.integration.GLOBAL[name] = c
|
||||
else
|
||||
GLOBAL[name] = c
|
||||
end
|
||||
|
||||
function c:Hold(opt)
|
||||
local multi, thread = require("multi"):init()
|
||||
if opt.key then
|
||||
return thread.hold(function()
|
||||
return self.tab[opt.key]
|
||||
end)
|
||||
else
|
||||
multi.error("Must provide a key to check opt.key = 'key'")
|
||||
end
|
||||
end
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedJobQueue(n)
|
||||
local c = {}
|
||||
c.cores = n or THREAD.getCores()*2
|
||||
c.Type = multi.registerType("s_jobqueue")
|
||||
c.OnJobCompleted = multi:newConnection()
|
||||
local funcs = multi:newSystemThreadedTable()
|
||||
local queueJob = multi:newSystemThreadedQueue()
|
||||
local queueReturn = multi:newSystemThreadedQueue()
|
||||
local doAll = multi:newSystemThreadedQueue()
|
||||
local ID=1
|
||||
local jid = 1
|
||||
function c:isEmpty()
|
||||
return queueJob:peek()==nil
|
||||
end
|
||||
function c:doToAll(func,...)
|
||||
for i=1,c.cores do
|
||||
doAll:push{ID,func,...}
|
||||
end
|
||||
ID = ID + 1
|
||||
return self
|
||||
end
|
||||
function c:registerFunction(name,func)
|
||||
funcs[name]=func
|
||||
return self
|
||||
end
|
||||
function c:pushJob(name,...)
|
||||
queueJob:push{name,jid,multi.pack(...)}
|
||||
jid = jid + 1
|
||||
return jid-1
|
||||
end
|
||||
local nFunc = 0
|
||||
function c:newFunction(name, func, holup) -- This registers with the queue
|
||||
if type(name)=="function" then
|
||||
holup = func
|
||||
func = name
|
||||
name = "JQ_Function_"..nFunc
|
||||
end
|
||||
nFunc = nFunc + 1
|
||||
c:registerFunction(name,func)
|
||||
return thread:newFunction(function(...)
|
||||
local id = c:pushJob(name,...)
|
||||
local link
|
||||
local rets
|
||||
link = c.OnJobCompleted(function(jid,...)
|
||||
if id==jid then
|
||||
rets = multi.pack(...)
|
||||
end
|
||||
end)
|
||||
return thread.hold(function()
|
||||
if rets then
|
||||
if #rets == 0 then
|
||||
return multi.NIL
|
||||
else
|
||||
return multi.unpack(rets)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end, holup), name
|
||||
end
|
||||
thread:newThread("JobQueueManager",function()
|
||||
while true do
|
||||
local job = thread.hold(function()
|
||||
return queueReturn:pop()
|
||||
end)
|
||||
if job then
|
||||
local id = table.remove(job,1)
|
||||
c.OnJobCompleted:Fire(id,multi.unpack(job))
|
||||
end
|
||||
end
|
||||
end)
|
||||
for i=1,c.cores do
|
||||
multi:newSystemThread("STJQ_"..multi.randomString(8),function(queue)
|
||||
local multi, thread = require("multi"):init()
|
||||
local idle = os.clock()
|
||||
local clock = os.clock
|
||||
local ref = 0
|
||||
_G["__QR"] = queueReturn
|
||||
setmetatable(_G,{__index = funcs})
|
||||
thread:newThread("JobHandler",function()
|
||||
while true do
|
||||
local dat = thread.hold(function()
|
||||
return queueJob:pop()
|
||||
end)
|
||||
idle = clock()
|
||||
thread:newThread("JobQueue-Spawn",function()
|
||||
local name = table.remove(dat, 1)
|
||||
local jid = table.remove(dat, 1)
|
||||
local args = table.remove(dat, 1)
|
||||
queueReturn:push{jid, funcs[name](args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]), queue}
|
||||
end)
|
||||
end
|
||||
end)
|
||||
thread:newThread("DoAllHandler",function()
|
||||
while true do
|
||||
local dat = thread.hold(function()
|
||||
return doAll:peek()
|
||||
end)
|
||||
if dat then
|
||||
if dat[1]>ref then
|
||||
ref = table.remove(dat, 1)
|
||||
func = table.remove(dat, 1)
|
||||
idle = clock()
|
||||
func(unpack(dat))
|
||||
doAll:pop()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
thread:newThread("IdleHandler",function()
|
||||
while true do
|
||||
thread.hold(function()
|
||||
return clock()-idle>3
|
||||
end)
|
||||
THREAD.sleep(.01)
|
||||
end
|
||||
end)
|
||||
multi:mainloop()
|
||||
end,i)
|
||||
end
|
||||
|
||||
function c:Hold(opt)
|
||||
return thread.hold(self.OnJobCompleted)
|
||||
end
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedConnection(name)
|
||||
local name = name or multi.randomString(16)
|
||||
local c = {}
|
||||
c.Type = multi.registerType("s_connection")
|
||||
c.CONN = 0x00
|
||||
c.TRIG = 0x01
|
||||
c.PING = 0x02
|
||||
c.PONG = 0x03
|
||||
local function remove(a, b)
|
||||
local ai = {}
|
||||
local r = {}
|
||||
for k,v in pairs(a) do ai[v]=true end
|
||||
for k,v in pairs(b) do
|
||||
if ai[v]==nil then table.insert(r,a[k]) end
|
||||
end
|
||||
return r
|
||||
end
|
||||
c.CID = THREAD_ID
|
||||
c.subscribe = multi:newSystemThreadedQueue("SUB_STC_"..self.Name):init()
|
||||
c.Name = name
|
||||
c.links = {} -- All triggers sent from main connection. When a connection is triggered on another thread, they speak to the main then send stuff out.
|
||||
-- Locals will only live in the thread that creates the original object
|
||||
local ping
|
||||
local pong = function(link, links)
|
||||
local res = thread.hold(function()
|
||||
return link:peek()[1] == c.PONG
|
||||
end,{sleep=3})
|
||||
|
||||
if not res then
|
||||
for i=1,#links do
|
||||
if links[i] == link then
|
||||
table.remove(links,i,link)
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
link:pop()
|
||||
end
|
||||
end
|
||||
|
||||
ping = thread:newFunction(function(self)
|
||||
ping:Pause()
|
||||
multi.ForEach(self.links, function(link) -- Sync new connections
|
||||
link:push{self.PING}
|
||||
multi:newThread("pong Thread", pong, link, self.links)
|
||||
end)
|
||||
|
||||
thread.sleep(3)
|
||||
|
||||
ping:Resume()
|
||||
end,false)
|
||||
|
||||
local function fire(...)
|
||||
for _, link in pairs(c.links) do
|
||||
link:push {c.TRIG, multi.pack(...)}
|
||||
end
|
||||
end
|
||||
|
||||
thread:newThread("STC_SUB_MAN"..name,function()
|
||||
local item
|
||||
local sub_func = function() -- This will keep things held up until there is something to process
|
||||
return c.subscribe:pop()
|
||||
end
|
||||
while true do
|
||||
thread.yield()
|
||||
-- We need to check on broken connections
|
||||
ping(c) -- Should return instantlly and process this in another thread
|
||||
item = thread.hold(sub_func)
|
||||
if item[1] == c.CONN then
|
||||
multi.ForEach(c.links, function(link) -- Sync new connections
|
||||
item[2]:push{c.CONN, link}
|
||||
end)
|
||||
c.links[#c.links+1] = item[2]
|
||||
elseif item[1] == c.TRIG then
|
||||
fire(multi.unpack(item[2]))
|
||||
c.proxy_conn:Fire(multi.unpack(item[2]))
|
||||
end
|
||||
end
|
||||
end)
|
||||
--- ^^^ This will only exist in the init thread
|
||||
|
||||
function c:Fire(...)
|
||||
local args = multi.pack(...)
|
||||
if self.CID == THREAD_ID then -- Host Call
|
||||
for _, link in pairs(self.links) do
|
||||
link:push {self.TRIG, args}
|
||||
end
|
||||
self.proxy_conn:Fire(...)
|
||||
else
|
||||
self.subscribe:push {self.TRIG, args}
|
||||
end
|
||||
end
|
||||
|
||||
function c:init()
|
||||
local multi, thread = require("multi"):init()
|
||||
self.links = {}
|
||||
self.proxy_conn = multi:newConnection()
|
||||
local mt = getmetatable(self.proxy_conn)
|
||||
local tempMT = {}
|
||||
for i,v in pairs(mt) do
|
||||
tempMT[i] = v
|
||||
end
|
||||
tempMT.__index = self.proxy_conn
|
||||
tempMT.__call = function(t,func) self.proxy_conn(func) end
|
||||
setmetatable(self, tempMT)
|
||||
if self.CID == THREAD_ID then return self end
|
||||
thread:newThread("STC_CONN_MAN"..name,function()
|
||||
local item
|
||||
local link_self_ref = multi:newSystemThreadedQueue()
|
||||
self.subscribe:push{self.CONN, link_self_ref}
|
||||
while true do
|
||||
item = thread.hold(function()
|
||||
return link_self_ref:peek()
|
||||
end)
|
||||
if item[1] == self.PING then
|
||||
link_self_ref:push{self.PONG}
|
||||
link_self_ref:pop()
|
||||
elseif item[1] == self.CONN then
|
||||
if item[2].Name ~= link_self_ref.Name then
|
||||
table.insert(self.links, item[2])
|
||||
end
|
||||
link_self_ref:pop()
|
||||
elseif item[1] == self.TRIG then
|
||||
self.proxy_conn:Fire(multi.unpack(item[2]))
|
||||
link_self_ref:pop()
|
||||
else
|
||||
-- This shouldn't be the case
|
||||
end
|
||||
end
|
||||
end)
|
||||
return self
|
||||
end
|
||||
|
||||
if multi.isMainThread then
|
||||
multi.integration.GLOBAL[name] = c
|
||||
else
|
||||
GLOBAL[name] = c
|
||||
end
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
require("multi.integration.sharedExtensions")
|
||||
@@ -0,0 +1,205 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
|
||||
package.path = "?/init.lua;?.lua;" .. package.path
|
||||
multi, thread = require("multi"):init() -- get it all and have it on all lanes
|
||||
if multi.integration then -- This allows us to call the lanes manager from supporting modules without a hassle
|
||||
return {
|
||||
init = function()
|
||||
return multi.integration.GLOBAL, multi.integration.THREAD
|
||||
end
|
||||
}
|
||||
end
|
||||
-- Step 1 get lanes
|
||||
lanes = require("lanes").configure()
|
||||
multi.SystemThreads = {}
|
||||
multi.isMainThread = true
|
||||
|
||||
_G.THREAD_NAME = "MAIN_THREAD"
|
||||
_G.THREAD_ID = 0
|
||||
|
||||
function multi:canSystemThread()
|
||||
return true
|
||||
end
|
||||
|
||||
function multi:getPlatform()
|
||||
return "lanes"
|
||||
end
|
||||
|
||||
-- Step 2 set up the Linda objects
|
||||
local __GlobalLinda = lanes.linda() -- handles global stuff
|
||||
local __SleepingLinda = lanes.linda() -- handles sleeping stuff
|
||||
local __ConsoleLinda = lanes.linda() -- handles console stuff
|
||||
local __StatusLinda = lanes.linda() -- handles pushstatus for stfunctions
|
||||
|
||||
local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda, __SleepingLinda, __StatusLinda, __ConsoleLinda)
|
||||
local count = 1
|
||||
local started = false
|
||||
local livingThreads = {}
|
||||
|
||||
function THREAD:newFunction(func, holdme)
|
||||
return thread:newFunctionBase(function(...)
|
||||
return multi:newSystemThread("TempSystemThread",func,...)
|
||||
end, holdme, multi.registerType("s_function"))()
|
||||
end
|
||||
|
||||
function multi:newSystemThread(name, func, ...)
|
||||
local name = name or multi.randomString(16)
|
||||
multi.InitSystemThreadErrorHandler()
|
||||
local rand = math.random(1, 10000000)
|
||||
local return_linda = lanes.linda()
|
||||
c = {}
|
||||
c.Name = name
|
||||
c.ID = count
|
||||
c.loadString = {"base","package","os","io","math","table","string","coroutine"}
|
||||
livingThreads[count] = {true, name}
|
||||
c.returns = return_linda
|
||||
c.Type = multi.registerType("s_thread")
|
||||
c.creationTime = os.clock()
|
||||
c.alive = true
|
||||
c.priority = THREAD.Priority_Normal
|
||||
local multi_settings = multi.defaultSettings
|
||||
local globe = {
|
||||
THREAD_NAME = name,
|
||||
THREAD_ID = count,
|
||||
THREAD = THREAD,
|
||||
GLOBAL = GLOBAL,
|
||||
_Console = __ConsoleLinda,
|
||||
_DEFER = {}
|
||||
}
|
||||
if GLOBAL["__env"] then
|
||||
for i,v in pairs(GLOBAL["__env"]) do
|
||||
globe[i] = v
|
||||
end
|
||||
end
|
||||
c.thread = lanes.gen("*",
|
||||
{
|
||||
globals = globe,
|
||||
priority = c.priority
|
||||
},function(...)
|
||||
multi, thread = require("multi"):init(multi_settings)
|
||||
require("multi.integration.lanesManager.extensions")
|
||||
require("multi.integration.sharedExtensions")
|
||||
local has_error = true
|
||||
returns = {pcall(func, ...)}
|
||||
return_linda:set("returns", returns)
|
||||
for i,v in pairs(_DEFER) do
|
||||
pcall(v)
|
||||
end
|
||||
has_error = false
|
||||
end)(...)
|
||||
count = count + 1
|
||||
function c:getName()
|
||||
return c.Name
|
||||
end
|
||||
function c:kill()
|
||||
self.thread:cancel()
|
||||
self.alive = false
|
||||
end
|
||||
table.insert(multi.SystemThreads, c)
|
||||
c.OnDeath = multi:newConnection()
|
||||
c.OnError = multi:newConnection()
|
||||
GLOBAL["__THREADS__"] = livingThreads
|
||||
c.OnError(multi.error)
|
||||
|
||||
if self.isActor then
|
||||
self:create(c)
|
||||
else
|
||||
multi.create(multi, c)
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
THREAD.newSystemThread = function(...)
|
||||
multi:newSystemThread(...)
|
||||
end
|
||||
|
||||
function multi.InitSystemThreadErrorHandler()
|
||||
if started == true then
|
||||
return
|
||||
end
|
||||
started = true
|
||||
thread:newThread("SystemThreadScheduler",function()
|
||||
local threads = multi.SystemThreads
|
||||
local _,data,status,push,temp
|
||||
while true do
|
||||
thread.yield()
|
||||
_,data = __ConsoleLinda:receive(0, "Q")
|
||||
if data then
|
||||
--print(data[1])
|
||||
end
|
||||
for i = #threads, 1, -1 do
|
||||
temp = threads[i]
|
||||
status = temp.thread.status
|
||||
push = __StatusLinda:get(temp.ID)
|
||||
if push then
|
||||
temp.statusconnector:Fire(multi.unpack(({__StatusLinda:receive(nil, temp.ID)})[2]))
|
||||
end
|
||||
if status == "done" or temp.returns:get("returns") then
|
||||
returns = ({temp.returns:receive(0, "returns")})[2]
|
||||
livingThreads[temp.ID] = {false, temp.Name}
|
||||
temp.alive = false
|
||||
if returns[1] == false then
|
||||
temp.OnError:Fire(temp, returns[2])
|
||||
else
|
||||
table.remove(returns,1)
|
||||
temp.OnDeath:Fire(multi.unpack(returns))
|
||||
end
|
||||
GLOBAL["__THREADS__"] = livingThreads
|
||||
table.remove(threads, i)
|
||||
elseif status == "running" then
|
||||
--
|
||||
elseif status == "waiting" then
|
||||
--
|
||||
elseif status == "error" then
|
||||
-- The thread never really errors, we handle this through our linda object
|
||||
elseif status == "cancelled" then
|
||||
livingThreads[temp.ID] = {false, temp.Name}
|
||||
temp.alive = false
|
||||
temp.OnError:Fire(temp,"thread_cancelled")
|
||||
GLOBAL["__THREADS__"] = livingThreads
|
||||
table.remove(threads, i)
|
||||
elseif status == "killed" then
|
||||
livingThreads[temp.ID] = {false, temp.Name}
|
||||
temp.alive = false
|
||||
temp.OnError:Fire(temp,"thread_killed")
|
||||
GLOBAL["__THREADS__"] = livingThreads
|
||||
table.remove(threads, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end).OnError(multi.error)
|
||||
end
|
||||
|
||||
multi.print("Integrated Lanes Threading!")
|
||||
multi.integration = {} -- for module creators
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.lanesManager.extensions")
|
||||
return {
|
||||
init = function()
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
}
|
||||
+150
-119
@@ -1,120 +1,151 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local function getOS()
|
||||
if package.config:sub(1, 1) == "\\" then
|
||||
return "windows"
|
||||
else
|
||||
return "unix"
|
||||
end
|
||||
end
|
||||
local function INIT(__GlobalLinda,__SleepingLinda)
|
||||
local THREAD = {}
|
||||
THREAD.Priority_Core = 3
|
||||
THREAD.Priority_High = 2
|
||||
THREAD.Priority_Above_Normal = 1
|
||||
THREAD.Priority_Normal = 0
|
||||
THREAD.Priority_Below_Normal = -1
|
||||
THREAD.Priority_Low = -2
|
||||
THREAD.Priority_Idle = -3
|
||||
function THREAD.set(name, val)
|
||||
__GlobalLinda:set(name, val)
|
||||
end
|
||||
function THREAD.get(name)
|
||||
__GlobalLinda:get(name)
|
||||
end
|
||||
function THREAD.waitFor(name)
|
||||
local function wait()
|
||||
math.randomseed(os.time())
|
||||
__SleepingLinda:receive(.001, "__non_existing_variable")
|
||||
end
|
||||
repeat
|
||||
wait()
|
||||
until __GlobalLinda:get(name)
|
||||
return __GlobalLinda:get(name)
|
||||
end
|
||||
if getOS() == "windows" then
|
||||
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
|
||||
else
|
||||
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
|
||||
end
|
||||
function THREAD.getCores()
|
||||
return THREAD.__CORES
|
||||
end
|
||||
function THREAD.getConsole()
|
||||
local c = {}
|
||||
c.queue = _Console
|
||||
function c.print(...)
|
||||
c.queue:send("Q", {...})
|
||||
end
|
||||
function c.error(err)
|
||||
c.queue:push{"ERROR in <"..__THREADNAME__..">: "..err,__THREADID__}
|
||||
error(err)
|
||||
end
|
||||
return c
|
||||
end
|
||||
function THREAD.getThreads()
|
||||
return GLOBAL.__THREADS__
|
||||
end
|
||||
if os.getOS() == "windows" then
|
||||
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
|
||||
else
|
||||
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
|
||||
end
|
||||
function THREAD.kill() -- trigger the lane destruction
|
||||
error("Thread was killed!")
|
||||
end
|
||||
function THREAD.getName()
|
||||
return THREAD_NAME
|
||||
end
|
||||
function THREAD.getID()
|
||||
return THREAD_ID
|
||||
end
|
||||
_G.THREAD_ID = 0
|
||||
function THREAD.sleep(n)
|
||||
math.randomseed(os.time())
|
||||
__SleepingLinda:receive(n, "__non_existing_variable")
|
||||
end
|
||||
function THREAD.hold(n)
|
||||
local function wait()
|
||||
math.randomseed(os.time())
|
||||
__SleepingLinda:receive(.001, "__non_existing_variable")
|
||||
end
|
||||
repeat
|
||||
wait()
|
||||
until n()
|
||||
end
|
||||
local GLOBAL = {}
|
||||
setmetatable(GLOBAL, {
|
||||
__index = function(t, k)
|
||||
return __GlobalLinda:get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
__GlobalLinda:set(k, v)
|
||||
end
|
||||
})
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
return {init = function(g,s)
|
||||
return INIT(g,s)
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local function getOS()
|
||||
if package.config:sub(1, 1) == "\\" then
|
||||
return "windows"
|
||||
else
|
||||
return "unix"
|
||||
end
|
||||
end
|
||||
|
||||
local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console)
|
||||
local THREAD = {}
|
||||
THREAD.Priority_Core = 3
|
||||
THREAD.Priority_High = 2
|
||||
THREAD.Priority_Above_Normal = 1
|
||||
THREAD.Priority_Normal = 0
|
||||
THREAD.Priority_Below_Normal = -1
|
||||
THREAD.Priority_Low = -2
|
||||
THREAD.Priority_Idle = -3
|
||||
|
||||
function THREAD.set(name, val)
|
||||
__GlobalLinda:set(name, val)
|
||||
end
|
||||
|
||||
function THREAD.get(name)
|
||||
return __GlobalLinda:get(name)
|
||||
end
|
||||
|
||||
function THREAD.waitFor(name)
|
||||
local multi, thread = require("multi"):init()
|
||||
return multi.hold(function()
|
||||
math.randomseed(os.time())
|
||||
__SleepingLinda:receive(.001, "__non_existing_variable")
|
||||
return __GlobalLinda:get(name)
|
||||
end)
|
||||
end
|
||||
|
||||
function THREAD.getCores()
|
||||
return THREAD.__CORES
|
||||
end
|
||||
|
||||
function THREAD.getConsole()
|
||||
local c = {}
|
||||
c.queue = __Console
|
||||
function c.print(...)
|
||||
c.queue:push("Q", table.concat(multi.pack(...), "\t"))
|
||||
end
|
||||
function c.error(err)
|
||||
c.queue:push("Q", "Error in <"..THREAD_NAME..":" .. THREAD_ID .. ">: ".. err)
|
||||
multi.error(err)
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
function THREAD.getThreads()
|
||||
return GLOBAL.__THREADS__
|
||||
end
|
||||
|
||||
if os.getOS() == "windows" then
|
||||
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
|
||||
else
|
||||
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
|
||||
end
|
||||
|
||||
function THREAD.kill() -- trigger the lane destruction
|
||||
error("Thread was killed!\1")
|
||||
end
|
||||
|
||||
function THREAD.sync()
|
||||
-- Maybe do something...
|
||||
end
|
||||
|
||||
function THREAD.pushStatus(...)
|
||||
local args = multi.pack(...)
|
||||
__StatusLinda:send(nil,THREAD_ID, args)
|
||||
end
|
||||
|
||||
_G.THREAD_ID = 0
|
||||
|
||||
function THREAD.sleep(n)
|
||||
math.randomseed(os.time())
|
||||
__SleepingLinda:receive(n, "__non_existing_variable")
|
||||
end
|
||||
|
||||
function THREAD.hold(n)
|
||||
local function wait()
|
||||
math.randomseed(os.time())
|
||||
__SleepingLinda:receive(.001, "__non_existing_variable")
|
||||
end
|
||||
repeat
|
||||
wait()
|
||||
until n()
|
||||
end
|
||||
|
||||
local GLOBAL = {}
|
||||
setmetatable(GLOBAL, {
|
||||
__index = function(t, k)
|
||||
return __GlobalLinda:get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
__GlobalLinda:set(k, v)
|
||||
end
|
||||
})
|
||||
|
||||
function THREAD.setENV(env, name)
|
||||
GLOBAL[name or "__env"] = env
|
||||
end
|
||||
|
||||
function THREAD.getENV(name)
|
||||
return GLOBAL[name or "__env"]
|
||||
end
|
||||
|
||||
function THREAD.exposeENV(name)
|
||||
name = name or "__env"
|
||||
local env = THREAD.getENV(name)
|
||||
for i,v in pairs(env) do
|
||||
_G[i] = v
|
||||
end
|
||||
end
|
||||
|
||||
function THREAD.defer(func)
|
||||
table.insert(_DEFER, func)
|
||||
end
|
||||
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
|
||||
return {init = function(g,s,st,c,onexit)
|
||||
return INIT(g,s,st,c,onexit)
|
||||
end}
|
||||
@@ -0,0 +1,244 @@
|
||||
if not ISTHREAD then
|
||||
multi, thread = require("multi").init()
|
||||
GLOBAL = multi.integration.GLOBAL
|
||||
THREAD = multi.integration.THREAD
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedQueue(name)
|
||||
local name = name or multi.randomString(16)
|
||||
|
||||
local c = {}
|
||||
|
||||
c.Name = name
|
||||
c.Type = multi.registerType("s_queue")
|
||||
c.chan = love.thread.getChannel(name)
|
||||
|
||||
function c:push(dat)
|
||||
self.chan:push(THREAD.packValue(dat))
|
||||
end
|
||||
|
||||
function c:pop()
|
||||
return THREAD.unpackValue(self.chan:pop())
|
||||
end
|
||||
|
||||
function c:peek()
|
||||
return THREAD.unpackValue(self.chan:peek())
|
||||
end
|
||||
|
||||
function c:init()
|
||||
self.chan = love.thread.getChannel(self.Name)
|
||||
return self
|
||||
end
|
||||
|
||||
function c:Hold(opt)
|
||||
local multi, thread = require("multi"):init()
|
||||
if opt.peek then
|
||||
return thread.hold(function()
|
||||
return self:peek()
|
||||
end)
|
||||
else
|
||||
return thread.hold(function()
|
||||
return self:pop()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
GLOBAL[name] = c
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedTable(name)
|
||||
local name = name or multi.randomString(16)
|
||||
|
||||
local c = {}
|
||||
|
||||
c.Name = name
|
||||
c.Type = multi.registerType("s_table")
|
||||
c.tab = THREAD.createTable(name)
|
||||
|
||||
function c:init()
|
||||
self.tab = THREAD.createTable(self.Name)
|
||||
setmetatable(self,{
|
||||
__index = function(t, k)
|
||||
return self.tab[k]
|
||||
end,
|
||||
__newindex = function(t,k,v)
|
||||
self.tab[k] = v
|
||||
end
|
||||
})
|
||||
return self
|
||||
end
|
||||
|
||||
c.__init = c.init
|
||||
|
||||
function c:Hold(opt)
|
||||
local multi, thread = require("multi"):init()
|
||||
if opt.key then
|
||||
return thread.hold(function()
|
||||
return self.tab[opt.key]
|
||||
end)
|
||||
else
|
||||
multi.error("Must provide a key to check opt.key = 'key'")
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(c,{
|
||||
__index = function(t, k)
|
||||
return c.tab[k]
|
||||
end,
|
||||
__newindex = function(t,k,v)
|
||||
c.tab[k] = v
|
||||
end
|
||||
})
|
||||
|
||||
GLOBAL[name] = c
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
local jqc = 1
|
||||
function multi:newSystemThreadedJobQueue(n)
|
||||
local c = {}
|
||||
|
||||
c.cores = n or THREAD.getCores()
|
||||
c.registerQueue = {}
|
||||
c.Type = multi.registerType("s_jobqueue")
|
||||
c.funcs = THREAD.createTable("__JobQueue_"..jqc.."_table")
|
||||
c.queue = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queue")
|
||||
c.queueReturn = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueReturn")
|
||||
c.queueAll = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueAll")
|
||||
c.id = 0
|
||||
c.OnJobCompleted = multi:newConnection()
|
||||
|
||||
local allfunc = 0
|
||||
|
||||
function c:doToAll(func)
|
||||
for i = 1, self.cores do
|
||||
self.queueAll:push({allfunc, func})
|
||||
end
|
||||
allfunc = allfunc + 1
|
||||
end
|
||||
function c:registerFunction(name, func)
|
||||
if self.funcs[name] then
|
||||
multi.error("A function by the name "..name.." has already been registered!")
|
||||
end
|
||||
self.funcs[name] = func
|
||||
end
|
||||
function c:pushJob(name,...)
|
||||
self.id = self.id + 1
|
||||
self.queue:push{name,self.id,...}
|
||||
return self.id
|
||||
end
|
||||
function c:isEmpty()
|
||||
return queueJob:peek()==nil
|
||||
end
|
||||
local nFunc = 0
|
||||
function c:newFunction(name,func,holup) -- This registers with the queue
|
||||
if type(name)=="function" then
|
||||
holup = func
|
||||
func = name
|
||||
name = "JQ_Function_"..nFunc
|
||||
end
|
||||
nFunc = nFunc + 1
|
||||
c:registerFunction(name,func)
|
||||
return thread:newFunction(function(...)
|
||||
local id = c:pushJob(name,...)
|
||||
local link
|
||||
local rets
|
||||
link = c.OnJobCompleted(function(jid,...)
|
||||
if id==jid then
|
||||
rets = multi.pack(...)
|
||||
end
|
||||
end)
|
||||
return thread.hold(function()
|
||||
if rets then
|
||||
return multi.unpack(rets) or multi.NIL
|
||||
end
|
||||
end)
|
||||
end,holup),name
|
||||
end
|
||||
thread:newThread("jobManager",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local dat = c.queueReturn:pop()
|
||||
if dat then
|
||||
c.OnJobCompleted:Fire(multi.unpack(dat))
|
||||
end
|
||||
end
|
||||
end)
|
||||
for i=1,c.cores do
|
||||
multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc)
|
||||
local multi, thread = require("multi"):init()
|
||||
require("love.timer")
|
||||
love.timer.sleep(1)
|
||||
local clock = os.clock
|
||||
local funcs = THREAD.createTable("__JobQueue_"..jqc.."_table")
|
||||
local queue = THREAD.waitFor("__JobQueue_"..jqc.."_queue")
|
||||
local queueReturn = THREAD.waitFor("__JobQueue_"..jqc.."_queueReturn")
|
||||
local lastProc = clock()
|
||||
local queueAll = THREAD.waitFor("__JobQueue_"..jqc.."_queueAll")
|
||||
local registry = {}
|
||||
_G["__QR"] = queueReturn
|
||||
setmetatable(_G,{__index = funcs})
|
||||
thread:newThread("startUp",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
lastProc = os.clock()
|
||||
queueAll:pop()[2]()
|
||||
end
|
||||
end
|
||||
end)
|
||||
thread:newThread("runner",function()
|
||||
thread.sleep(.1)
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
lastProc = os.clock()
|
||||
queueAll:pop()[2]()
|
||||
end
|
||||
local dat = thread.hold(queue)
|
||||
if dat then
|
||||
multi:newThread("Test",function()
|
||||
lastProc = os.clock()
|
||||
local name = table.remove(dat,1)
|
||||
local id = table.remove(dat,1)
|
||||
local tab = {funcs[name](multi.unpack(dat))}
|
||||
table.insert(tab,1,id)
|
||||
--local test = queueReturn.push
|
||||
queueReturn:push(tab)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
thread:newThread("Idler",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
if clock()-lastProc> 2 then
|
||||
THREAD.sleep(.05)
|
||||
else
|
||||
THREAD.sleep(.001)
|
||||
end
|
||||
end
|
||||
end)
|
||||
multi:mainloop()
|
||||
end,jqc)
|
||||
end
|
||||
|
||||
function c:Hold(opt)
|
||||
return thread.hold(self.OnJobCompleted)
|
||||
end
|
||||
|
||||
jqc = jqc + 1
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
@@ -0,0 +1,137 @@
|
||||
if ISTHREAD then
|
||||
error("You cannot require the loveManager from within a thread!")
|
||||
end
|
||||
|
||||
local ThreadFileData = [[
|
||||
ISTHREAD = true
|
||||
args = {...}
|
||||
THREAD_ID = args[1]
|
||||
THREAD_NAME = args[2]
|
||||
GLOBAL, THREAD, DEFER = require("multi.integration.loveManager.threads"):init()
|
||||
__FUNC = THREAD.unpackValue(args[3])
|
||||
ARGS = THREAD.unpackValue(args[4])
|
||||
settings = args[5]
|
||||
if ARGS == nil then ARGS = {} end
|
||||
math.randomseed(THREAD_ID)
|
||||
math.random()
|
||||
math.random()
|
||||
math.random()
|
||||
stab = THREAD.createTable(THREAD_NAME .. THREAD_ID)
|
||||
if GLOBAL["__env"] then
|
||||
local env = THREAD.getENV()
|
||||
for i,v in pairs(env) do
|
||||
_G[i] = v
|
||||
end
|
||||
end
|
||||
multi, thread = require("multi"):init{error=true, warning=true, print=true, priority=true}
|
||||
multi.defaultSettings.print = true
|
||||
require("multi.integration.loveManager.extensions")
|
||||
require("multi.integration.sharedExtensions")
|
||||
local returns = {pcall(__FUNC, multi.unpack(ARGS))}
|
||||
table.remove(returns,1)
|
||||
stab["returns"] = returns
|
||||
for i,v in pairs(DEFER) do
|
||||
pcall(v)
|
||||
end
|
||||
]]
|
||||
|
||||
_G.THREAD_NAME = "MAIN_THREAD"
|
||||
_G.THREAD_ID = 0
|
||||
|
||||
local multi, thread = require("multi"):init()
|
||||
local GLOBAL, THREAD = require("multi.integration.loveManager.threads"):init()
|
||||
|
||||
multi.registerType("s_function")
|
||||
multi.registerType("s_thread")
|
||||
|
||||
multi.integration = {}
|
||||
multi.isMainThread = true
|
||||
local threads = {}
|
||||
local tid = 0
|
||||
function multi:newSystemThread(name, func, ...)
|
||||
multi.InitSystemThreadErrorHandler()
|
||||
local name = name or multi.randomString(16)
|
||||
tid = tid + 1
|
||||
local c = {}
|
||||
c.Type = multi.STHREAD
|
||||
c.Name = name
|
||||
c.ID = tid
|
||||
c.thread = love.thread.newThread(ThreadFileData)
|
||||
c.thread:start(c.ID, c.Name, THREAD.packValue(func), THREAD.packValue({...}), multi.defaultSettings)
|
||||
c.stab = THREAD.createTable(name .. c.ID)
|
||||
c.creationTime = os.clock()
|
||||
c.OnDeath = multi:newConnection()
|
||||
c.OnError = multi:newConnection()
|
||||
c.status_channel = love.thread.getChannel("__status_channel__" .. c.ID)
|
||||
|
||||
function c:getName() return c.name end
|
||||
|
||||
table.insert(threads, c)
|
||||
|
||||
c.OnError(multi.error)
|
||||
|
||||
if self.isActor then
|
||||
self:create(c)
|
||||
else
|
||||
multi.create(multi, c)
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
local started = false
|
||||
local console_channel = love.thread.getChannel("__console_channel__")
|
||||
|
||||
function THREAD:newFunction(func, holdme)
|
||||
return thread:newFunctionBase(function(...)
|
||||
return multi:newSystemThread("SystemThreaded Function Handler", func, ...)
|
||||
end, holdme, multi.SFUNCTION)()
|
||||
end
|
||||
|
||||
function love.threaderror(thread, errorstr)
|
||||
multi.error("Thread error! " .. errorstr)
|
||||
end
|
||||
|
||||
function multi.InitSystemThreadErrorHandler()
|
||||
if started == true then return end
|
||||
started = true
|
||||
thread:newThread("Love System Thread Handler", function()
|
||||
while true do
|
||||
thread.yield()
|
||||
for i = #threads, 1, -1 do
|
||||
local th = threads[i]
|
||||
if th.status_channel:peek() ~= nil then
|
||||
th.statusconnector:Fire(multi.unpack(th.status_channel:pop()))
|
||||
end
|
||||
local th_err = th.thread:getError()
|
||||
if th_err == "Thread Killed!\1" then
|
||||
th.OnDeath:Fire("Thread Killed!")
|
||||
table.remove(threads, i)
|
||||
elseif th_err then
|
||||
th.OnError:Fire(th, th_err)
|
||||
table.remove(threads, i)
|
||||
elseif th.stab.returns then
|
||||
th.OnDeath:Fire(multi.unpack(th.stab.returns))
|
||||
th.stab.returns = nil
|
||||
table.remove(threads, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
THREAD.newSystemThread = function(...)
|
||||
multi:newSystemThread(...)
|
||||
end
|
||||
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.loveManager.extensions")
|
||||
require("multi.integration.sharedExtensions")
|
||||
multi.print("Integrated Love Threading!")
|
||||
|
||||
return {
|
||||
init = function()
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
require("love.timer")
|
||||
require("love.system")
|
||||
require("love.data")
|
||||
require("love.thread")
|
||||
local multi, thread = require("multi"):init()
|
||||
|
||||
-- Checks if the given value is a LOVE2D object (i.e. has metatable with __index field) and if that __index field contains functions typical of LOVE2D objects
|
||||
function isLoveObject(value)
|
||||
-- Check if the value has metatable
|
||||
if type(value) == "userdata" and getmetatable(value) then
|
||||
-- Check if the metatable has the __index field
|
||||
local index = getmetatable(value).__index
|
||||
if type(index) == "table" then
|
||||
-- Check if the metatable's __index table contains functions typical of LOVE2D objects
|
||||
if index.draw or index.update or index.getWidth or index.getHeight or index.getString or index.getPointer then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Converts any function values in a table to a string with the value "\1\2:func:<function_string>" where <function_string> is the Lua stringified version of the function
|
||||
function tableToFunctionString(t)
|
||||
if type(t) == "nil" then return "\1\2:nil:" end
|
||||
if type(t) == "function" then return "\1\2:func:"..string.dump(t) end
|
||||
if type(t) ~= "table" then return t end
|
||||
local newtable = {}
|
||||
for k, v in pairs(t) do
|
||||
if type(v) == "function" then
|
||||
newtable[k] = "\1\2:func:"..string.dump(v)
|
||||
elseif type(v) == "table" then
|
||||
newtable[k] = tableToFunctionString(v)
|
||||
elseif isLoveObject(v) then
|
||||
newtable[k] = v
|
||||
elseif type(v) == "userdata" then
|
||||
newtable[k] = tostring(v)
|
||||
else
|
||||
newtable[k] = v
|
||||
end
|
||||
end
|
||||
return newtable
|
||||
end
|
||||
|
||||
-- Converts strings with the value "\1\2:func:<function_string>" back to functions
|
||||
function functionStringToTable(t)
|
||||
if type(t) == "string" and t:sub(1, 8) == "\1\2:func:" then return loadstring(t:sub(9, -1)) end
|
||||
if type(t) == "string" and t:sub(1, 7) == "\1\2:nil:" then return nil end
|
||||
if type(t) ~= "table" then return t end
|
||||
for k, v in pairs(t) do
|
||||
if type(v) == "string" then
|
||||
if v:sub(1, 8) == "\1\2:func:" then
|
||||
t[k] = loadstring(v:sub(9, -1))
|
||||
else
|
||||
t[k] = v
|
||||
end
|
||||
elseif type(v) == "table" then
|
||||
t[k] = functionStringToTable(v)
|
||||
else
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
if t.init then
|
||||
t:init()
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local function packValue(t)
|
||||
return tableToFunctionString(t)
|
||||
end
|
||||
|
||||
local function unpackValue(t)
|
||||
return functionStringToTable(t)
|
||||
end
|
||||
|
||||
local function createTable(n)
|
||||
if not n then
|
||||
n = "STAB"..multi.randomString(8)
|
||||
end
|
||||
local __proxy = {}
|
||||
local function set(name, val)
|
||||
local chan = love.thread.getChannel(n .. name)
|
||||
if chan:getCount() == 1 then chan:pop() end
|
||||
__proxy[name] = true
|
||||
chan:push(packValue(val))
|
||||
end
|
||||
local function get(name)
|
||||
return unpackValue(love.thread.getChannel(n .. name):peek())
|
||||
-- if type(data) == "table" and data.init then
|
||||
-- return data:init()
|
||||
-- else
|
||||
-- return data
|
||||
-- end
|
||||
end
|
||||
return setmetatable({},
|
||||
{
|
||||
__index = function(t, k)
|
||||
return get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
set(k,v)
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
function INIT()
|
||||
local GLOBAL, THREAD, DEFER = createTable("__GLOBAL__"), {}, {}
|
||||
local status_channel, console_channel = love.thread.getChannel("__status_channel__" .. THREAD_ID),
|
||||
love.thread.getChannel("__console_channel__")
|
||||
|
||||
-- Non portable methods, shouldn't be used unless you know what you are doing
|
||||
THREAD.packValue = packValue
|
||||
THREAD.unpackValue = unpackValue
|
||||
THREAD.createTable = createTable
|
||||
|
||||
function THREAD.set(name, val)
|
||||
GLOBAL[name] = val
|
||||
end
|
||||
|
||||
function THREAD.get(name, val)
|
||||
return GLOBAL[name]
|
||||
end
|
||||
|
||||
THREAD.waitFor = thread:newFunction(function(name)
|
||||
local function wait()
|
||||
math.randomseed(os.time())
|
||||
thread.yield()
|
||||
end
|
||||
repeat
|
||||
wait()
|
||||
until GLOBAL[name] ~= nil
|
||||
return GLOBAL[name]
|
||||
end, true)
|
||||
|
||||
function THREAD.getCores()
|
||||
return love.system.getProcessorCount()
|
||||
end
|
||||
|
||||
function THREAD.getConsole()
|
||||
local c = {}
|
||||
c.queue = console_channel
|
||||
function c.print(...)
|
||||
c.queue:push(table.concat(multi.pack(...), "\t"))
|
||||
end
|
||||
function c.error(err)
|
||||
c.queue:push("Error in <"..THREAD_NAME..":" .. THREAD_ID .. ">: ".. err)
|
||||
multi.error(err)
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
function THREAD.getThreads()
|
||||
--
|
||||
end
|
||||
|
||||
function THREAD.kill() -- trigger the lane destruction
|
||||
error("Thread was killed!\1")
|
||||
end
|
||||
|
||||
function THREAD.pushStatus(...)
|
||||
status_channel:push(multi.pack(...))
|
||||
end
|
||||
|
||||
function THREAD.sleep(n)
|
||||
love.timer.sleep(n)
|
||||
end
|
||||
|
||||
THREAD.hold = thread:newFunction(function(n)
|
||||
thread.hold(n)
|
||||
end, true)
|
||||
|
||||
function THREAD.setENV(env, name)
|
||||
GLOBAL[name or "__env"] = env
|
||||
end
|
||||
|
||||
function THREAD.getENV(name)
|
||||
return GLOBAL[name or "__env"]
|
||||
end
|
||||
|
||||
function THREAD.exposeENV(name)
|
||||
name = name or "__env"
|
||||
local env = THREAD.getENV(name)
|
||||
for i,v in pairs(env) do
|
||||
_G[i] = v
|
||||
end
|
||||
end
|
||||
|
||||
function THREAD.defer(func)
|
||||
table.insert(DEFER, func)
|
||||
end
|
||||
|
||||
function THREAD.sync()
|
||||
-- Maybe do something...
|
||||
end
|
||||
|
||||
return GLOBAL, THREAD, DEFER
|
||||
end
|
||||
|
||||
return {
|
||||
init = function()
|
||||
return INIT()
|
||||
end
|
||||
}
|
||||
+203
-199
@@ -1,200 +1,204 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi").init()
|
||||
GLOBAL = multi.integration.GLOBAL
|
||||
THREAD = multi.integration.THREAD
|
||||
function multi:newSystemThreadedQueue(name)
|
||||
local c = {}
|
||||
c.Name = name
|
||||
local fRef = {"func",nil}
|
||||
function c:init()
|
||||
local q = {}
|
||||
q.chan = love.thread.getChannel(self.Name)
|
||||
function q:push(dat)
|
||||
if type(dat) == "function" then
|
||||
fRef[2] = THREAD.dump(dat)
|
||||
self.chan:push(fRef)
|
||||
return
|
||||
else
|
||||
self.chan:push(dat)
|
||||
end
|
||||
end
|
||||
function q:pop()
|
||||
local dat = self.chan:pop()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
function q:peek()
|
||||
local dat = self.chan:peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
return q
|
||||
end
|
||||
THREAD.package(name,c)
|
||||
return c
|
||||
end
|
||||
function multi:newSystemThreadedTable(name)
|
||||
local c = {}
|
||||
c.name = name
|
||||
function c:init()
|
||||
return THREAD.createTable(self.name)
|
||||
end
|
||||
THREAD.package(name,c)
|
||||
return c
|
||||
end
|
||||
local jqc = 1
|
||||
function multi:newSystemThreadedJobQueue(n)
|
||||
local c = {}
|
||||
c.cores = n or THREAD.getCores()
|
||||
c.registerQueue = {}
|
||||
c.funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table")
|
||||
c.queue = love.thread.getChannel("__JobQueue_"..jqc.."_queue")
|
||||
c.queueReturn = love.thread.getChannel("__JobQueue_"..jqc.."_queueReturn")
|
||||
c.queueAll = love.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
|
||||
c.id = 0
|
||||
c.OnJobCompleted = multi:newConnection()
|
||||
local allfunc = 0
|
||||
function c:doToAll(func)
|
||||
local f = THREAD.dump(func)
|
||||
for i = 1, self.cores do
|
||||
self.queueAll:push({allfunc,f})
|
||||
end
|
||||
allfunc = allfunc + 1
|
||||
end
|
||||
function c:registerFunction(name,func)
|
||||
if self.funcs[name] then
|
||||
error("A function by the name "..name.." has already been registered!")
|
||||
end
|
||||
self.funcs[name] = func
|
||||
end
|
||||
function c:pushJob(name,...)
|
||||
self.id = self.id + 1
|
||||
self.queue:push{name,self.id,...}
|
||||
return self.id
|
||||
end
|
||||
local nFunc = 0
|
||||
function c:newFunction(name,func,holup) -- This registers with the queue
|
||||
if type(name)=="function" then
|
||||
holup = func
|
||||
func = name
|
||||
name = "JQ_Function_"..nFunc
|
||||
end
|
||||
nFunc = nFunc + 1
|
||||
c:registerFunction(name,func)
|
||||
return thread:newFunction(function(...)
|
||||
local id = c:pushJob(name,...)
|
||||
local link
|
||||
local rets
|
||||
link = c.OnJobCompleted(function(jid,...)
|
||||
if id==jid then
|
||||
rets = {...}
|
||||
link:Remove()
|
||||
end
|
||||
end)
|
||||
return thread.hold(function()
|
||||
if rets then
|
||||
return unpack(rets) or multi.NIL
|
||||
end
|
||||
end)
|
||||
end,holup),name
|
||||
end
|
||||
multi:newThread("jobManager",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local dat = c.queueReturn:pop()
|
||||
if dat then
|
||||
c.OnJobCompleted:Fire(unpack(dat))
|
||||
end
|
||||
end
|
||||
end)
|
||||
for i=1,c.cores do
|
||||
multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc)
|
||||
local multi, thread = require("multi"):init()
|
||||
require("love.timer")
|
||||
local function atomic(channel)
|
||||
return channel:pop()
|
||||
end
|
||||
local clock = os.clock
|
||||
local funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table")
|
||||
local queue = love.thread.getChannel("__JobQueue_"..jqc.."_queue")
|
||||
local queueReturn = love.thread.getChannel("__JobQueue_"..jqc.."_queueReturn")
|
||||
local lastProc = clock()
|
||||
local queueAll = love.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
|
||||
local registry = {}
|
||||
setmetatable(_G,{__index = funcs})
|
||||
multi:newThread("startUp",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
lastProc = os.clock()
|
||||
THREAD.loadDump(queueAll:pop()[2])()
|
||||
end
|
||||
end
|
||||
end)
|
||||
multi:newThread("runner",function()
|
||||
thread.sleep(.1)
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
lastProc = os.clock()
|
||||
THREAD.loadDump(queueAll:pop()[2])()
|
||||
end
|
||||
local dat = queue:performAtomic(atomic)
|
||||
if dat then
|
||||
lastProc = os.clock()
|
||||
local name = table.remove(dat,1)
|
||||
local id = table.remove(dat,1)
|
||||
local tab = {funcs[name](unpack(dat))}
|
||||
table.insert(tab,1,id)
|
||||
queueReturn:push(tab)
|
||||
end
|
||||
end
|
||||
end):OnError(function(...)
|
||||
error(...)
|
||||
end)
|
||||
multi:newThread("Idler",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
if clock()-lastProc> 2 then
|
||||
THREAD.sleep(.05)
|
||||
else
|
||||
THREAD.sleep(.001)
|
||||
end
|
||||
end
|
||||
end)
|
||||
multi:mainloop()
|
||||
end,jqc)
|
||||
end
|
||||
jqc = jqc + 1
|
||||
return c
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi").init()
|
||||
GLOBAL = multi.integration.GLOBAL
|
||||
THREAD = multi.integration.THREAD
|
||||
function multi:newSystemThreadedQueue(name)
|
||||
local c = {}
|
||||
c.Name = name
|
||||
local fRef = {"func",nil}
|
||||
function c:init()
|
||||
local q = {}
|
||||
q.chan = lovr.thread.getChannel(self.Name)
|
||||
function q:push(dat)
|
||||
if type(dat) == "function" then
|
||||
fRef[2] = THREAD.dump(dat)
|
||||
self.chan:push(fRef)
|
||||
return
|
||||
else
|
||||
self.chan:push(dat)
|
||||
end
|
||||
end
|
||||
function q:pop()
|
||||
local dat = self.chan:pop()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
function q:peek()
|
||||
local dat = self.chan:peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
return q
|
||||
end
|
||||
THREAD.package(name,c)
|
||||
return c
|
||||
end
|
||||
function multi:newSystemThreadedTable(name)
|
||||
local c = {}
|
||||
c.name = name
|
||||
function c:init()
|
||||
return THREAD.createTable(self.name)
|
||||
end
|
||||
THREAD.package(name,c)
|
||||
return c
|
||||
end
|
||||
local jqc = 1
|
||||
function multi:newSystemThreadedJobQueue(n)
|
||||
local c = {}
|
||||
c.cores = n or THREAD.getCores()
|
||||
c.registerQueue = {}
|
||||
c.funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table")
|
||||
c.queue = lovr.thread.getChannel("__JobQueue_"..jqc.."_queue")
|
||||
c.queueReturn = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueReturn")
|
||||
c.queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
|
||||
c.id = 0
|
||||
c.OnJobCompleted = multi:newConnection()
|
||||
local allfunc = 0
|
||||
function c:doToAll(func)
|
||||
local f = THREAD.dump(func)
|
||||
for i = 1, self.cores do
|
||||
self.queueAll:push({allfunc,f})
|
||||
end
|
||||
allfunc = allfunc + 1
|
||||
end
|
||||
function c:registerFunction(name,func)
|
||||
if self.funcs[name] then
|
||||
error("A function by the name "..name.." has already been registered!")
|
||||
end
|
||||
self.funcs[name] = func
|
||||
end
|
||||
function c:pushJob(name,...)
|
||||
self.id = self.id + 1
|
||||
self.queue:push{name,self.id,...}
|
||||
return self.id
|
||||
end
|
||||
function c:isEmpty()
|
||||
return queueJob:peek()==nil
|
||||
end
|
||||
local nFunc = 0
|
||||
function c:newFunction(name,func,holup) -- This registers with the queue
|
||||
if type(name)=="function" then
|
||||
holup = func
|
||||
func = name
|
||||
name = "JQ_Function_"..nFunc
|
||||
end
|
||||
nFunc = nFunc + 1
|
||||
c:registerFunction(name,func)
|
||||
return thread:newFunction(function(...)
|
||||
local id = c:pushJob(name,...)
|
||||
local link
|
||||
local rets
|
||||
link = c.OnJobCompleted(function(jid,...)
|
||||
if id==jid then
|
||||
rets = multi.pack(...)
|
||||
link:Destroy()
|
||||
end
|
||||
end)
|
||||
return thread.hold(function()
|
||||
if rets then
|
||||
return multi.unpack(rets) or multi.NIL
|
||||
end
|
||||
end)
|
||||
end,holup),name
|
||||
end
|
||||
thread:newThread("jobManager",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local dat = c.queueReturn:pop()
|
||||
if dat then
|
||||
c.OnJobCompleted:Fire(multi.unpack(dat))
|
||||
end
|
||||
end
|
||||
end)
|
||||
for i=1,c.cores do
|
||||
multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc)
|
||||
local multi, thread = require("multi"):init()
|
||||
require("lovr.timer")
|
||||
local function atomic(channel)
|
||||
return channel:pop()
|
||||
end
|
||||
local clock = os.clock
|
||||
local funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table")
|
||||
local queue = lovr.thread.getChannel("__JobQueue_"..jqc.."_queue")
|
||||
local queueReturn = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueReturn")
|
||||
local lastProc = clock()
|
||||
local queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
|
||||
local registry = {}
|
||||
_G["__QR"] = queueReturn
|
||||
setmetatable(_G,{__index = funcs})
|
||||
thread:newThread("startUp",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
lastProc = os.clock()
|
||||
THREAD.loadDump(queueAll:pop()[2])()
|
||||
end
|
||||
end
|
||||
end)
|
||||
thread:newThread("runner",function()
|
||||
thread.sleep(.1)
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
lastProc = os.clock()
|
||||
THREAD.loadDump(queueAll:pop()[2])()
|
||||
end
|
||||
local dat = queue:performAtomic(atomic)
|
||||
if dat then
|
||||
lastProc = os.clock()
|
||||
local name = table.remove(dat,1)
|
||||
local id = table.remove(dat,1)
|
||||
local tab = {funcs[name](multi.unpack(dat))}
|
||||
table.insert(tab,1,id)
|
||||
queueReturn:push(tab)
|
||||
end
|
||||
end
|
||||
end):OnError(function(...)
|
||||
error(...)
|
||||
end)
|
||||
thread:newThread("Idler",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
if clock()-lastProc> 2 then
|
||||
THREAD.sleep(.05)
|
||||
else
|
||||
THREAD.sleep(.001)
|
||||
end
|
||||
end
|
||||
end)
|
||||
multi:mainloop()
|
||||
end,jqc)
|
||||
end
|
||||
jqc = jqc + 1
|
||||
return c
|
||||
end
|
||||
@@ -1,86 +1,98 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
if ISTHREAD then
|
||||
error("You cannot require the loveManager from within a thread!")
|
||||
end
|
||||
local ThreadFileData = [[
|
||||
ISTHREAD = true
|
||||
THREAD = require("multi.integration.loveManager.threads") -- order is important!
|
||||
sThread = THREAD
|
||||
__IMPORTS = {...}
|
||||
__FUNC__=table.remove(__IMPORTS,1)
|
||||
__THREADID__=table.remove(__IMPORTS,1)
|
||||
__THREADNAME__=table.remove(__IMPORTS,1)
|
||||
stab = THREAD.createStaticTable(__THREADNAME__)
|
||||
GLOBAL = THREAD.getGlobal()
|
||||
multi, thread = require("multi").init()
|
||||
stab["returns"] = {THREAD.loadDump(__FUNC__)(unpack(__IMPORTS))}
|
||||
]]
|
||||
local multi, thread = require("multi.compat.love2d"):init()
|
||||
local THREAD = {}
|
||||
__THREADID__ = 0
|
||||
__THREADNAME__ = "MainThread"
|
||||
multi.integration={}
|
||||
multi.integration.love2d={}
|
||||
local THREAD = require("multi.integration.loveManager.threads")
|
||||
local GLOBAL = THREAD.getGlobal()
|
||||
local THREAD_ID = 1
|
||||
local OBJECT_ID = 0
|
||||
local stf = 0
|
||||
function THREAD:newFunction(func,holup)
|
||||
stf = stf + 1
|
||||
return function(...)
|
||||
local t = multi:newSystemThread("STF"..stf,func,...)
|
||||
return thread:newFunction(function()
|
||||
return thread.hold(function()
|
||||
if t.stab["returns"] then
|
||||
local dat = t.stab.returns
|
||||
t.stab.returns = nil
|
||||
return unpack(dat)
|
||||
end
|
||||
end)
|
||||
end,holup)()
|
||||
end
|
||||
end
|
||||
function multi:newSystemThread(name,func,...)
|
||||
local c = {}
|
||||
c.name = name
|
||||
c.ID=THREAD_ID
|
||||
c.thread=love.thread.newThread(ThreadFileData)
|
||||
c.thread:start(THREAD.dump(func),c.ID,c.name,...)
|
||||
c.stab = THREAD.createStaticTable(name)
|
||||
GLOBAL["__THREAD_"..c.ID] = {ID=c.ID,Name=c.name,Thread=c.thread}
|
||||
GLOBAL["__THREAD_COUNT"] = THREAD_ID
|
||||
THREAD_ID=THREAD_ID+1
|
||||
return c
|
||||
end
|
||||
function love.threaderror(thread, errorstr)
|
||||
print("Thread error!\n"..errorstr)
|
||||
end
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.loveManager.extensions")
|
||||
return {init=function()
|
||||
return GLOBAL,THREAD
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
-- TODO make compatible with lovr
|
||||
if ISTHREAD then
|
||||
error("You cannot require the lovrManager from within a thread!")
|
||||
end
|
||||
local ThreadFileData = [[
|
||||
ISTHREAD = true
|
||||
THREAD = require("multi.integration.lovrManager.threads") -- order is important!
|
||||
sThread = THREAD
|
||||
__IMPORTS = {...}
|
||||
__FUNC__=table.remove(__IMPORTS,1)
|
||||
__THREADID__=table.remove(__IMPORTS,1)
|
||||
__THREADNAME__=table.remove(__IMPORTS,1)
|
||||
stab = THREAD.createStaticTable(__THREADNAME__)
|
||||
GLOBAL = THREAD.getGlobal()
|
||||
multi, thread = require("multi").init()
|
||||
stab["returns"] = {THREAD.loadDump(__FUNC__)(multi.unpack(__IMPORTS))}
|
||||
]]
|
||||
local multi, thread = require("multi.compat.lovr2d"):init()
|
||||
local THREAD = {}
|
||||
__THREADID__ = 0
|
||||
__THREADNAME__ = "MainThread"
|
||||
_G.THREAD_NAME = "MAIN_THREAD"
|
||||
_G.THREAD_ID = 0
|
||||
multi.integration={}
|
||||
multi.integration.lovr2d={}
|
||||
local THREAD = require("multi.integration.lovrManager.threads")
|
||||
local GLOBAL = THREAD.getGlobal()
|
||||
local THREAD_ID = 1
|
||||
local OBJECT_ID = 0
|
||||
local stf = 0
|
||||
function THREAD:newFunction(func,holup)
|
||||
stf = stf + 1
|
||||
return function(...)
|
||||
local t = multi:newSystemThread("STF"..stf,func,...)
|
||||
return thread:newFunction(function()
|
||||
return thread.hold(function()
|
||||
if t.stab["returns"] then
|
||||
local dat = t.stab.returns
|
||||
t.stab.returns = nil
|
||||
return multi.unpack(dat)
|
||||
end
|
||||
end)
|
||||
end,holup)()
|
||||
end
|
||||
end
|
||||
function multi:newSystemThread(name,func,...)
|
||||
local c = {}
|
||||
c.name = name
|
||||
c.ID=THREAD_ID
|
||||
c.thread=lovr.thread.newThread(ThreadFileData)
|
||||
c.thread:start(THREAD.dump(func),c.ID,c.name,...)
|
||||
c.stab = THREAD.createStaticTable(name)
|
||||
GLOBAL["__THREAD_"..c.ID] = {ID=c.ID,Name=c.name,Thread=c.thread}
|
||||
GLOBAL["__THREAD_COUNT"] = THREAD_ID
|
||||
THREAD_ID=THREAD_ID+1
|
||||
|
||||
if self.isActor then
|
||||
self:create(c)
|
||||
else
|
||||
multi.create(multi, c)
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
THREAD.newSystemThread = multi.newSystemThread
|
||||
function lovr.threaderror(thread, errorstr)
|
||||
multi.print("Thread error!\n"..errorstr)
|
||||
end
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.lovrManager.extensions")
|
||||
multi.print("Integrated lovr Threading!")
|
||||
return {init=function()
|
||||
return GLOBAL,THREAD
|
||||
end}
|
||||
@@ -1,221 +1,222 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
require("love.timer")
|
||||
require("love.system")
|
||||
require("love.data")
|
||||
local socket = require("socket")
|
||||
local multi, thread = require("multi").init()
|
||||
local threads = {}
|
||||
function threads.loadDump(d)
|
||||
return loadstring(d:getString())
|
||||
end
|
||||
function threads.dump(func)
|
||||
return love.data.newByteData(string.dump(func))
|
||||
end
|
||||
local fRef = {"func",nil}
|
||||
local function manage(channel, value)
|
||||
channel:clear()
|
||||
if type(value) == "function" then
|
||||
fRef[2] = THREAD.dump(value)
|
||||
channel:push(fRef)
|
||||
return
|
||||
else
|
||||
channel:push(value)
|
||||
end
|
||||
end
|
||||
local function RandomVariable(length)
|
||||
local res = {}
|
||||
math.randomseed(socket.gettime()*10000)
|
||||
for i = 1, length do
|
||||
res[#res+1] = string.char(math.random(97, 122))
|
||||
end
|
||||
return table.concat(res)
|
||||
end
|
||||
local GNAME = "__GLOBAL_"
|
||||
local proxy = {}
|
||||
function threads.set(name,val)
|
||||
if not proxy[name] then proxy[name] = love.thread.getChannel(GNAME..name) end
|
||||
proxy[name]:performAtomic(manage, val)
|
||||
end
|
||||
function threads.get(name)
|
||||
if not proxy[name] then proxy[name] = love.thread.getChannel(GNAME..name) end
|
||||
local dat = proxy[name]:peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
function threads.waitFor(name)
|
||||
if thread.isThread() then
|
||||
return thread.hold(function()
|
||||
return threads.get(name)
|
||||
end)
|
||||
end
|
||||
while threads.get(name)==nil do
|
||||
love.timer.sleep(.001)
|
||||
end
|
||||
local dat = threads.get(name)
|
||||
if type(dat) == "table" and dat.init then
|
||||
dat.init = threads.loadDump(dat.init)
|
||||
end
|
||||
return dat
|
||||
end
|
||||
function threads.package(name,val)
|
||||
local init = val.init
|
||||
val.init=threads.dump(val.init)
|
||||
GLOBAL[name]=val
|
||||
val.init=init
|
||||
end
|
||||
function threads.getCores()
|
||||
return love.system.getProcessorCount()
|
||||
end
|
||||
function threads.kill()
|
||||
error("Thread Killed!")
|
||||
end
|
||||
function threads.getThreads()
|
||||
local t = {}
|
||||
for i=1,GLOBAL["__THREAD_COUNT"] do
|
||||
t[#t+1]=GLOBAL["__THREAD_"..i]
|
||||
end
|
||||
return t
|
||||
end
|
||||
function threads.getThread(n)
|
||||
return GLOBAL["__THREAD_"..n]
|
||||
end
|
||||
function threads.getName()
|
||||
return __THREADNAME__
|
||||
end
|
||||
function threads.getID()
|
||||
return __THREADID__
|
||||
end
|
||||
function threads.sleep(n)
|
||||
love.timer.sleep(n)
|
||||
end
|
||||
function threads.getGlobal()
|
||||
return setmetatable({},
|
||||
{
|
||||
__index = function(t, k)
|
||||
return THREAD.get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
THREAD.set(k,v)
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
function threads.createTable(n)
|
||||
local _proxy = {}
|
||||
local function set(name,val)
|
||||
if not _proxy[name] then _proxy[name] = love.thread.getChannel(n..name) end
|
||||
_proxy[name]:performAtomic(manage, val)
|
||||
end
|
||||
local function get(name)
|
||||
if not _proxy[name] then _proxy[name] = love.thread.getChannel(n..name) end
|
||||
local dat = _proxy[name]:peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
return setmetatable({},
|
||||
{
|
||||
__index = function(t, k)
|
||||
return get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
set(k,v)
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
function threads.getConsole()
|
||||
local c = {}
|
||||
c.queue = love.thread.getChannel("__CONSOLE__")
|
||||
function c.print(...)
|
||||
c.queue:push{...}
|
||||
end
|
||||
function c.error(err)
|
||||
c.queue:push{"ERROR in <"..__THREADNAME__..">: "..err,__THREADID__}
|
||||
error(err)
|
||||
end
|
||||
return c
|
||||
end
|
||||
if not ISTHREAD then
|
||||
local clock = os.clock
|
||||
local lastproc = clock()
|
||||
local queue = love.thread.getChannel("__CONSOLE__")
|
||||
multi:newThread("consoleManager",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
dat = queue:pop()
|
||||
if dat then
|
||||
lastproc = clock()
|
||||
print(unpack(dat))
|
||||
end
|
||||
if clock()-lastproc>2 then
|
||||
thread.sleep(.1)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
function threads.createStaticTable(n)
|
||||
local __proxy = {}
|
||||
local function set(name,val)
|
||||
if __proxy[name] then return end
|
||||
local chan = love.thread.getChannel(n..name)
|
||||
if chan:getCount()>0 then return end
|
||||
chan:performAtomic(manage, val)
|
||||
__proxy[name] = val
|
||||
end
|
||||
local function get(name)
|
||||
if __proxy[name] then return __proxy[name] end
|
||||
local dat = love.thread.getChannel(n..name):peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
__proxy[name] = THREAD.loadDump(dat[2])
|
||||
return __proxy[name]
|
||||
else
|
||||
__proxy[name] = dat
|
||||
return __proxy[name]
|
||||
end
|
||||
end
|
||||
return setmetatable({},
|
||||
{
|
||||
__index = function(t, k)
|
||||
return get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
set(k,v)
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
function threads.hold(n)
|
||||
local dat
|
||||
while not(dat) do
|
||||
dat = n()
|
||||
end
|
||||
end
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
-- TODO make compatible with lovr
|
||||
require("lovr.timer")
|
||||
require("lovr.system")
|
||||
require("lovr.data")
|
||||
local socket = require("socket")
|
||||
local multi, thread = require("multi").init()
|
||||
local threads = {}
|
||||
function threads.loadDump(d)
|
||||
return loadstring(d:getString())
|
||||
end
|
||||
function threads.dump(func)
|
||||
return lovr.data.newByteData(string.dump(func))
|
||||
end
|
||||
local fRef = {"func",nil}
|
||||
local function manage(channel, value)
|
||||
channel:clear()
|
||||
if type(value) == "function" then
|
||||
fRef[2] = THREAD.dump(value)
|
||||
channel:push(fRef)
|
||||
return
|
||||
else
|
||||
channel:push(value)
|
||||
end
|
||||
end
|
||||
local function RandomVariable(length)
|
||||
local res = {}
|
||||
math.randomseed(socket.gettime()*10000)
|
||||
for i = 1, length do
|
||||
res[#res+1] = string.char(math.random(97, 122))
|
||||
end
|
||||
return table.concat(res)
|
||||
end
|
||||
local GNAME = "__GLOBAL_"
|
||||
local proxy = {}
|
||||
function threads.set(name,val)
|
||||
if not proxy[name] then proxy[name] = lovr.thread.getChannel(GNAME..name) end
|
||||
proxy[name]:performAtomic(manage, val)
|
||||
end
|
||||
function threads.get(name)
|
||||
if not proxy[name] then proxy[name] = lovr.thread.getChannel(GNAME..name) end
|
||||
local dat = proxy[name]:peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
function threads.waitFor(name)
|
||||
if thread.isThread() then
|
||||
return thread.hold(function()
|
||||
return threads.get(name)
|
||||
end)
|
||||
end
|
||||
while threads.get(name)==nil do
|
||||
lovr.timer.sleep(.001)
|
||||
end
|
||||
local dat = threads.get(name)
|
||||
if type(dat) == "table" and dat.init then
|
||||
dat.init = threads.loadDump(dat.init)
|
||||
end
|
||||
return dat
|
||||
end
|
||||
function threads.package(name,val)
|
||||
local init = val.init
|
||||
val.init=threads.dump(val.init)
|
||||
GLOBAL[name]=val
|
||||
val.init=init
|
||||
end
|
||||
function threads.getCores()
|
||||
return lovr.system.getProcessorCount()
|
||||
end
|
||||
function threads.kill()
|
||||
error("Thread Killed!")
|
||||
end
|
||||
function threads.getThreads()
|
||||
local t = {}
|
||||
for i=1,GLOBAL["__THREAD_COUNT"] do
|
||||
t[#t+1]=GLOBAL["__THREAD_"..i]
|
||||
end
|
||||
return t
|
||||
end
|
||||
function threads.getThread(n)
|
||||
return GLOBAL["__THREAD_"..n]
|
||||
end
|
||||
function threads.getName()
|
||||
return __THREADNAME__
|
||||
end
|
||||
function threads.getID()
|
||||
return __THREADID__
|
||||
end
|
||||
function threads.sleep(n)
|
||||
lovr.timer.sleep(n)
|
||||
end
|
||||
function threads.getGlobal()
|
||||
return setmetatable({},
|
||||
{
|
||||
__index = function(t, k)
|
||||
return THREAD.get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
THREAD.set(k,v)
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
function threads.createTable(n)
|
||||
local _proxy = {}
|
||||
local function set(name,val)
|
||||
if not _proxy[name] then _proxy[name] = lovr.thread.getChannel(n..name) end
|
||||
_proxy[name]:performAtomic(manage, val)
|
||||
end
|
||||
local function get(name)
|
||||
if not _proxy[name] then _proxy[name] = lovr.thread.getChannel(n..name) end
|
||||
local dat = _proxy[name]:peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
return THREAD.loadDump(dat[2])
|
||||
else
|
||||
return dat
|
||||
end
|
||||
end
|
||||
return setmetatable({},
|
||||
{
|
||||
__index = function(t, k)
|
||||
return get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
set(k,v)
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
function threads.getConsole()
|
||||
local c = {}
|
||||
c.queue = lovr.thread.getChannel("__CONSOLE__")
|
||||
function c.print(...)
|
||||
c.queue:push(multi.pack(...))
|
||||
end
|
||||
function c.error(err)
|
||||
c.queue:push{"ERROR in <"..__THREADNAME__..">: "..err,__THREADID__}
|
||||
error(err)
|
||||
end
|
||||
return c
|
||||
end
|
||||
if not ISTHREAD then
|
||||
local clock = os.clock
|
||||
local lastproc = clock()
|
||||
local queue = lovr.thread.getChannel("__CONSOLE__")
|
||||
thread:newThread("consoleManager",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
dat = queue:pop()
|
||||
if dat then
|
||||
lastproc = clock()
|
||||
print(multi.unpack(dat))
|
||||
end
|
||||
if clock()-lastproc>2 then
|
||||
thread.sleep(.1)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
function threads.createStaticTable(n)
|
||||
local __proxy = {}
|
||||
local function set(name,val)
|
||||
if __proxy[name] then return end
|
||||
local chan = lovr.thread.getChannel(n..name)
|
||||
if chan:getCount()>0 then return end
|
||||
chan:performAtomic(manage, val)
|
||||
__proxy[name] = val
|
||||
end
|
||||
local function get(name)
|
||||
if __proxy[name] then return __proxy[name] end
|
||||
local dat = lovr.thread.getChannel(n..name):peek()
|
||||
if type(dat)=="table" and dat[1]=="func" then
|
||||
__proxy[name] = THREAD.loadDump(dat[2])
|
||||
return __proxy[name]
|
||||
else
|
||||
__proxy[name] = dat
|
||||
return __proxy[name]
|
||||
end
|
||||
end
|
||||
return setmetatable({},
|
||||
{
|
||||
__index = function(t, k)
|
||||
return get(k)
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
set(k,v)
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
function threads.hold(n)
|
||||
local dat
|
||||
while not(dat) do
|
||||
dat = n()
|
||||
end
|
||||
end
|
||||
return threads
|
||||
@@ -1,137 +1,138 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
|
||||
-- This module probably will not be maintained any longer!
|
||||
package.path = "?/init.lua;?.lua;" .. package.path
|
||||
local function _INIT(luvitThread, timer)
|
||||
-- lots of this stuff should be able to stay the same
|
||||
function os.getOS()
|
||||
if package.config:sub(1, 1) == "\\" then
|
||||
return "windows"
|
||||
else
|
||||
return "unix"
|
||||
end
|
||||
end
|
||||
-- Step 1 get setup threads on luvit... Sigh how do i even...
|
||||
local multi, thread = require("multi").init()
|
||||
isMainThread = true
|
||||
function multi:canSystemThread()
|
||||
return true
|
||||
end
|
||||
function multi:getPlatform()
|
||||
return "luvit"
|
||||
end
|
||||
local multi = multi
|
||||
-- Step 2 set up the Global table... is this possible?
|
||||
local GLOBAL = {}
|
||||
setmetatable(
|
||||
GLOBAL,
|
||||
{
|
||||
__index = function(t, k)
|
||||
--print("No Global table when using luvit integration!")
|
||||
return nil
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
}
|
||||
)
|
||||
local THREAD = {}
|
||||
function THREAD.set(name, val)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.get(name)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
local function randomString(n)
|
||||
local str = ""
|
||||
local strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","1","2","3","4","5","6","7","8","9","0","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}
|
||||
for i = 1, n do
|
||||
str = str .. "" .. strings[math.random(1, #strings)]
|
||||
end
|
||||
return str
|
||||
end
|
||||
function THREAD.waitFor(name)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.testFor(name, val, sym)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.getCores()
|
||||
return THREAD.__CORES
|
||||
end
|
||||
if os.getOS() == "windows" then
|
||||
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
|
||||
else
|
||||
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
|
||||
end
|
||||
function THREAD.kill() -- trigger the thread destruction
|
||||
error("Thread was Killed!")
|
||||
end
|
||||
-- hmmm if im cleaver I can get this to work... but since data passing isn't going to be a thing its probably not important
|
||||
function THREAD.sleep(n)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.hold(n)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
-- Step 5 Basic Threads!
|
||||
local function entry(path, name, func, ...)
|
||||
local timer = require "timer"
|
||||
local luvitThread = require "thread"
|
||||
package.path = path
|
||||
loadstring(func)(...)
|
||||
end
|
||||
function multi:newSystemThread(name, func, ...)
|
||||
local c = {}
|
||||
local __self = c
|
||||
c.name = name
|
||||
c.Type = "sthread"
|
||||
c.thread = {}
|
||||
c.func = string.dump(func)
|
||||
function c:kill()
|
||||
-- print("No Global table when using luvit integration!")
|
||||
end
|
||||
luvitThread.start(entry, package.path, name, c.func, ...)
|
||||
return c
|
||||
end
|
||||
multi.print("Integrated Luvit!")
|
||||
multi.integration = {} -- for module creators
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.shared")
|
||||
-- Start the main mainloop... This allows you to process your multi objects, but the engine on the main thread will be limited to .001 or 1 millisecond sigh...
|
||||
local interval =
|
||||
timer.setInterval(
|
||||
1,
|
||||
function()
|
||||
multi:uManager()
|
||||
end
|
||||
)
|
||||
return multi
|
||||
end
|
||||
return {init = function(threadHandle, timerHandle)
|
||||
local multi = _INIT(threadHandle, timerHandle)
|
||||
return GLOBAL, THREAD
|
||||
end}
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
|
||||
-- This module probably will not be maintained any longer!
|
||||
package.path = "?/init.lua;?.lua;" .. package.path
|
||||
local function _INIT(luvitThread, timer)
|
||||
-- lots of this stuff should be able to stay the same
|
||||
function os.getOS()
|
||||
if package.config:sub(1, 1) == "\\" then
|
||||
return "windows"
|
||||
else
|
||||
return "unix"
|
||||
end
|
||||
end
|
||||
-- Step 1 get setup threads on luvit... Sigh how do i even...
|
||||
local multi, thread = require("multi").init()
|
||||
multi.isMainThread = true
|
||||
function multi:canSystemThread()
|
||||
return true
|
||||
end
|
||||
function multi:getPlatform()
|
||||
return "luvit"
|
||||
end
|
||||
local multi = multi
|
||||
-- Step 2 set up the Global table... is this possible?
|
||||
local GLOBAL = {}
|
||||
setmetatable(
|
||||
GLOBAL,
|
||||
{
|
||||
__index = function(t, k)
|
||||
--print("No Global table when using luvit integration!")
|
||||
return nil
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
}
|
||||
)
|
||||
local THREAD = {}
|
||||
function THREAD.set(name, val)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.get(name)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
local function randomString(n)
|
||||
local str = ""
|
||||
local strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","1","2","3","4","5","6","7","8","9","0","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}
|
||||
for i = 1, n do
|
||||
str = str .. "" .. strings[math.random(1, #strings)]
|
||||
end
|
||||
return str
|
||||
end
|
||||
function THREAD.waitFor(name)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.testFor(name, val, sym)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.getCores()
|
||||
return THREAD.__CORES
|
||||
end
|
||||
if os.getOS() == "windows" then
|
||||
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
|
||||
else
|
||||
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
|
||||
end
|
||||
function THREAD.kill() -- trigger the thread destruction
|
||||
error("Thread was Killed!")
|
||||
end
|
||||
-- hmmm if im cleaver I can get this to work... but since data passing isn't going to be a thing its probably not important
|
||||
function THREAD.sleep(n)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
function THREAD.hold(n)
|
||||
--print("No Global table when using luvit integration!")
|
||||
end
|
||||
-- Step 5 Basic Threads!
|
||||
local function entry(path, name, func, ...)
|
||||
local timer = require "timer"
|
||||
local luvitThread = require "thread"
|
||||
package.path = path
|
||||
loadstring(func)(...)
|
||||
end
|
||||
function multi:newSystemThread(name, func, ...)
|
||||
local c = {}
|
||||
local __self = c
|
||||
c.name = name
|
||||
c.Type = multi.STHREAD
|
||||
c.thread = {}
|
||||
c.func = string.dump(func)
|
||||
function c:kill()
|
||||
-- print("No Global table when using luvit integration!")
|
||||
end
|
||||
luvitThread.start(entry, package.path, name, c.func, ...)
|
||||
return c
|
||||
end
|
||||
THREAD.newSystemThread = multi.newSystemThread
|
||||
multi.print("Integrated Luvit!")
|
||||
multi.integration = {} -- for module creators
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.shared")
|
||||
-- Start the main mainloop... This allows you to process your multi objects, but the engine on the main thread will be limited to .001 or 1 millisecond sigh...
|
||||
local interval =
|
||||
timer.setInterval(
|
||||
1,
|
||||
function()
|
||||
multi:uManager()
|
||||
end
|
||||
)
|
||||
return multi
|
||||
end
|
||||
return {init = function(threadHandle, timerHandle)
|
||||
local multi = _INIT(threadHandle, timerHandle)
|
||||
return GLOBAL, THREAD
|
||||
end}
|
||||
+33
-33
@@ -1,34 +1,34 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
_G["__CHANNEL__"] = {}
|
||||
local channel = {}
|
||||
channel.__index = channel
|
||||
|
||||
-- Creates/Gets a channel of name
|
||||
function channel:newChannel(name)
|
||||
local chan = _G["__CHANNEL__"]
|
||||
if chan then
|
||||
|
||||
end
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
_G["__CHANNEL__"] = {}
|
||||
local channel = {}
|
||||
channel.__index = channel
|
||||
|
||||
-- Creates/Gets a channel of name
|
||||
function channel:newChannel(name)
|
||||
local chan = _G["__CHANNEL__"]
|
||||
if chan then
|
||||
|
||||
end
|
||||
end
|
||||
+45
-45
@@ -1,46 +1,46 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local node = require("multi.integration.networkManager.node")
|
||||
local net = require("net")
|
||||
local bin = require("bin")
|
||||
local child = {}
|
||||
child.__index = child
|
||||
function multi:newChildNode(cd)
|
||||
local c = {}
|
||||
setmetatable(c,child)
|
||||
local name
|
||||
if cd then
|
||||
if cd.name then
|
||||
name = cd.name
|
||||
end
|
||||
c.node = node:new(cd.nodePort or cmd.defaultPort,nil,name)
|
||||
if cd.managerHost then
|
||||
cd.managerPort = cd.managerPort or cmd.defaultManagerPort
|
||||
c.node:registerWithManager(cd.managerHost,cd.managerPort)
|
||||
end
|
||||
end
|
||||
return c
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local node = require("multi.integration.networkManager.node")
|
||||
local net = require("net")
|
||||
local bin = require("bin")
|
||||
local child = {}
|
||||
child.__index = child
|
||||
function multi:newChildNode(cd)
|
||||
local c = {}
|
||||
setmetatable(c,child)
|
||||
local name
|
||||
if cd then
|
||||
if cd.name then
|
||||
name = cd.name
|
||||
end
|
||||
c.node = node:new(cd.nodePort or cmd.defaultPort,nil,name)
|
||||
if cd.managerHost then
|
||||
cd.managerPort = cd.managerPort or cmd.defaultManagerPort
|
||||
c.node:registerWithManager(cd.managerHost,cd.managerPort)
|
||||
end
|
||||
end
|
||||
return c
|
||||
end
|
||||
+34
-34
@@ -1,35 +1,35 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
return function(self,data)
|
||||
local cmd,data = data:match("!(.-)!(.*)")
|
||||
--print(">",cmd,data)
|
||||
if cmd == "PONG" then
|
||||
self:send("!PONG!")
|
||||
elseif cmd == "CHANNEL" then
|
||||
--
|
||||
elseif cmd == "RETURNS" then
|
||||
local rets = bin.new(data):getBlock("t")
|
||||
self.node.master.OnDataReturned:Fire(rets)
|
||||
end
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
return function(self,data)
|
||||
local cmd,data = data:match("!(.-)!(.*)")
|
||||
--print(">",cmd,data)
|
||||
if cmd == "PONG" then
|
||||
self:send("!PONG!")
|
||||
elseif cmd == "CHANNEL" then
|
||||
--
|
||||
elseif cmd == "RETURNS" then
|
||||
local rets = bin.new(data):getBlock("t")
|
||||
self.node.master.OnDataReturned:Fire(rets)
|
||||
end
|
||||
end
|
||||
@@ -1,42 +1,42 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local cmds = {
|
||||
defaultManagerPort = 0XDE2,
|
||||
defaultWait = 0X002,
|
||||
defaultPort = 0X000, -- We will let the OS assign us one
|
||||
standardSkip = 0X018,
|
||||
ERROR = 0X000,
|
||||
PING = 0X001,
|
||||
PONG = 0X002,
|
||||
QUEUE = 0X003,
|
||||
TASK = 0X004,
|
||||
INITNODE = 0X005,
|
||||
INITMASTER = 0X006,
|
||||
GLOBAL = 0X007,
|
||||
LOAD = 0X008,
|
||||
CALL = 0X009,
|
||||
REG = 0X00A,
|
||||
CONSOLE = 0X00B,
|
||||
}
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local cmds = {
|
||||
defaultManagerPort = 0XDE2,
|
||||
defaultWait = 0X002,
|
||||
defaultPort = 0X000, -- We will let the OS assign us one
|
||||
standardSkip = 0X018,
|
||||
ERROR = 0X000,
|
||||
PING = 0X001,
|
||||
PONG = 0X002,
|
||||
QUEUE = 0X003,
|
||||
TASK = 0X004,
|
||||
INITNODE = 0X005,
|
||||
INITMASTER = 0X006,
|
||||
GLOBAL = 0X007,
|
||||
LOAD = 0X008,
|
||||
CALL = 0X009,
|
||||
REG = 0X00A,
|
||||
CONSOLE = 0X00B,
|
||||
}
|
||||
return cmds
|
||||
+22
-22
@@ -1,23 +1,23 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
@@ -1,57 +1,57 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local net = require("net")
|
||||
local bin = require("bin")
|
||||
local char = string.char
|
||||
local byte = string.byte
|
||||
bin.setBitsInterface(infinabits)
|
||||
--[[
|
||||
--[=[ Pre reqs:
|
||||
- Network contains nodes
|
||||
- Network can broadcast/has nodemanager/ is simple and can be scanned
|
||||
|
||||
Outline:
|
||||
- multi:newMasterNode(connectionDetails)
|
||||
-- master:setDefaultNode(nodeName) -- Set default node
|
||||
-- master:newNetworkThread(nodeName,func,...) -- Thread is ran on a random node or the default one if set if nodeName is set to nil
|
||||
-- master:newNetworkChannel(nodeName)
|
||||
-- master:sendTo(nodeName,data)
|
||||
- multi:newNode(connectionDetails)
|
||||
- multi:newNodeManager(connectionDetails) -- This will be incharge of a lot of data handling
|
||||
]=]
|
||||
|
||||
local nGLOBAL, nTHREAD = require("multi.integration.networkManager"):init()
|
||||
local master = multi:newMasterNode()
|
||||
master:newNetworkThread("simpleNode",function(a,b,c)
|
||||
print(a,b,c)
|
||||
end,1,2,3)
|
||||
]]
|
||||
|
||||
-- The init file should provide the structure that all the other modules build off of
|
||||
return {
|
||||
init = function()
|
||||
--
|
||||
end
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local net = require("net")
|
||||
--local bin = require("bin")
|
||||
local char = string.char
|
||||
local byte = string.byte
|
||||
bin.setBitsInterface(infinabits)
|
||||
--[[
|
||||
--[=[ Pre reqs:
|
||||
- Network contains nodes
|
||||
- Network can broadcast/has nodemanager/ is simple and can be scanned
|
||||
|
||||
Outline:
|
||||
- multi:newMasterNode(connectionDetails)
|
||||
-- master:setDefaultNode(nodeName) -- Set default node
|
||||
-- master:newNetworkThread(nodeName,func,...) -- Thread is ran on a random node or the default one if set if nodeName is set to nil
|
||||
-- master:newNetworkChannel(nodeName)
|
||||
-- master:sendTo(nodeName,data)
|
||||
- multi:newNode(connectionDetails)
|
||||
- multi:newNodeManager(connectionDetails) -- This will be incharge of a lot of data handling
|
||||
]=]
|
||||
|
||||
local nGLOBAL, nTHREAD = require("multi.integration.networkManager"):init()
|
||||
local master = multi:newMasterNode()
|
||||
master:newNetworkThread("simpleNode",function(a,b,c)
|
||||
print(a,b,c)
|
||||
end,1,2,3)
|
||||
]]
|
||||
|
||||
-- The init file should provide the structure that all the other modules build off of
|
||||
return {
|
||||
init = function()
|
||||
--
|
||||
end
|
||||
}
|
||||
+162
-162
@@ -1,163 +1,163 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local node = require("multi.integration.networkManager.node")
|
||||
local net = require("net")
|
||||
local bin = require("bin")
|
||||
local master = {}
|
||||
master.__index = master
|
||||
function master:addNode(ip,port)
|
||||
return node:new(ip,port)
|
||||
end
|
||||
function master:getNodesFromBroadcast()
|
||||
net:newCastedClients("NODE_.+")
|
||||
net.OnCastedClientInfo(function(client, n, ip, port)
|
||||
self.nodes[n] = node:new(client)
|
||||
end)
|
||||
end
|
||||
function master:getNodesFromManager(ip,port)
|
||||
local mn = self.nodes
|
||||
if not self.manager then
|
||||
self.manager = net:newTCPClient(ip,port)
|
||||
if not self.manager then
|
||||
error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!")
|
||||
end
|
||||
end
|
||||
self.manager.OnDataRecieved(function(self,data,client)
|
||||
local cmd = data:match("!(.+)!")
|
||||
data = data:gsub("!"..cmd.."!","")
|
||||
if cmd == "NODE" then
|
||||
local n,h,p = data:match("(.-)|(.-)|(.+)")
|
||||
mn[n] = node:new(h,tonumber(p))
|
||||
end
|
||||
end)
|
||||
self.manager:send("!NODES!")
|
||||
end
|
||||
function master:setDefaultNode(nodeName)
|
||||
if self:nodeExists(nodeName) then
|
||||
self.defaultNode = nodeName
|
||||
end
|
||||
end
|
||||
function master:getRandomNode()
|
||||
local t = {}
|
||||
for i,v in pairs(self.nodes) do t[#t+1] = i end
|
||||
return t[math.random(1,#t)]
|
||||
end
|
||||
local netID = 0
|
||||
function master:newNetworkThread(nodeName,func,...)
|
||||
local args = {...}
|
||||
local dat = bin.new()
|
||||
local ret
|
||||
local nID = netID
|
||||
local conn = multi:newConnection()
|
||||
multi:newThread(function()
|
||||
dat:addBlock{
|
||||
args = args,
|
||||
func = func,
|
||||
id = netID
|
||||
}
|
||||
netID = netID + 1
|
||||
if type(nodeName) == "function" then
|
||||
func = nodeName
|
||||
nodeName = self.defaultNode or self:getRandomNode()
|
||||
if not func then
|
||||
error("You must provide a function!")
|
||||
end
|
||||
end
|
||||
self:sendTo(nodeName,"!N_THREAD!"..dat.data)
|
||||
self.OnDataReturned(function(rets)
|
||||
if rets.ID == nID then
|
||||
conn:Fire(unpack(rets.rets))
|
||||
end
|
||||
end)
|
||||
end)
|
||||
return conn
|
||||
end
|
||||
function master:newNetworkChannel(nodeName)
|
||||
--
|
||||
end
|
||||
function master:sendTo(nodeName,data)
|
||||
self:queue("send",nodeName,data)
|
||||
end
|
||||
function master:demandNodeExistance(nodeName)
|
||||
if self.nodes[nodeName] then
|
||||
return multi.hold(self.nodes[nodeName]:ping().pong)
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
function master:queue(c,...)
|
||||
table.insert(self._queue,{c,{...}})
|
||||
end
|
||||
function multi:newMasterNode(cd)
|
||||
local c = {}
|
||||
setmetatable(c, master)
|
||||
c.OnNodeDiscovered = multi:newConnection()
|
||||
c.OnNodeRemoved = multi:newConnection()
|
||||
c.OnDataRecieved = multi:newConnection()
|
||||
c.OnDataReturned = multi:newConnection()
|
||||
c.defaultNode = ""
|
||||
c.nodes = {}
|
||||
setmetatable(c.nodes,
|
||||
{__newindex = function(t,k,v)
|
||||
rawset(t,k,v)
|
||||
v.master = c
|
||||
c.OnNodeDiscovered:Fire(k,v)
|
||||
end})
|
||||
c._queue = {}
|
||||
if cd then
|
||||
if cd.nodeHost then
|
||||
cd.nodePort = cd.nodePort or cmd.defaultPort
|
||||
local n,no = c:addNode(cd.nodeHost,cd.nodePort)
|
||||
if n then
|
||||
c.nodes[n] = no
|
||||
end
|
||||
elseif cd.managerHost then
|
||||
cd.managerPort = cd.managerPort or cmd.defaultManagerPort
|
||||
c:getNodesFromManager(cd.managerHost,cd.managerPort)
|
||||
else
|
||||
c:getNodesFromBroadcast()
|
||||
end
|
||||
else
|
||||
c:getNodesFromBroadcast()
|
||||
end
|
||||
multi:newThread("CMDQueueProcessor",function()
|
||||
while true do
|
||||
thread.skip(128)
|
||||
local data = table.remove(c._queue,1)
|
||||
if data then
|
||||
local cmd = data[1]
|
||||
if cmd == "send" then
|
||||
local nodeName = data[2][1]
|
||||
local dat = data[2][2]
|
||||
c.nodes[nodeName]:send(dat)
|
||||
end
|
||||
end
|
||||
end
|
||||
end):OnError(function(...)
|
||||
print(...)
|
||||
end)
|
||||
return c
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local node = require("multi.integration.networkManager.node")
|
||||
local net = require("net")
|
||||
local bin = require("bin")
|
||||
local master = {}
|
||||
master.__index = master
|
||||
function master:addNode(ip,port)
|
||||
return node:new(ip,port)
|
||||
end
|
||||
function master:getNodesFromBroadcast()
|
||||
net:newCastedClients("NODE_.+")
|
||||
net.OnCastedClientInfo(function(client, n, ip, port)
|
||||
self.nodes[n] = node:new(client)
|
||||
end)
|
||||
end
|
||||
function master:getNodesFromManager(ip,port)
|
||||
local mn = self.nodes
|
||||
if not self.manager then
|
||||
self.manager = net:newTCPClient(ip,port)
|
||||
if not self.manager then
|
||||
error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!")
|
||||
end
|
||||
end
|
||||
self.manager.OnDataRecieved(function(self,data,client)
|
||||
local cmd = data:match("!(.+)!")
|
||||
data = data:gsub("!"..cmd.."!","")
|
||||
if cmd == "NODE" then
|
||||
local n,h,p = data:match("(.-)|(.-)|(.+)")
|
||||
mn[n] = node:new(h,tonumber(p))
|
||||
end
|
||||
end)
|
||||
self.manager:send("!NODES!")
|
||||
end
|
||||
function master:setDefaultNode(nodeName)
|
||||
if self:nodeExists(nodeName) then
|
||||
self.defaultNode = nodeName
|
||||
end
|
||||
end
|
||||
function master:getRandomNode()
|
||||
local t = {}
|
||||
for i,v in pairs(self.nodes) do t[#t+1] = i end
|
||||
return t[math.random(1,#t)]
|
||||
end
|
||||
local netID = 0
|
||||
function master:newNetworkThread(nodeName,func,...)
|
||||
local args = {...}
|
||||
local dat = bin.new()
|
||||
local ret
|
||||
local nID = netID
|
||||
local conn = multi:newConnection()
|
||||
thread:newthread(function()
|
||||
dat:addBlock{
|
||||
args = args,
|
||||
func = func,
|
||||
id = netID
|
||||
}
|
||||
netID = netID + 1
|
||||
if type(nodeName) == "function" then
|
||||
func = nodeName
|
||||
nodeName = self.defaultNode or self:getRandomNode()
|
||||
if not func then
|
||||
error("You must provide a function!")
|
||||
end
|
||||
end
|
||||
self:sendTo(nodeName,"!N_THREAD!"..dat.data)
|
||||
self.OnDataReturned(function(rets)
|
||||
if rets.ID == nID then
|
||||
conn:Fire(unpack(rets.rets))
|
||||
end
|
||||
end)
|
||||
end)
|
||||
return conn
|
||||
end
|
||||
function master:newNetworkChannel(nodeName)
|
||||
--
|
||||
end
|
||||
function master:sendTo(nodeName,data)
|
||||
self:queue("send",nodeName,data)
|
||||
end
|
||||
function master:demandNodeExistance(nodeName)
|
||||
if self.nodes[nodeName] then
|
||||
return multi.hold(self.nodes[nodeName]:ping().pong)
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
function master:queue(c,...)
|
||||
table.insert(self._queue,{c,{...}})
|
||||
end
|
||||
function multi:newMasterNode(cd)
|
||||
local c = {}
|
||||
setmetatable(c, master)
|
||||
c.OnNodeDiscovered = multi:newConnection()
|
||||
c.OnNodeRemoved = multi:newConnection()
|
||||
c.OnDataRecieved = multi:newConnection()
|
||||
c.OnDataReturned = multi:newConnection()
|
||||
c.defaultNode = ""
|
||||
c.nodes = {}
|
||||
setmetatable(c.nodes,
|
||||
{__newindex = function(t,k,v)
|
||||
rawset(t,k,v)
|
||||
v.master = c
|
||||
c.OnNodeDiscovered:Fire(k,v)
|
||||
end})
|
||||
c._queue = {}
|
||||
if cd then
|
||||
if cd.nodeHost then
|
||||
cd.nodePort = cd.nodePort or cmd.defaultPort
|
||||
local n,no = c:addNode(cd.nodeHost,cd.nodePort)
|
||||
if n then
|
||||
c.nodes[n] = no
|
||||
end
|
||||
elseif cd.managerHost then
|
||||
cd.managerPort = cd.managerPort or cmd.defaultManagerPort
|
||||
c:getNodesFromManager(cd.managerHost,cd.managerPort)
|
||||
else
|
||||
c:getNodesFromBroadcast()
|
||||
end
|
||||
else
|
||||
c:getNodesFromBroadcast()
|
||||
end
|
||||
thread:newthread("CMDQueueProcessor",function()
|
||||
while true do
|
||||
thread.skip(128)
|
||||
local data = table.remove(c._queue,1)
|
||||
if data then
|
||||
local cmd = data[1]
|
||||
if cmd == "send" then
|
||||
local nodeName = data[2][1]
|
||||
local dat = data[2][2]
|
||||
c.nodes[nodeName]:send(dat)
|
||||
end
|
||||
end
|
||||
end
|
||||
end):OnError(function(...)
|
||||
print(...)
|
||||
end)
|
||||
return c
|
||||
end
|
||||
@@ -1,127 +1,127 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local net = require("net")
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local multi,thread = require("multi"):init()
|
||||
local node = {}
|
||||
node.__index = node
|
||||
local rand = {}
|
||||
for i = 65,90 do
|
||||
rand[#rand+1] = string.char(i)
|
||||
end
|
||||
local function randName(n)
|
||||
local str = {}
|
||||
for i=1,(n or 10) do
|
||||
str[#str+1] = rand[math.random(1,#rand)]
|
||||
end
|
||||
return table.concat(str)
|
||||
end
|
||||
local getNames = thread:newFunction(function(names)
|
||||
local listen = socket.udp() -- make a new socket
|
||||
listen:setsockname(net.getLocalIP(), 11111)
|
||||
listen:settimeout(0)
|
||||
local data, ip, port = listen:receivefrom()
|
||||
thread.holdWithin(1,function()
|
||||
if data then
|
||||
local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)")
|
||||
if n then
|
||||
names[n]=true
|
||||
end
|
||||
end
|
||||
end)
|
||||
return multi.NIL
|
||||
end)
|
||||
local function setName(ref,name)
|
||||
if name then
|
||||
ref.name = "NODE_"..name
|
||||
ref.connection:broadcast(name)
|
||||
return
|
||||
end
|
||||
local names = {}
|
||||
getNames(names).wait() -- Prevents duplicate names from spawning!
|
||||
local name = randName()
|
||||
while names["NODE_"..name] do
|
||||
name = randName()
|
||||
end
|
||||
ref.name = "NODE_"..name
|
||||
ref.connection:broadcast(ref.name)
|
||||
end
|
||||
node.ServerCode = require("multi.integration.networkManager.serverSide")
|
||||
node.ClientCode = require("multi.integration.networkManager.clientSide")
|
||||
function node.random()
|
||||
return randName(12)
|
||||
end
|
||||
function node:registerWithManager(ip,port)
|
||||
if self.type ~= "server" then return end
|
||||
if not self.manager then
|
||||
self.manager = net:newTCPClient(ip,port)
|
||||
if not self.manager then
|
||||
error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!")
|
||||
end
|
||||
end
|
||||
thread:newFunction(function()
|
||||
thread.hold(function() return self.name end)
|
||||
self.manager:send("!REG_NODE!"..self.name.."|"..net.getLocalIP().."|"..self.connection.port)
|
||||
end)()
|
||||
end
|
||||
function node:new(host,port,name)
|
||||
local c = {}
|
||||
c.links = {}
|
||||
setmetatable(c,node)
|
||||
if type(host)=="number" or type(host)=="nil" then
|
||||
c.connection = net:newTCPServer(host or cmd.defaultPort)
|
||||
c.connection:enableBinaryMode()
|
||||
c.type = "server"
|
||||
c.connection.node = c
|
||||
c.connection.OnDataRecieved(self.ServerCode)
|
||||
setName(c)
|
||||
elseif type(host)=="table" and host.Type == "tcp" then
|
||||
c.connection = host
|
||||
c.connection:enableBinaryMode()
|
||||
c.type = "client"
|
||||
c.connection.node = c
|
||||
c.connection.OnDataRecieved(self.ClientCode)
|
||||
c.name = "MASTER_NODE"
|
||||
elseif type(host) == "string" and type(port)=="number" then
|
||||
c.connection = net:newTCPClient(host, port)
|
||||
c.connection:enableBinaryMode()
|
||||
c.type = "client"
|
||||
c.connection.node = c
|
||||
c.connection.OnDataRecieved(self.ClientCode)
|
||||
c.name = "MASTER_NODE"
|
||||
else
|
||||
error("Invalid arguments!")
|
||||
end
|
||||
return c
|
||||
end
|
||||
function node:ping()
|
||||
if self.type ~= "client" then return end
|
||||
self:send("!PING!")
|
||||
return {pong=self.connection.OnDataRecieved}
|
||||
end
|
||||
function node:send(data)
|
||||
if self.type ~= "client" then return end
|
||||
self.connection:send(data)
|
||||
end
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local net = require("net")
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local multi,thread = require("multi"):init()
|
||||
local node = {}
|
||||
node.__index = node
|
||||
local rand = {}
|
||||
for i = 65,90 do
|
||||
rand[#rand+1] = string.char(i)
|
||||
end
|
||||
local function randName(n)
|
||||
local str = {}
|
||||
for i=1,(n or 10) do
|
||||
str[#str+1] = rand[math.random(1,#rand)]
|
||||
end
|
||||
return table.concat(str)
|
||||
end
|
||||
local getNames = thread:newFunction(function(names)
|
||||
local listen = socket.udp() -- make a new socket
|
||||
listen:setsockname(net.getLocalIP(), 11111)
|
||||
listen:settimeout(0)
|
||||
local data, ip, port = listen:receivefrom()
|
||||
thread.holdWithin(1,function()
|
||||
if data then
|
||||
local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)")
|
||||
if n then
|
||||
names[n]=true
|
||||
end
|
||||
end
|
||||
end)
|
||||
return multi.NIL
|
||||
end)
|
||||
local function setName(ref,name)
|
||||
if name then
|
||||
ref.name = "NODE_"..name
|
||||
ref.connection:broadcast(name)
|
||||
return
|
||||
end
|
||||
local names = {}
|
||||
getNames(names).wait() -- Prevents duplicate names from spawning!
|
||||
local name = randName()
|
||||
while names["NODE_"..name] do
|
||||
name = randName()
|
||||
end
|
||||
ref.name = "NODE_"..name
|
||||
ref.connection:broadcast(ref.name)
|
||||
end
|
||||
node.ServerCode = require("multi.integration.networkManager.serverSide")
|
||||
node.ClientCode = require("multi.integration.networkManager.clientSide")
|
||||
function node.random()
|
||||
return randName(12)
|
||||
end
|
||||
function node:registerWithManager(ip,port)
|
||||
if self.type ~= "server" then return end
|
||||
if not self.manager then
|
||||
self.manager = net:newTCPClient(ip,port)
|
||||
if not self.manager then
|
||||
error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!")
|
||||
end
|
||||
end
|
||||
thread:newFunction(function()
|
||||
thread.hold(function() return self.name end)
|
||||
self.manager:send("!REG_NODE!"..self.name.."|"..net.getLocalIP().."|"..self.connection.port)
|
||||
end)()
|
||||
end
|
||||
function node:new(host,port,name)
|
||||
local c = {}
|
||||
c.links = {}
|
||||
setmetatable(c,node)
|
||||
if type(host)=="number" or type(host)=="nil" then
|
||||
c.connection = net:newTCPServer(host or cmd.defaultPort)
|
||||
c.connection:enableBinaryMode()
|
||||
c.type = "server"
|
||||
c.connection.node = c
|
||||
c.connection.OnDataRecieved(self.ServerCode)
|
||||
setName(c)
|
||||
elseif type(host)=="table" and host.Type == "tcp" then
|
||||
c.connection = host
|
||||
c.connection:enableBinaryMode()
|
||||
c.type = "client"
|
||||
c.connection.node = c
|
||||
c.connection.OnDataRecieved(self.ClientCode)
|
||||
c.name = "MASTER_NODE"
|
||||
elseif type(host) == "string" and type(port)=="number" then
|
||||
c.connection = net:newTCPClient(host, port)
|
||||
c.connection:enableBinaryMode()
|
||||
c.type = "client"
|
||||
c.connection.node = c
|
||||
c.connection.OnDataRecieved(self.ClientCode)
|
||||
c.name = "MASTER_NODE"
|
||||
else
|
||||
error("Invalid arguments!")
|
||||
end
|
||||
return c
|
||||
end
|
||||
function node:ping()
|
||||
if self.type ~= "client" then return end
|
||||
self:send("!PING!")
|
||||
return {pong=self.connection.OnDataRecieved}
|
||||
end
|
||||
function node:send(data)
|
||||
if self.type ~= "client" then return end
|
||||
self.connection:send(data)
|
||||
end
|
||||
return node
|
||||
+47
-47
@@ -1,48 +1,48 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local net = require("net")
|
||||
local bin = require("bin")
|
||||
local nodes = { -- Testing stuff
|
||||
|
||||
}
|
||||
function multi:newNodeManager(port)
|
||||
print("Running node manager on port: "..(port or cmd.defaultManagerPort))
|
||||
local server = net:newTCPServer(port or cmd.defaultManagerPort)
|
||||
server.OnDataRecieved(function(serv, data, client)
|
||||
local cmd = data:match("!(.+)!")
|
||||
data = data:gsub("!"..cmd.."!","")
|
||||
if cmd == "NODES" then
|
||||
for i,v in ipairs(nodes) do
|
||||
-- Sample data
|
||||
serv:send(client, "!NODE!".. v[1].."|"..v[2].."|"..v[3])
|
||||
end
|
||||
elseif cmd == "REG_NODE" then
|
||||
local name, ip, port = data:match("(.-)|(.-)|(.+)")
|
||||
table.insert(nodes,{name,ip,port})
|
||||
print("Registering Node:",name, ip, port)
|
||||
end
|
||||
end)
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local cmd = require("multi.integration.networkManager.cmds")
|
||||
local net = require("net")
|
||||
local bin = require("bin")
|
||||
local nodes = { -- Testing stuff
|
||||
|
||||
}
|
||||
function multi:newNodeManager(port)
|
||||
print("Running node manager on port: "..(port or cmd.defaultManagerPort))
|
||||
local server = net:newTCPServer(port or cmd.defaultManagerPort)
|
||||
server.OnDataRecieved(function(serv, data, client)
|
||||
local cmd = data:match("!(.+)!")
|
||||
data = data:gsub("!"..cmd.."!","")
|
||||
if cmd == "NODES" then
|
||||
for i,v in ipairs(nodes) do
|
||||
-- Sample data
|
||||
serv:send(client, "!NODE!".. v[1].."|"..v[2].."|"..v[3])
|
||||
end
|
||||
elseif cmd == "REG_NODE" then
|
||||
local name, ip, port = data:match("(.-)|(.-)|(.+)")
|
||||
table.insert(nodes,{name,ip,port})
|
||||
print("Registering Node:",name, ip, port)
|
||||
end
|
||||
end)
|
||||
end
|
||||
+46
-46
@@ -1,47 +1,47 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local bin, bits = require("bin").init()
|
||||
return function(self,data,client)
|
||||
local cmd,data = data:match("!(.-)!(.*)")
|
||||
--print("SERVER",cmd,data)
|
||||
if cmd == "PING" then
|
||||
self:send(client,"!PONG!")
|
||||
elseif cmd == "N_THREAD" then
|
||||
print(1)
|
||||
local dat = bin.new(data)
|
||||
print(2)
|
||||
local t = dat:getBlock("t")
|
||||
print(3)
|
||||
local ret = bin.new()
|
||||
print(4)
|
||||
ret:addBlock{ID = t.id,rets = {t.func(unpack(t.args))}}
|
||||
print(5)
|
||||
print(client,"!RETURNS!"..ret:getData())
|
||||
self:send(client,"!RETURNS!"..ret:getData())
|
||||
print(6)
|
||||
elseif cmd == "CHANNEL" then
|
||||
local dat = bin.new(data):getBlock("t")
|
||||
|
||||
end
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local bin, bits = require("bin").init()
|
||||
return function(self,data,client)
|
||||
local cmd,data = data:match("!(.-)!(.*)")
|
||||
--print("SERVER",cmd,data)
|
||||
if cmd == "PING" then
|
||||
self:send(client,"!PONG!")
|
||||
elseif cmd == "N_THREAD" then
|
||||
print(1)
|
||||
local dat = bin.new(data)
|
||||
print(2)
|
||||
local t = dat:getBlock("t")
|
||||
print(3)
|
||||
local ret = bin.new()
|
||||
print(4)
|
||||
ret:addBlock{ID = t.id,rets = {t.func(unpack(t.args))}}
|
||||
print(5)
|
||||
print(client,"!RETURNS!"..ret:getData())
|
||||
self:send(client,"!RETURNS!"..ret:getData())
|
||||
print(6)
|
||||
elseif cmd == "CHANNEL" then
|
||||
local dat = bin.new(data):getBlock("t")
|
||||
|
||||
end
|
||||
end
|
||||
+22
-22
@@ -1,23 +1,23 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
@@ -1,27 +1,27 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local bin = require("bin")
|
||||
local utils = {}
|
||||
-- Will contain data that handles sterilizing and managing data
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local bin = require("bin")
|
||||
local utils = {}
|
||||
-- Will contain data that handles sterilizing and managing data
|
||||
return utils
|
||||
@@ -0,0 +1,213 @@
|
||||
-- Advanced process management. Mutates the multi namespace
|
||||
local multi, thread = require("multi"):init()
|
||||
local ok, chronos = pcall(require, "chronos") -- hpc
|
||||
|
||||
if not ok then chronos = nil end
|
||||
|
||||
-- This is an integration, we cannot directly access locals that are in the main file.
|
||||
|
||||
local PList = {
|
||||
multi.Priority_Core,
|
||||
multi.Priority_Very_High,
|
||||
multi.Priority_High,
|
||||
multi.Priority_Above_Normal,
|
||||
multi.Priority_Normal,
|
||||
multi.Priority_Below_Normal,
|
||||
multi.Priority_Low,
|
||||
multi.Priority_Very_Low,
|
||||
multi.Priority_Idle
|
||||
}
|
||||
|
||||
-- Restructered these functions since they rely on local variables from the core library
|
||||
|
||||
local mainloop = multi.mainloopRef
|
||||
local mainloop_p = multi.mainloop_p
|
||||
local uManagerRef = multi.uManagerRef
|
||||
local uManagerRefP = multi.uManagerRefP1
|
||||
|
||||
local PROFILE_COUNT = 5
|
||||
|
||||
-- self:setCurrentProcess() a bit slower than using the local var, but there isn't another option
|
||||
|
||||
local priorityManager = multi:newProcessor("Priority Manager", true)
|
||||
priorityManager.newThread = function() multi.warn("You cannot spawn threads on the priority manager!") end
|
||||
|
||||
priorityManager.setPriorityScheme = function() multi.warn("You cannot set priority on the priorityManager!") end
|
||||
|
||||
local function average(t)
|
||||
local sum = 0
|
||||
for _,v in pairs(t) do
|
||||
sum = sum + v
|
||||
end
|
||||
return sum / #t
|
||||
end
|
||||
|
||||
local function getPriority(obj)
|
||||
local avg = average(obj.__profiling)
|
||||
if avg < 0.0002 then
|
||||
return PList[1]
|
||||
elseif avg < 0.0004 then
|
||||
return PList[2]
|
||||
elseif avg < 0.0008 then
|
||||
return PList[3]
|
||||
elseif avg < 0.001 then
|
||||
return PList[4]
|
||||
elseif avg < 0.0025 then
|
||||
return PList[5]
|
||||
elseif avg < 0.005 then
|
||||
return PList[6]
|
||||
elseif avg < 0.008 then
|
||||
return PList[7]
|
||||
elseif avg < 0.01 then
|
||||
return PList[8]
|
||||
else
|
||||
return PList[9]
|
||||
end
|
||||
end
|
||||
|
||||
local start, stop
|
||||
|
||||
priorityManager.uManager = function(self)
|
||||
-- proc.run already checks if the processor is active
|
||||
self:setCurrentProcess()
|
||||
local Loop=self.Mainloop
|
||||
local ctask
|
||||
for _D=#Loop,1,-1 do
|
||||
ctask = Loop[_D]
|
||||
ctask:setCurrentTask()
|
||||
start = chronos.nanotime()
|
||||
if ctask:Act() then
|
||||
stop = chronos.nanotime()
|
||||
if ctask.__profiling then
|
||||
table.insert(ctask.__profiling, stop - start)
|
||||
end
|
||||
if ctask.__profiling and #ctask.__profiling == PROFILE_COUNT then
|
||||
ctask:setPriority(getPriority(ctask))
|
||||
ctask:reallocate(ctask.__restoreProc)
|
||||
ctask.__restoreProc = nil
|
||||
ctask.__profiling = nil
|
||||
end
|
||||
end
|
||||
self:setCurrentProcess()
|
||||
end
|
||||
end
|
||||
|
||||
local function processHook(obj, proc)
|
||||
if obj.Type == multi.registerType("process", "processes") or not(obj.IsAnActor) then return end
|
||||
obj.__restoreProc = proc
|
||||
obj.__profiling = {}
|
||||
obj:reallocate(priorityManager)
|
||||
end
|
||||
|
||||
local function init()
|
||||
local registry = {}
|
||||
|
||||
multi.priorityScheme = {
|
||||
RoundRobin = "RoundRobin",
|
||||
PriorityBased = "PriorityBased",
|
||||
TimeBased = "TimeBased"
|
||||
}
|
||||
|
||||
function multi:setProfilerCount(count)
|
||||
PROFILE_COUNT = count
|
||||
end
|
||||
|
||||
function multi:recalibrate()
|
||||
if self.__processConn then
|
||||
local items = self.Mainloop
|
||||
for i,v in pairs(items) do
|
||||
processHook(v, self)
|
||||
end
|
||||
else
|
||||
multi.error("Cannot recalibrate the priority if not using Time based mangement!")
|
||||
end
|
||||
end
|
||||
|
||||
function multi:isRegistredScheme(scheme)
|
||||
return registry[name] ~= nil
|
||||
end
|
||||
|
||||
function multi:getRegisteredScheme(scheme)
|
||||
return registry[name].mainloop, registry[name].umanager, registry[name].condition
|
||||
end
|
||||
|
||||
local empty_func = function() return true end
|
||||
function multi:registerScheme(name,options)
|
||||
local mainloop = options.mainloop or multi.error("You must provide a mainloop option when registring a scheme!")
|
||||
local umanager = options.umanager or multi.error("You must provide a umanager option when registring a scheme!")
|
||||
|
||||
if not options.condition then
|
||||
multi.warn("You might want to use condition when registring a scheme! A function that returns true has been auto generated for you!")
|
||||
end
|
||||
|
||||
local condition = options.condition or empty_func
|
||||
|
||||
if registry[name] and not registry[name].static then
|
||||
multi.warn("A scheme named: \"" .. name .. "\" has already been registred, overriting!")
|
||||
else
|
||||
multi.error("A scheme named: \"" .. name .. "\" has already been registred!")
|
||||
end
|
||||
|
||||
registry[name] = {
|
||||
mainloop = mainloop,
|
||||
umanager = umanger,
|
||||
condition = condition,
|
||||
static = options.static or false
|
||||
}
|
||||
|
||||
multi.priorityScheme[name] = name
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function multi:setPriorityScheme(scheme)
|
||||
|
||||
if not self.Type == multi.registerType("process", "processes") or not self.Type == multi.registerType("rootprocess") then
|
||||
multi.warn("You should only invoke setPriorityScheme on a processor object!")
|
||||
end
|
||||
|
||||
if scheme == multi.priorityScheme.RoundRobin then
|
||||
if self.__processConn then self.OnObjectCreated:Unconnect(self.__processConn) self.__processConn = nil end
|
||||
self.mainloop = mainloop
|
||||
self.uManager = uManagerRef
|
||||
elseif scheme == multi.priorityScheme.PriorityBased then
|
||||
if self.__processConn then self.OnObjectCreated:Unconnect(self.__processConn) self.__processConn = nil end
|
||||
self.mainloop = mainloop_p
|
||||
self.uManager = uManagerRefP
|
||||
elseif scheme == multi.priorityScheme.TimeBased then
|
||||
if not chronos then return multi.warn("Unable to use TimeBased Priority without the chronos library!") end
|
||||
if self.__processConn then multi.warn("Already enabled TimeBased Priority!") end
|
||||
self.__processConn = self.OnObjectCreated(processHook)
|
||||
self.mainloop = mainloop_p
|
||||
self.uManager = uManagerRefP
|
||||
elseif self:isRegistredScheme(scheme) then
|
||||
local mainloop, umanager, condition = self:getRegisteredScheme(scheme)
|
||||
if condition() then
|
||||
self.mainloop = mainloop
|
||||
self.uManager = umanager
|
||||
end
|
||||
else
|
||||
self.error("Invalid priority scheme selected!")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local function init_chronos()
|
||||
-- Let's implement a higher precision clock
|
||||
multi.setClock(chronos.nanotime) -- This is also in .000 format. So a plug and play works.
|
||||
thread:newThread("System Priority Manager", function()
|
||||
while true do
|
||||
thread.yield()
|
||||
priorityManager.run()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if chronos then
|
||||
init_chronos()
|
||||
else
|
||||
multi.warn("In order to have time based priority management, you need to install the chronos library!")
|
||||
end
|
||||
|
||||
init()
|
||||
@@ -0,0 +1,221 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
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)
|
||||
local c = {}
|
||||
c.data = {}
|
||||
c.Type = multi.registerType("s_queue")
|
||||
function c:push(v)
|
||||
table.insert(self.data,v)
|
||||
end
|
||||
function c:pop()
|
||||
return table.remove(self.data,1)
|
||||
end
|
||||
function c:peek()
|
||||
return self.data[1]
|
||||
end
|
||||
function c:init()
|
||||
return self
|
||||
end
|
||||
function c:Hold(opt)
|
||||
if opt.peek then
|
||||
return thread.hold(function()
|
||||
return self:peek()
|
||||
end)
|
||||
else
|
||||
return thread.hold(function()
|
||||
return self:pop()
|
||||
end)
|
||||
end
|
||||
end
|
||||
GLOBAL[name or "_"] = c
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedTable(name)
|
||||
local c = {}
|
||||
c.Type = multi.registerType("s_table")
|
||||
function c:init()
|
||||
return self
|
||||
end
|
||||
function c:Hold(opt)
|
||||
if opt.key then
|
||||
return thread.hold(function()
|
||||
return self.tab[opt.key]
|
||||
end)
|
||||
else
|
||||
multi.error("Must provide a key to check opt.key = 'key'")
|
||||
end
|
||||
end
|
||||
GLOBAL[name or "_"] = c
|
||||
return c
|
||||
end
|
||||
|
||||
local setfenv = multi.isolateFunction
|
||||
|
||||
local jqc = 1
|
||||
function multi:newSystemThreadedJobQueue(n)
|
||||
local c = {}
|
||||
|
||||
c.cores = n or THREAD.getCores()
|
||||
c.registerQueue = {}
|
||||
c.Type = multi.registerType("s_jobqueue")
|
||||
c.funcs = multi:newSystemThreadedTable("__JobQueue_"..jqc.."_table")
|
||||
c.queue = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queue")
|
||||
c.queueReturn = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueReturn")
|
||||
c.queueAll = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueAll")
|
||||
c.id = 0
|
||||
c.OnJobCompleted = multi:newConnection()
|
||||
|
||||
local allfunc = 0
|
||||
|
||||
function c:doToAll(func)
|
||||
for i = 1, self.cores do
|
||||
self.queueAll:push({allfunc, func})
|
||||
end
|
||||
allfunc = allfunc + 1
|
||||
end
|
||||
function c:registerFunction(name, func)
|
||||
if self.funcs[name] then
|
||||
multi.error("A function by the name "..name.." has already been registered!")
|
||||
end
|
||||
self.funcs[name] = func
|
||||
end
|
||||
function c:pushJob(name,...)
|
||||
self.id = self.id + 1
|
||||
self.queue:push{name,self.id,...}
|
||||
return self.id
|
||||
end
|
||||
function c:isEmpty()
|
||||
return queueJob:peek()==nil
|
||||
end
|
||||
local nFunc = 0
|
||||
function c:newFunction(name,func,holup) -- This registers with the queue
|
||||
if type(name)=="function" then
|
||||
holup = func
|
||||
func = name
|
||||
name = "JQ_Function_"..nFunc
|
||||
end
|
||||
nFunc = nFunc + 1
|
||||
c:registerFunction(name,func)
|
||||
return thread:newFunction(function(...)
|
||||
local id = c:pushJob(name,...)
|
||||
local link
|
||||
local rets
|
||||
link = c.OnJobCompleted(function(jid,...)
|
||||
if id==jid then
|
||||
rets = multi.pack(...)
|
||||
end
|
||||
end)
|
||||
return thread.hold(function()
|
||||
if rets then
|
||||
return multi.unpack(rets) or multi.NIL
|
||||
end
|
||||
end)
|
||||
end,holup),name
|
||||
end
|
||||
thread:newThread("jobManager",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local dat = c.queueReturn:pop()
|
||||
if dat then
|
||||
c.OnJobCompleted:Fire(multi.unpack(dat))
|
||||
end
|
||||
end
|
||||
end)
|
||||
for i=1,c.cores do
|
||||
multi:newSystemThread("STJQ_"..multi.randomString(8),function(jqc)
|
||||
local GLOBAL, THREAD = require("multi.integration.pseudoManager"):init()
|
||||
local multi, thread = require("multi"):init()
|
||||
local clock = os.clock
|
||||
local funcs = THREAD.waitFor("__JobQueue_"..jqc.."_table")
|
||||
local queue = THREAD.waitFor("__JobQueue_"..jqc.."_queue")
|
||||
local queueReturn = THREAD.waitFor("__JobQueue_"..jqc.."_queueReturn")
|
||||
local queueAll = THREAD.waitFor("__JobQueue_"..jqc.."_queueAll")
|
||||
local registry = {}
|
||||
_G["__QR"] = queueReturn
|
||||
setmetatable(_G,{__index = funcs})
|
||||
thread:newThread("startUp",function()
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
queueAll:pop()[2]()
|
||||
end
|
||||
end
|
||||
end)
|
||||
thread:newThread("runner",function()
|
||||
thread.sleep(.1)
|
||||
while true do
|
||||
thread.yield()
|
||||
local all = queueAll:peek()
|
||||
if all and not registry[all[1]] then
|
||||
queueAll:pop()[2]()
|
||||
end
|
||||
local dat = thread.hold(queue)
|
||||
if dat then
|
||||
multi:newThread("JobSubRunner",function()
|
||||
local name = table.remove(dat,1)
|
||||
local id = table.remove(dat,1)
|
||||
local tab = {multi.isolateFunction(funcs[name],_G)(multi.unpack(dat))}
|
||||
table.insert(tab,1,id)
|
||||
queueReturn:push(tab)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
multi:mainloop()
|
||||
end, jqc)
|
||||
end
|
||||
|
||||
function c:Hold(opt)
|
||||
return thread.hold(self.OnJobCompleted)
|
||||
end
|
||||
|
||||
jqc = jqc + 1
|
||||
|
||||
self:create(c)
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:newSystemThreadedConnection(name)
|
||||
local conn = multi:newConnection()
|
||||
conn.init = function(self) return self end
|
||||
GLOBAL[name or "_"] = conn
|
||||
return conn
|
||||
end
|
||||
|
||||
require("multi.integration.sharedExtensions")
|
||||
@@ -0,0 +1,121 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
package.path = "?/init.lua;?.lua;" .. package.path
|
||||
local multi, thread = require("multi"):init()
|
||||
local pseudoProcessor = multi:newProcessor()
|
||||
if multi.integration then
|
||||
return {
|
||||
init = function()
|
||||
return multi.integration.GLOBAL, multi.integration.THREAD
|
||||
end
|
||||
}
|
||||
end
|
||||
multi.isMainThread = true
|
||||
local activator = require("multi.integration.pseudoManager.threads")
|
||||
local GLOBAL, THREAD = activator.init(thread)
|
||||
|
||||
_G.THREAD_NAME = "MAIN_THREAD"
|
||||
_G.THREAD_ID = 0
|
||||
|
||||
function multi:canSystemThread() -- We are emulating system threading
|
||||
return true
|
||||
end
|
||||
|
||||
function multi:getPlatform()
|
||||
return "pesudo"
|
||||
end
|
||||
|
||||
local function split(str)
|
||||
local tab = {}
|
||||
for word in string.gmatch(str, '([^,]+)') do
|
||||
table.insert(tab,word)
|
||||
end
|
||||
return tab
|
||||
end
|
||||
|
||||
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,xpcall,math,coroutine,string,table]]
|
||||
tab = split(tab)
|
||||
|
||||
local id = 0
|
||||
|
||||
function multi:newSystemThread(name, func, ...)
|
||||
local env
|
||||
env = {
|
||||
GLOBAL = GLOBAL,
|
||||
THREAD = THREAD,
|
||||
THREAD_NAME = tostring(name),
|
||||
__THREADNAME__ = tostring(name),
|
||||
THREAD_ID = id,
|
||||
thread = thread,
|
||||
multi = multi,
|
||||
}
|
||||
|
||||
for i, v in pairs(_G) do
|
||||
if not(env[i]) and not(i == "_G") and not(i == "local_global") then
|
||||
env[i] = v
|
||||
else
|
||||
multi.warn("skipping:",i)
|
||||
end
|
||||
end
|
||||
|
||||
if GLOBAL["__env"] then
|
||||
for i,v in pairs(GLOBAL["__env"]) do
|
||||
env[i] = v
|
||||
end
|
||||
end
|
||||
|
||||
env._G = env
|
||||
|
||||
local GLOBAL, THREAD = activator.init(thread, env)
|
||||
|
||||
local th = pseudoProcessor:newISOThread(name, func, env, ...)
|
||||
th.Type = multi.registerType("s_thread", "pseudoThreads")
|
||||
th.OnError(multi.error)
|
||||
|
||||
id = id + 1
|
||||
|
||||
return th
|
||||
end
|
||||
|
||||
THREAD.newSystemThread = multi.newSystemThread
|
||||
-- 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
|
||||
|
||||
function THREAD:newFunction(func,holdme)
|
||||
return thread:newFunctionBase(function(...)
|
||||
return multi:newSystemThread("TempSystemThread",func,...)
|
||||
end, holdme, multi.registerType("s_function", "pseudoFunctions"))()
|
||||
end
|
||||
|
||||
multi.print("Integrated Pesudo Threading!")
|
||||
multi.integration = {} -- for module creators
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.pseudoManager.extensions")
|
||||
require("multi.integration.sharedExtensions")
|
||||
return {
|
||||
init = function()
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
|
||||
local function getOS()
|
||||
if package.config:sub(1, 1) == "\\" then
|
||||
return "windows"
|
||||
else
|
||||
return "unix"
|
||||
end
|
||||
end
|
||||
|
||||
local function INIT(thread)
|
||||
local THREAD = {}
|
||||
local GLOBAL = {}
|
||||
|
||||
THREAD.Priority_Core = 3
|
||||
THREAD.Priority_High = 2
|
||||
THREAD.Priority_Above_Normal = 1
|
||||
THREAD.Priority_Normal = 0
|
||||
THREAD.Priority_Below_Normal = -1
|
||||
THREAD.Priority_Low = -2
|
||||
THREAD.Priority_Idle = -3
|
||||
|
||||
function THREAD.set(name, val)
|
||||
GLOBAL[name] = val
|
||||
end
|
||||
|
||||
function THREAD.get(name)
|
||||
return GLOBAL[name]
|
||||
end
|
||||
|
||||
function THREAD.waitFor(name)
|
||||
return thread.hold(function() return GLOBAL[name] end)
|
||||
end
|
||||
|
||||
if getOS() == "windows" then
|
||||
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
|
||||
else
|
||||
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
|
||||
end
|
||||
|
||||
function THREAD.getCores()
|
||||
return THREAD.__CORES
|
||||
end
|
||||
|
||||
function THREAD.getConsole()
|
||||
local c = {}
|
||||
function c.print(...)
|
||||
print(...)
|
||||
end
|
||||
function c.error(err)
|
||||
error("ERROR in <"..GLOBAL["$__THREADNAME__"]..">: "..err)
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
function THREAD.getThreads()
|
||||
return {}--GLOBAL.__THREADS__
|
||||
end
|
||||
|
||||
THREAD.pushStatus = thread.pushStatus
|
||||
|
||||
function THREAD.kill()
|
||||
error("Thread was killed!")
|
||||
end
|
||||
|
||||
THREAD.sleep = thread.sleep
|
||||
|
||||
THREAD.hold = thread.hold
|
||||
|
||||
THREAD.defer = thread.defer
|
||||
|
||||
function THREAD.setENV(env, name)
|
||||
name = name or "__env"
|
||||
GLOBAL[name] = env
|
||||
end
|
||||
|
||||
function THREAD.getENV(name)
|
||||
name = name or "__env"
|
||||
return GLOBAL[name]
|
||||
end
|
||||
|
||||
function THREAD.exposeENV(name)
|
||||
name = name or "__env"
|
||||
local env = THREAD.getENV(name)
|
||||
for i,v in pairs(env) do
|
||||
-- This may need to be reworked!
|
||||
local_global[i] = v
|
||||
end
|
||||
end
|
||||
|
||||
function THREAD.sync()
|
||||
thread.sleep(.5)
|
||||
end
|
||||
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
|
||||
return {init = function(thread, global)
|
||||
return INIT(thread, global)
|
||||
end}
|
||||
@@ -0,0 +1,336 @@
|
||||
--[[ todo finish the targeted job!
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
|
||||
local multi, thread = require("multi"):init()
|
||||
|
||||
-- Returns a handler that allows a user to interact with an object on another thread!
|
||||
-- Create on the thread that you want to interact with, send over the handle
|
||||
|
||||
function multi:chop(obj)
|
||||
if not _G["UIDS"] then
|
||||
_G["UIDS"] = {}
|
||||
end
|
||||
local multi, thread = require("multi"):init()
|
||||
local list = {[0] = multi.randomString(12)}
|
||||
_G[list[0]] = obj
|
||||
for i,v in pairs(obj) do
|
||||
if type(v) == "function" or type(v) == "table" and v.Type == multi.registerType("s_function") then
|
||||
table.insert(list, i)
|
||||
elseif type(v) == "table" and v.Type == multi.registerType("connector", "connections") then
|
||||
table.insert(list, {i, multi:newProxy(multi:chop(v)):init()})
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
function multi:newProxy(list)
|
||||
|
||||
local c = {}
|
||||
|
||||
c.name = multi.randomString(12)
|
||||
c.is_init = false
|
||||
local multi, thread = nil, nil
|
||||
function c:init()
|
||||
local multi, thread = nil, nil
|
||||
local function copy(obj)
|
||||
if type(obj) ~= 'table' then return obj end
|
||||
local res = {}
|
||||
for k, v in pairs(obj) do res[copy(k)] = copy(v) end
|
||||
return res
|
||||
end
|
||||
if not(self.is_init) then
|
||||
THREAD.sync()
|
||||
self.is_init = true
|
||||
local multi, thread = require("multi"):init()
|
||||
self.proxy_link = "PL" .. multi.randomString(12)
|
||||
|
||||
if multi.integration then
|
||||
GLOBAL = multi.integration.GLOBAL
|
||||
THREAD = multi.integration.THREAD
|
||||
end
|
||||
|
||||
GLOBAL[self.proxy_link] = self
|
||||
|
||||
local function check()
|
||||
return self.send:pop()
|
||||
end
|
||||
|
||||
self.send = multi:newSystemThreadedQueue(self.name.."_S"):init()
|
||||
self.recv = multi:newSystemThreadedQueue(self.name.."_R"):init()
|
||||
self.funcs = list
|
||||
self._funcs = copy(list)
|
||||
self.Type = multi.registerType("proxy", "proxies")
|
||||
self.TID = THREAD_ID
|
||||
|
||||
thread:newThread("Proxy_Handler_" .. multi.randomString(4), function()
|
||||
while true do
|
||||
local data = thread.hold(check)
|
||||
if data then
|
||||
-- Let's not hold the main threadloop
|
||||
thread:newThread("Temp_Thread", function()
|
||||
local func = table.remove(data, 1)
|
||||
local sref = table.remove(data, 1)
|
||||
local ret
|
||||
if sref then
|
||||
ret = {_G[list[0]][func](_G[list[0]], multi.unpack(data))}
|
||||
else
|
||||
ret = {_G[list[0]][func](multi.unpack(data))}
|
||||
end
|
||||
|
||||
for i = 1,#ret do
|
||||
if type(ret[i]) == "table" and ret[i].Type ~= nil and ret[i].Type ~= multi.registerType("proxy", "proxies") then
|
||||
ret[i] = "\1PARENT_REF"
|
||||
end
|
||||
if type(ret[i]) == "table" and getmetatable(ret[i]) then
|
||||
setmetatable(ret[i],nil) -- remove that metatable, we do not need it on the other side!
|
||||
end
|
||||
if ret[i] == _G[list[0]] then
|
||||
-- We cannot return itself, that return can contain bad values.
|
||||
ret[i] = "\1SELF_REF"
|
||||
end
|
||||
end
|
||||
table.insert(ret, 1, func)
|
||||
self.recv:push(ret)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
return self
|
||||
else
|
||||
THREAD.sync()
|
||||
if not self.funcs then return self end
|
||||
local function copy(obj)
|
||||
if type(obj) ~= 'table' then return obj end
|
||||
local res = {}
|
||||
for k, v in pairs(obj) do res[copy(k)] = copy(v) end
|
||||
return res
|
||||
end
|
||||
local multi, thread = require("multi"):init()
|
||||
local me = self
|
||||
local funcs = copy(self.funcs)
|
||||
if multi.integration then
|
||||
GLOBAL = multi.integration.GLOBAL
|
||||
THREAD = multi.integration.THREAD
|
||||
end
|
||||
self.send = THREAD.waitFor(self.name.."_S"):init()
|
||||
self.recv = THREAD.waitFor(self.name.."_R"):init()
|
||||
self.Type = multi.registerType("proxy", "proxies")
|
||||
for _,v in pairs(funcs) do
|
||||
if type(v) == "table" then
|
||||
-- We have a connection
|
||||
v[2]:init(proc_name)
|
||||
self[v[1]] = v[2]
|
||||
v[2].Parent = self
|
||||
setmetatable(v[2],getmetatable(multi:newConnection()))
|
||||
else
|
||||
self[v] = thread:newFunction(function(self,...)
|
||||
if self == me then
|
||||
me.send:push({v, true, ...})
|
||||
else
|
||||
me.send:push({v, false, ...})
|
||||
end
|
||||
return thread.hold(function()
|
||||
local data = me.recv:peek()
|
||||
if data and data[1] == v then
|
||||
me.recv:pop()
|
||||
table.remove(data, 1)
|
||||
for i=1,#data do
|
||||
if data[i] == "\1SELF_REF" then
|
||||
data[i] = me
|
||||
elseif data[i] == "\1PARENT_REF" then
|
||||
data[i] = me.Parent
|
||||
end
|
||||
end
|
||||
return multi.unpack(data)
|
||||
end
|
||||
end)
|
||||
end, true)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
end
|
||||
function c:getTransferable()
|
||||
local cp = {}
|
||||
local multi, thread = require("multi"):init()
|
||||
local function copy(obj)
|
||||
if type(obj) ~= 'table' then return obj end
|
||||
local res = {}
|
||||
for k, v in pairs(obj) do res[copy(k)] = copy(v) end
|
||||
return res
|
||||
end
|
||||
cp.is_init = true
|
||||
cp.proxy_link = self.proxy_link
|
||||
cp.name = self.name
|
||||
cp.funcs = copy(self._funcs)
|
||||
cp.init = function(self)
|
||||
local multi, thread = require("multi"):init()
|
||||
if multi.integration then
|
||||
GLOBAL = multi.integration.GLOBAL
|
||||
THREAD = multi.integration.THREAD
|
||||
end
|
||||
local proxy = THREAD.waitFor(self.proxy_link)
|
||||
proxy.funcs = self.funcs
|
||||
return proxy:init()
|
||||
end
|
||||
return cp
|
||||
end
|
||||
self:create(c)
|
||||
return c
|
||||
end
|
||||
|
||||
local targets = {}
|
||||
local references = {}
|
||||
|
||||
local jid = -1
|
||||
function multi:newSystemThreadedProcessor(cores)
|
||||
|
||||
local name = "STP_"..multi.randomString(4) -- set a random name if none was given.
|
||||
|
||||
local autoscale = autoscale or false -- Will scale up the number of cores that the process uses.
|
||||
local c = {}
|
||||
|
||||
setmetatable(c,{__index = multi})
|
||||
|
||||
c.Type = multi.registerType("s_process", "s_processes")
|
||||
c.threads = {}
|
||||
c.cores = cores or 8
|
||||
c.Name = name
|
||||
c.Mainloop = {}
|
||||
c.__count = 0
|
||||
c.processors = {}
|
||||
c.proc_list = {}
|
||||
c.OnObjectCreated = multi:newConnection()
|
||||
c.parent = self
|
||||
c.jobqueue = multi:newSystemThreadedJobQueue(c.cores)
|
||||
|
||||
function c:pushJob(ID, name, ...)
|
||||
local tq = THREAD.waitFor(self.Name .. "_target_tq_" .. ID):init()
|
||||
tq:push{name, jid, multi.pack(...)}
|
||||
jid = jid - 1
|
||||
return jid + 1
|
||||
end
|
||||
|
||||
c.jobqueue:registerFunction("packObj",function(obj)
|
||||
local multi, thread = require("multi"):init()
|
||||
|
||||
local list = multi:chop(obj)
|
||||
obj.__link_name = list[0]
|
||||
|
||||
local proxy = multi:newProxy(list):init()
|
||||
|
||||
return proxy
|
||||
end)
|
||||
|
||||
c.spawnThread = c.jobqueue:newFunction("__spawnThread__", function(name, func, ...)
|
||||
local multi, thread = require("multi"):init()
|
||||
local obj = thread:newThread(name, func, ...)
|
||||
return packObj(obj)
|
||||
end, true)
|
||||
|
||||
c.spawnTask = c.jobqueue:newFunction("__spawnTask__", function(obj, func, ...)
|
||||
local multi, thread = require("multi"):init()
|
||||
local obj = multi[obj](multi, func, ...)
|
||||
return packObj(obj)
|
||||
end, true)
|
||||
|
||||
local implement = {
|
||||
"newLoop",
|
||||
"newTLoop",
|
||||
"newUpdater",
|
||||
"newEvent",
|
||||
"newAlarm",
|
||||
"newStep",
|
||||
"newTStep",
|
||||
"newService"
|
||||
}
|
||||
|
||||
for _, method in pairs(implement) do
|
||||
c[method] = thread:newFunction(function(self, ...)
|
||||
proxy = self.spawnTask(method, ...)
|
||||
proxy:init()
|
||||
references[proxy] = self
|
||||
return proxy
|
||||
end, true)
|
||||
end
|
||||
|
||||
function c:newThread(name, func, ...)
|
||||
proxy = self.spawnThread(name, func, ...):init(self.Name)
|
||||
references[proxy] = self
|
||||
table.insert(self.threads, proxy)
|
||||
return proxy
|
||||
end
|
||||
|
||||
function c:newFunction(func, holdme)
|
||||
return self.jobqueue:newFunction(func, holdme)
|
||||
end
|
||||
|
||||
function c:newSharedTable(name)
|
||||
if not name then multi.error("You must provide a name when creating a table!") end
|
||||
local tbl_name = "TABLE_"..multi.randomString(8)
|
||||
self.jobqueue:doToAll(function(tbl_name, interaction)
|
||||
_G[interaction] = THREAD.waitFor(tbl_name):init()
|
||||
end, tbl_name, name)
|
||||
return multi:newSystemThreadedTable(tbl_name):init()
|
||||
end
|
||||
|
||||
function c:getHandler()
|
||||
return function() end -- return empty function
|
||||
end
|
||||
|
||||
function c:getThreads()
|
||||
return self.threads
|
||||
end
|
||||
|
||||
function c:getFullName()
|
||||
return self.parent:getFullName() .. "." .. c.Name
|
||||
end
|
||||
|
||||
function c:getName()
|
||||
return self.Name
|
||||
end
|
||||
|
||||
function c.run()
|
||||
return self
|
||||
end
|
||||
|
||||
function c.isActive()
|
||||
return true
|
||||
end
|
||||
|
||||
function c.Start()
|
||||
return self
|
||||
end
|
||||
|
||||
function c.Stop()
|
||||
return self
|
||||
end
|
||||
|
||||
function c:Destroy()
|
||||
return false
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
-- Allows the creation of states
|
||||
@@ -0,0 +1,13 @@
|
||||
-- We need to detect what enviroment we are running our code in.
|
||||
return {
|
||||
init = function()
|
||||
if love then
|
||||
return require("multi.integration.loveManager"):init()
|
||||
else
|
||||
if pcall(require,"lanes") then
|
||||
return require("multi.integration.lanesManager"):init()
|
||||
end
|
||||
return require("multi.integration.pesudoManager"):init()
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
function love.conf(t)
|
||||
t.identity = nil -- The name of the save directory (string)
|
||||
t.version = "12.0" -- The LOVE version this game was made for (string)
|
||||
t.console = true -- Attach a console (boolean, Windows only)
|
||||
|
||||
-- t.modules.audio = false -- Enable the audio module (boolean)
|
||||
-- t.modules.event = false -- Enable the event module (boolean)
|
||||
-- t.modules.graphics = false -- Enable the graphics module (boolean)
|
||||
-- t.modules.image = false -- Enable the image module (boolean)
|
||||
-- t.modules.joystick = false -- Enable the joystick module (boolean)
|
||||
-- t.modules.keyboard = false -- Enable the keyboard module (boolean)
|
||||
-- t.modules.math = false -- Enable the math module (boolean)
|
||||
-- t.modules.mouse = false -- Enable the mouse module (boolean)
|
||||
-- t.modules.physics = false -- Enable the physics module (boolean)
|
||||
-- t.modules.sound = false -- Enable the sound module (boolean)
|
||||
-- t.modules.system = true -- Enable the system module (boolean)
|
||||
-- t.modules.timer = true -- Enable the timer module (boolean)
|
||||
-- t.modules.window = false -- Enable the window module (boolean)
|
||||
-- t.modules.thread = true -- Enable the thread module (boolean)
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
package.path = "../?/init.lua;../?.lua;"..package.path
|
||||
local multi, thread = require("multi"):init{print=true, warning = true, error=true}
|
||||
local utils = require("multi.integration.loveManager.utils")
|
||||
|
||||
local people = {1,2,3}
|
||||
|
||||
function dump(o)
|
||||
if type(o) == 'table' then
|
||||
local s = '{ '
|
||||
for k,v in pairs(o) do
|
||||
if type(k) ~= 'number' then k = '"'..k..'"' end
|
||||
s = s .. '['..k..'] = ' .. dump(v) .. '('..type(v):sub(1,1)..'),'
|
||||
end
|
||||
return s .. '} '
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
local fpeople = utils.pack(people)
|
||||
|
||||
print("Pack:", dump(fpeople))
|
||||
|
||||
local people = utils.unpack(fpeople)
|
||||
|
||||
print("Unpack:", dump(people))
|
||||
print(type(people[3]))
|
||||
|
||||
-- GLOBAL, THREAD = require("multi.integration.loveManager"):init()
|
||||
|
||||
-- local queue = multi:newSystemThreadedQueue("TestQueue")
|
||||
-- local tab = multi:newSystemThreadedTable("TestTable")
|
||||
|
||||
-- local test = multi:newSystemThread("Test",function()
|
||||
-- local queue = THREAD.waitFor("TestQueue")
|
||||
-- local tab = THREAD.waitFor("TestTable")
|
||||
-- print("THREAD_ID:",THREAD_ID)
|
||||
-- queue:push("Did it work?")
|
||||
-- tab["Test"] = true
|
||||
-- return 1,2,3
|
||||
-- end)
|
||||
|
||||
-- multi:newThread("QueueTest", function()
|
||||
-- print(thread.hold(queue))
|
||||
-- print(thread.hold(tab, {key="Test"}))
|
||||
-- print("Done!")
|
||||
-- end)
|
||||
|
||||
-- local jq = multi:newSystemThreadedJobQueue(n)
|
||||
|
||||
-- jq:registerFunction("test2",function()
|
||||
-- print("This works!")
|
||||
-- end)
|
||||
|
||||
-- jq:registerFunction("test",function(a, b, c)
|
||||
-- print(a, b+c)
|
||||
-- test2()
|
||||
-- return a+b+c
|
||||
-- end)
|
||||
|
||||
-- print("Job:",jq:pushJob("test",1,2,3))
|
||||
-- print("Job:",jq:pushJob("test",2,3,4))
|
||||
-- print("Job:",jq:pushJob("test",5,6,7))
|
||||
|
||||
-- jq.OnJobCompleted(function(...)
|
||||
-- print("Job Completed!", ...)
|
||||
-- end)
|
||||
|
||||
-- function love.draw()
|
||||
-- --
|
||||
-- end
|
||||
|
||||
-- function love.update()
|
||||
-- multi:uManager()
|
||||
-- end
|
||||
@@ -0,0 +1 @@
|
||||
../
|
||||
@@ -1,95 +0,0 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi").init()
|
||||
os.sleep = love.timer.sleep
|
||||
multi.drawF = {}
|
||||
function multi:onDraw(func, i)
|
||||
i = i or 1
|
||||
table.insert(self.drawF, i, func)
|
||||
end
|
||||
multi.OnKeyPressed = multi:newConnection()
|
||||
multi.OnKeyReleased = multi:newConnection()
|
||||
multi.OnMousePressed = multi:newConnection()
|
||||
multi.OnMouseReleased = multi:newConnection()
|
||||
multi.OnMouseWheelMoved = multi:newConnection()
|
||||
multi.OnMouseMoved = multi:newConnection()
|
||||
multi.OnDraw = multi:newConnection()
|
||||
multi.OnTextInput = multi:newConnection()
|
||||
multi.OnUpdate = multi:newConnection()
|
||||
multi.OnQuit = multi:newConnection()
|
||||
multi.OnPreLoad(function()
|
||||
local function Hook(func, conn)
|
||||
if love[func] ~= nil then
|
||||
love[func] = Library.convert(love[func])
|
||||
love[func]:inject(function(...)
|
||||
conn:Fire(...)
|
||||
return {...}
|
||||
end,1)
|
||||
elseif love[func] == nil then
|
||||
love[func] = function(...)
|
||||
conn:Fire(...)
|
||||
end
|
||||
end
|
||||
end
|
||||
Hook("quit", multi.OnQuit)
|
||||
Hook("keypressed", multi.OnKeyPressed)
|
||||
Hook("keyreleased", multi.OnKeyReleased)
|
||||
Hook("mousepressed", multi.OnMousePressed)
|
||||
Hook("mousereleased", multi.OnMouseReleased)
|
||||
Hook("wheelmoved", multi.OnMouseWheelMoved)
|
||||
Hook("mousemoved", multi.OnMouseMoved)
|
||||
Hook("draw", multi.OnDraw)
|
||||
Hook("textinput", multi.OnTextInput)
|
||||
Hook("update", multi.OnUpdate)
|
||||
multi.OnDraw(function()
|
||||
for i = 1, #multi.drawF do
|
||||
love.graphics.setColor(255, 255, 255, 255)
|
||||
multi.drawF[i]()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
function multi:loveloop(light)
|
||||
local link
|
||||
link = multi:newThread(function()
|
||||
local mainloop = love.run()
|
||||
while true do
|
||||
thread.yield()
|
||||
pcall(mainloop)
|
||||
end
|
||||
end).OnError(function(...)
|
||||
print(...)
|
||||
end)
|
||||
if light==false then
|
||||
multi:mainloop()
|
||||
else
|
||||
multi:lightloop()
|
||||
end
|
||||
end
|
||||
|
||||
multi.OnQuit(function()
|
||||
multi.Stop()
|
||||
love.event.quit()
|
||||
end)
|
||||
return multi
|
||||
-2188
File diff suppressed because it is too large
Load Diff
@@ -1,168 +0,0 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
local multi, thread = require("multi"):init()
|
||||
local GLOBAL, THREAD = multi.integration.GLOBAL,multi.integration.THREAD
|
||||
function multi:newSystemThreadedQueue(name)
|
||||
local c = {}
|
||||
c.linda = lanes.linda()
|
||||
function c:push(v)
|
||||
self.linda:send("Q", v)
|
||||
end
|
||||
function c:pop()
|
||||
return ({self.linda:receive(0, "Q")})[2]
|
||||
end
|
||||
function c:peek()
|
||||
return self.linda:get("Q")
|
||||
end
|
||||
function c:init()
|
||||
return self
|
||||
end
|
||||
GLOBAL[name or "_"] = c
|
||||
return c
|
||||
end
|
||||
function multi:newSystemThreadedTable(name)
|
||||
local c = {}
|
||||
c.link = lanes.linda()
|
||||
setmetatable(c,{
|
||||
__index = function(t,k)
|
||||
return c.link:get(k)
|
||||
end,
|
||||
__newindex = function(t,k,v)
|
||||
c.link:set(k,v)
|
||||
end
|
||||
})
|
||||
function c:init()
|
||||
return self
|
||||
end
|
||||
GLOBAL[name or "_"] = c
|
||||
return c
|
||||
end
|
||||
function multi:newSystemThreadedJobQueue(n)
|
||||
local c = {}
|
||||
c.cores = n or THREAD.getCores()*2
|
||||
c.OnJobCompleted = multi:newConnection()
|
||||
local funcs = multi:newSystemThreadedTable()
|
||||
local queueJob = multi:newSystemThreadedQueue()
|
||||
local queueReturn = multi:newSystemThreadedQueue()
|
||||
local doAll = multi:newSystemThreadedQueue()
|
||||
local ID=1
|
||||
local jid = 1
|
||||
function c:doToAll(func)
|
||||
for i=1,c.cores do
|
||||
doAll:push{ID,func}
|
||||
end
|
||||
ID = ID + 1
|
||||
return self
|
||||
end
|
||||
function c:registerFunction(name,func)
|
||||
funcs[name]=func
|
||||
return self
|
||||
end
|
||||
function c:pushJob(name,...)
|
||||
queueJob:push{name,jid,{...}}
|
||||
jid = jid + 1
|
||||
return jid-1
|
||||
end
|
||||
local nFunc = 0
|
||||
function c:newFunction(name,func,holup) -- This registers with the queue
|
||||
if type(name)=="function" then
|
||||
holup = func
|
||||
func = name
|
||||
name = "JQ_Function_"..nFunc
|
||||
end
|
||||
nFunc = nFunc + 1
|
||||
c:registerFunction(name,func)
|
||||
return thread:newFunction(function(...)
|
||||
local id = c:pushJob(name,...)
|
||||
local link
|
||||
local rets
|
||||
link = c.OnJobCompleted(function(jid,...)
|
||||
if id==jid then
|
||||
rets = {...}
|
||||
link:Remove()
|
||||
end
|
||||
end)
|
||||
return thread.hold(function()
|
||||
if rets then
|
||||
return unpack(rets) or multi.NIL
|
||||
end
|
||||
end)
|
||||
end,holup),name
|
||||
end
|
||||
multi:newThread("JobQueueManager",function()
|
||||
while true do
|
||||
local job = thread.hold(function()
|
||||
return queueReturn:pop()
|
||||
end)
|
||||
local id = table.remove(job,1)
|
||||
c.OnJobCompleted:Fire(id,unpack(job))
|
||||
end
|
||||
end)
|
||||
for i=1,c.cores do
|
||||
multi:newSystemThread("SystemThreadedJobQueue",function(queue)
|
||||
local multi,thread = require("multi"):init()
|
||||
local idle = os.clock()
|
||||
local clock = os.clock
|
||||
local ref = 0
|
||||
setmetatable(_G,{__index = funcs})
|
||||
multi:newThread("JobHandler",function()
|
||||
while true do
|
||||
local dat = thread.hold(function()
|
||||
return queueJob:pop()
|
||||
end)
|
||||
idle = clock()
|
||||
local name = table.remove(dat,1)
|
||||
local jid = table.remove(dat,1)
|
||||
local args = table.remove(dat,1)
|
||||
queueReturn:push{jid, funcs[name](unpack(args)),queue}
|
||||
end
|
||||
end)
|
||||
multi:newThread("DoAllHandler",function()
|
||||
while true do
|
||||
local dat = thread.hold(function()
|
||||
return doAll:peek()
|
||||
end)
|
||||
if dat then
|
||||
if dat[1]>ref then
|
||||
idle = clock()
|
||||
ref = dat[1]
|
||||
dat[2]()
|
||||
doAll:pop()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
multi:newThread("IdleHandler",function()
|
||||
while true do
|
||||
thread.hold(function()
|
||||
return clock()-idle>3
|
||||
end)
|
||||
THREAD.sleep(.01)
|
||||
end
|
||||
end)
|
||||
multi:mainloop()
|
||||
end,i).priority = thread.Priority_Core
|
||||
end
|
||||
return c
|
||||
end
|
||||
@@ -1,157 +0,0 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Ryan Ward
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]
|
||||
package.path = "?/init.lua;?.lua;" .. package.path
|
||||
multi, thread = require("multi").init() -- get it all and have it on all lanes
|
||||
if multi.integration then -- This allows us to call the lanes manager from supporting modules without a hassel
|
||||
return {
|
||||
init = function()
|
||||
return multi.integration.GLOBAL, multi.integration.THREAD
|
||||
end
|
||||
}
|
||||
end
|
||||
-- Step 1 get lanes
|
||||
lanes = require("lanes").configure()
|
||||
multi.SystemThreads = {}
|
||||
multi.isMainThread = true
|
||||
function multi:canSystemThread()
|
||||
return true
|
||||
end
|
||||
function multi:getPlatform()
|
||||
return "lanes"
|
||||
end
|
||||
-- Step 2 set up the Linda objects
|
||||
local __GlobalLinda = lanes.linda() -- handles global stuff
|
||||
local __SleepingLinda = lanes.linda() -- handles sleeping stuff
|
||||
local __ConsoleLinda = lanes.linda() -- handles console stuff
|
||||
multi:newLoop(function()
|
||||
local _,data = __ConsoleLinda:receive(0, "Q")
|
||||
if data then
|
||||
print(unpack(data))
|
||||
end
|
||||
end)
|
||||
local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda,__SleepingLinda)
|
||||
local threads = {}
|
||||
local count = 1
|
||||
local started = false
|
||||
local livingThreads = {}
|
||||
function THREAD:newFunction(func,holup)
|
||||
return function(...)
|
||||
local t = multi:newSystemThread("SystemThreadedFunction",function(...)
|
||||
return func(...)
|
||||
end,...)
|
||||
return thread:newFunction(function()
|
||||
thread.hold(function() return t.thread end)
|
||||
return thread.hold(function()
|
||||
return t.thread:join(.001)
|
||||
end)
|
||||
end,holup)()
|
||||
end
|
||||
end
|
||||
function multi:newSystemThread(name, func, ...)
|
||||
multi.InitSystemThreadErrorHandler()
|
||||
rand = math.random(1, 10000000)
|
||||
local c = {}
|
||||
local __self = c
|
||||
c.name = name
|
||||
c.Name = name
|
||||
c.Id = count
|
||||
c.loadString = {"base","package","os","io","math","table","string","coroutine"}
|
||||
livingThreads[count] = {true, name}
|
||||
c.Type = "sthread"
|
||||
c.creationTime = os.clock()
|
||||
c.alive = true
|
||||
c.priority = THREAD.Priority_Normal
|
||||
local args = {...}
|
||||
multi:newThread(function()
|
||||
c.thread = lanes.gen(table.concat(c.loadString,","),
|
||||
{
|
||||
globals={ -- Set up some globals
|
||||
THREAD_NAME=name,
|
||||
THREAD_ID=count,
|
||||
THREAD = THREAD,
|
||||
GLOBAL = GLOBAL,
|
||||
_Console = __ConsoleLinda
|
||||
},
|
||||
priority=c.priority
|
||||
},func)(unpack(args))
|
||||
thread.kill()
|
||||
end)
|
||||
count = count + 1
|
||||
function c:kill()
|
||||
self.thread:cancel()
|
||||
multi.print("Thread: '" .. self.name .. "' has been stopped!")
|
||||
self.alive = false
|
||||
end
|
||||
table.insert(multi.SystemThreads, c)
|
||||
c.OnError = multi:newConnection()
|
||||
GLOBAL["__THREADS__"] = livingThreads
|
||||
return c
|
||||
end
|
||||
multi.OnSystemThreadDied = multi:newConnection()
|
||||
function multi.InitSystemThreadErrorHandler()
|
||||
if started == true then
|
||||
return
|
||||
end
|
||||
started = true
|
||||
multi:newThread(
|
||||
"ThreadErrorHandler",
|
||||
function()
|
||||
local threads = multi.SystemThreads
|
||||
while true do
|
||||
thread.sleep(.5) -- switching states often takes a huge hit on performance. half a second to tell me there is an error is good enough.
|
||||
for i = #threads, 1, -1 do
|
||||
local v, err, t = threads[i].thread:join(.001)
|
||||
if err then
|
||||
if err:find("Thread was killed!") then
|
||||
print(err)
|
||||
livingThreads[threads[i].Id] = {false, threads[i].Name}
|
||||
threads[i].alive = false
|
||||
multi.OnSystemThreadDied:Fire(threads[i].Id)
|
||||
GLOBAL["__THREADS__"] = livingThreads
|
||||
table.remove(threads, i)
|
||||
elseif err:find("stack traceback") then
|
||||
print(err)
|
||||
threads[i].OnError:Fire(threads[i], err, "Error in systemThread: '" .. threads[i].name .. "' <" .. err .. ">")
|
||||
threads[i].alive = false
|
||||
livingThreads[threads[i].Id] = {false, threads[i].Name}
|
||||
multi.OnSystemThreadDied:Fire(threads[i].Id)
|
||||
GLOBAL["__THREADS__"] = livingThreads
|
||||
table.remove(threads, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
multi.print("Integrated Lanes!")
|
||||
multi.integration = {} -- for module creators
|
||||
multi.integration.GLOBAL = GLOBAL
|
||||
multi.integration.THREAD = THREAD
|
||||
require("multi.integration.lanesManager.extensions")
|
||||
return {
|
||||
init = function()
|
||||
return GLOBAL, THREAD
|
||||
end
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
-- Planned system threaded objects
|
||||
-- multi:newSystemThreadedConnection(name, protect)
|
||||
+511
-511
File diff suppressed because it is too large
Load Diff
@@ -1,53 +1,53 @@
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end event:new("Event_"..fname,condition,also) end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,var) return event.EventTracker[var] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then loadstring(event.Events[d])() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then loadstring(event.Events[d])() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then loadstring(event.Events[d])() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
createStep=function(self,tag,reset,endc)
|
||||
if not(endc) then endc=false end
|
||||
if not(reset) then reset=0 end
|
||||
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc,
|
||||
Step=function(self) if self~=nil then _G.__CStep__=self if self.active==true then loadstring("Step_"..tag.."("..self.pos..",__CStep__)")() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then loadstring("Step_"..self.Name.."_End(__CStep__)")() end end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end event:new("Event_"..fname,condition,also) end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,var) return event.EventTracker[var] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then loadstring(event.Events[d])() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then loadstring(event.Events[d])() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then loadstring(event.Events[d])() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
createStep=function(self,tag,reset,endc)
|
||||
if not(endc) then endc=false end
|
||||
if not(reset) then reset=0 end
|
||||
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc,
|
||||
Step=function(self) if self~=nil then _G.__CStep__=self if self.active==true then loadstring("Step_"..tag.."("..self.pos..",__CStep__)")() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then loadstring("Step_"..self.Name.."_End(__CStep__)")() end end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
--addAlarm=function(self,tag) end,
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))() end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,var) return event.EventTracker[var] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
RManager=function() event.OnCreate() while event.Active==true do event.OnUpdate() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end event.OnClose() end,
|
||||
createStep=function(self,tag,reset,endc)
|
||||
if not(endc) then endc=false end
|
||||
if not(reset) then reset=0 end
|
||||
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc,
|
||||
Step=function(self) if self~=nil then _G.__CStep__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
--addAlarm=function(self,tag) end,
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))() end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,var) return event.EventTracker[var] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
RManager=function() event.OnCreate() while event.Active==true do event.OnUpdate() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end event.OnClose() end,
|
||||
createStep=function(self,tag,reset,endc)
|
||||
if not(endc) then endc=false end
|
||||
if not(reset) then reset=0 end
|
||||
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc,
|
||||
Step=function(self) if self~=nil then _G.__CStep__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
--addAlarm=function(self,tag) end,
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))() end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,var) return event.EventTracker[var] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
RManager=function() event.OnCreate() while event.Active==true do event.OnUpdate() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end event.OnClose() end,
|
||||
createStep=function(self,tag,reset,endc)
|
||||
if not(endc) then endc=false end
|
||||
if not(reset) then reset=0 end
|
||||
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc,
|
||||
Step=function(self) if self~=nil then _G.__CStep__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
--addAlarm=function(self,tag) end,
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))() end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,var) return event.EventTracker[var] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
RManager=function() event.OnCreate() while event.Active==true do event.OnUpdate() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end event.OnClose() end,
|
||||
createStep=function(self,tag,reset,endc)
|
||||
if not(endc) then endc=false end
|
||||
if not(reset) then reset=0 end
|
||||
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc,
|
||||
Step=function(self) if self~=nil then _G.__CStep__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -1,98 +1,98 @@
|
||||
require("Data/BasicCommands")
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
TSteps={},
|
||||
LoadOrder="/E/S/U",-- types = ESU,EUS,USE,UES,SEU,SUE
|
||||
setLoadOrder=function(self,str) event.LoadOrder=string.upper(str) end,
|
||||
DO_Order=function() LoadOrder=event.LoadOrder LoadOrder=LoadOrder:gsub("/E", "event.RUN_EVENTS(); ") LoadOrder=LoadOrder:gsub("/S", "event.RUN_STEPS(); ") LoadOrder=LoadOrder:gsub("/U", "event.RUN_UPDATES(); ") assert(loadstring(LoadOrder))() end,
|
||||
RUN_EVENTS=function() for d=1,#event.Events do assert(loadstring(event.Events[d]))() end end,
|
||||
RUN_STEPS=function() for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end,
|
||||
RUN_UPDATES=function() event.OnUpdate() end,
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))() end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,varname) return event.EventTracker[varname] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do event.DO_Order() end event.OnClose() end,
|
||||
--Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
createStep=function(self,tag,reset,skip,endc)
|
||||
if not(endc) then endc=false end
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip=skip or 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
createTStep=function(self,tag,reset,timer,endc)
|
||||
if not(endc) then endc=false end
|
||||
timer=timer or 1
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip= 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self if self.active==true then assert(loadstring("TStep_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CStep__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self assert(loadstring("TStep_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CStep__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
event:setAlarm("TStep_"..tag,timer)
|
||||
event:addTracker("_TStep_"..tag,temp)
|
||||
table.insert(event.TSteps,temp)
|
||||
assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:setAlarm(alarm,"..timer..") end"))()
|
||||
return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
require("Data/BasicCommands")
|
||||
IsEvent=true
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
TSteps={},
|
||||
LoadOrder="/E/S/U",-- types = ESU,EUS,USE,UES,SEU,SUE
|
||||
setLoadOrder=function(self,str) event.LoadOrder=string.upper(str) end,
|
||||
DO_Order=function() LoadOrder=event.LoadOrder LoadOrder=LoadOrder:gsub("/E", "event.RUN_EVENTS(); ") LoadOrder=LoadOrder:gsub("/S", "event.RUN_STEPS(); ") LoadOrder=LoadOrder:gsub("/U", "event.RUN_UPDATES(); ") assert(loadstring(LoadOrder))() end,
|
||||
RUN_EVENTS=function() for d=1,#event.Events do assert(loadstring(event.Events[d]))() end end,
|
||||
RUN_STEPS=function() for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end,
|
||||
RUN_UPDATES=function() event.OnUpdate() end,
|
||||
setAlarm=function(self,tag,set) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:addTracker("_Alarm_"..tag,SetCounter()) assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))() end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroy("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,varname) return event.EventTracker[varname] end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroy=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do event.DO_Order() end event.OnClose() end,
|
||||
--Manager=function() event.OnCreate() while event.Active==true do for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end event.OnClose() end,
|
||||
CManager=function() for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end for d=1,#event.Events do if event.Active==true then assert(loadstring(event.Events[d]))() end end for s_g=1,#event.Steps do event.Steps[s_g]:Step() end event.OnUpdate() end,
|
||||
createStep=function(self,tag,reset,skip,endc)
|
||||
if not(endc) then endc=false end
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip=skip or 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self assert(loadstring("Step_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CStep__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp end,
|
||||
createTStep=function(self,tag,reset,timer,endc)
|
||||
if not(endc) then endc=false end
|
||||
timer=timer or 1
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip= 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self if self.active==true then assert(loadstring("TStep_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CStep__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CStep__=self assert(loadstring("TStep_"..tag.."("..self.pos..",__CStep__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CStep__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
event:setAlarm("TStep_"..tag,timer)
|
||||
event:addTracker("_TStep_"..tag,temp)
|
||||
table.insert(event.TSteps,temp)
|
||||
assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:setAlarm(alarm,"..timer..") end"))()
|
||||
return temp end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
|
||||
+203
-203
@@ -1,203 +1,203 @@
|
||||
function dump(t,indent)
|
||||
local names = {}
|
||||
if not indent then indent = "" end
|
||||
for n,g in pairs(t) do
|
||||
table.insert(names,n)
|
||||
end
|
||||
table.sort(names)
|
||||
for i,n in pairs(names) do
|
||||
local v = t[n]
|
||||
if type(v) == "table" then
|
||||
if(v==t) then -- prevent endless loop if table contains reference to itself
|
||||
print(indent..tostring(n)..": <-")
|
||||
else
|
||||
print(indent..tostring(n)..":")
|
||||
dump(v,indent.." ")
|
||||
end
|
||||
else
|
||||
if type(v) == "function" then
|
||||
print(indent..tostring(n).."()")
|
||||
else
|
||||
print(indent..tostring(n)..": "..tostring(v))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function SetCounter()
|
||||
return os.clock()
|
||||
end
|
||||
----------------------------------------------------------------------------------------------------
|
||||
function GetCounter(count)
|
||||
if count~=nil then
|
||||
return os.clock()-count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
----------------------------------------------------------------------------------------------------
|
||||
clock=os.clock
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
Alarms={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
TSteps={},
|
||||
CTask="",
|
||||
LoadOrder="/E/S/A/U",
|
||||
UpdateObj=
|
||||
{
|
||||
LoadOrder="",
|
||||
Resume=function(self) event.LoadOrder=self.LoadOrder end,
|
||||
Pause=function(self) self.LoadOrder=event.LoadOrder event.LoadOrder=event.LoadOrder:gsub("/U", "") end,
|
||||
},
|
||||
setLoadOrder=function(self,str) event.LoadOrder=string.upper(str) end,
|
||||
DO_Order=function() LoadOrder=event.LoadOrder LoadOrder=LoadOrder:gsub("/A", "event.RUN_ALARMS(); ") LoadOrder=LoadOrder:gsub("/E", "event.RUN_EVENTS(); ") LoadOrder=LoadOrder:gsub("/S", "event.RUN_STEPS(); ") LoadOrder=LoadOrder:gsub("/U", "event.RUN_UPDATES(); ") assert(loadstring(LoadOrder))() end,
|
||||
RUN_EVENTS=function() event.CTask="events" for d=1,#event.Events do assert(loadstring(event.Events[d]))() end end,
|
||||
RUN_STEPS=function() event.CTask="steps" for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end,
|
||||
RUN_UPDATES=function() _G.__CAction__=event.UpdateObj event.CTask="updates" event.OnUpdate() end,
|
||||
RUN_ALARMS=function() for i=1,#event.Alarms do event.Alarms[i]:Tick() end end,
|
||||
--System Used Functions
|
||||
Hold=function(self,task) -- as many conditions and times that you want can be used
|
||||
local action=__CAction__
|
||||
action:Pause()
|
||||
if type(task)=="number" then
|
||||
local func=function() end
|
||||
local alarm=event:newAlarm(task,func,true)
|
||||
while alarm.active==true do
|
||||
event.CManager()
|
||||
end
|
||||
alarm:Destroy()
|
||||
action:Resume()
|
||||
elseif type(task)=="string" then
|
||||
assert(loadstring("while not("..task..") do event.CManager() end"))()
|
||||
action:Resume()
|
||||
end
|
||||
end,
|
||||
newAlarm=function(self,set,func,start)
|
||||
if not(start) then timer=0 active=false else timer=clock() active=true end
|
||||
if not(func) then func=(function() end) end
|
||||
Alarm=
|
||||
{
|
||||
active=active,
|
||||
timer=timer,
|
||||
set=set or 0,
|
||||
func=func,
|
||||
Tick=function(self) _G.__CAction__=self if self.active==true then if clock()-self.timer>=self.set then self:Pause() self:Ring() end end end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Set=function(self,amt) self.set=amt self.timer=clock() self:Resume() end,
|
||||
OnRing=function(self,func) self.func=func end,
|
||||
Ring=function(self) self:func(self) end,
|
||||
Reset=function(self) self.timer=clock() self:Resume() end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Destroy=function(self) for i=1,#event.Alarms do if tostring(event.Alarms[i])==tostring(self) then table.remove(event.Alarms,i) end end end,
|
||||
}
|
||||
table.insert(event.Alarms,Alarm)
|
||||
return Alarm
|
||||
end,
|
||||
setAlarm=function(self,tag,set)
|
||||
if event:eventExist("Alarm_"..tag.."(\""..tag.."\")")==false then
|
||||
event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]])
|
||||
event:addTracker("_Alarm_"..tag,SetCounter())
|
||||
assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))()
|
||||
else
|
||||
event:addTracker("_Alarm_"..tag,SetCounter())
|
||||
end
|
||||
end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroyEvent("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,varname) return event.EventTracker[varname] end,
|
||||
listTrackers=function(self) return event.EventTracker end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroyEvent=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do event.DO_Order() end event.OnClose() end,
|
||||
CManager=function() if event.Active==true then event.DO_Order() end end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end if event.Active==true then event.DO_Order() end end,
|
||||
createStep=function(self,tag,reset,skip,endc)
|
||||
if not(endc) then
|
||||
endc=false
|
||||
end
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip=skip or 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self assert(loadstring("Step_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) _G.__CAction__=self assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() self:Reset() end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp
|
||||
end,
|
||||
createTStep=function(self,tag,reset,timer,endc)
|
||||
if not(endc) then
|
||||
endc=false
|
||||
end
|
||||
timer=timer or 1
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip= 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self if self.active==true then assert(loadstring("TStep_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CAction__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self assert(loadstring("TStep_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CAction__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
event:setAlarm("TStep_"..tag,timer)
|
||||
event:addTracker("_TStep_"..tag,temp)
|
||||
table.insert(event.TSteps,temp)
|
||||
assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:updateAlarm(alarm,"..timer..") end"))()
|
||||
return temp
|
||||
end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
tstepExist=function(self,tag)
|
||||
for a_s=1,#event.TSteps do
|
||||
if event.TSteps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
function dump(t,indent)
|
||||
local names = {}
|
||||
if not indent then indent = "" end
|
||||
for n,g in pairs(t) do
|
||||
table.insert(names,n)
|
||||
end
|
||||
table.sort(names)
|
||||
for i,n in pairs(names) do
|
||||
local v = t[n]
|
||||
if type(v) == "table" then
|
||||
if(v==t) then -- prevent endless loop if table contains reference to itself
|
||||
print(indent..tostring(n)..": <-")
|
||||
else
|
||||
print(indent..tostring(n)..":")
|
||||
dump(v,indent.." ")
|
||||
end
|
||||
else
|
||||
if type(v) == "function" then
|
||||
print(indent..tostring(n).."()")
|
||||
else
|
||||
print(indent..tostring(n)..": "..tostring(v))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function SetCounter()
|
||||
return os.clock()
|
||||
end
|
||||
----------------------------------------------------------------------------------------------------
|
||||
function GetCounter(count)
|
||||
if count~=nil then
|
||||
return os.clock()-count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
----------------------------------------------------------------------------------------------------
|
||||
clock=os.clock
|
||||
event={
|
||||
Active=true,
|
||||
CT=false,
|
||||
tag={},
|
||||
Events={},
|
||||
Alarms={},
|
||||
EventTracker={},
|
||||
Steps={},
|
||||
TSteps={},
|
||||
CTask="",
|
||||
LoadOrder="/E/S/A/U",
|
||||
UpdateObj=
|
||||
{
|
||||
LoadOrder="",
|
||||
Resume=function(self) event.LoadOrder=self.LoadOrder end,
|
||||
Pause=function(self) self.LoadOrder=event.LoadOrder event.LoadOrder=event.LoadOrder:gsub("/U", "") end,
|
||||
},
|
||||
setLoadOrder=function(self,str) event.LoadOrder=string.upper(str) end,
|
||||
DO_Order=function() LoadOrder=event.LoadOrder LoadOrder=LoadOrder:gsub("/A", "event.RUN_ALARMS(); ") LoadOrder=LoadOrder:gsub("/E", "event.RUN_EVENTS(); ") LoadOrder=LoadOrder:gsub("/S", "event.RUN_STEPS(); ") LoadOrder=LoadOrder:gsub("/U", "event.RUN_UPDATES(); ") assert(loadstring(LoadOrder))() end,
|
||||
RUN_EVENTS=function() event.CTask="events" for d=1,#event.Events do assert(loadstring(event.Events[d]))() end end,
|
||||
RUN_STEPS=function() event.CTask="steps" for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end,
|
||||
RUN_UPDATES=function() _G.__CAction__=event.UpdateObj event.CTask="updates" event.OnUpdate() end,
|
||||
RUN_ALARMS=function() for i=1,#event.Alarms do event.Alarms[i]:Tick() end end,
|
||||
--System Used Functions
|
||||
Hold=function(self,task) -- as many conditions and times that you want can be used
|
||||
local action=__CAction__
|
||||
action:Pause()
|
||||
if type(task)=="number" then
|
||||
local func=function() end
|
||||
local alarm=event:newAlarm(task,func,true)
|
||||
while alarm.active==true do
|
||||
event.CManager()
|
||||
end
|
||||
alarm:Destroy()
|
||||
action:Resume()
|
||||
elseif type(task)=="string" then
|
||||
assert(loadstring("while not("..task..") do event.CManager() end"))()
|
||||
action:Resume()
|
||||
end
|
||||
end,
|
||||
newAlarm=function(self,set,func,start)
|
||||
if not(start) then timer=0 active=false else timer=clock() active=true end
|
||||
if not(func) then func=(function() end) end
|
||||
Alarm=
|
||||
{
|
||||
active=active,
|
||||
timer=timer,
|
||||
set=set or 0,
|
||||
func=func,
|
||||
Tick=function(self) _G.__CAction__=self if self.active==true then if clock()-self.timer>=self.set then self:Pause() self:Ring() end end end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Set=function(self,amt) self.set=amt self.timer=clock() self:Resume() end,
|
||||
OnRing=function(self,func) self.func=func end,
|
||||
Ring=function(self) self:func(self) end,
|
||||
Reset=function(self) self.timer=clock() self:Resume() end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Destroy=function(self) for i=1,#event.Alarms do if tostring(event.Alarms[i])==tostring(self) then table.remove(event.Alarms,i) end end end,
|
||||
}
|
||||
table.insert(event.Alarms,Alarm)
|
||||
return Alarm
|
||||
end,
|
||||
setAlarm=function(self,tag,set)
|
||||
if event:eventExist("Alarm_"..tag.."(\""..tag.."\")")==false then
|
||||
event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]])
|
||||
event:addTracker("_Alarm_"..tag,SetCounter())
|
||||
assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))()
|
||||
else
|
||||
event:addTracker("_Alarm_"..tag,SetCounter())
|
||||
end
|
||||
end,
|
||||
setEvent=function(self,fname,condition,also) if not(string.find(fname,"(",1,true)) and not(string.find(fname,")",1,true)) then fname=fname.."()" end a=string.find(fname,"(",1,true) tempstr=string.sub(fname,1,a-1) event:new("Event_"..fname,condition,also) assert(loadstring("if Event_"..tempstr.."==nil then function Event_"..tempstr.."() print('No function \"Event_"..tempstr.."()\" exists make sure you created it') end end"))() end,
|
||||
removeAlarm=function(self,tag) event:destroyEvent("Alarm_"..tag) event:removeTracker("_Alarm_"..tag) end,
|
||||
updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
|
||||
addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
|
||||
getTracker=function(self,varname) return event.EventTracker[varname] end,
|
||||
listTrackers=function(self) return event.EventTracker end,
|
||||
removeTracker=function(self,var) event.EventTracker[var]=nil end,
|
||||
trackerExist=function(self,tag) return event.EventTracker[tag]~=nil end,
|
||||
updateTracker=function(self,tag,val) if event:trackerExist(tag) then event.EventTracker[tag]=val end end,
|
||||
alarmExist=function(self,tag) return (event:getTracker("_Alarm_"..tag)~=nil) end,
|
||||
new=function(self,fname,condition,also) if not(also) then also="" end table.insert(self.Events,"if "..condition.." then "..also.." "..fname.." end") table.insert(event.tag,fname) end,
|
||||
eventExist=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then return true end end return false end,
|
||||
destroyEvent=function(self,tag) for j=1,#event.tag do if event.tag[j]==tag then table.remove(event.tag,j) table.remove(event.Events,j) end end end,
|
||||
Stop=function() event.Active=false end,
|
||||
OnCreate=function() end,
|
||||
OnUpdate=function() end,
|
||||
OnClose=function() end,
|
||||
getActive=function() return event.tag end,
|
||||
Manager=function() event.OnCreate() while event.Active==true do event.DO_Order() end event.OnClose() end,
|
||||
CManager=function() if event.Active==true then event.DO_Order() end end,
|
||||
UManager=function() if event.CT==false then event.CT=true event.OnCreate() end if event.Active==true then event.DO_Order() end end,
|
||||
createStep=function(self,tag,reset,skip,endc)
|
||||
if not(endc) then
|
||||
endc=false
|
||||
end
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip=skip or 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self if self.active==true then assert(loadstring("Step_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self assert(loadstring("Step_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) _G.__CAction__=self assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() self:Reset() end,
|
||||
}
|
||||
table.insert(event.Steps,temp) return temp
|
||||
end,
|
||||
createTStep=function(self,tag,reset,timer,endc)
|
||||
if not(endc) then
|
||||
endc=false
|
||||
end
|
||||
timer=timer or 1
|
||||
temp=
|
||||
{
|
||||
Name=tag,
|
||||
pos=1,
|
||||
endAt=reset or math.huge,
|
||||
active=true,
|
||||
endc=endc,
|
||||
skip= 0,
|
||||
spos=0,
|
||||
Step=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self if self.active==true then assert(loadstring("TStep_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CAction__)"))() end end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
FStep=function(self) if self~=nil then if self.spos==0 then _G.__CAction__=self assert(loadstring("TStep_"..tag.."("..self.pos..",__CAction__)"))() self.pos=self.pos+1 end end if self.endAt+1<=self.pos then self:Reset() if endc==true then assert(loadstring("TStep_"..self.Name.."_End(__CAction__)"))() end end self.spos=self.spos+1 if self.spos>=self.skip then self.spos=0 end end,
|
||||
Remove=function(self) for as=1,#event.Steps do if event.Steps[as].Name==self.Name then table.remove(event.Steps,as) end end end,
|
||||
Reset=function(self) self.pos=1 end,
|
||||
Set=function(self,amt) self.pos=amt end,
|
||||
Pause=function(self) self.active=false end,
|
||||
Resume=function(self) self.active=true end,
|
||||
Stop=function(self) self:Reset() self:Pause() end,
|
||||
Start=function(self) self:Resume() end,
|
||||
End=function(self) self.pos=self.EndAt self.endc=true end,
|
||||
}
|
||||
event:setAlarm("TStep_"..tag,timer)
|
||||
event:addTracker("_TStep_"..tag,temp)
|
||||
table.insert(event.TSteps,temp)
|
||||
assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:updateAlarm(alarm,"..timer..") end"))()
|
||||
return temp
|
||||
end,
|
||||
stepExist=function(self,tag)
|
||||
for a_s=1,#event.Steps do
|
||||
if event.Steps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
tstepExist=function(self,tag)
|
||||
for a_s=1,#event.TSteps do
|
||||
if event.TSteps[a_s].Name==tag then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
}
|
||||
|
||||
+728
-728
File diff suppressed because it is too large
Load Diff
+728
-728
File diff suppressed because it is too large
Load Diff
+365
-365
@@ -1,365 +1,365 @@
|
||||
multi = {}
|
||||
multi.__index = multi
|
||||
multi.Mainloop={}
|
||||
multi.Tasks={}
|
||||
multi.Tasks2={}
|
||||
multi.Garbage={}
|
||||
multi.Children={}
|
||||
multi.Paused={}
|
||||
multi.MasterId=0
|
||||
multi.Active=true
|
||||
multi.Id=-1
|
||||
-- System
|
||||
function multi:newBase(ins)
|
||||
local c = {}
|
||||
setmetatable(c, multi)
|
||||
c.Parent=self
|
||||
c.Active=true
|
||||
c.func={}
|
||||
c.Id=0
|
||||
c.Act=function() end
|
||||
if ins then
|
||||
table.insert(multi.Mainloop,ins,c)
|
||||
else
|
||||
table.insert(multi.Mainloop,c)
|
||||
end
|
||||
multi.MasterId=multi.MasterId+1
|
||||
return c
|
||||
end
|
||||
function multi:reboot(r)
|
||||
multi.Mainloop={}
|
||||
multi.Tasks={}
|
||||
multi.Tasks2={}
|
||||
multi.Garbage={}
|
||||
multi.Children={}
|
||||
multi.Paused={}
|
||||
multi.MasterId=0
|
||||
multi.Active=true
|
||||
multi.Id=-1
|
||||
if r then
|
||||
for i,v in pairs(_G) do
|
||||
if type(i)=="table" then
|
||||
if i.Parent and i.Id and i.Act then
|
||||
i={}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--Processor
|
||||
function multi.Do_Order()
|
||||
for _D=#multi.Mainloop,1,-1 do
|
||||
if multi.Mainloop[_D]~=nil then
|
||||
multi.Mainloop[_D].Id=_D
|
||||
multi.Mainloop[_D]:Act()
|
||||
end
|
||||
end
|
||||
end
|
||||
function multi:benchMark(sec)
|
||||
local temp=multi:newStep(2)
|
||||
temp.CC=0
|
||||
temp:OnStep(function(pos,step) step.CC=step.CC+1 end)
|
||||
local Loud=multi:newAlarm(sec)
|
||||
Loud.Link=temp
|
||||
Loud:OnRing(function(alarm) alarm.Link.CC=alarm.Link.CC print((alarm.Link.CC).." steps in "..alarm.set.." second(s)") alarm.bench=alarm.Link.CC alarm.Link:Destroy() alarm:Destroy() end)
|
||||
return Loud
|
||||
end
|
||||
--Helpers
|
||||
function multi:FreeMainEvent()
|
||||
self.func={}
|
||||
end
|
||||
function multi:isPaused()
|
||||
return not(self.Active)
|
||||
end
|
||||
function multi:Pause(n)
|
||||
if not(n) then
|
||||
self.Active=false
|
||||
table.remove(multi.Mainloop,self.Id)
|
||||
table.insert(multi.Paused,self)
|
||||
else
|
||||
self:hold(n)
|
||||
end
|
||||
end
|
||||
function multi:Resume()
|
||||
if self:isPaused() then
|
||||
self.Active=true
|
||||
table.remove(multi.Paused,self.Id)
|
||||
table.insert(multi.Mainloop,self)
|
||||
end
|
||||
end
|
||||
function multi:Remove()
|
||||
self:Pause()
|
||||
self:Destroy()
|
||||
end
|
||||
function multi:Destroy()
|
||||
self:Pause()
|
||||
if self:isPaused() then
|
||||
for i=1,#multi.Paused do
|
||||
if multi.Paused[i]==self then
|
||||
table.remove(multi.Paused,i)
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
table.remove(multi.Mainloop,self.Id)
|
||||
end
|
||||
self.Act=function() end
|
||||
end
|
||||
function multi:hold(task)
|
||||
self:Pause()
|
||||
if type(task)=="number" then
|
||||
local alarm=multi:newAlarm(task)
|
||||
while alarm.Active==true do
|
||||
if love then
|
||||
multi.lManager()
|
||||
else
|
||||
multi.Do_Order()
|
||||
end
|
||||
end
|
||||
alarm:Destroy()
|
||||
self:Resume()
|
||||
elseif type(task)=="function" then
|
||||
local env=multi:newEvent(task)
|
||||
env:OnEvent(function(envt) envt:Pause() envt:Stop() end)
|
||||
while env.Active do
|
||||
if love then
|
||||
multi.lManager()
|
||||
else
|
||||
multi.Do_Order()
|
||||
end
|
||||
end
|
||||
env:Destroy()
|
||||
self:Resume()
|
||||
else
|
||||
print("Error Data Type!!!")
|
||||
end
|
||||
end
|
||||
function multi:oneTime(func,...)
|
||||
for _k=1,#multi.Tasks2 do
|
||||
if multi.Tasks2[_k]==func then
|
||||
return false
|
||||
end
|
||||
end
|
||||
table.insert(multi.Tasks2,func)
|
||||
func(...)
|
||||
return true
|
||||
end
|
||||
--Constructors
|
||||
function multi:newEvent(task)
|
||||
local c=multi:newBase()
|
||||
c.Type="Event"
|
||||
c.Task=task or function() end
|
||||
function c:Act()
|
||||
if self.Task(self) and self.Active==true then
|
||||
self:Pause()
|
||||
for _E=1,#self.func do
|
||||
self.func[_E](self)
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:OnEvent(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
function multi:newAlarm(set)
|
||||
local c=multi:newBase()
|
||||
c.Type="Alarm"
|
||||
c.timer=os.clock()
|
||||
c.set=set or 0
|
||||
function c:Act()
|
||||
if self.Active==true then
|
||||
if os.clock()-self.timer>=self.set then
|
||||
self:Pause()
|
||||
for i=1,#self.func do
|
||||
self.func[i](self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:Reset(n)
|
||||
if n then self.set=n end
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
function c:OnRing(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
function multi:newTask(func)
|
||||
table.insert(multi.Tasks,func)
|
||||
end
|
||||
function multi:newLoop()
|
||||
local c=multi:newBase()
|
||||
c.Type="Loop"
|
||||
function c:Act()
|
||||
if self.Active==true then
|
||||
for i=1,#self.func do
|
||||
self.func[i](os.clock()-multi.Start,self)
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:OnLoop(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
function multi:newStep(start,reset,count,skip)
|
||||
local c=multi:newBase()
|
||||
think=1
|
||||
c.Type="Step"
|
||||
c.pos=start or 1
|
||||
c.endAt=reset or math.huge
|
||||
c.skip=skip or 0
|
||||
c.spos=0
|
||||
c.count=count or 1*think
|
||||
c.funcE={}
|
||||
c.start=start or 1
|
||||
if start~=nil and reset~=nil then
|
||||
if start>reset then
|
||||
think=-1
|
||||
end
|
||||
end
|
||||
function c:Act()
|
||||
if self~=nil then
|
||||
if self.spos==0 then
|
||||
if self.Active==true then
|
||||
for i=1,#self.func do
|
||||
self.func[i](self.pos,self)
|
||||
end
|
||||
self.pos=self.pos+self.count
|
||||
end
|
||||
end
|
||||
end
|
||||
self.spos=self.spos+1
|
||||
if self.spos>=self.skip then
|
||||
self.spos=0
|
||||
end
|
||||
end
|
||||
function c:OnStep(func)
|
||||
table.insert(self.func,1,func)
|
||||
end
|
||||
function c:OnEnd(func)
|
||||
table.insert(self.funcE,func)
|
||||
end
|
||||
function c:Update(start,reset,count,skip)
|
||||
self.start=start or self.start
|
||||
self.endAt=reset or self.endAt
|
||||
self.skip=skip or self.skip
|
||||
self.count=count or self.count
|
||||
self:Resume()
|
||||
end
|
||||
c:OnStep(function(p,s)
|
||||
if s.count>0 and s.endAt==p then
|
||||
for fe=1,#s.funcE do
|
||||
s.funcE[fe](s)
|
||||
end
|
||||
s.pos=s.start-1
|
||||
elseif s.count<0 and s.endAt==p then
|
||||
for fe=1,#s.funcE do
|
||||
s.funcE[fe](s)
|
||||
end
|
||||
s.pos=s.start-1
|
||||
end
|
||||
end)
|
||||
return c
|
||||
end
|
||||
function multi:newTStep(start,reset,count,set)
|
||||
local c=multi:newBase()
|
||||
think=1
|
||||
c.Type="TStep"
|
||||
c.start=start or 1
|
||||
local reset = reset or math.huge
|
||||
c.endAt=reset
|
||||
c.pos=start or 1
|
||||
c.skip=skip or 0
|
||||
c.count=count or 1*think
|
||||
c.funcE={}
|
||||
c.timer=os.clock()
|
||||
c.set=set or 1
|
||||
function c:Update(start,reset,count,set)
|
||||
self.start=start or self.start
|
||||
self.pos=start
|
||||
self.endAt=reset or self.endAt
|
||||
self.set=set or self.set
|
||||
self.count=count or self.count or 1
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
function c:Act()
|
||||
if self.Active then
|
||||
if os.clock()-self.timer>=self.set then
|
||||
self:Reset()
|
||||
for i=1,#self.func do
|
||||
self.func[i](self.pos,self)
|
||||
end
|
||||
if self.endAt==self.pos then
|
||||
for fe=1,#self.funcE do
|
||||
self.funcE[fe](self)
|
||||
end
|
||||
self.pos=self.start-1
|
||||
end
|
||||
self.pos=self.pos+self.count
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:OnEnd(func)
|
||||
table.insert(self.funcE,func)
|
||||
end
|
||||
function c:Reset(n)
|
||||
if n then self.set=n end
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
function c:OnStep(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:inQueue(func)
|
||||
if self.Id==-1 then
|
||||
print("Error: Can't queue the multi object")
|
||||
return
|
||||
end
|
||||
local c=multi:newBase(self.Id)
|
||||
self.Id=self.Id-1
|
||||
c.Type="Queue"
|
||||
c.Task=func
|
||||
c.Link=self
|
||||
function c:Act()
|
||||
self.Task(self.Link)
|
||||
self:Destroy()
|
||||
end
|
||||
end
|
||||
function multi:newTrigger(func)
|
||||
local c=multi:newBase()
|
||||
c.Type="Trigger"
|
||||
c.trigfunc=func or function() end
|
||||
function c:Fire(...)
|
||||
self:trigfunc(self,...)
|
||||
end
|
||||
return c
|
||||
end
|
||||
--Managers
|
||||
function multi:mainloop()
|
||||
for i=1,#multi.Tasks do
|
||||
multi.Tasks[i]()
|
||||
end
|
||||
multi.Start=os.clock()
|
||||
while self.Active do
|
||||
multi.Do_Order()
|
||||
end
|
||||
end
|
||||
function multi._tFunc(dt)
|
||||
if dt then
|
||||
multi.pump=true
|
||||
end
|
||||
multi.pumpvar=dt
|
||||
multi.Start=os.clock()
|
||||
end
|
||||
function multi:uManager(dt)
|
||||
multi:oneTime(multi._tFunc,dt)
|
||||
multi.Do_Order()
|
||||
end
|
||||
multi = {}
|
||||
multi.__index = multi
|
||||
multi.Mainloop={}
|
||||
multi.Tasks={}
|
||||
multi.Tasks2={}
|
||||
multi.Garbage={}
|
||||
multi.Children={}
|
||||
multi.Paused={}
|
||||
multi.MasterId=0
|
||||
multi.Active=true
|
||||
multi.Id=-1
|
||||
-- System
|
||||
function multi:newBase(ins)
|
||||
local c = {}
|
||||
setmetatable(c, multi)
|
||||
c.Parent=self
|
||||
c.Active=true
|
||||
c.func={}
|
||||
c.Id=0
|
||||
c.Act=function() end
|
||||
if ins then
|
||||
table.insert(multi.Mainloop,ins,c)
|
||||
else
|
||||
table.insert(multi.Mainloop,c)
|
||||
end
|
||||
multi.MasterId=multi.MasterId+1
|
||||
return c
|
||||
end
|
||||
function multi:reboot(r)
|
||||
multi.Mainloop={}
|
||||
multi.Tasks={}
|
||||
multi.Tasks2={}
|
||||
multi.Garbage={}
|
||||
multi.Children={}
|
||||
multi.Paused={}
|
||||
multi.MasterId=0
|
||||
multi.Active=true
|
||||
multi.Id=-1
|
||||
if r then
|
||||
for i,v in pairs(_G) do
|
||||
if type(i)=="table" then
|
||||
if i.Parent and i.Id and i.Act then
|
||||
i={}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--Processor
|
||||
function multi.Do_Order()
|
||||
for _D=#multi.Mainloop,1,-1 do
|
||||
if multi.Mainloop[_D]~=nil then
|
||||
multi.Mainloop[_D].Id=_D
|
||||
multi.Mainloop[_D]:Act()
|
||||
end
|
||||
end
|
||||
end
|
||||
function multi:benchMark(sec)
|
||||
local temp=multi:newStep(2)
|
||||
temp.CC=0
|
||||
temp:OnStep(function(pos,step) step.CC=step.CC+1 end)
|
||||
local Loud=multi:newAlarm(sec)
|
||||
Loud.Link=temp
|
||||
Loud:OnRing(function(alarm) alarm.Link.CC=alarm.Link.CC print((alarm.Link.CC).." steps in "..alarm.set.." second(s)") alarm.bench=alarm.Link.CC alarm.Link:Destroy() alarm:Destroy() end)
|
||||
return Loud
|
||||
end
|
||||
--Helpers
|
||||
function multi:FreeMainEvent()
|
||||
self.func={}
|
||||
end
|
||||
function multi:isPaused()
|
||||
return not(self.Active)
|
||||
end
|
||||
function multi:Pause(n)
|
||||
if not(n) then
|
||||
self.Active=false
|
||||
table.remove(multi.Mainloop,self.Id)
|
||||
table.insert(multi.Paused,self)
|
||||
else
|
||||
self:hold(n)
|
||||
end
|
||||
end
|
||||
function multi:Resume()
|
||||
if self:isPaused() then
|
||||
self.Active=true
|
||||
table.remove(multi.Paused,self.Id)
|
||||
table.insert(multi.Mainloop,self)
|
||||
end
|
||||
end
|
||||
function multi:Remove()
|
||||
self:Pause()
|
||||
self:Destroy()
|
||||
end
|
||||
function multi:Destroy()
|
||||
self:Pause()
|
||||
if self:isPaused() then
|
||||
for i=1,#multi.Paused do
|
||||
if multi.Paused[i]==self then
|
||||
table.remove(multi.Paused,i)
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
table.remove(multi.Mainloop,self.Id)
|
||||
end
|
||||
self.Act=function() end
|
||||
end
|
||||
function multi:hold(task)
|
||||
self:Pause()
|
||||
if type(task)=="number" then
|
||||
local alarm=multi:newAlarm(task)
|
||||
while alarm.Active==true do
|
||||
if love then
|
||||
multi.lManager()
|
||||
else
|
||||
multi.Do_Order()
|
||||
end
|
||||
end
|
||||
alarm:Destroy()
|
||||
self:Resume()
|
||||
elseif type(task)=="function" then
|
||||
local env=multi:newEvent(task)
|
||||
env:OnEvent(function(envt) envt:Pause() envt:Stop() end)
|
||||
while env.Active do
|
||||
if love then
|
||||
multi.lManager()
|
||||
else
|
||||
multi.Do_Order()
|
||||
end
|
||||
end
|
||||
env:Destroy()
|
||||
self:Resume()
|
||||
else
|
||||
print("Error Data Type!!!")
|
||||
end
|
||||
end
|
||||
function multi:oneTime(func,...)
|
||||
for _k=1,#multi.Tasks2 do
|
||||
if multi.Tasks2[_k]==func then
|
||||
return false
|
||||
end
|
||||
end
|
||||
table.insert(multi.Tasks2,func)
|
||||
func(...)
|
||||
return true
|
||||
end
|
||||
--Constructors
|
||||
function multi:newEvent(task)
|
||||
local c=multi:newBase()
|
||||
c.Type="Event"
|
||||
c.Task=task or function() end
|
||||
function c:Act()
|
||||
if self.Task(self) and self.Active==true then
|
||||
self:Pause()
|
||||
for _E=1,#self.func do
|
||||
self.func[_E](self)
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:OnEvent(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
function multi:newAlarm(set)
|
||||
local c=multi:newBase()
|
||||
c.Type="Alarm"
|
||||
c.timer=os.clock()
|
||||
c.set=set or 0
|
||||
function c:Act()
|
||||
if self.Active==true then
|
||||
if os.clock()-self.timer>=self.set then
|
||||
self:Pause()
|
||||
for i=1,#self.func do
|
||||
self.func[i](self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:Reset(n)
|
||||
if n then self.set=n end
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
function c:OnRing(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
function multi:newTask(func)
|
||||
table.insert(multi.Tasks,func)
|
||||
end
|
||||
function multi:newLoop()
|
||||
local c=multi:newBase()
|
||||
c.Type="Loop"
|
||||
function c:Act()
|
||||
if self.Active==true then
|
||||
for i=1,#self.func do
|
||||
self.func[i](os.clock()-multi.Start,self)
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:OnLoop(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
function multi:newStep(start,reset,count,skip)
|
||||
local c=multi:newBase()
|
||||
think=1
|
||||
c.Type="Step"
|
||||
c.pos=start or 1
|
||||
c.endAt=reset or math.huge
|
||||
c.skip=skip or 0
|
||||
c.spos=0
|
||||
c.count=count or 1*think
|
||||
c.funcE={}
|
||||
c.start=start or 1
|
||||
if start~=nil and reset~=nil then
|
||||
if start>reset then
|
||||
think=-1
|
||||
end
|
||||
end
|
||||
function c:Act()
|
||||
if self~=nil then
|
||||
if self.spos==0 then
|
||||
if self.Active==true then
|
||||
for i=1,#self.func do
|
||||
self.func[i](self.pos,self)
|
||||
end
|
||||
self.pos=self.pos+self.count
|
||||
end
|
||||
end
|
||||
end
|
||||
self.spos=self.spos+1
|
||||
if self.spos>=self.skip then
|
||||
self.spos=0
|
||||
end
|
||||
end
|
||||
function c:OnStep(func)
|
||||
table.insert(self.func,1,func)
|
||||
end
|
||||
function c:OnEnd(func)
|
||||
table.insert(self.funcE,func)
|
||||
end
|
||||
function c:Update(start,reset,count,skip)
|
||||
self.start=start or self.start
|
||||
self.endAt=reset or self.endAt
|
||||
self.skip=skip or self.skip
|
||||
self.count=count or self.count
|
||||
self:Resume()
|
||||
end
|
||||
c:OnStep(function(p,s)
|
||||
if s.count>0 and s.endAt==p then
|
||||
for fe=1,#s.funcE do
|
||||
s.funcE[fe](s)
|
||||
end
|
||||
s.pos=s.start-1
|
||||
elseif s.count<0 and s.endAt==p then
|
||||
for fe=1,#s.funcE do
|
||||
s.funcE[fe](s)
|
||||
end
|
||||
s.pos=s.start-1
|
||||
end
|
||||
end)
|
||||
return c
|
||||
end
|
||||
function multi:newTStep(start,reset,count,set)
|
||||
local c=multi:newBase()
|
||||
think=1
|
||||
c.Type="TStep"
|
||||
c.start=start or 1
|
||||
local reset = reset or math.huge
|
||||
c.endAt=reset
|
||||
c.pos=start or 1
|
||||
c.skip=skip or 0
|
||||
c.count=count or 1*think
|
||||
c.funcE={}
|
||||
c.timer=os.clock()
|
||||
c.set=set or 1
|
||||
function c:Update(start,reset,count,set)
|
||||
self.start=start or self.start
|
||||
self.pos=start
|
||||
self.endAt=reset or self.endAt
|
||||
self.set=set or self.set
|
||||
self.count=count or self.count or 1
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
function c:Act()
|
||||
if self.Active then
|
||||
if os.clock()-self.timer>=self.set then
|
||||
self:Reset()
|
||||
for i=1,#self.func do
|
||||
self.func[i](self.pos,self)
|
||||
end
|
||||
if self.endAt==self.pos then
|
||||
for fe=1,#self.funcE do
|
||||
self.funcE[fe](self)
|
||||
end
|
||||
self.pos=self.start-1
|
||||
end
|
||||
self.pos=self.pos+self.count
|
||||
end
|
||||
end
|
||||
end
|
||||
function c:OnEnd(func)
|
||||
table.insert(self.funcE,func)
|
||||
end
|
||||
function c:Reset(n)
|
||||
if n then self.set=n end
|
||||
self.timer=os.clock()
|
||||
self:Resume()
|
||||
end
|
||||
function c:OnStep(func)
|
||||
table.insert(self.func,func)
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
function multi:inQueue(func)
|
||||
if self.Id==-1 then
|
||||
print("Error: Can't queue the multi object")
|
||||
return
|
||||
end
|
||||
local c=multi:newBase(self.Id)
|
||||
self.Id=self.Id-1
|
||||
c.Type="Queue"
|
||||
c.Task=func
|
||||
c.Link=self
|
||||
function c:Act()
|
||||
self.Task(self.Link)
|
||||
self:Destroy()
|
||||
end
|
||||
end
|
||||
function multi:newTrigger(func)
|
||||
local c=multi:newBase()
|
||||
c.Type="Trigger"
|
||||
c.trigfunc=func or function() end
|
||||
function c:Fire(...)
|
||||
self:trigfunc(self,...)
|
||||
end
|
||||
return c
|
||||
end
|
||||
--Managers
|
||||
function multi:mainloop()
|
||||
for i=1,#multi.Tasks do
|
||||
multi.Tasks[i]()
|
||||
end
|
||||
multi.Start=os.clock()
|
||||
while self.Active do
|
||||
multi.Do_Order()
|
||||
end
|
||||
end
|
||||
function multi._tFunc(dt)
|
||||
if dt then
|
||||
multi.pump=true
|
||||
end
|
||||
multi.pumpvar=dt
|
||||
multi.Start=os.clock()
|
||||
end
|
||||
function multi:uManager(dt)
|
||||
multi:oneTime(multi._tFunc,dt)
|
||||
multi.Do_Order()
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1056
-1056
File diff suppressed because it is too large
Load Diff
+1112
-1112
File diff suppressed because it is too large
Load Diff
+1375
-1375
File diff suppressed because it is too large
Load Diff
+1391
-1391
File diff suppressed because it is too large
Load Diff
+1434
-1434
File diff suppressed because it is too large
Load Diff
+1460
-1460
File diff suppressed because it is too large
Load Diff
+1518
-1518
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,33 @@
|
||||
package = "multi"
|
||||
version = "1.10.0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.10.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.10.0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.10.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
package = "multi"
|
||||
version = "1.11.0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.11.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.11.0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.11.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,30 @@
|
||||
package = "multi"
|
||||
version = "1.8-2"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.2",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.8-2"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.2",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,30 @@
|
||||
package = "multi"
|
||||
version = "1.8-3"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.3",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.8-3"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.3",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,30 @@
|
||||
package = "multi"
|
||||
version = "1.8-4"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.4",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.8-4"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.4",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,30 @@
|
||||
package = "multi"
|
||||
version = "1.8-5"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.5",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.8-5"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.5",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,30 @@
|
||||
package = "multi"
|
||||
version = "1.8-6"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.6",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.8-6"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.8.6",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package = "multi"
|
||||
version = "1.9-1"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.9.1",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.9-1"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.9.1",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1, < 5.2"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,33 @@
|
||||
package = "multi"
|
||||
version = "1.9-2"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.9.2",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.9-2"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.9.2",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,33 @@
|
||||
package = "multi"
|
||||
version = "1.9-3"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.9.3",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "1.9-3"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v1.9.3",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multiobjs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d. Optional) The core of the library works on lua 5.1+ however the systemthreading features are limited to 5.1 due to love2d and lua lanes and now luvit (See ReadMe on gotchas) being lua 5.1 only!
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
-- Note the required Lua syntax when listing submodules as keys
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.all"] = "multi/all.lua",
|
||||
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
package = "multi"
|
||||
version = "12.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v12.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
"lua-net"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "12.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v12.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
"lua-net"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
package = "multi"
|
||||
version = "12.2-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v12.2.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
"lua-net"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "12.2-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v12.2.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
"lua-net"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package = "multi"
|
||||
version = "12.2-1"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v12.2.1",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "12.2-1"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v12.2.1",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi.init"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package = "multi"
|
||||
version = "13.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v13.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "13.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v13.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package = "multi"
|
||||
version = "13.1-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v13.1.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "13.1-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v13.1.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,35 @@
|
||||
package = "multi"
|
||||
version = "14.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v14.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "14.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v14.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. From simple side by side code using multi-objs, to using coroutine based Threads and System threads(When you have lua lanes installed or are using love2d)
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,35 @@
|
||||
package = "multi"
|
||||
version = "14.1-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v14.1.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multitasking, coroutine based multi tasking, and system threading (Requires use of an integration). Check github for how to use.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
--["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
package = "multi"
|
||||
version = "14.1-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v14.1.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multitasking, coroutine based multi tasking, and system threading (Requires use of an integration). Check github for how to use.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"bin",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
--["multi.integration.shared"] = "multi/integration/shared.lua"
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
package = "multi"
|
||||
version = "14.2-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v14.2.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for how to use.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
}
|
||||
package = "multi"
|
||||
version = "14.2-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v14.2.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for how to use.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package = "multi"
|
||||
version = "15.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v15.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for how to use.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.integration.threading"] = "multi/integration/threading.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
|
||||
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
|
||||
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package = "multi"
|
||||
version = "15.1-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "V15.1.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
"lanes",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.compat.love2d"] = "multi/compat/love2d.lua",
|
||||
["multi.compat.lovr"] = "multi/compat/lovr.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua",
|
||||
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
|
||||
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
|
||||
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "multi/integration/threading.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package = "multi"
|
||||
version = "15.2-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v15.2.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua",
|
||||
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
|
||||
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
|
||||
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "multi/integration/threading.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package = "multi"
|
||||
version = "15.2-1"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v15.2.1",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "multi/init.lua",
|
||||
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua",
|
||||
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
|
||||
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
|
||||
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "multi/integration/threading.lua",
|
||||
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package = "multi"
|
||||
version = "15.3-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v15.3.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "init.lua",
|
||||
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
|
||||
["multi.integration.pesudoManager"] = "integration/pesudoManager/init.lua",
|
||||
["multi.integration.pesudoManager.extensions"] = "integration/pesudoManager/extensions.lua",
|
||||
["multi.integration.pesudoManager.threads"] = "integration/pesudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "integration/threading.lua",
|
||||
--["multi.integration.networkManager"] = "integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package = "multi"
|
||||
version = "15.3-1"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "15.3.1",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "init.lua",
|
||||
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
|
||||
["multi.integration.pesudoManager"] = "integration/pesudoManager/init.lua",
|
||||
["multi.integration.pesudoManager.extensions"] = "integration/pesudoManager/extensions.lua",
|
||||
["multi.integration.pesudoManager.threads"] = "integration/pesudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "integration/threading.lua",
|
||||
--["multi.integration.networkManager"] = "integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package = "multi"
|
||||
version = "16.0-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v16.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "init.lua",
|
||||
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
|
||||
["multi.integration.loveManager.utils"] = "integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
|
||||
["multi.integration.pseudoManager"] = "integration/pseudoManager/init.lua",
|
||||
["multi.integration.pseudoManager.extensions"] = "integration/pseudoManager/extensions.lua",
|
||||
["multi.integration.pseudoManager.threads"] = "integration/pseudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "integration/threading.lua",
|
||||
["multi.integration.sharedExtensions"] = "integration/sharedExtensions/init.lua",
|
||||
["multi.integration.priorityManager"] = "integration/priorityManager/init.lua",
|
||||
--["multi.integration.networkManager"] = "integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package = "multi"
|
||||
version = "16.0-1"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v16.0.1",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "init.lua",
|
||||
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
|
||||
["multi.integration.loveManager.utils"] = "integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
|
||||
["multi.integration.pseudoManager"] = "integration/pseudoManager/init.lua",
|
||||
["multi.integration.pseudoManager.extensions"] = "integration/pseudoManager/extensions.lua",
|
||||
["multi.integration.pseudoManager.threads"] = "integration/pseudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "integration/threading.lua",
|
||||
["multi.integration.sharedExtensions"] = "integration/sharedExtensions/init.lua",
|
||||
["multi.integration.priorityManager"] = "integration/priorityManager/init.lua",
|
||||
--["multi.integration.networkManager"] = "integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package = "multi"
|
||||
version = "16.1-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v16.1.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "init.lua",
|
||||
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
|
||||
["multi.integration.loveManager.utils"] = "integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
|
||||
["multi.integration.pseudoManager"] = "integration/pseudoManager/init.lua",
|
||||
["multi.integration.pseudoManager.extensions"] = "integration/pseudoManager/extensions.lua",
|
||||
["multi.integration.pseudoManager.threads"] = "integration/pseudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "integration/threading.lua",
|
||||
["multi.integration.sharedExtensions"] = "integration/sharedExtensions/init.lua",
|
||||
["multi.integration.priorityManager"] = "integration/priorityManager/init.lua",
|
||||
--["multi.integration.networkManager"] = "integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package = "multi"
|
||||
version = "16.2-0"
|
||||
source = {
|
||||
url = "git://github.com/rayaman/multi.git",
|
||||
tag = "v16.2.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua Multi tasking library",
|
||||
detailed = [[
|
||||
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||
Check github for documentation.
|
||||
]],
|
||||
homepage = "https://github.com/rayaman/multi",
|
||||
license = "MIT"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["multi"] = "init.lua",
|
||||
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
|
||||
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
|
||||
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
|
||||
["multi.integration.loveManager"] = "integration/loveManager/init.lua",
|
||||
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
|
||||
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
|
||||
["multi.integration.loveManager.utils"] = "integration/loveManager/threads.lua",
|
||||
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
|
||||
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
|
||||
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
|
||||
["multi.integration.pseudoManager"] = "integration/pseudoManager/init.lua",
|
||||
["multi.integration.pseudoManager.extensions"] = "integration/pseudoManager/extensions.lua",
|
||||
["multi.integration.pseudoManager.threads"] = "integration/pseudoManager/threads.lua",
|
||||
["multi.integration.luvitManager"] = "integration/luvitManager.lua",
|
||||
["multi.integration.threading"] = "integration/threading.lua",
|
||||
["multi.integration.sharedExtensions"] = "integration/sharedExtensions/init.lua",
|
||||
["multi.integration.priorityManager"] = "integration/priorityManager/init.lua",
|
||||
--["multi.integration.networkManager"] = "integration/networkManager.lua",
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
-- set up the package
|
||||
package.path="?/init.lua;?.lua;"..package.path
|
||||
-- Import the libraries
|
||||
multi = require("multi")
|
||||
local GLOBAL, THREAD = require("multi.integration.lanesManager").init()
|
||||
nGLOBAL = require("multi.integration.networkManager").init()
|
||||
-- Act as a master node
|
||||
master = multi:newMaster{
|
||||
name = "Main", -- the name of the master
|
||||
--noBroadCast = true, -- if using the node manager, set this to true to avoid double connections
|
||||
--managerDetails = {"localhost",12345}, -- the details to connect to the node manager (ip,port)
|
||||
}
|
||||
master.OnError(function(name,err)
|
||||
print(name.." has encountered an error: "..err)
|
||||
end)
|
||||
master.OnNodeConnected(function(name)
|
||||
-- name is the name of the node that connected
|
||||
end)
|
||||
-- Starting the multitasker
|
||||
settings = {
|
||||
priority = 0, -- 0, 1 or 2
|
||||
protect = false,
|
||||
}
|
||||
multi:threadloop(settings) -- both mainloop and threadloop can be used. one pirotizes threads where the other pirotizes multiobjs
|
||||
--multi:mainloop(settings)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user