120 Commits
Author SHA1 Message Date
server 7b0cb7a853 added priorityManager to rockspec 2024-02-24 23:57:42 -05:00
server ffaab32d5e Cleaned up changes.md 2024-02-24 23:27:27 -05:00
server 946217310f lanes uses a threaded function like waitfor function 2024-02-24 23:23:35 -05:00
server b4c3708f50 Fixed, conf 2024-02-24 23:13:48 -05:00
server e3ac0951ab Threading working in love2d 2024-02-24 23:05:05 -05:00
server 42b4e0fcf4 Added test for defer 2023-11-26 22:13:18 -05:00
server f07b1ebb57 Fixed typo 2023-11-26 21:12:44 -05:00
server ea6503d7b2 Fixed issues 2023-11-26 21:10:37 -05:00
server b7a7e5bf16 Add test for rockspec 2023-11-26 20:57:59 -05:00
server 5ac17f8e59 Testing paths 2023-11-26 13:14:02 -05:00
server 2b9f732d88 Working on paths 2023-11-26 13:10:16 -05:00
server 726f55e5c6 Fixed paths 2023-11-26 12:59:54 -05:00
server 91561f7f24 Fixed tests on lanes and pseudo threading, todo fix love2d threading 2023-11-26 12:49:23 -05:00
server 8d843a5958 Added thread.defer(func) 2023-11-09 22:04:11 -05:00
server 30db370cc9 Updated changes.md and fixed some bugs 2023-11-02 23:59:34 -04:00
server 0af807a930 Fixed newTask() 2023-11-02 09:31:09 -04:00
server 9ad2c45b8f Document new features to conns, todo fix newTask 2023-11-01 23:37:00 -04:00
server e7ff234cef Merge branch 'v16.0.0' of https://github.com/rayaman/multi into v16.0.0 2023-10-28 17:57:29 -04:00
server f540396932 Added boost method 2023-10-28 17:57:21 -04:00
server 46ace58ab8 Added function / connection 2023-10-17 21:37:33 -04:00
server ef7464f70d Working on getting pseudoThreading tests to work 2023-10-15 13:21:57 -04:00
server ad929da484 Some work on the debug manager, proxies working on lanes, todo get pseudo manager and love2d working 2023-10-03 22:21:37 -04:00
server 3d55704726 Planning out debugManager 2023-09-07 21:17:15 -04:00
server 13221ca47e Test for 5.1 2023-09-04 19:50:50 -04:00
server 98198a4af2 Fixed error code issue 2023-09-04 19:48:13 -04:00
server 5f5723e936 Working on new type system, planning out debugmanager 2023-09-04 12:03:00 -04:00
server a660b63581 Closer to getting things working... 2023-08-06 00:38:22 -04:00
server bab9b13cb8 Push error when an error happens 2023-08-03 23:40:43 -04:00
server 8c2bde7ed8 Should now push non 0 exit codes 2023-08-03 23:33:16 -04:00
server d50c187710 Not hard crashing when error is encountered 2023-08-03 23:22:01 -04:00
server 5359be0772 testing... 2023-08-03 23:11:32 -04:00
server 59cbeb6597 Fixed packing of values into threads, need to fix system proxies and system threaded processors 2023-08-01 23:45:06 -04:00
server bb0592f3eb new pack/unpack for tables, current issue is things being turned into strings 2023-07-30 00:47:27 -04:00
server bbaac2d779 jobqueues having isues with stp 2023-07-17 00:44:59 -04:00
server 9e6552d42e Working on adding a Hold method to all objects. Will document how they all work when done. 2023-07-16 11:10:35 -04:00
server afdd98ab13 Rewriting love2d threading binding 2023-07-15 01:16:03 -04:00
server e43fe34a7c Still implementing new love2d threading code 2023-07-10 15:54:36 -04:00
server f4cdde6040 Rewriting loveManager, too much outdated code 2023-07-09 21:54:01 -04:00
server cec53f6f4e Added timeout to build 2023-07-04 23:56:56 -04:00
server d57dc7dc22 Edited symlink 2023-07-04 23:45:43 -04:00
server 6be948f068 Removed link 2023-07-04 23:43:40 -04:00
server c8abadd8d6 Update multi 2023-07-04 23:41:17 -04:00
server 15bbec9379 Fixed pull 2023-07-04 23:39:40 -04:00
server befe863846 packagepath set 2023-07-04 23:38:30 -04:00
server 761e739e18 actually pull the repo 2023-07-04 23:32:03 -04:00
server a9673385d9 Moved other tests while testing 2023-07-04 23:30:15 -04:00
server 0b0f971802 Use workspace 2023-07-04 23:28:54 -04:00
server 755f207554 Testing love2d 2023-07-04 23:26:37 -04:00
server 49a1b944d0 Fixed love2d tests 2023-07-04 23:25:08 -04:00
server 883bdb9830 No window for love2d 2023-07-04 23:20:00 -04:00
server 8a83c617fa use sudo 2023-07-04 23:16:03 -04:00
server 06580e0bfa Use appimage 2023-07-04 23:14:24 -04:00
server 0a72f16e68 Fixed path 2023-07-04 23:07:30 -04:00
server 721571d1a4 Use ubuntu for build 2023-07-04 23:05:37 -04:00
server 7c95b2e8ca Use later love-build 2023-07-04 23:04:06 -04:00
server a6fac9d1d4 Test love2d 2023-07-04 23:00:48 -04:00
server 7ba642342d Testing love2d tests 2023-07-04 22:49:06 -04:00
server acc94ea17e Removed system threaded connections, soon to be replaced by proxies 2023-07-04 16:00:37 -04:00
server 81fc7b95c9 Fixed issue with errors not going through 2023-07-04 13:46:25 -04:00
server 03a2f686a8 fixing stuff 2023-07-04 13:32:38 -04:00
server 96cc41effb Throw an error when things break 2023-07-04 13:25:18 -04:00
server 8c987b81ab typo fixed 2023-07-04 13:20:23 -04:00
server 1064d8a1cc fixing actions 2023-07-04 13:12:23 -04:00
server cd4cc5fd2d Testing... 2023-07-04 13:10:12 -04:00
server 614e032aa5 Testing actions, fixing bugs with lanes 2023-07-04 13:05:07 -04:00
server b2569118a2 Started work on the debugManager 2023-06-30 16:14:21 -04:00
server d36204c87f Merge pull request #59 from rayaman/compare
Compare
2023-06-25 21:48:41 -04:00
server 660c10ec3b Removed extra bloat, proxies are portable now! 2023-06-25 21:46:37 -04:00
server c39aa229f8 Fixed critical issue with coroutine based threads 2023-06-20 00:05:12 -04:00
server c80f44c68e Debugging what is going on... 2023-06-19 00:24:07 -04:00
server 1b3e3303e9 Really close to portable proxies, currently extreamly unstable! 2023-06-18 00:08:51 -04:00
server 6fe10b22ab Testing 2023-06-17 21:33:34 -04:00
server 257ed03728 THREAD_NAME set for main thread, connections break the rules for proxies 2023-06-03 12:07:33 -04:00
server 5e2ab9af3d Added an easy way to share a table, found some limitations with lanes threading. 2023-05-31 21:51:47 -04:00
server d520e0a93a Fixed some bugs 2023-05-30 23:50:36 -04:00
server 03ecb47f6f Finished getLoad(type) 2023-05-29 01:29:12 -04:00
server 3effcb7384 Getting loads of processors implemented 2023-05-28 00:37:17 -04:00
server 06c31bee85 Clean up connection events when holding, working on scheduling tasks/threads to system threaded processors 2023-05-27 23:57:58 -04:00
server 5c03b34290 thread.hold(proxy.conn) 2023-05-27 00:10:21 -04:00
server af38ebbb81 Added tstep to STP, updated changes.md 2023-05-24 23:31:07 -04:00
server de9b08fa2e Proxies work with connections now :D 2023-05-24 23:17:18 -04:00
server ab9e949b68 newProxy implemented 2023-05-21 09:43:44 -04:00
server ea4be86ae2 newProxy and STP work 2023-05-16 23:40:14 -04:00
server 160c72d2f3 Working on systemthreadedprocess, and experimental newProxy for threading 2023-05-14 00:52:35 -04:00
server 5caa90f6c7 updated changes.md 2023-05-07 23:04:06 -04:00
server a5add93747 Changes to threads 2023-05-07 23:03:15 -04:00
server ec9f7dec61 Trying to fix exposeENV with pseudoThreading 2023-05-07 01:31:29 -04:00
server e616b51d6f fixing 2023-05-07 00:24:07 -04:00
server cfa4c0f0b6 Fixed typo in pseudoManager 2023-05-07 00:19:34 -04:00
server 9f3b663fa2 Typo in changes.md 2023-05-06 16:52:48 -04:00
server 4fe428e572 THREAD.exposeENV(), thread:newProcessor() 2023-05-06 16:46:15 -04:00
server 5cc18b04ae Threaded processors 2023-05-06 03:18:00 -04:00
server 33202260e3 Fixed issues with missing code 2023-05-05 16:33:31 -04:00
server 189552ac65 Working on custom prioritySchemes 2023-05-03 23:09:37 -04:00
server 42149ffab2 Working on priority management 2023-04-30 23:53:54 -04:00
server 03dbe1ee5b Working on new priority scheme 2023-04-30 01:06:20 -04:00
server 8cf047d713 removed extra __cores in lanes/pseudo 2023-04-29 13:47:25 -04:00
server 9e1d31fc2a Modified tests to make it more seamless 2023-04-25 22:32:24 -04:00
server 0e6c30b478 Updated files for testing 2023-04-25 22:05:32 -04:00
server d8218f0bf7 All tests working 2023-04-25 21:57:25 -04:00
server 45b51c15c7 Fixed love2d to succeed with tests 2023-04-25 21:31:36 -04:00
server 61b5ea9d14 Added test cases for threading, fixed issues. Todo test love2d 2023-04-25 00:13:47 -04:00
server d2cfdfa8e8 Writing tests for system threading 2023-04-24 00:15:35 -04:00
server 8e6d174f20 Plan on testing parity between the threading modules 2023-04-20 23:23:51 -04:00
server c65b850529 Updated changes.md 2023-04-04 23:07:39 -04:00
server a105d8a575 removed test 2023-01-22 23:04:09 -05:00
server 7da192e8dc Fixed some issues with threads 2023-01-21 13:18:44 -05:00
server ef9267d8fc Fixed broken threads for love 2023-01-20 00:11:55 -05:00
server 0994ee2d2a Working on issue where threads created in threads don't work 2023-01-19 00:16:32 -05:00
server 22f1375380 Working on issue with love threaded functions not waiting when in a thread 2023-01-18 15:42:38 -05:00
server 6ed5555706 Fixed issue with double thread activations (Looking for another solution) 2023-01-17 23:45:26 -05:00
server a7a902acd6 Updated connections 2023-01-15 13:28:45 -05:00
server 3776fdff9d Connections can be % with functions 2023-01-11 22:53:03 -05:00
server 7114b87bdd Testing types 2023-01-10 00:07:12 -05:00
server 0bccc0dd87 Concat conns now properly transfer events 2023-01-07 09:57:31 -05:00
server cf980951a4 Updated version 2023-01-07 01:35:32 -05:00
server a81e55f41c Updated readme 2023-01-07 01:34:41 -05:00
server 5cf3947b15 Updated files 2023-01-07 01:32:22 -05:00
server 298529edc2 Merge branch 'master' into v16.0.0 2023-01-07 01:26:29 -05:00
server 5137bb9483 Fixed spelling, started ideaing for 16.0.0 2022-12-31 17:06:04 -05:00
100 changed files with 28622 additions and 30512 deletions
+25
View File
@@ -0,0 +1,25 @@
name: Build & Run tests Love2d
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
strategy:
fail-fast: false
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Install love2d
run: |
sudo apt install fuse
wget https://github.com/love2d/love/releases/download/11.4/love-11.4-x86_64.AppImage -O love.AppImage
sudo chmod +x love.AppImage
- name: Run Tests
run: |
./love.AppImage tests
+41 -32
View File
@@ -1,32 +1,41 @@
name: Lua Unit Tests (Matrix) name: Build & Run tests Ubuntu
on: on:
push: push:
branches: [ master ] branches: [ master ]
pull_request: pull_request:
branches: [ master ] branches: [ master ]
jobs: jobs:
test: build:
runs-on: ubuntu-latest strategy:
fail-fast: false
strategy: matrix:
matrix: build-type: [Release] # Debug
luaVersion: ["5.1", "5.2", "5.3", "5.4"] lua: ["lua 5.1", "lua 5.2", "lua 5.3", "lua 5.4", "luajit 2.1.0-beta3"]
os: ["ubuntu-latest"]
steps: runs-on: ${{ matrix.os }}
- name: Checkout repository steps:
uses: actions/checkout@v4 - uses: actions/checkout@v2
with:
- name: Setup Lua submodules: recursive
uses: leafo/gh-actions-lua@v10
with: - uses: actions/setup-python@v2
luaVersion: ${{ matrix.luaVersion }} with:
python-version: '3.10'
- name: Verify Lua version
run: lua -v - name: Setup env
run: |
- name: Run unit tests pip install hererocks
run: | hererocks lua-pkg --${{ matrix.lua }} -rlatest
# Replace with your actual test file
lua tests/multi_test.lua - name: Install lanes and multi
run: |
source ${{github.workspace}}/lua-pkg/bin/activate
luarocks install lanes
luarocks install rockspecs/multi-16.0-0.rockspec
- name: Run Tests
run: |
source ${{github.workspace}}/lua-pkg/bin/activate
lua tests/runtests.lua
+2 -2
View File
@@ -1,3 +1,3 @@
*.code-workspace *.code-workspace
lua5.4/* lua5.4/*
test.lua test.lua
+21 -21
View File
@@ -1,21 +1,21 @@
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
+25 -25
View File
@@ -1,26 +1,26 @@
# NTHREAD Namespace # NTHREAD Namespace
- [ ] NTHREAD.set(name, val) - [ ] NTHREAD.set(name, val)
- [ ] NTHREAD.get(name, val) - [ ] NTHREAD.get(name, val)
- [ ] NTHREAD.waitFor(name) - [ ] NTHREAD.waitFor(name)
- [ ] NTHREAD.getCores()* - [ ] NTHREAD.getCores()*
- [ ] NTHREAD.getConsole() - [ ] NTHREAD.getConsole()
- [ ] NTHREAD.getThreads() - [ ] NTHREAD.getThreads()
- [ ] NTHREAD.kill() - [ ] NTHREAD.kill()
- [ ] NTHREAD.getName() - [ ] NTHREAD.getName()
- [ ] NTHREAD.getID() - [ ] NTHREAD.getID()
- [ ] NTHREAD.pushStatus(...) - [ ] NTHREAD.pushStatus(...)
- [ ] NTHREAD.sleep(n) - [ ] NTHREAD.sleep(n)
- [ ] NTHREAD.hold(n) - [ ] NTHREAD.hold(n)
- [ ] NTHREAD.setENV(env) - [ ] NTHREAD.setENV(env)
- [ ] NTHREAD.getENV() - [ ] NTHREAD.getENV()
# Extensions # Extensions
- [ ] multi:newNetworkThreadedQueue(name) - [ ] multi:newNetworkThreadedQueue(name)
- [ ] multi:newNetworkThreadedTable(name) - [ ] multi:newNetworkThreadedTable(name)
- [ ] multi:newNetworkThreadedJobQueue(n) - [ ] multi:newNetworkThreadedJobQueue(n)
- [ ] multi:newNetworkThreadedConnection(name) - [ ] multi:newNetworkThreadedConnection(name)
# Core # Core
- [ ] NTHREAD:newFunction(func, holdme) - [ ] NTHREAD:newFunction(func, holdme)
- [ ] NTHREAD:newNetworkThread(name, func, ...) - [ ] NTHREAD:newNetworkThread(name, func, ...)
- [ ] mulit:newNetworkThread(name, func, ...) - [ ] mulit:newNetworkThread(name, func, ...)
+101 -100
View File
@@ -1,100 +1,101 @@
# Multi Version: 16.3.0 - # Multi Version: 16.0.0 - Connecting the dots
**Key Changes** **Key Changes**
- Fixed connection multiplying - Expanded connection logic
- Optimizing the library - New integration priorityManager
- Updated task management support - Tests for threads
- Consistent behavior between the threading integrations
Refer to the [Change Log](https://github.com/rayaman/multi/blob/master/docs/changes.md) for more infromation - Improved love2d threading
- Bug fixes
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and someone will look into it!
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.
My multitasking library for lua. It is a pure lua binding, with exceptions of the integrations.
</br>
</br>
Progress is being made in [v16.3.0](https://github.com/rayaman/multi/tree/v16.3.0)
--- Progress is being made in [v16.0.0](https://github.com/rayaman/multi/tree/v16.0.0)
---
</br>
</br>
INSTALLING
---------- INSTALLING
Link to optional dependencies: ----------
- [lanes](https://github.com/LuaLanes/lanes) `luarocks install lanes` Link to optional dependencies:
- [lanes](https://github.com/LuaLanes/lanes) `luarocks install lanes`
- [chronos](https://github.com/ldrumm/chronos) `luarocks install chronos`
- [chronos](https://github.com/ldrumm/chronos) `luarocks install chronos`
- [love2d](https://love2d.org/)
- [love2d](https://love2d.org/)
When using love2d add multi:uManager() or any processor to love.update()
When using love2d add multi:uManager() or any processor to love.update()
```lua
function love.update(dt) ```lua
multi:uManager() function love.update(dt)
end 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! 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 ```
``` luarocks install multi
```
Discord
------- Discord
Have a question or need realtime assistance? Feel free to join the discord!</br> -------
https://discord.gg/U8UspuA Have a question or need realtime assistance? Feel free to join the discord!</br>
https://discord.gg/U8UspuA
Planned features/TODO
--------------------- Planned features/TODO
- [x] ~~Create test suite (In progress, mostly done)~~ ---------------------
- [ ] Network Parallelism rework - [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)
----- Usage: [Check out the documentation for more info](https://github.com/rayaman/multi/blob/master/Documentation.md)
-----
You can run tests in 2 ways:
``` 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 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() ```lua
GLOBAL, THREAD = require("multi.integration.threading"):init() local multi, thread = require("multi"):init()
GLOBAL, THREAD = require("multi.integration.threading"):init()
multi:newSystemThread("System Thread",function()
while true do multi:newSystemThread("System Thread",function()
THREAD.sleep(.1) while true do
io.write(" World") THREAD.sleep(.1)
THREAD.kill() io.write(" World")
end THREAD.kill()
end) end
end)
multi:newThread("Coroutine Based Thread",function()
while true do multi:newThread("Coroutine Based Thread",function()
io.write("Hello") while true do
thread.sleep(.1) io.write("Hello")
thread.kill() thread.sleep(.1)
end thread.kill()
end) end
end)
multi:newTLoop(function(loop)
print("!") multi:newTLoop(function(loop)
loop:Destroy() print("!")
os.exit() loop:Destroy()
end,.3) os.exit()
end,.3)
multi:mainloop()
multi:mainloop()
--[[
while true do --[[
multi:uManager() while true do
end multi:uManager()
]] end
``` ]]
```
Known Bugs/Issues
----------------- Known Bugs/Issues
Check the [Issues tab](https://github.com/rayaman/multi/issues) for issues -----------------
Check the [Issues tab](https://github.com/rayaman/multi/issues) for issues
+971 -971
View File
File diff suppressed because it is too large Load Diff
+3504 -3697
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2580 -2993
View File
File diff suppressed because it is too large Load Diff
+106 -106
View File
@@ -1,106 +1,106 @@
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
multi.defaultSettings.debugging = true multi.defaultSettings.debugging = true
local dbg = {} local dbg = {}
dbg.__index = dbg dbg.__index = dbg
dbg.processors = {} dbg.processors = {}
-- Hooks to all on object created events! -- Hooks to all on object created events!
local c_cache = {} local c_cache = {}
local d_cache = {} local d_cache = {}
local proc = multi:newProcessor("Debug_Processor").Start() local proc = multi:newProcessor("Debug_Processor").Start()
dbg.OnObjectCreated = function(obj, process) dbg.OnObjectCreated = function(obj, process)
if c_cache[obj] then if c_cache[obj] then
return false return false
else else
c_cache[obj] = true c_cache[obj] = true
proc:newTask(function() proc:newTask(function()
c_cache[obj] = false c_cache[obj] = false
end) end)
return true return true
end end
end .. multi:newConnection() end .. multi:newConnection()
dbg.OnObjectDestroyed = function(obj, process) dbg.OnObjectDestroyed = function(obj, process)
if d_cache[obj] then if d_cache[obj] then
return false return false
else else
d_cache[obj] = true d_cache[obj] = true
proc:newTask(function() proc:newTask(function()
d_cache[obj] = false d_cache[obj] = false
end) end)
return true return true
end end
end .. multi:newConnection() end .. multi:newConnection()
local creation_hook, destruction_hook local creation_hook, destruction_hook
local types local types
local objects = {} local objects = {}
creation_hook = function(obj, process) creation_hook = function(obj, process)
types = multi:getTypes() types = multi:getTypes()
if obj.Type == multi.PROCESS and not dbg.processors[obj] then if obj.Type == multi.PROCESS and not dbg.processors[obj] then
obj.OnObjectCreated(creation_hook) obj.OnObjectCreated(creation_hook)
obj.OnObjectDestroyed(destruction_hook) obj.OnObjectDestroyed(destruction_hook)
end end
table.insert(objects, obj) table.insert(objects, obj)
dbg.OnObjectCreated:Fire(obj, process) dbg.OnObjectCreated:Fire(obj, process)
end end
destruction_hook = function(obj, process) destruction_hook = function(obj, process)
for i = 1, #objects do for i = 1, #objects do
if objects[i] == obj then if objects[i] == obj then
table.remove(objects, i) table.remove(objects, i)
break break
end end
end end
dbg.OnObjectDestroyed:Fire(obj, process) dbg.OnObjectDestroyed:Fire(obj, process)
end end
function dbg:getObjects(typ) function dbg:getObjects(typ)
if type(typ) == "string" then if type(typ) == "string" then
local objs = {} local objs = {}
for i = 1, #objects do for i = 1, #objects do
if objects[i].Type == typ then if objects[i].Type == typ then
objs[#objs+1] = objects[i] objs[#objs+1] = objects[i]
end end
end end
return objs return objs
elseif type(typ) == "table" then -- Process elseif type(typ) == "table" then -- Process
local objs = {} local objs = {}
for i = 1, #objects do for i = 1, #objects do
if objects[i].Parent == typ then if objects[i].Parent == typ then
objs[#objs+1] = objects[i] objs[#objs+1] = objects[i]
end end
end end
return objs return objs
elseif type(typ) == "function" then elseif type(typ) == "function" then
local objs = {} local objs = {}
-- Keep objects local/private, return true to add to list, false to reject, "break" to break loop -- Keep objects local/private, return true to add to list, false to reject, "break" to break loop
for i = 1, #objects do for i = 1, #objects do
local ret = typ(objects[i]) local ret = typ(objects[i])
if ret then if ret then
objs[#objs+1] = objects[i] objs[#objs+1] = objects[i]
elseif ret == "break" then elseif ret == "break" then
break break
end end
end end
return objs return objs
end end
end end
local debug_stats = {} local debug_stats = {}
local tmulti = multi:getThreadManagerProcess() local tmulti = multi:getThreadManagerProcess()
multi.OnObjectCreated(creation_hook) multi.OnObjectCreated(creation_hook)
tmulti.OnObjectCreated(creation_hook) tmulti.OnObjectCreated(creation_hook)
multi.OnObjectDestroyed(destroction_hook) multi.OnObjectDestroyed(destroction_hook)
tmulti.OnObjectDestroyed(destroction_hook) tmulti.OnObjectDestroyed(destroction_hook)
-- We write to a debug interface in the multi namespace -- We write to a debug interface in the multi namespace
multi.debugging = dbg multi.debugging = dbg
+45 -45
View File
@@ -1,46 +1,46 @@
local multi, thread = require("multi"):init{error=true} local multi, thread = require("multi"):init{error=true}
multi.error("Currntly not supported!") multi.error("Currntly not supported!")
os.exit(1) os.exit(1)
local effil = require("effil") local effil = require("effil")
-- I like some of the things that this library offers. -- I like some of the things that this library offers.
-- Current limitations prevent me from being able to use effil, -- Current limitations prevent me from being able to use effil,
-- but I might fork and work on it myself. -- but I might fork and work on it myself.
-- Configs -- Configs
effil.allow_table_upvalues(false) effil.allow_table_upvalues(false)
local GLOBAL,THREAD = require("multi.integration.effilManager.threads").init() local GLOBAL,THREAD = require("multi.integration.effilManager.threads").init()
local count = 1 local count = 1
local started = false local started = false
local livingThreads = {} local livingThreads = {}
function multi:newSystemThread(name, func, ...) function multi:newSystemThread(name, func, ...)
local name = name or multi.randomString(16) local name = name or multi.randomString(16)
local rand = math.random(1, 10000000) local rand = math.random(1, 10000000)
c = {} c = {}
c.name = name c.name = name
c.Name = name c.Name = name
c.Id = count c.Id = count
end end
function THREAD:newFunction(func, holdme) function THREAD:newFunction(func, holdme)
return thread:newFunctionBase(function(...) return thread:newFunctionBase(function(...)
return multi:newSystemThread("TempSystemThread",func,...) return multi:newSystemThread("TempSystemThread",func,...)
end, holdme, multi.SFUNCTION)() end, holdme, multi.SFUNCTION)()
end end
THREAD.newSystemThread = function(...) THREAD.newSystemThread = function(...)
multi:newSystemThread(...) multi:newSystemThread(...)
end end
multi.print("Integrated Effil Threading!") multi.print("Integrated Effil Threading!")
multi.integration = {} -- for module creators multi.integration = {} -- for module creators
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.effilManager.extensions") require("multi.integration.effilManager.extensions")
return { return {
init = function() init = function()
return GLOBAL, THREAD return GLOBAL, THREAD
end end
} }
+392 -396
View File
@@ -1,397 +1,393 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
if not (GLOBAL and THREAD) then if not (GLOBAL and THREAD) then
GLOBAL, THREAD = multi.integration.GLOBAL, multi.integration.THREAD GLOBAL, THREAD = multi.integration.GLOBAL, multi.integration.THREAD
else else
lanes = require("lanes") lanes = require("lanes")
end end
function multi:newSystemThreadedQueue(name) function multi:newSystemThreadedQueue(name)
local name = name or multi.randomString(16) local name = name or multi.randomString(16)
local c = {} local c = {}
c.Name = name c.Name = name
c.linda = lanes.linda() c.linda = lanes.linda()
c.Type = multi.registerType("s_queue") c.Type = multi.registerType("s_queue")
function c:push(v) function c:push(v)
self.linda:send("Q", v) self.linda:send("Q", v)
end end
function c:pop() function c:pop()
return ({self.linda:receive(0, "Q")})[2] return ({self.linda:receive(0, "Q")})[2]
end end
function c:peek() function c:peek()
return self.linda:get("Q") return self.linda:get("Q")
end end
function c:init() function c:init()
return self return self
end end
if multi.isMainThread then if multi.isMainThread then
multi.integration.GLOBAL[name] = c multi.integration.GLOBAL[name] = c
else else
GLOBAL[name] = c GLOBAL[name] = c
end end
local peek = function() function c:Hold(opt)
return c:peek() local multi, thread = require("multi"):init()
end if opt.peek then
return thread.hold(function()
local pop = function() return self:peek()
return c:pop() end)
end else
return thread.hold(function()
function c:Hold(opt) return self:pop()
local multi, thread = require("multi"):init() end)
if opt.peek then end
return thread.hold(peek) end
else
return thread.hold(pop) self:create(c)
end
end return c
end
self:create(c)
function multi:newSystemThreadedTable(name)
return c local name = name or multi.randomString(16)
end local c = {}
c.link = lanes.linda()
function multi:newSystemThreadedTable(name) c.Name = name
local name = name or multi.randomString(16) c.Type = multi.registerType("s_table")
local c = {}
c.link = lanes.linda() function c:init()
c.Name = name return self
c.Type = multi.registerType("s_table") end
function c:init() setmetatable(c,{
return self __index = function(t,k)
end return c.link:get(k)
end,
setmetatable(c,{ __newindex = function(t,k,v)
__index = function(t,k) c.link:set(k, v)
return c.link:get(k) end
end, })
__newindex = function(t,k,v)
c.link:set(k, v) if multi.isMainThread then
end multi.integration.GLOBAL[name] = c
}) else
GLOBAL[name] = c
if multi.isMainThread then end
multi.integration.GLOBAL[name] = c
else function c:Hold(opt)
GLOBAL[name] = c local multi, thread = require("multi"):init()
end if opt.key then
return thread.hold(function()
function c:Hold(opt) return self.tab[opt.key]
local multi, thread = require("multi"):init() end)
if opt.key then else
return thread.hold(function() multi.error("Must provide a key to check opt.key = 'key'")
return self.tab[opt.key] end
end) end
else
multi.error("Must provide a key to check opt.key = 'key'") self:create(c)
end
end return c
end
self:create(c)
function multi:newSystemThreadedJobQueue(n)
return c local c = {}
end c.cores = n or THREAD.getCores()*2
c.Type = multi.registerType("s_jobqueue")
function multi:newSystemThreadedJobQueue(n) c.OnJobCompleted = multi:newConnection()
local c = {} local funcs = multi:newSystemThreadedTable()
c.cores = n or THREAD.getCores()*2 local queueJob = multi:newSystemThreadedQueue()
c.Type = multi.registerType("s_jobqueue") local queueReturn = multi:newSystemThreadedQueue()
c.OnJobCompleted = multi:newConnection() local doAll = multi:newSystemThreadedQueue()
local funcs = multi:newSystemThreadedTable() local ID=1
local queueJob = multi:newSystemThreadedQueue() local jid = 1
local queueReturn = multi:newSystemThreadedQueue() function c:isEmpty()
local doAll = multi:newSystemThreadedQueue() return queueJob:peek()==nil
local ID=1 end
local jid = 1 function c:doToAll(func,...)
function c:isEmpty() for i=1,c.cores do
return queueJob:peek()==nil doAll:push{ID,func,...}
end end
function c:doToAll(func,...) ID = ID + 1
for i=1,c.cores do return self
doAll:push{ID,func,...} end
end function c:registerFunction(name,func)
ID = ID + 1 funcs[name]=func
return self return self
end end
function c:registerFunction(name,func) function c:pushJob(name,...)
funcs[name]=func queueJob:push{name,jid,multi.pack(...)}
return self jid = jid + 1
end return jid-1
function c:pushJob(name,...) end
queueJob:push{name,jid,multi.pack(...)} local nFunc = 0
jid = jid + 1 function c:newFunction(name, func, holup) -- This registers with the queue
return jid-1 if type(name)=="function" then
end holup = func
local nFunc = 0 func = name
function c:newFunction(name, func, holup) -- This registers with the queue name = "JQ_Function_"..nFunc
if type(name)=="function" then end
holup = func nFunc = nFunc + 1
func = name c:registerFunction(name,func)
name = "JQ_Function_"..nFunc return thread:newFunction(function(...)
end local id = c:pushJob(name,...)
nFunc = nFunc + 1 local link
c:registerFunction(name,func) local rets
return thread:newFunction(function(...) link = c.OnJobCompleted(function(jid,...)
local id = c:pushJob(name,...) if id==jid then
local link rets = multi.pack(...)
local rets end
link = c.OnJobCompleted(function(jid,...) end)
if id==jid then return thread.hold(function()
rets = multi.pack(...) if rets then
end if #rets == 0 then
end) return multi.NIL
return thread.hold(function() else
if rets then return multi.unpack(rets)
if #rets == 0 then end
return multi.NIL end
else end)
return multi.unpack(rets) end, holup), name
end end
end thread:newThread("JobQueueManager",function()
end) while true do
end, holup), name local job = thread.hold(function()
end return queueReturn:pop()
thread:newThread("JobQueueManager",function() end)
while true do if job then
local job = thread.hold(function() local id = table.remove(job,1)
return queueReturn:pop() c.OnJobCompleted:Fire(id,multi.unpack(job))
end) end
if job then end
local id = table.remove(job,1) end)
c.OnJobCompleted:Fire(id,multi.unpack(job)) for i=1,c.cores do
end multi:newSystemThread("STJQ_"..multi.randomString(8),function(queue)
end local multi, thread = require("multi"):init()
end) local idle = os.clock()
for i=1,c.cores do local clock = os.clock
multi:newSystemThread("STJQ_"..multi.randomString(8),function(queue) local ref = 0
local multi, thread = require("multi"):init() _G["__QR"] = queueReturn
local idle = os.clock() setmetatable(_G,{__index = funcs})
local clock = os.clock thread:newThread("JobHandler",function()
local ref = 0 while true do
_G["__QR"] = queueReturn local dat = thread.hold(function()
setmetatable(_G,{__index = funcs}) return queueJob:pop()
thread:newThread("JobHandler",function() end)
while true do idle = clock()
local dat = thread.hold(function() thread:newThread("JobQueue-Spawn",function()
return queueJob:pop() local name = table.remove(dat, 1)
end) local jid = table.remove(dat, 1)
idle = clock() local args = table.remove(dat, 1)
thread:newThread("JobQueue-Spawn",function() queueReturn:push{jid, funcs[name](args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]), queue}
local name = table.remove(dat, 1) end)
local jid = table.remove(dat, 1) end
local args = table.remove(dat, 1) end)
queueReturn:push{jid, funcs[name](args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]), queue} thread:newThread("DoAllHandler",function()
end) while true do
end local dat = thread.hold(function()
end) return doAll:peek()
thread:newThread("DoAllHandler",function() end)
while true do if dat then
local dat = thread.hold(function() if dat[1]>ref then
return doAll:peek() ref = table.remove(dat, 1)
end) func = table.remove(dat, 1)
if dat then idle = clock()
if dat[1]>ref then func(unpack(dat))
ref = table.remove(dat, 1) doAll:pop()
func = table.remove(dat, 1) end
idle = clock() end
func(unpack(dat)) end
doAll:pop() end)
end thread:newThread("IdleHandler",function()
end while true do
end thread.hold(function()
end) return clock()-idle>3
thread:newThread("IdleHandler",function() end)
while true do THREAD.sleep(.01)
thread.hold(function() end
return clock()-idle>3 end)
end) multi:mainloop()
THREAD.sleep(.01) end,i)
end end
end)
multi:mainloop() function c:Hold(opt)
end,i) return thread.hold(self.OnJobCompleted)
end end
function c:Hold(opt) self:create(c)
return thread.hold(self.OnJobCompleted)
end return c
end
self:create(c)
function multi:newSystemThreadedConnection(name)
return c local name = name or multi.randomString(16)
end local c = {}
c.Type = multi.registerType("s_connection")
function multi:newSystemThreadedConnection(name) c.CONN = 0x00
local name = name or multi.randomString(16) c.TRIG = 0x01
local c = {} c.PING = 0x02
c.Type = multi.registerType("s_connection") c.PONG = 0x03
c.CONN = 0x00 local function remove(a, b)
c.TRIG = 0x01 local ai = {}
c.PING = 0x02 local r = {}
c.PONG = 0x03 for k,v in pairs(a) do ai[v]=true end
local function remove(a, b) for k,v in pairs(b) do
local ai = {} if ai[v]==nil then table.insert(r,a[k]) end
local r = {} end
for k,v in pairs(a) do ai[v]=true end return r
for k,v in pairs(b) do end
if ai[v]==nil then table.insert(r,a[k]) end c.CID = THREAD_ID
end c.subscribe = multi:newSystemThreadedQueue("SUB_STC_"..self.Name):init()
return r c.Name = name
end 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.
c.CID = THREAD_ID -- Locals will only live in the thread that creates the original object
c.subscribe = multi:newSystemThreadedQueue("SUB_STC_"..self.Name):init() local ping
c.Name = name local pong = function(link, links)
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. local res = thread.hold(function()
-- Locals will only live in the thread that creates the original object return link:peek()[1] == c.PONG
local ping end,{sleep=3})
local pong = function(link, links)
local res = thread.hold(function() if not res then
return link:peek()[1] == c.PONG for i=1,#links do
end,{sleep=3}) if links[i] == link then
table.remove(links,i,link)
if not res then break
for i=1,#links do end
if links[i] == link then end
table.remove(links,i,link) else
break link:pop()
end end
end end
else
link:pop() ping = thread:newFunction(function(self)
end ping:Pause()
end multi.ForEach(self.links, function(link) -- Sync new connections
link:push{self.PING}
ping = thread:newFunction(function(self) multi:newThread("pong Thread", pong, link, self.links)
ping:Pause() end)
multi.ForEach(self.links, function(link) -- Sync new connections
link:push{self.PING} thread.sleep(3)
multi:newThread("pong Thread", pong, link, self.links)
end) ping:Resume()
end,false)
thread.sleep(3)
local function fire(...)
ping:Resume() for _, link in pairs(c.links) do
end,false) link:push {c.TRIG, multi.pack(...)}
end
local function fire(...) end
for _, link in pairs(c.links) do
link:push {c.TRIG, multi.pack(...)} thread:newThread("STC_SUB_MAN"..name,function()
end local item
end local sub_func = function() -- This will keep things held up until there is something to process
return c.subscribe:pop()
thread:newThread("STC_SUB_MAN"..name,function() end
local item while true do
local sub_func = function() -- This will keep things held up until there is something to process thread.yield()
return c.subscribe:pop() -- We need to check on broken connections
end ping(c) -- Should return instantlly and process this in another thread
while true do item = thread.hold(sub_func)
thread.yield() if item[1] == c.CONN then
-- We need to check on broken connections multi.ForEach(c.links, function(link) -- Sync new connections
ping(c) -- Should return instantlly and process this in another thread item[2]:push{c.CONN, link}
item = thread.hold(sub_func) end)
if item[1] == c.CONN then c.links[#c.links+1] = item[2]
multi.ForEach(c.links, function(link) -- Sync new connections elseif item[1] == c.TRIG then
item[2]:push{c.CONN, link} fire(multi.unpack(item[2]))
end) c.proxy_conn:Fire(multi.unpack(item[2]))
c.links[#c.links+1] = item[2] end
elseif item[1] == c.TRIG then end
fire(multi.unpack(item[2])) end)
c.proxy_conn:Fire(multi.unpack(item[2])) --- ^^^ This will only exist in the init thread
end
end function c:Fire(...)
end) local args = multi.pack(...)
--- ^^^ This will only exist in the init thread if self.CID == THREAD_ID then -- Host Call
for _, link in pairs(self.links) do
function c:Fire(...) link:push {self.TRIG, args}
local args = multi.pack(...) end
if self.CID == THREAD_ID then -- Host Call self.proxy_conn:Fire(...)
for _, link in pairs(self.links) do else
link:push {self.TRIG, args} self.subscribe:push {self.TRIG, args}
end end
self.proxy_conn:Fire(...) end
else
self.subscribe:push {self.TRIG, args} function c:init()
end local multi, thread = require("multi"):init()
end self.links = {}
self.proxy_conn = multi:newConnection()
function c:init() local mt = getmetatable(self.proxy_conn)
local multi, thread = require("multi"):init() local tempMT = {}
self.links = {} for i,v in pairs(mt) do
self.proxy_conn = multi:newConnection() tempMT[i] = v
local mt = getmetatable(self.proxy_conn) end
local tempMT = {} tempMT.__index = self.proxy_conn
for i,v in pairs(mt) do tempMT.__call = function(t,func) self.proxy_conn(func) end
tempMT[i] = v setmetatable(self, tempMT)
end if self.CID == THREAD_ID then return self end
tempMT.__index = self.proxy_conn thread:newThread("STC_CONN_MAN"..name,function()
tempMT.__call = function(t,func) self.proxy_conn(func) end local item
setmetatable(self, tempMT) local link_self_ref = multi:newSystemThreadedQueue()
if self.CID == THREAD_ID then return self end self.subscribe:push{self.CONN, link_self_ref}
thread:newThread("STC_CONN_MAN"..name,function() while true do
local item item = thread.hold(function()
local link_self_ref = multi:newSystemThreadedQueue() return link_self_ref:peek()
self.subscribe:push{self.CONN, link_self_ref} end)
while true do if item[1] == self.PING then
item = thread.hold(function() link_self_ref:push{self.PONG}
return link_self_ref:peek() link_self_ref:pop()
end) elseif item[1] == self.CONN then
if item[1] == self.PING then if item[2].Name ~= link_self_ref.Name then
link_self_ref:push{self.PONG} table.insert(self.links, item[2])
link_self_ref:pop() end
elseif item[1] == self.CONN then link_self_ref:pop()
if item[2].Name ~= link_self_ref.Name then elseif item[1] == self.TRIG then
table.insert(self.links, item[2]) self.proxy_conn:Fire(multi.unpack(item[2]))
end link_self_ref:pop()
link_self_ref:pop() else
elseif item[1] == self.TRIG then -- This shouldn't be the case
self.proxy_conn:Fire(multi.unpack(item[2])) end
link_self_ref:pop() end
else end)
-- This shouldn't be the case return self
end end
end
end) if multi.isMainThread then
return self multi.integration.GLOBAL[name] = c
end else
GLOBAL[name] = c
if multi.isMainThread then end
multi.integration.GLOBAL[name] = c
else self:create(c)
GLOBAL[name] = c
end return c
end
self:create(c)
return c
end
require("multi.integration.sharedExtensions") require("multi.integration.sharedExtensions")
+205 -205
View File
@@ -1,205 +1,205 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
package.path = "?/init.lua;?.lua;" .. package.path package.path = "?/init.lua;?.lua;" .. package.path
multi, thread = require("multi"):init() -- get it all and have it on all lanes 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 if multi.integration then -- This allows us to call the lanes manager from supporting modules without a hassle
return { return {
init = function() init = function()
return multi.integration.GLOBAL, multi.integration.THREAD return multi.integration.GLOBAL, multi.integration.THREAD
end end
} }
end end
-- Step 1 get lanes -- Step 1 get lanes
lanes = require("lanes").configure() lanes = require("lanes").configure()
multi.SystemThreads = {} multi.SystemThreads = {}
multi.isMainThread = true multi.isMainThread = true
_G.THREAD_NAME = "MAIN_THREAD" _G.THREAD_NAME = "MAIN_THREAD"
_G.THREAD_ID = 0 _G.THREAD_ID = 0
function multi:canSystemThread() function multi:canSystemThread()
return true return true
end end
function multi:getPlatform() function multi:getPlatform()
return "lanes" return "lanes"
end end
-- Step 2 set up the Linda objects -- Step 2 set up the Linda objects
local __GlobalLinda = lanes.linda() -- handles global stuff local __GlobalLinda = lanes.linda() -- handles global stuff
local __SleepingLinda = lanes.linda() -- handles sleeping stuff local __SleepingLinda = lanes.linda() -- handles sleeping stuff
local __ConsoleLinda = lanes.linda() -- handles console stuff local __ConsoleLinda = lanes.linda() -- handles console stuff
local __StatusLinda = lanes.linda() -- handles pushstatus for stfunctions local __StatusLinda = lanes.linda() -- handles pushstatus for stfunctions
local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda, __SleepingLinda, __StatusLinda, __ConsoleLinda) local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda, __SleepingLinda, __StatusLinda, __ConsoleLinda)
local count = 1 local count = 1
local started = false local started = false
local livingThreads = {} local livingThreads = {}
function THREAD:newFunction(func, holdme) function THREAD:newFunction(func, holdme)
return thread:newFunctionBase(function(...) return thread:newFunctionBase(function(...)
return multi:newSystemThread("TempSystemThread",func,...) return multi:newSystemThread("TempSystemThread",func,...)
end, holdme, multi.registerType("s_function"))() end, holdme, multi.registerType("s_function"))()
end end
function multi:newSystemThread(name, func, ...) function multi:newSystemThread(name, func, ...)
local name = name or multi.randomString(16) local name = name or multi.randomString(16)
multi.InitSystemThreadErrorHandler() multi.InitSystemThreadErrorHandler()
local rand = math.random(1, 10000000) local rand = math.random(1, 10000000)
local return_linda = lanes.linda() local return_linda = lanes.linda()
c = {} c = {}
c.Name = name c.Name = name
c.ID = count c.ID = count
c.loadString = {"base","package","os","io","math","table","string","coroutine"} c.loadString = {"base","package","os","io","math","table","string","coroutine"}
livingThreads[count] = {true, name} livingThreads[count] = {true, name}
c.returns = return_linda c.returns = return_linda
c.Type = multi.registerType("s_thread") c.Type = multi.registerType("s_thread")
c.creationTime = os.clock() c.creationTime = os.clock()
c.alive = true c.alive = true
c.priority = THREAD.Priority_Normal c.priority = THREAD.Priority_Normal
local multi_settings = multi.defaultSettings local multi_settings = multi.defaultSettings
local globe = { local globe = {
THREAD_NAME = name, THREAD_NAME = name,
THREAD_ID = count, THREAD_ID = count,
THREAD = THREAD, THREAD = THREAD,
GLOBAL = GLOBAL, GLOBAL = GLOBAL,
_Console = __ConsoleLinda, _Console = __ConsoleLinda,
_DEFER = {} _DEFER = {}
} }
if GLOBAL["__env"] then if GLOBAL["__env"] then
for i,v in pairs(GLOBAL["__env"]) do for i,v in pairs(GLOBAL["__env"]) do
globe[i] = v globe[i] = v
end end
end end
c.thread = lanes.gen("*", c.thread = lanes.gen("*",
{ {
globals = globe, globals = globe,
priority = c.priority priority = c.priority
},function(...) },function(...)
multi, thread = require("multi"):init(multi_settings) multi, thread = require("multi"):init(multi_settings)
require("multi.integration.lanesManager.extensions") require("multi.integration.lanesManager.extensions")
require("multi.integration.sharedExtensions") require("multi.integration.sharedExtensions")
local has_error = true local has_error = true
returns = {pcall(func, ...)} returns = {pcall(func, ...)}
return_linda:set("returns", returns) return_linda:set("returns", returns)
for i,v in pairs(_DEFER) do for i,v in pairs(_DEFER) do
pcall(v) pcall(v)
end end
has_error = false has_error = false
end)(...) end)(...)
count = count + 1 count = count + 1
function c:getName() function c:getName()
return c.Name return c.Name
end end
function c:kill() function c:kill()
self.thread:cancel() self.thread:cancel()
self.alive = false self.alive = false
end end
table.insert(multi.SystemThreads, c) table.insert(multi.SystemThreads, c)
c.OnDeath = multi:newConnection() c.OnDeath = multi:newConnection()
c.OnError = multi:newConnection() c.OnError = multi:newConnection()
GLOBAL["__THREADS__"] = livingThreads GLOBAL["__THREADS__"] = livingThreads
c.OnError(multi.error) c.OnError(multi.error)
if self.isActor then if self.isActor then
self:create(c) self:create(c)
else else
multi.create(multi, c) multi.create(multi, c)
end end
return c return c
end end
THREAD.newSystemThread = function(...) THREAD.newSystemThread = function(...)
multi:newSystemThread(...) multi:newSystemThread(...)
end end
function multi.InitSystemThreadErrorHandler() function multi.InitSystemThreadErrorHandler()
if started == true then if started == true then
return return
end end
started = true started = true
thread:newThread("SystemThreadScheduler",function() thread:newThread("SystemThreadScheduler",function()
local threads = multi.SystemThreads local threads = multi.SystemThreads
local _,data,status,push,temp local _,data,status,push,temp
while true do while true do
thread.yield() thread.yield()
_,data = __ConsoleLinda:receive(0, "Q") _,data = __ConsoleLinda:receive(0, "Q")
if data then if data then
--print(data[1]) --print(data[1])
end end
for i = #threads, 1, -1 do for i = #threads, 1, -1 do
temp = threads[i] temp = threads[i]
status = temp.thread.status status = temp.thread.status
push = __StatusLinda:get(temp.ID) push = __StatusLinda:get(temp.ID)
if push then if push then
temp.statusconnector:Fire(multi.unpack(({__StatusLinda:receive(nil, temp.ID)})[2])) temp.statusconnector:Fire(multi.unpack(({__StatusLinda:receive(nil, temp.ID)})[2]))
end end
if status == "done" or temp.returns:get("returns") then if status == "done" or temp.returns:get("returns") then
returns = ({temp.returns:receive(0, "returns")})[2] returns = ({temp.returns:receive(0, "returns")})[2]
livingThreads[temp.ID] = {false, temp.Name} livingThreads[temp.ID] = {false, temp.Name}
temp.alive = false temp.alive = false
if returns[1] == false then if returns[1] == false then
temp.OnError:Fire(temp, returns[2]) temp.OnError:Fire(temp, returns[2])
else else
table.remove(returns,1) table.remove(returns,1)
temp.OnDeath:Fire(multi.unpack(returns)) temp.OnDeath:Fire(multi.unpack(returns))
end end
GLOBAL["__THREADS__"] = livingThreads GLOBAL["__THREADS__"] = livingThreads
table.remove(threads, i) table.remove(threads, i)
elseif status == "running" then elseif status == "running" then
-- --
elseif status == "waiting" then elseif status == "waiting" then
-- --
elseif status == "error" then elseif status == "error" then
-- The thread never really errors, we handle this through our linda object -- The thread never really errors, we handle this through our linda object
elseif status == "cancelled" then elseif status == "cancelled" then
livingThreads[temp.ID] = {false, temp.Name} livingThreads[temp.ID] = {false, temp.Name}
temp.alive = false temp.alive = false
temp.OnError:Fire(temp,"thread_cancelled") temp.OnError:Fire(temp,"thread_cancelled")
GLOBAL["__THREADS__"] = livingThreads GLOBAL["__THREADS__"] = livingThreads
table.remove(threads, i) table.remove(threads, i)
elseif status == "killed" then elseif status == "killed" then
livingThreads[temp.ID] = {false, temp.Name} livingThreads[temp.ID] = {false, temp.Name}
temp.alive = false temp.alive = false
temp.OnError:Fire(temp,"thread_killed") temp.OnError:Fire(temp,"thread_killed")
GLOBAL["__THREADS__"] = livingThreads GLOBAL["__THREADS__"] = livingThreads
table.remove(threads, i) table.remove(threads, i)
end end
end end
end end
end).OnError(multi.error) end).OnError(multi.error)
end end
multi.print("Integrated Lanes Threading!") multi.print("Integrated Lanes Threading!")
multi.integration = {} -- for module creators multi.integration = {} -- for module creators
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.lanesManager.extensions") require("multi.integration.lanesManager.extensions")
return { return {
init = function() init = function()
return GLOBAL, THREAD return GLOBAL, THREAD
end end
} }
+150 -150
View File
@@ -1,151 +1,151 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local function getOS() local function getOS()
if package.config:sub(1, 1) == "\\" then if package.config:sub(1, 1) == "\\" then
return "windows" return "windows"
else else
return "unix" return "unix"
end end
end end
local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console) local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console)
local THREAD = {} local THREAD = {}
THREAD.Priority_Core = 3 THREAD.Priority_Core = 3
THREAD.Priority_High = 2 THREAD.Priority_High = 2
THREAD.Priority_Above_Normal = 1 THREAD.Priority_Above_Normal = 1
THREAD.Priority_Normal = 0 THREAD.Priority_Normal = 0
THREAD.Priority_Below_Normal = -1 THREAD.Priority_Below_Normal = -1
THREAD.Priority_Low = -2 THREAD.Priority_Low = -2
THREAD.Priority_Idle = -3 THREAD.Priority_Idle = -3
function THREAD.set(name, val) function THREAD.set(name, val)
__GlobalLinda:set(name, val) __GlobalLinda:set(name, val)
end end
function THREAD.get(name) function THREAD.get(name)
return __GlobalLinda:get(name) return __GlobalLinda:get(name)
end end
function THREAD.waitFor(name) function THREAD.waitFor(name)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
return multi.hold(function() return multi.hold(function()
math.randomseed(os.time()) math.randomseed(os.time())
__SleepingLinda:receive(.001, "__non_existing_variable") __SleepingLinda:receive(.001, "__non_existing_variable")
return __GlobalLinda:get(name) return __GlobalLinda:get(name)
end) end)
end end
function THREAD.getCores() function THREAD.getCores()
return THREAD.__CORES return THREAD.__CORES
end end
function THREAD.getConsole() function THREAD.getConsole()
local c = {} local c = {}
c.queue = __Console c.queue = __Console
function c.print(...) function c.print(...)
c.queue:push("Q", table.concat(multi.pack(...), "\t")) c.queue:push("Q", table.concat(multi.pack(...), "\t"))
end end
function c.error(err) function c.error(err)
c.queue:push("Q", "Error in <"..THREAD_NAME..":" .. THREAD_ID .. ">: ".. err) c.queue:push("Q", "Error in <"..THREAD_NAME..":" .. THREAD_ID .. ">: ".. err)
multi.error(err) multi.error(err)
end end
return c return c
end end
function THREAD.getThreads() function THREAD.getThreads()
return GLOBAL.__THREADS__ return GLOBAL.__THREADS__
end end
if os.getOS() == "windows" then if os.getOS() == "windows" then
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS")) THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
else else
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n")) THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
end end
function THREAD.kill() -- trigger the lane destruction function THREAD.kill() -- trigger the lane destruction
error("Thread was killed!\1") error("Thread was killed!\1")
end end
function THREAD.sync() function THREAD.sync()
-- Maybe do something... -- Maybe do something...
end end
function THREAD.pushStatus(...) function THREAD.pushStatus(...)
local args = multi.pack(...) local args = multi.pack(...)
__StatusLinda:send(nil,THREAD_ID, args) __StatusLinda:send(nil,THREAD_ID, args)
end end
_G.THREAD_ID = 0 _G.THREAD_ID = 0
function THREAD.sleep(n) function THREAD.sleep(n)
math.randomseed(os.time()) math.randomseed(os.time())
__SleepingLinda:receive(n, "__non_existing_variable") __SleepingLinda:receive(n, "__non_existing_variable")
end end
function THREAD.hold(n) function THREAD.hold(n)
local function wait() local function wait()
math.randomseed(os.time()) math.randomseed(os.time())
__SleepingLinda:receive(.001, "__non_existing_variable") __SleepingLinda:receive(.001, "__non_existing_variable")
end end
repeat repeat
wait() wait()
until n() until n()
end end
local GLOBAL = {} local GLOBAL = {}
setmetatable(GLOBAL, { setmetatable(GLOBAL, {
__index = function(t, k) __index = function(t, k)
return __GlobalLinda:get(k) return __GlobalLinda:get(k)
end, end,
__newindex = function(t, k, v) __newindex = function(t, k, v)
__GlobalLinda:set(k, v) __GlobalLinda:set(k, v)
end end
}) })
function THREAD.setENV(env, name) function THREAD.setENV(env, name)
GLOBAL[name or "__env"] = env GLOBAL[name or "__env"] = env
end end
function THREAD.getENV(name) function THREAD.getENV(name)
return GLOBAL[name or "__env"] return GLOBAL[name or "__env"]
end end
function THREAD.exposeENV(name) function THREAD.exposeENV(name)
name = name or "__env" name = name or "__env"
local env = THREAD.getENV(name) local env = THREAD.getENV(name)
for i,v in pairs(env) do for i,v in pairs(env) do
_G[i] = v _G[i] = v
end end
end end
function THREAD.defer(func) function THREAD.defer(func)
table.insert(_DEFER, func) table.insert(_DEFER, func)
end end
return GLOBAL, THREAD return GLOBAL, THREAD
end end
return {init = function(g,s,st,c,onexit) return {init = function(g,s,st,c,onexit)
return INIT(g,s,st,c,onexit) return INIT(g,s,st,c,onexit)
end} end}
+243 -243
View File
@@ -1,244 +1,244 @@
if not ISTHREAD then if not ISTHREAD then
multi, thread = require("multi").init() multi, thread = require("multi").init()
GLOBAL = multi.integration.GLOBAL GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD THREAD = multi.integration.THREAD
end end
function multi:newSystemThreadedQueue(name) function multi:newSystemThreadedQueue(name)
local name = name or multi.randomString(16) local name = name or multi.randomString(16)
local c = {} local c = {}
c.Name = name c.Name = name
c.Type = multi.registerType("s_queue") c.Type = multi.registerType("s_queue")
c.chan = love.thread.getChannel(name) c.chan = love.thread.getChannel(name)
function c:push(dat) function c:push(dat)
self.chan:push(THREAD.packValue(dat)) self.chan:push(THREAD.packValue(dat))
end end
function c:pop() function c:pop()
return THREAD.unpackValue(self.chan:pop()) return THREAD.unpackValue(self.chan:pop())
end end
function c:peek() function c:peek()
return THREAD.unpackValue(self.chan:peek()) return THREAD.unpackValue(self.chan:peek())
end end
function c:init() function c:init()
self.chan = love.thread.getChannel(self.Name) self.chan = love.thread.getChannel(self.Name)
return self return self
end end
function c:Hold(opt) function c:Hold(opt)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
if opt.peek then if opt.peek then
return thread.hold(function() return thread.hold(function()
return self:peek() return self:peek()
end) end)
else else
return thread.hold(function() return thread.hold(function()
return self:pop() return self:pop()
end) end)
end end
end end
GLOBAL[name] = c GLOBAL[name] = c
self:create(c) self:create(c)
return c return c
end end
function multi:newSystemThreadedTable(name) function multi:newSystemThreadedTable(name)
local name = name or multi.randomString(16) local name = name or multi.randomString(16)
local c = {} local c = {}
c.Name = name c.Name = name
c.Type = multi.registerType("s_table") c.Type = multi.registerType("s_table")
c.tab = THREAD.createTable(name) c.tab = THREAD.createTable(name)
function c:init() function c:init()
self.tab = THREAD.createTable(self.Name) self.tab = THREAD.createTable(self.Name)
setmetatable(self,{ setmetatable(self,{
__index = function(t, k) __index = function(t, k)
return self.tab[k] return self.tab[k]
end, end,
__newindex = function(t,k,v) __newindex = function(t,k,v)
self.tab[k] = v self.tab[k] = v
end end
}) })
return self return self
end end
c.__init = c.init c.__init = c.init
function c:Hold(opt) function c:Hold(opt)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
if opt.key then if opt.key then
return thread.hold(function() return thread.hold(function()
return self.tab[opt.key] return self.tab[opt.key]
end) end)
else else
multi.error("Must provide a key to check opt.key = 'key'") multi.error("Must provide a key to check opt.key = 'key'")
end end
end end
setmetatable(c,{ setmetatable(c,{
__index = function(t, k) __index = function(t, k)
return c.tab[k] return c.tab[k]
end, end,
__newindex = function(t,k,v) __newindex = function(t,k,v)
c.tab[k] = v c.tab[k] = v
end end
}) })
GLOBAL[name] = c GLOBAL[name] = c
self:create(c) self:create(c)
return c return c
end end
local jqc = 1 local jqc = 1
function multi:newSystemThreadedJobQueue(n) function multi:newSystemThreadedJobQueue(n)
local c = {} local c = {}
c.cores = n or THREAD.getCores() c.cores = n or THREAD.getCores()
c.registerQueue = {} c.registerQueue = {}
c.Type = multi.registerType("s_jobqueue") c.Type = multi.registerType("s_jobqueue")
c.funcs = THREAD.createTable("__JobQueue_"..jqc.."_table") c.funcs = THREAD.createTable("__JobQueue_"..jqc.."_table")
c.queue = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queue") c.queue = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queue")
c.queueReturn = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueReturn") c.queueReturn = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueReturn")
c.queueAll = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueAll") c.queueAll = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueAll")
c.id = 0 c.id = 0
c.OnJobCompleted = multi:newConnection() c.OnJobCompleted = multi:newConnection()
local allfunc = 0 local allfunc = 0
function c:doToAll(func) function c:doToAll(func)
for i = 1, self.cores do for i = 1, self.cores do
self.queueAll:push({allfunc, func}) self.queueAll:push({allfunc, func})
end end
allfunc = allfunc + 1 allfunc = allfunc + 1
end end
function c:registerFunction(name, func) function c:registerFunction(name, func)
if self.funcs[name] then if self.funcs[name] then
multi.error("A function by the name "..name.." has already been registered!") multi.error("A function by the name "..name.." has already been registered!")
end end
self.funcs[name] = func self.funcs[name] = func
end end
function c:pushJob(name,...) function c:pushJob(name,...)
self.id = self.id + 1 self.id = self.id + 1
self.queue:push{name,self.id,...} self.queue:push{name,self.id,...}
return self.id return self.id
end end
function c:isEmpty() function c:isEmpty()
return queueJob:peek()==nil return queueJob:peek()==nil
end end
local nFunc = 0 local nFunc = 0
function c:newFunction(name,func,holup) -- This registers with the queue function c:newFunction(name,func,holup) -- This registers with the queue
if type(name)=="function" then if type(name)=="function" then
holup = func holup = func
func = name func = name
name = "JQ_Function_"..nFunc name = "JQ_Function_"..nFunc
end end
nFunc = nFunc + 1 nFunc = nFunc + 1
c:registerFunction(name,func) c:registerFunction(name,func)
return thread:newFunction(function(...) return thread:newFunction(function(...)
local id = c:pushJob(name,...) local id = c:pushJob(name,...)
local link local link
local rets local rets
link = c.OnJobCompleted(function(jid,...) link = c.OnJobCompleted(function(jid,...)
if id==jid then if id==jid then
rets = multi.pack(...) rets = multi.pack(...)
end end
end) end)
return thread.hold(function() return thread.hold(function()
if rets then if rets then
return multi.unpack(rets) or multi.NIL return multi.unpack(rets) or multi.NIL
end end
end) end)
end,holup),name end,holup),name
end end
thread:newThread("jobManager",function() thread:newThread("jobManager",function()
while true do while true do
thread.yield() thread.yield()
local dat = c.queueReturn:pop() local dat = c.queueReturn:pop()
if dat then if dat then
c.OnJobCompleted:Fire(multi.unpack(dat)) c.OnJobCompleted:Fire(multi.unpack(dat))
end end
end end
end) end)
for i=1,c.cores do for i=1,c.cores do
multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc) multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
require("love.timer") require("love.timer")
love.timer.sleep(1) love.timer.sleep(1)
local clock = os.clock local clock = os.clock
local funcs = THREAD.createTable("__JobQueue_"..jqc.."_table") local funcs = THREAD.createTable("__JobQueue_"..jqc.."_table")
local queue = THREAD.waitFor("__JobQueue_"..jqc.."_queue") local queue = THREAD.waitFor("__JobQueue_"..jqc.."_queue")
local queueReturn = THREAD.waitFor("__JobQueue_"..jqc.."_queueReturn") local queueReturn = THREAD.waitFor("__JobQueue_"..jqc.."_queueReturn")
local lastProc = clock() local lastProc = clock()
local queueAll = THREAD.waitFor("__JobQueue_"..jqc.."_queueAll") local queueAll = THREAD.waitFor("__JobQueue_"..jqc.."_queueAll")
local registry = {} local registry = {}
_G["__QR"] = queueReturn _G["__QR"] = queueReturn
setmetatable(_G,{__index = funcs}) setmetatable(_G,{__index = funcs})
thread:newThread("startUp",function() thread:newThread("startUp",function()
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
if all and not registry[all[1]] then if all and not registry[all[1]] then
lastProc = os.clock() lastProc = os.clock()
queueAll:pop()[2]() queueAll:pop()[2]()
end end
end end
end) end)
thread:newThread("runner",function() thread:newThread("runner",function()
thread.sleep(.1) thread.sleep(.1)
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
if all and not registry[all[1]] then if all and not registry[all[1]] then
lastProc = os.clock() lastProc = os.clock()
queueAll:pop()[2]() queueAll:pop()[2]()
end end
local dat = thread.hold(queue) local dat = thread.hold(queue)
if dat then if dat then
multi:newThread("Test",function() multi:newThread("Test",function()
lastProc = os.clock() lastProc = os.clock()
local name = table.remove(dat,1) local name = table.remove(dat,1)
local id = table.remove(dat,1) local id = table.remove(dat,1)
local tab = {funcs[name](multi.unpack(dat))} local tab = {funcs[name](multi.unpack(dat))}
table.insert(tab,1,id) table.insert(tab,1,id)
--local test = queueReturn.push --local test = queueReturn.push
queueReturn:push(tab) queueReturn:push(tab)
end) end)
end end
end end
end) end)
thread:newThread("Idler",function() thread:newThread("Idler",function()
while true do while true do
thread.yield() thread.yield()
if clock()-lastProc> 2 then if clock()-lastProc> 2 then
THREAD.sleep(.05) THREAD.sleep(.05)
else else
THREAD.sleep(.001) THREAD.sleep(.001)
end end
end end
end) end)
multi:mainloop() multi:mainloop()
end,jqc) end,jqc)
end end
function c:Hold(opt) function c:Hold(opt)
return thread.hold(self.OnJobCompleted) return thread.hold(self.OnJobCompleted)
end end
jqc = jqc + 1 jqc = jqc + 1
self:create(c) self:create(c)
return c return c
end end
+137 -137
View File
@@ -1,137 +1,137 @@
if ISTHREAD then if ISTHREAD then
error("You cannot require the loveManager from within a thread!") error("You cannot require the loveManager from within a thread!")
end end
local ThreadFileData = [[ local ThreadFileData = [[
ISTHREAD = true ISTHREAD = true
args = {...} args = {...}
THREAD_ID = args[1] THREAD_ID = args[1]
THREAD_NAME = args[2] THREAD_NAME = args[2]
GLOBAL, THREAD, DEFER = require("multi.integration.loveManager.threads"):init() GLOBAL, THREAD, DEFER = require("multi.integration.loveManager.threads"):init()
__FUNC = THREAD.unpackValue(args[3]) __FUNC = THREAD.unpackValue(args[3])
ARGS = THREAD.unpackValue(args[4]) ARGS = THREAD.unpackValue(args[4])
settings = args[5] settings = args[5]
if ARGS == nil then ARGS = {} end if ARGS == nil then ARGS = {} end
math.randomseed(THREAD_ID) math.randomseed(THREAD_ID)
math.random() math.random()
math.random() math.random()
math.random() math.random()
stab = THREAD.createTable(THREAD_NAME .. THREAD_ID) stab = THREAD.createTable(THREAD_NAME .. THREAD_ID)
if GLOBAL["__env"] then if GLOBAL["__env"] then
local env = THREAD.getENV() local env = THREAD.getENV()
for i,v in pairs(env) do for i,v in pairs(env) do
_G[i] = v _G[i] = v
end end
end end
multi, thread = require("multi"):init{error=true, warning=true, print=true, priority=true} multi, thread = require("multi"):init{error=true, warning=true, print=true, priority=true}
multi.defaultSettings.print = true multi.defaultSettings.print = true
require("multi.integration.loveManager.extensions") require("multi.integration.loveManager.extensions")
require("multi.integration.sharedExtensions") require("multi.integration.sharedExtensions")
local returns = {pcall(__FUNC, multi.unpack(ARGS))} local returns = {pcall(__FUNC, multi.unpack(ARGS))}
table.remove(returns,1) table.remove(returns,1)
stab["returns"] = returns stab["returns"] = returns
for i,v in pairs(DEFER) do for i,v in pairs(DEFER) do
pcall(v) pcall(v)
end end
]] ]]
_G.THREAD_NAME = "MAIN_THREAD" _G.THREAD_NAME = "MAIN_THREAD"
_G.THREAD_ID = 0 _G.THREAD_ID = 0
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local GLOBAL, THREAD = require("multi.integration.loveManager.threads"):init() local GLOBAL, THREAD = require("multi.integration.loveManager.threads"):init()
multi.registerType("s_function") multi.registerType("s_function")
multi.registerType("s_thread") multi.registerType("s_thread")
multi.integration = {} multi.integration = {}
multi.isMainThread = true multi.isMainThread = true
local threads = {} local threads = {}
local tid = 0 local tid = 0
function multi:newSystemThread(name, func, ...) function multi:newSystemThread(name, func, ...)
multi.InitSystemThreadErrorHandler() multi.InitSystemThreadErrorHandler()
local name = name or multi.randomString(16) local name = name or multi.randomString(16)
tid = tid + 1 tid = tid + 1
local c = {} local c = {}
c.Type = multi.STHREAD c.Type = multi.STHREAD
c.Name = name c.Name = name
c.ID = tid c.ID = tid
c.thread = love.thread.newThread(ThreadFileData) c.thread = love.thread.newThread(ThreadFileData)
c.thread:start(c.ID, c.Name, THREAD.packValue(func), THREAD.packValue({...}), multi.defaultSettings) c.thread:start(c.ID, c.Name, THREAD.packValue(func), THREAD.packValue({...}), multi.defaultSettings)
c.stab = THREAD.createTable(name .. c.ID) c.stab = THREAD.createTable(name .. c.ID)
c.creationTime = os.clock() c.creationTime = os.clock()
c.OnDeath = multi:newConnection() c.OnDeath = multi:newConnection()
c.OnError = multi:newConnection() c.OnError = multi:newConnection()
c.status_channel = love.thread.getChannel("__status_channel__" .. c.ID) c.status_channel = love.thread.getChannel("__status_channel__" .. c.ID)
function c:getName() return c.name end function c:getName() return c.name end
table.insert(threads, c) table.insert(threads, c)
c.OnError(multi.error) c.OnError(multi.error)
if self.isActor then if self.isActor then
self:create(c) self:create(c)
else else
multi.create(multi, c) multi.create(multi, c)
end end
return c return c
end end
local started = false local started = false
local console_channel = love.thread.getChannel("__console_channel__") local console_channel = love.thread.getChannel("__console_channel__")
function THREAD:newFunction(func, holdme) function THREAD:newFunction(func, holdme)
return thread:newFunctionBase(function(...) return thread:newFunctionBase(function(...)
return multi:newSystemThread("SystemThreaded Function Handler", func, ...) return multi:newSystemThread("SystemThreaded Function Handler", func, ...)
end, holdme, multi.SFUNCTION)() end, holdme, multi.SFUNCTION)()
end end
function love.threaderror(thread, errorstr) function love.threaderror(thread, errorstr)
multi.error("Thread error! " .. errorstr) multi.error("Thread error! " .. errorstr)
end end
function multi.InitSystemThreadErrorHandler() function multi.InitSystemThreadErrorHandler()
if started == true then return end if started == true then return end
started = true started = true
thread:newThread("Love System Thread Handler", function() thread:newThread("Love System Thread Handler", function()
while true do while true do
thread.yield() thread.yield()
for i = #threads, 1, -1 do for i = #threads, 1, -1 do
local th = threads[i] local th = threads[i]
if th.status_channel:peek() ~= nil then if th.status_channel:peek() ~= nil then
th.statusconnector:Fire(multi.unpack(th.status_channel:pop())) th.statusconnector:Fire(multi.unpack(th.status_channel:pop()))
end end
local th_err = th.thread:getError() local th_err = th.thread:getError()
if th_err == "Thread Killed!\1" then if th_err == "Thread Killed!\1" then
th.OnDeath:Fire("Thread Killed!") th.OnDeath:Fire("Thread Killed!")
table.remove(threads, i) table.remove(threads, i)
elseif th_err then elseif th_err then
th.OnError:Fire(th, th_err) th.OnError:Fire(th, th_err)
table.remove(threads, i) table.remove(threads, i)
elseif th.stab.returns then elseif th.stab.returns then
th.OnDeath:Fire(multi.unpack(th.stab.returns)) th.OnDeath:Fire(multi.unpack(th.stab.returns))
th.stab.returns = nil th.stab.returns = nil
table.remove(threads, i) table.remove(threads, i)
end end
end end
end end
end) end)
end end
THREAD.newSystemThread = function(...) THREAD.newSystemThread = function(...)
multi:newSystemThread(...) multi:newSystemThread(...)
end end
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.loveManager.extensions") require("multi.integration.loveManager.extensions")
require("multi.integration.sharedExtensions") require("multi.integration.sharedExtensions")
multi.print("Integrated Love Threading!") multi.print("Integrated Love Threading!")
return { return {
init = function() init = function()
return GLOBAL, THREAD return GLOBAL, THREAD
end end
} }
+227 -227
View File
@@ -1,228 +1,228 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
require("love.timer") require("love.timer")
require("love.system") require("love.system")
require("love.data") require("love.data")
require("love.thread") require("love.thread")
local multi, thread = require("multi"):init() 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 -- 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) function isLoveObject(value)
-- Check if the value has metatable -- Check if the value has metatable
if type(value) == "userdata" and getmetatable(value) then if type(value) == "userdata" and getmetatable(value) then
-- Check if the metatable has the __index field -- Check if the metatable has the __index field
local index = getmetatable(value).__index local index = getmetatable(value).__index
if type(index) == "table" then if type(index) == "table" then
-- Check if the metatable's __index table contains functions typical of LOVE2D objects -- 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 if index.draw or index.update or index.getWidth or index.getHeight or index.getString or index.getPointer then
return true return true
end end
end end
end end
return false return false
end 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 -- 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) function tableToFunctionString(t)
if type(t) == "nil" then return "\1\2:nil:" end 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) == "function" then return "\1\2:func:"..string.dump(t) end
if type(t) ~= "table" then return t end if type(t) ~= "table" then return t end
local newtable = {} local newtable = {}
for k, v in pairs(t) do for k, v in pairs(t) do
if type(v) == "function" then if type(v) == "function" then
newtable[k] = "\1\2:func:"..string.dump(v) newtable[k] = "\1\2:func:"..string.dump(v)
elseif type(v) == "table" then elseif type(v) == "table" then
newtable[k] = tableToFunctionString(v) newtable[k] = tableToFunctionString(v)
elseif isLoveObject(v) then elseif isLoveObject(v) then
newtable[k] = v newtable[k] = v
elseif type(v) == "userdata" then elseif type(v) == "userdata" then
newtable[k] = tostring(v) newtable[k] = tostring(v)
else else
newtable[k] = v newtable[k] = v
end end
end end
return newtable return newtable
end end
-- Converts strings with the value "\1\2:func:<function_string>" back to functions -- Converts strings with the value "\1\2:func:<function_string>" back to functions
function functionStringToTable(t) 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, 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) == "string" and t:sub(1, 7) == "\1\2:nil:" then return nil end
if type(t) ~= "table" then return t end if type(t) ~= "table" then return t end
for k, v in pairs(t) do for k, v in pairs(t) do
if type(v) == "string" then if type(v) == "string" then
if v:sub(1, 8) == "\1\2:func:" then if v:sub(1, 8) == "\1\2:func:" then
t[k] = loadstring(v:sub(9, -1)) t[k] = loadstring(v:sub(9, -1))
else else
t[k] = v t[k] = v
end end
elseif type(v) == "table" then elseif type(v) == "table" then
t[k] = functionStringToTable(v) t[k] = functionStringToTable(v)
else else
t[k] = v t[k] = v
end end
end end
if t.init then if t.init then
t:init() t:init()
end end
return t return t
end end
local function packValue(t) local function packValue(t)
return tableToFunctionString(t) return tableToFunctionString(t)
end end
local function unpackValue(t) local function unpackValue(t)
return functionStringToTable(t) return functionStringToTable(t)
end end
local function createTable(n) local function createTable(n)
if not n then if not n then
n = "STAB"..multi.randomString(8) n = "STAB"..multi.randomString(8)
end end
local __proxy = {} local __proxy = {}
local function set(name, val) local function set(name, val)
local chan = love.thread.getChannel(n .. name) local chan = love.thread.getChannel(n .. name)
if chan:getCount() == 1 then chan:pop() end if chan:getCount() == 1 then chan:pop() end
__proxy[name] = true __proxy[name] = true
chan:push(packValue(val)) chan:push(packValue(val))
end end
local function get(name) local function get(name)
return unpackValue(love.thread.getChannel(n .. name):peek()) return unpackValue(love.thread.getChannel(n .. name):peek())
-- if type(data) == "table" and data.init then -- if type(data) == "table" and data.init then
-- return data:init() -- return data:init()
-- else -- else
-- return data -- return data
-- end -- end
end end
return setmetatable({}, return setmetatable({},
{ {
__index = function(t, k) __index = function(t, k)
return get(k) return get(k)
end, end,
__newindex = function(t, k, v) __newindex = function(t, k, v)
set(k,v) set(k,v)
end end
} }
) )
end end
function INIT() function INIT()
local GLOBAL, THREAD, DEFER = createTable("__GLOBAL__"), {}, {} local GLOBAL, THREAD, DEFER = createTable("__GLOBAL__"), {}, {}
local status_channel, console_channel = love.thread.getChannel("__status_channel__" .. THREAD_ID), local status_channel, console_channel = love.thread.getChannel("__status_channel__" .. THREAD_ID),
love.thread.getChannel("__console_channel__") love.thread.getChannel("__console_channel__")
-- Non portable methods, shouldn't be used unless you know what you are doing -- Non portable methods, shouldn't be used unless you know what you are doing
THREAD.packValue = packValue THREAD.packValue = packValue
THREAD.unpackValue = unpackValue THREAD.unpackValue = unpackValue
THREAD.createTable = createTable THREAD.createTable = createTable
function THREAD.set(name, val) function THREAD.set(name, val)
GLOBAL[name] = val GLOBAL[name] = val
end end
function THREAD.get(name, val) function THREAD.get(name, val)
return GLOBAL[name] return GLOBAL[name]
end end
THREAD.waitFor = thread:newFunction(function(name) THREAD.waitFor = thread:newFunction(function(name)
local function wait() local function wait()
math.randomseed(os.time()) math.randomseed(os.time())
thread.yield() thread.yield()
end end
repeat repeat
wait() wait()
until GLOBAL[name] ~= nil until GLOBAL[name] ~= nil
return GLOBAL[name] return GLOBAL[name]
end, true) end, true)
function THREAD.getCores() function THREAD.getCores()
return love.system.getProcessorCount() return love.system.getProcessorCount()
end end
function THREAD.getConsole() function THREAD.getConsole()
local c = {} local c = {}
c.queue = console_channel c.queue = console_channel
function c.print(...) function c.print(...)
c.queue:push(table.concat(multi.pack(...), "\t")) c.queue:push(table.concat(multi.pack(...), "\t"))
end end
function c.error(err) function c.error(err)
c.queue:push("Error in <"..THREAD_NAME..":" .. THREAD_ID .. ">: ".. err) c.queue:push("Error in <"..THREAD_NAME..":" .. THREAD_ID .. ">: ".. err)
multi.error(err) multi.error(err)
end end
return c return c
end end
function THREAD.getThreads() function THREAD.getThreads()
-- --
end end
function THREAD.kill() -- trigger the lane destruction function THREAD.kill() -- trigger the lane destruction
error("Thread was killed!\1") error("Thread was killed!\1")
end end
function THREAD.pushStatus(...) function THREAD.pushStatus(...)
status_channel:push(multi.pack(...)) status_channel:push(multi.pack(...))
end end
function THREAD.sleep(n) function THREAD.sleep(n)
love.timer.sleep(n) love.timer.sleep(n)
end end
THREAD.hold = thread:newFunction(function(n) THREAD.hold = thread:newFunction(function(n)
thread.hold(n) thread.hold(n)
end, true) end, true)
function THREAD.setENV(env, name) function THREAD.setENV(env, name)
GLOBAL[name or "__env"] = env GLOBAL[name or "__env"] = env
end end
function THREAD.getENV(name) function THREAD.getENV(name)
return GLOBAL[name or "__env"] return GLOBAL[name or "__env"]
end end
function THREAD.exposeENV(name) function THREAD.exposeENV(name)
name = name or "__env" name = name or "__env"
local env = THREAD.getENV(name) local env = THREAD.getENV(name)
for i,v in pairs(env) do for i,v in pairs(env) do
_G[i] = v _G[i] = v
end end
end end
function THREAD.defer(func) function THREAD.defer(func)
table.insert(DEFER, func) table.insert(DEFER, func)
end end
function THREAD.sync() function THREAD.sync()
-- Maybe do something... -- Maybe do something...
end end
return GLOBAL, THREAD, DEFER return GLOBAL, THREAD, DEFER
end end
return { return {
init = function() init = function()
return INIT() return INIT()
end end
} }
+203 -203
View File
@@ -1,204 +1,204 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi").init() local multi, thread = require("multi").init()
GLOBAL = multi.integration.GLOBAL GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD THREAD = multi.integration.THREAD
function multi:newSystemThreadedQueue(name) function multi:newSystemThreadedQueue(name)
local c = {} local c = {}
c.Name = name c.Name = name
local fRef = {"func",nil} local fRef = {"func",nil}
function c:init() function c:init()
local q = {} local q = {}
q.chan = lovr.thread.getChannel(self.Name) q.chan = lovr.thread.getChannel(self.Name)
function q:push(dat) function q:push(dat)
if type(dat) == "function" then if type(dat) == "function" then
fRef[2] = THREAD.dump(dat) fRef[2] = THREAD.dump(dat)
self.chan:push(fRef) self.chan:push(fRef)
return return
else else
self.chan:push(dat) self.chan:push(dat)
end end
end end
function q:pop() function q:pop()
local dat = self.chan:pop() local dat = self.chan:pop()
if type(dat)=="table" and dat[1]=="func" then if type(dat)=="table" and dat[1]=="func" then
return THREAD.loadDump(dat[2]) return THREAD.loadDump(dat[2])
else else
return dat return dat
end end
end end
function q:peek() function q:peek()
local dat = self.chan:peek() local dat = self.chan:peek()
if type(dat)=="table" and dat[1]=="func" then if type(dat)=="table" and dat[1]=="func" then
return THREAD.loadDump(dat[2]) return THREAD.loadDump(dat[2])
else else
return dat return dat
end end
end end
return q return q
end end
THREAD.package(name,c) THREAD.package(name,c)
return c return c
end end
function multi:newSystemThreadedTable(name) function multi:newSystemThreadedTable(name)
local c = {} local c = {}
c.name = name c.name = name
function c:init() function c:init()
return THREAD.createTable(self.name) return THREAD.createTable(self.name)
end end
THREAD.package(name,c) THREAD.package(name,c)
return c return c
end end
local jqc = 1 local jqc = 1
function multi:newSystemThreadedJobQueue(n) function multi:newSystemThreadedJobQueue(n)
local c = {} local c = {}
c.cores = n or THREAD.getCores() c.cores = n or THREAD.getCores()
c.registerQueue = {} c.registerQueue = {}
c.funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table") c.funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table")
c.queue = lovr.thread.getChannel("__JobQueue_"..jqc.."_queue") c.queue = lovr.thread.getChannel("__JobQueue_"..jqc.."_queue")
c.queueReturn = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueReturn") c.queueReturn = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueReturn")
c.queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll") c.queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
c.id = 0 c.id = 0
c.OnJobCompleted = multi:newConnection() c.OnJobCompleted = multi:newConnection()
local allfunc = 0 local allfunc = 0
function c:doToAll(func) function c:doToAll(func)
local f = THREAD.dump(func) local f = THREAD.dump(func)
for i = 1, self.cores do for i = 1, self.cores do
self.queueAll:push({allfunc,f}) self.queueAll:push({allfunc,f})
end end
allfunc = allfunc + 1 allfunc = allfunc + 1
end end
function c:registerFunction(name,func) function c:registerFunction(name,func)
if self.funcs[name] then if self.funcs[name] then
error("A function by the name "..name.." has already been registered!") error("A function by the name "..name.." has already been registered!")
end end
self.funcs[name] = func self.funcs[name] = func
end end
function c:pushJob(name,...) function c:pushJob(name,...)
self.id = self.id + 1 self.id = self.id + 1
self.queue:push{name,self.id,...} self.queue:push{name,self.id,...}
return self.id return self.id
end end
function c:isEmpty() function c:isEmpty()
return queueJob:peek()==nil return queueJob:peek()==nil
end end
local nFunc = 0 local nFunc = 0
function c:newFunction(name,func,holup) -- This registers with the queue function c:newFunction(name,func,holup) -- This registers with the queue
if type(name)=="function" then if type(name)=="function" then
holup = func holup = func
func = name func = name
name = "JQ_Function_"..nFunc name = "JQ_Function_"..nFunc
end end
nFunc = nFunc + 1 nFunc = nFunc + 1
c:registerFunction(name,func) c:registerFunction(name,func)
return thread:newFunction(function(...) return thread:newFunction(function(...)
local id = c:pushJob(name,...) local id = c:pushJob(name,...)
local link local link
local rets local rets
link = c.OnJobCompleted(function(jid,...) link = c.OnJobCompleted(function(jid,...)
if id==jid then if id==jid then
rets = multi.pack(...) rets = multi.pack(...)
link:Destroy() link:Destroy()
end end
end) end)
return thread.hold(function() return thread.hold(function()
if rets then if rets then
return multi.unpack(rets) or multi.NIL return multi.unpack(rets) or multi.NIL
end end
end) end)
end,holup),name end,holup),name
end end
thread:newThread("jobManager",function() thread:newThread("jobManager",function()
while true do while true do
thread.yield() thread.yield()
local dat = c.queueReturn:pop() local dat = c.queueReturn:pop()
if dat then if dat then
c.OnJobCompleted:Fire(multi.unpack(dat)) c.OnJobCompleted:Fire(multi.unpack(dat))
end end
end end
end) end)
for i=1,c.cores do for i=1,c.cores do
multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc) multi:newSystemThread("JobQueue_"..jqc.."_worker_"..i,function(jqc)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
require("lovr.timer") require("lovr.timer")
local function atomic(channel) local function atomic(channel)
return channel:pop() return channel:pop()
end end
local clock = os.clock local clock = os.clock
local funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table") local funcs = THREAD.createStaticTable("__JobQueue_"..jqc.."_table")
local queue = lovr.thread.getChannel("__JobQueue_"..jqc.."_queue") local queue = lovr.thread.getChannel("__JobQueue_"..jqc.."_queue")
local queueReturn = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueReturn") local queueReturn = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueReturn")
local lastProc = clock() local lastProc = clock()
local queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll") local queueAll = lovr.thread.getChannel("__JobQueue_"..jqc.."_queueAll")
local registry = {} local registry = {}
_G["__QR"] = queueReturn _G["__QR"] = queueReturn
setmetatable(_G,{__index = funcs}) setmetatable(_G,{__index = funcs})
thread:newThread("startUp",function() thread:newThread("startUp",function()
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
if all and not registry[all[1]] then if all and not registry[all[1]] then
lastProc = os.clock() lastProc = os.clock()
THREAD.loadDump(queueAll:pop()[2])() THREAD.loadDump(queueAll:pop()[2])()
end end
end end
end) end)
thread:newThread("runner",function() thread:newThread("runner",function()
thread.sleep(.1) thread.sleep(.1)
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
if all and not registry[all[1]] then if all and not registry[all[1]] then
lastProc = os.clock() lastProc = os.clock()
THREAD.loadDump(queueAll:pop()[2])() THREAD.loadDump(queueAll:pop()[2])()
end end
local dat = queue:performAtomic(atomic) local dat = queue:performAtomic(atomic)
if dat then if dat then
lastProc = os.clock() lastProc = os.clock()
local name = table.remove(dat,1) local name = table.remove(dat,1)
local id = table.remove(dat,1) local id = table.remove(dat,1)
local tab = {funcs[name](multi.unpack(dat))} local tab = {funcs[name](multi.unpack(dat))}
table.insert(tab,1,id) table.insert(tab,1,id)
queueReturn:push(tab) queueReturn:push(tab)
end end
end end
end):OnError(function(...) end):OnError(function(...)
error(...) error(...)
end) end)
thread:newThread("Idler",function() thread:newThread("Idler",function()
while true do while true do
thread.yield() thread.yield()
if clock()-lastProc> 2 then if clock()-lastProc> 2 then
THREAD.sleep(.05) THREAD.sleep(.05)
else else
THREAD.sleep(.001) THREAD.sleep(.001)
end end
end end
end) end)
multi:mainloop() multi:mainloop()
end,jqc) end,jqc)
end end
jqc = jqc + 1 jqc = jqc + 1
return c return c
end end
+97 -97
View File
@@ -1,98 +1,98 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
-- TODO make compatible with lovr -- TODO make compatible with lovr
if ISTHREAD then if ISTHREAD then
error("You cannot require the lovrManager from within a thread!") error("You cannot require the lovrManager from within a thread!")
end end
local ThreadFileData = [[ local ThreadFileData = [[
ISTHREAD = true ISTHREAD = true
THREAD = require("multi.integration.lovrManager.threads") -- order is important! THREAD = require("multi.integration.lovrManager.threads") -- order is important!
sThread = THREAD sThread = THREAD
__IMPORTS = {...} __IMPORTS = {...}
__FUNC__=table.remove(__IMPORTS,1) __FUNC__=table.remove(__IMPORTS,1)
__THREADID__=table.remove(__IMPORTS,1) __THREADID__=table.remove(__IMPORTS,1)
__THREADNAME__=table.remove(__IMPORTS,1) __THREADNAME__=table.remove(__IMPORTS,1)
stab = THREAD.createStaticTable(__THREADNAME__) stab = THREAD.createStaticTable(__THREADNAME__)
GLOBAL = THREAD.getGlobal() GLOBAL = THREAD.getGlobal()
multi, thread = require("multi").init() multi, thread = require("multi").init()
stab["returns"] = {THREAD.loadDump(__FUNC__)(multi.unpack(__IMPORTS))} stab["returns"] = {THREAD.loadDump(__FUNC__)(multi.unpack(__IMPORTS))}
]] ]]
local multi, thread = require("multi.compat.lovr2d"):init() local multi, thread = require("multi.compat.lovr2d"):init()
local THREAD = {} local THREAD = {}
__THREADID__ = 0 __THREADID__ = 0
__THREADNAME__ = "MainThread" __THREADNAME__ = "MainThread"
_G.THREAD_NAME = "MAIN_THREAD" _G.THREAD_NAME = "MAIN_THREAD"
_G.THREAD_ID = 0 _G.THREAD_ID = 0
multi.integration={} multi.integration={}
multi.integration.lovr2d={} multi.integration.lovr2d={}
local THREAD = require("multi.integration.lovrManager.threads") local THREAD = require("multi.integration.lovrManager.threads")
local GLOBAL = THREAD.getGlobal() local GLOBAL = THREAD.getGlobal()
local THREAD_ID = 1 local THREAD_ID = 1
local OBJECT_ID = 0 local OBJECT_ID = 0
local stf = 0 local stf = 0
function THREAD:newFunction(func,holup) function THREAD:newFunction(func,holup)
stf = stf + 1 stf = stf + 1
return function(...) return function(...)
local t = multi:newSystemThread("STF"..stf,func,...) local t = multi:newSystemThread("STF"..stf,func,...)
return thread:newFunction(function() return thread:newFunction(function()
return thread.hold(function() return thread.hold(function()
if t.stab["returns"] then if t.stab["returns"] then
local dat = t.stab.returns local dat = t.stab.returns
t.stab.returns = nil t.stab.returns = nil
return multi.unpack(dat) return multi.unpack(dat)
end end
end) end)
end,holup)() end,holup)()
end end
end end
function multi:newSystemThread(name,func,...) function multi:newSystemThread(name,func,...)
local c = {} local c = {}
c.name = name c.name = name
c.ID=THREAD_ID c.ID=THREAD_ID
c.thread=lovr.thread.newThread(ThreadFileData) c.thread=lovr.thread.newThread(ThreadFileData)
c.thread:start(THREAD.dump(func),c.ID,c.name,...) c.thread:start(THREAD.dump(func),c.ID,c.name,...)
c.stab = THREAD.createStaticTable(name) c.stab = THREAD.createStaticTable(name)
GLOBAL["__THREAD_"..c.ID] = {ID=c.ID,Name=c.name,Thread=c.thread} GLOBAL["__THREAD_"..c.ID] = {ID=c.ID,Name=c.name,Thread=c.thread}
GLOBAL["__THREAD_COUNT"] = THREAD_ID GLOBAL["__THREAD_COUNT"] = THREAD_ID
THREAD_ID=THREAD_ID+1 THREAD_ID=THREAD_ID+1
if self.isActor then if self.isActor then
self:create(c) self:create(c)
else else
multi.create(multi, c) multi.create(multi, c)
end end
return c return c
end end
THREAD.newSystemThread = multi.newSystemThread THREAD.newSystemThread = multi.newSystemThread
function lovr.threaderror(thread, errorstr) function lovr.threaderror(thread, errorstr)
multi.print("Thread error!\n"..errorstr) multi.print("Thread error!\n"..errorstr)
end end
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.lovrManager.extensions") require("multi.integration.lovrManager.extensions")
multi.print("Integrated lovr Threading!") multi.print("Integrated lovr Threading!")
return {init=function() return {init=function()
return GLOBAL,THREAD return GLOBAL,THREAD
end} end}
+221 -221
View File
@@ -1,222 +1,222 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
-- TODO make compatible with lovr -- TODO make compatible with lovr
require("lovr.timer") require("lovr.timer")
require("lovr.system") require("lovr.system")
require("lovr.data") require("lovr.data")
local socket = require("socket") local socket = require("socket")
local multi, thread = require("multi").init() local multi, thread = require("multi").init()
local threads = {} local threads = {}
function threads.loadDump(d) function threads.loadDump(d)
return loadstring(d:getString()) return loadstring(d:getString())
end end
function threads.dump(func) function threads.dump(func)
return lovr.data.newByteData(string.dump(func)) return lovr.data.newByteData(string.dump(func))
end end
local fRef = {"func",nil} local fRef = {"func",nil}
local function manage(channel, value) local function manage(channel, value)
channel:clear() channel:clear()
if type(value) == "function" then if type(value) == "function" then
fRef[2] = THREAD.dump(value) fRef[2] = THREAD.dump(value)
channel:push(fRef) channel:push(fRef)
return return
else else
channel:push(value) channel:push(value)
end end
end end
local function RandomVariable(length) local function RandomVariable(length)
local res = {} local res = {}
math.randomseed(socket.gettime()*10000) math.randomseed(socket.gettime()*10000)
for i = 1, length do for i = 1, length do
res[#res+1] = string.char(math.random(97, 122)) res[#res+1] = string.char(math.random(97, 122))
end end
return table.concat(res) return table.concat(res)
end end
local GNAME = "__GLOBAL_" local GNAME = "__GLOBAL_"
local proxy = {} local proxy = {}
function threads.set(name,val) function threads.set(name,val)
if not proxy[name] then proxy[name] = lovr.thread.getChannel(GNAME..name) end if not proxy[name] then proxy[name] = lovr.thread.getChannel(GNAME..name) end
proxy[name]:performAtomic(manage, val) proxy[name]:performAtomic(manage, val)
end end
function threads.get(name) function threads.get(name)
if not proxy[name] then proxy[name] = lovr.thread.getChannel(GNAME..name) end if not proxy[name] then proxy[name] = lovr.thread.getChannel(GNAME..name) end
local dat = proxy[name]:peek() local dat = proxy[name]:peek()
if type(dat)=="table" and dat[1]=="func" then if type(dat)=="table" and dat[1]=="func" then
return THREAD.loadDump(dat[2]) return THREAD.loadDump(dat[2])
else else
return dat return dat
end end
end end
function threads.waitFor(name) function threads.waitFor(name)
if thread.isThread() then if thread.isThread() then
return thread.hold(function() return thread.hold(function()
return threads.get(name) return threads.get(name)
end) end)
end end
while threads.get(name)==nil do while threads.get(name)==nil do
lovr.timer.sleep(.001) lovr.timer.sleep(.001)
end end
local dat = threads.get(name) local dat = threads.get(name)
if type(dat) == "table" and dat.init then if type(dat) == "table" and dat.init then
dat.init = threads.loadDump(dat.init) dat.init = threads.loadDump(dat.init)
end end
return dat return dat
end end
function threads.package(name,val) function threads.package(name,val)
local init = val.init local init = val.init
val.init=threads.dump(val.init) val.init=threads.dump(val.init)
GLOBAL[name]=val GLOBAL[name]=val
val.init=init val.init=init
end end
function threads.getCores() function threads.getCores()
return lovr.system.getProcessorCount() return lovr.system.getProcessorCount()
end end
function threads.kill() function threads.kill()
error("Thread Killed!") error("Thread Killed!")
end end
function threads.getThreads() function threads.getThreads()
local t = {} local t = {}
for i=1,GLOBAL["__THREAD_COUNT"] do for i=1,GLOBAL["__THREAD_COUNT"] do
t[#t+1]=GLOBAL["__THREAD_"..i] t[#t+1]=GLOBAL["__THREAD_"..i]
end end
return t return t
end end
function threads.getThread(n) function threads.getThread(n)
return GLOBAL["__THREAD_"..n] return GLOBAL["__THREAD_"..n]
end end
function threads.getName() function threads.getName()
return __THREADNAME__ return __THREADNAME__
end end
function threads.getID() function threads.getID()
return __THREADID__ return __THREADID__
end end
function threads.sleep(n) function threads.sleep(n)
lovr.timer.sleep(n) lovr.timer.sleep(n)
end end
function threads.getGlobal() function threads.getGlobal()
return setmetatable({}, return setmetatable({},
{ {
__index = function(t, k) __index = function(t, k)
return THREAD.get(k) return THREAD.get(k)
end, end,
__newindex = function(t, k, v) __newindex = function(t, k, v)
THREAD.set(k,v) THREAD.set(k,v)
end end
} }
) )
end end
function threads.createTable(n) function threads.createTable(n)
local _proxy = {} local _proxy = {}
local function set(name,val) local function set(name,val)
if not _proxy[name] then _proxy[name] = lovr.thread.getChannel(n..name) end if not _proxy[name] then _proxy[name] = lovr.thread.getChannel(n..name) end
_proxy[name]:performAtomic(manage, val) _proxy[name]:performAtomic(manage, val)
end end
local function get(name) local function get(name)
if not _proxy[name] then _proxy[name] = lovr.thread.getChannel(n..name) end if not _proxy[name] then _proxy[name] = lovr.thread.getChannel(n..name) end
local dat = _proxy[name]:peek() local dat = _proxy[name]:peek()
if type(dat)=="table" and dat[1]=="func" then if type(dat)=="table" and dat[1]=="func" then
return THREAD.loadDump(dat[2]) return THREAD.loadDump(dat[2])
else else
return dat return dat
end end
end end
return setmetatable({}, return setmetatable({},
{ {
__index = function(t, k) __index = function(t, k)
return get(k) return get(k)
end, end,
__newindex = function(t, k, v) __newindex = function(t, k, v)
set(k,v) set(k,v)
end end
} }
) )
end end
function threads.getConsole() function threads.getConsole()
local c = {} local c = {}
c.queue = lovr.thread.getChannel("__CONSOLE__") c.queue = lovr.thread.getChannel("__CONSOLE__")
function c.print(...) function c.print(...)
c.queue:push(multi.pack(...)) c.queue:push(multi.pack(...))
end end
function c.error(err) function c.error(err)
c.queue:push{"ERROR in <"..__THREADNAME__..">: "..err,__THREADID__} c.queue:push{"ERROR in <"..__THREADNAME__..">: "..err,__THREADID__}
error(err) error(err)
end end
return c return c
end end
if not ISTHREAD then if not ISTHREAD then
local clock = os.clock local clock = os.clock
local lastproc = clock() local lastproc = clock()
local queue = lovr.thread.getChannel("__CONSOLE__") local queue = lovr.thread.getChannel("__CONSOLE__")
thread:newThread("consoleManager",function() thread:newThread("consoleManager",function()
while true do while true do
thread.yield() thread.yield()
dat = queue:pop() dat = queue:pop()
if dat then if dat then
lastproc = clock() lastproc = clock()
print(multi.unpack(dat)) print(multi.unpack(dat))
end end
if clock()-lastproc>2 then if clock()-lastproc>2 then
thread.sleep(.1) thread.sleep(.1)
end end
end end
end) end)
end end
function threads.createStaticTable(n) function threads.createStaticTable(n)
local __proxy = {} local __proxy = {}
local function set(name,val) local function set(name,val)
if __proxy[name] then return end if __proxy[name] then return end
local chan = lovr.thread.getChannel(n..name) local chan = lovr.thread.getChannel(n..name)
if chan:getCount()>0 then return end if chan:getCount()>0 then return end
chan:performAtomic(manage, val) chan:performAtomic(manage, val)
__proxy[name] = val __proxy[name] = val
end end
local function get(name) local function get(name)
if __proxy[name] then return __proxy[name] end if __proxy[name] then return __proxy[name] end
local dat = lovr.thread.getChannel(n..name):peek() local dat = lovr.thread.getChannel(n..name):peek()
if type(dat)=="table" and dat[1]=="func" then if type(dat)=="table" and dat[1]=="func" then
__proxy[name] = THREAD.loadDump(dat[2]) __proxy[name] = THREAD.loadDump(dat[2])
return __proxy[name] return __proxy[name]
else else
__proxy[name] = dat __proxy[name] = dat
return __proxy[name] return __proxy[name]
end end
end end
return setmetatable({}, return setmetatable({},
{ {
__index = function(t, k) __index = function(t, k)
return get(k) return get(k)
end, end,
__newindex = function(t, k, v) __newindex = function(t, k, v)
set(k,v) set(k,v)
end end
} }
) )
end end
function threads.hold(n) function threads.hold(n)
local dat local dat
while not(dat) do while not(dat) do
dat = n() dat = n()
end end
end end
return threads return threads
+138 -138
View File
@@ -1,138 +1,138 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
-- This module probably will not be maintained any longer! -- This module probably will not be maintained any longer!
package.path = "?/init.lua;?.lua;" .. package.path package.path = "?/init.lua;?.lua;" .. package.path
local function _INIT(luvitThread, timer) local function _INIT(luvitThread, timer)
-- lots of this stuff should be able to stay the same -- lots of this stuff should be able to stay the same
function os.getOS() function os.getOS()
if package.config:sub(1, 1) == "\\" then if package.config:sub(1, 1) == "\\" then
return "windows" return "windows"
else else
return "unix" return "unix"
end end
end end
-- Step 1 get setup threads on luvit... Sigh how do i even... -- Step 1 get setup threads on luvit... Sigh how do i even...
local multi, thread = require("multi").init() local multi, thread = require("multi").init()
multi.isMainThread = true multi.isMainThread = true
function multi:canSystemThread() function multi:canSystemThread()
return true return true
end end
function multi:getPlatform() function multi:getPlatform()
return "luvit" return "luvit"
end end
local multi = multi local multi = multi
-- Step 2 set up the Global table... is this possible? -- Step 2 set up the Global table... is this possible?
local GLOBAL = {} local GLOBAL = {}
setmetatable( setmetatable(
GLOBAL, GLOBAL,
{ {
__index = function(t, k) __index = function(t, k)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
return nil return nil
end, end,
__newindex = function(t, k, v) __newindex = function(t, k, v)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
end end
} }
) )
local THREAD = {} local THREAD = {}
function THREAD.set(name, val) function THREAD.set(name, val)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
end end
function THREAD.get(name) function THREAD.get(name)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
end end
local function randomString(n) local function randomString(n)
local str = "" 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"} 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 for i = 1, n do
str = str .. "" .. strings[math.random(1, #strings)] str = str .. "" .. strings[math.random(1, #strings)]
end end
return str return str
end end
function THREAD.waitFor(name) function THREAD.waitFor(name)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
end end
function THREAD.testFor(name, val, sym) function THREAD.testFor(name, val, sym)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
end end
function THREAD.getCores() function THREAD.getCores()
return THREAD.__CORES return THREAD.__CORES
end end
if os.getOS() == "windows" then if os.getOS() == "windows" then
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS")) THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
else else
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n")) THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
end end
function THREAD.kill() -- trigger the thread destruction function THREAD.kill() -- trigger the thread destruction
error("Thread was Killed!") error("Thread was Killed!")
end 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 -- 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) function THREAD.sleep(n)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
end end
function THREAD.hold(n) function THREAD.hold(n)
--print("No Global table when using luvit integration!") --print("No Global table when using luvit integration!")
end end
-- Step 5 Basic Threads! -- Step 5 Basic Threads!
local function entry(path, name, func, ...) local function entry(path, name, func, ...)
local timer = require "timer" local timer = require "timer"
local luvitThread = require "thread" local luvitThread = require "thread"
package.path = path package.path = path
loadstring(func)(...) loadstring(func)(...)
end end
function multi:newSystemThread(name, func, ...) function multi:newSystemThread(name, func, ...)
local c = {} local c = {}
local __self = c local __self = c
c.name = name c.name = name
c.Type = multi.STHREAD c.Type = multi.STHREAD
c.thread = {} c.thread = {}
c.func = string.dump(func) c.func = string.dump(func)
function c:kill() function c:kill()
-- print("No Global table when using luvit integration!") -- print("No Global table when using luvit integration!")
end end
luvitThread.start(entry, package.path, name, c.func, ...) luvitThread.start(entry, package.path, name, c.func, ...)
return c return c
end end
THREAD.newSystemThread = multi.newSystemThread THREAD.newSystemThread = multi.newSystemThread
multi.print("Integrated Luvit!") multi.print("Integrated Luvit!")
multi.integration = {} -- for module creators multi.integration = {} -- for module creators
multi.integration.GLOBAL = GLOBAL multi.integration.GLOBAL = GLOBAL
multi.integration.THREAD = THREAD multi.integration.THREAD = THREAD
require("multi.integration.shared") 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... -- 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 = local interval =
timer.setInterval( timer.setInterval(
1, 1,
function() function()
multi:uManager() multi:uManager()
end end
) )
return multi return multi
end end
return {init = function(threadHandle, timerHandle) return {init = function(threadHandle, timerHandle)
local multi = _INIT(threadHandle, timerHandle) local multi = _INIT(threadHandle, timerHandle)
return GLOBAL, THREAD return GLOBAL, THREAD
end} end}
+33 -33
View File
@@ -1,34 +1,34 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
_G["__CHANNEL__"] = {} _G["__CHANNEL__"] = {}
local channel = {} local channel = {}
channel.__index = channel channel.__index = channel
-- Creates/Gets a channel of name -- Creates/Gets a channel of name
function channel:newChannel(name) function channel:newChannel(name)
local chan = _G["__CHANNEL__"] local chan = _G["__CHANNEL__"]
if chan then if chan then
end end
end end
+45 -45
View File
@@ -1,46 +1,46 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local cmd = require("multi.integration.networkManager.cmds") local cmd = require("multi.integration.networkManager.cmds")
local node = require("multi.integration.networkManager.node") local node = require("multi.integration.networkManager.node")
local net = require("net") local net = require("net")
local bin = require("bin") local bin = require("bin")
local child = {} local child = {}
child.__index = child child.__index = child
function multi:newChildNode(cd) function multi:newChildNode(cd)
local c = {} local c = {}
setmetatable(c,child) setmetatable(c,child)
local name local name
if cd then if cd then
if cd.name then if cd.name then
name = cd.name name = cd.name
end end
c.node = node:new(cd.nodePort or cmd.defaultPort,nil,name) c.node = node:new(cd.nodePort or cmd.defaultPort,nil,name)
if cd.managerHost then if cd.managerHost then
cd.managerPort = cd.managerPort or cmd.defaultManagerPort cd.managerPort = cd.managerPort or cmd.defaultManagerPort
c.node:registerWithManager(cd.managerHost,cd.managerPort) c.node:registerWithManager(cd.managerHost,cd.managerPort)
end end
end end
return c return c
end end
+34 -34
View File
@@ -1,35 +1,35 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
return function(self,data) return function(self,data)
local cmd,data = data:match("!(.-)!(.*)") local cmd,data = data:match("!(.-)!(.*)")
--print(">",cmd,data) --print(">",cmd,data)
if cmd == "PONG" then if cmd == "PONG" then
self:send("!PONG!") self:send("!PONG!")
elseif cmd == "CHANNEL" then elseif cmd == "CHANNEL" then
-- --
elseif cmd == "RETURNS" then elseif cmd == "RETURNS" then
local rets = bin.new(data):getBlock("t") local rets = bin.new(data):getBlock("t")
self.node.master.OnDataReturned:Fire(rets) self.node.master.OnDataReturned:Fire(rets)
end end
end end
+41 -41
View File
@@ -1,42 +1,42 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local cmds = { local cmds = {
defaultManagerPort = 0XDE2, defaultManagerPort = 0XDE2,
defaultWait = 0X002, defaultWait = 0X002,
defaultPort = 0X000, -- We will let the OS assign us one defaultPort = 0X000, -- We will let the OS assign us one
standardSkip = 0X018, standardSkip = 0X018,
ERROR = 0X000, ERROR = 0X000,
PING = 0X001, PING = 0X001,
PONG = 0X002, PONG = 0X002,
QUEUE = 0X003, QUEUE = 0X003,
TASK = 0X004, TASK = 0X004,
INITNODE = 0X005, INITNODE = 0X005,
INITMASTER = 0X006, INITMASTER = 0X006,
GLOBAL = 0X007, GLOBAL = 0X007,
LOAD = 0X008, LOAD = 0X008,
CALL = 0X009, CALL = 0X009,
REG = 0X00A, REG = 0X00A,
CONSOLE = 0X00B, CONSOLE = 0X00B,
} }
return cmds return cmds
+22 -22
View File
@@ -1,23 +1,23 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
+56 -56
View File
@@ -1,57 +1,57 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local net = require("net") local net = require("net")
--local bin = require("bin") --local bin = require("bin")
local char = string.char local char = string.char
local byte = string.byte local byte = string.byte
bin.setBitsInterface(infinabits) bin.setBitsInterface(infinabits)
--[[ --[[
--[=[ Pre reqs: --[=[ Pre reqs:
- Network contains nodes - Network contains nodes
- Network can broadcast/has nodemanager/ is simple and can be scanned - Network can broadcast/has nodemanager/ is simple and can be scanned
Outline: Outline:
- multi:newMasterNode(connectionDetails) - multi:newMasterNode(connectionDetails)
-- master:setDefaultNode(nodeName) -- Set default node -- 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: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:newNetworkChannel(nodeName)
-- master:sendTo(nodeName,data) -- master:sendTo(nodeName,data)
- multi:newNode(connectionDetails) - multi:newNode(connectionDetails)
- multi:newNodeManager(connectionDetails) -- This will be incharge of a lot of data handling - multi:newNodeManager(connectionDetails) -- This will be incharge of a lot of data handling
]=] ]=]
local nGLOBAL, nTHREAD = require("multi.integration.networkManager"):init() local nGLOBAL, nTHREAD = require("multi.integration.networkManager"):init()
local master = multi:newMasterNode() local master = multi:newMasterNode()
master:newNetworkThread("simpleNode",function(a,b,c) master:newNetworkThread("simpleNode",function(a,b,c)
print(a,b,c) print(a,b,c)
end,1,2,3) end,1,2,3)
]] ]]
-- The init file should provide the structure that all the other modules build off of -- The init file should provide the structure that all the other modules build off of
return { return {
init = function() init = function()
-- --
end end
} }
+162 -162
View File
@@ -1,163 +1,163 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local cmd = require("multi.integration.networkManager.cmds") local cmd = require("multi.integration.networkManager.cmds")
local node = require("multi.integration.networkManager.node") local node = require("multi.integration.networkManager.node")
local net = require("net") local net = require("net")
local bin = require("bin") local bin = require("bin")
local master = {} local master = {}
master.__index = master master.__index = master
function master:addNode(ip,port) function master:addNode(ip,port)
return node:new(ip,port) return node:new(ip,port)
end end
function master:getNodesFromBroadcast() function master:getNodesFromBroadcast()
net:newCastedClients("NODE_.+") net:newCastedClients("NODE_.+")
net.OnCastedClientInfo(function(client, n, ip, port) net.OnCastedClientInfo(function(client, n, ip, port)
self.nodes[n] = node:new(client) self.nodes[n] = node:new(client)
end) end)
end end
function master:getNodesFromManager(ip,port) function master:getNodesFromManager(ip,port)
local mn = self.nodes local mn = self.nodes
if not self.manager then if not self.manager then
self.manager = net:newTCPClient(ip,port) self.manager = net:newTCPClient(ip,port)
if not self.manager then if not self.manager then
error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!") error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!")
end end
end end
self.manager.OnDataRecieved(function(self,data,client) self.manager.OnDataRecieved(function(self,data,client)
local cmd = data:match("!(.+)!") local cmd = data:match("!(.+)!")
data = data:gsub("!"..cmd.."!","") data = data:gsub("!"..cmd.."!","")
if cmd == "NODE" then if cmd == "NODE" then
local n,h,p = data:match("(.-)|(.-)|(.+)") local n,h,p = data:match("(.-)|(.-)|(.+)")
mn[n] = node:new(h,tonumber(p)) mn[n] = node:new(h,tonumber(p))
end end
end) end)
self.manager:send("!NODES!") self.manager:send("!NODES!")
end end
function master:setDefaultNode(nodeName) function master:setDefaultNode(nodeName)
if self:nodeExists(nodeName) then if self:nodeExists(nodeName) then
self.defaultNode = nodeName self.defaultNode = nodeName
end end
end end
function master:getRandomNode() function master:getRandomNode()
local t = {} local t = {}
for i,v in pairs(self.nodes) do t[#t+1] = i end for i,v in pairs(self.nodes) do t[#t+1] = i end
return t[math.random(1,#t)] return t[math.random(1,#t)]
end end
local netID = 0 local netID = 0
function master:newNetworkThread(nodeName,func,...) function master:newNetworkThread(nodeName,func,...)
local args = {...} local args = {...}
local dat = bin.new() local dat = bin.new()
local ret local ret
local nID = netID local nID = netID
local conn = multi:newConnection() local conn = multi:newConnection()
thread:newthread(function() thread:newthread(function()
dat:addBlock{ dat:addBlock{
args = args, args = args,
func = func, func = func,
id = netID id = netID
} }
netID = netID + 1 netID = netID + 1
if type(nodeName) == "function" then if type(nodeName) == "function" then
func = nodeName func = nodeName
nodeName = self.defaultNode or self:getRandomNode() nodeName = self.defaultNode or self:getRandomNode()
if not func then if not func then
error("You must provide a function!") error("You must provide a function!")
end end
end end
self:sendTo(nodeName,"!N_THREAD!"..dat.data) self:sendTo(nodeName,"!N_THREAD!"..dat.data)
self.OnDataReturned(function(rets) self.OnDataReturned(function(rets)
if rets.ID == nID then if rets.ID == nID then
conn:Fire(unpack(rets.rets)) conn:Fire(unpack(rets.rets))
end end
end) end)
end) end)
return conn return conn
end end
function master:newNetworkChannel(nodeName) function master:newNetworkChannel(nodeName)
-- --
end end
function master:sendTo(nodeName,data) function master:sendTo(nodeName,data)
self:queue("send",nodeName,data) self:queue("send",nodeName,data)
end end
function master:demandNodeExistance(nodeName) function master:demandNodeExistance(nodeName)
if self.nodes[nodeName] then if self.nodes[nodeName] then
return multi.hold(self.nodes[nodeName]:ping().pong) return multi.hold(self.nodes[nodeName]:ping().pong)
else else
return false return false
end end
end end
function master:queue(c,...) function master:queue(c,...)
table.insert(self._queue,{c,{...}}) table.insert(self._queue,{c,{...}})
end end
function multi:newMasterNode(cd) function multi:newMasterNode(cd)
local c = {} local c = {}
setmetatable(c, master) setmetatable(c, master)
c.OnNodeDiscovered = multi:newConnection() c.OnNodeDiscovered = multi:newConnection()
c.OnNodeRemoved = multi:newConnection() c.OnNodeRemoved = multi:newConnection()
c.OnDataRecieved = multi:newConnection() c.OnDataRecieved = multi:newConnection()
c.OnDataReturned = multi:newConnection() c.OnDataReturned = multi:newConnection()
c.defaultNode = "" c.defaultNode = ""
c.nodes = {} c.nodes = {}
setmetatable(c.nodes, setmetatable(c.nodes,
{__newindex = function(t,k,v) {__newindex = function(t,k,v)
rawset(t,k,v) rawset(t,k,v)
v.master = c v.master = c
c.OnNodeDiscovered:Fire(k,v) c.OnNodeDiscovered:Fire(k,v)
end}) end})
c._queue = {} c._queue = {}
if cd then if cd then
if cd.nodeHost then if cd.nodeHost then
cd.nodePort = cd.nodePort or cmd.defaultPort cd.nodePort = cd.nodePort or cmd.defaultPort
local n,no = c:addNode(cd.nodeHost,cd.nodePort) local n,no = c:addNode(cd.nodeHost,cd.nodePort)
if n then if n then
c.nodes[n] = no c.nodes[n] = no
end end
elseif cd.managerHost then elseif cd.managerHost then
cd.managerPort = cd.managerPort or cmd.defaultManagerPort cd.managerPort = cd.managerPort or cmd.defaultManagerPort
c:getNodesFromManager(cd.managerHost,cd.managerPort) c:getNodesFromManager(cd.managerHost,cd.managerPort)
else else
c:getNodesFromBroadcast() c:getNodesFromBroadcast()
end end
else else
c:getNodesFromBroadcast() c:getNodesFromBroadcast()
end end
thread:newthread("CMDQueueProcessor",function() thread:newthread("CMDQueueProcessor",function()
while true do while true do
thread.skip(128) thread.skip(128)
local data = table.remove(c._queue,1) local data = table.remove(c._queue,1)
if data then if data then
local cmd = data[1] local cmd = data[1]
if cmd == "send" then if cmd == "send" then
local nodeName = data[2][1] local nodeName = data[2][1]
local dat = data[2][2] local dat = data[2][2]
c.nodes[nodeName]:send(dat) c.nodes[nodeName]:send(dat)
end end
end end
end end
end):OnError(function(...) end):OnError(function(...)
print(...) print(...)
end) end)
return c return c
end end
+126 -126
View File
@@ -1,127 +1,127 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local net = require("net") local net = require("net")
local cmd = require("multi.integration.networkManager.cmds") local cmd = require("multi.integration.networkManager.cmds")
local multi,thread = require("multi"):init() local multi,thread = require("multi"):init()
local node = {} local node = {}
node.__index = node node.__index = node
local rand = {} local rand = {}
for i = 65,90 do for i = 65,90 do
rand[#rand+1] = string.char(i) rand[#rand+1] = string.char(i)
end end
local function randName(n) local function randName(n)
local str = {} local str = {}
for i=1,(n or 10) do for i=1,(n or 10) do
str[#str+1] = rand[math.random(1,#rand)] str[#str+1] = rand[math.random(1,#rand)]
end end
return table.concat(str) return table.concat(str)
end end
local getNames = thread:newFunction(function(names) local getNames = thread:newFunction(function(names)
local listen = socket.udp() -- make a new socket local listen = socket.udp() -- make a new socket
listen:setsockname(net.getLocalIP(), 11111) listen:setsockname(net.getLocalIP(), 11111)
listen:settimeout(0) listen:settimeout(0)
local data, ip, port = listen:receivefrom() local data, ip, port = listen:receivefrom()
thread.holdWithin(1,function() thread.holdWithin(1,function()
if data then if data then
local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)") local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)")
if n then if n then
names[n]=true names[n]=true
end end
end end
end) end)
return multi.NIL return multi.NIL
end) end)
local function setName(ref,name) local function setName(ref,name)
if name then if name then
ref.name = "NODE_"..name ref.name = "NODE_"..name
ref.connection:broadcast(name) ref.connection:broadcast(name)
return return
end end
local names = {} local names = {}
getNames(names).wait() -- Prevents duplicate names from spawning! getNames(names).wait() -- Prevents duplicate names from spawning!
local name = randName() local name = randName()
while names["NODE_"..name] do while names["NODE_"..name] do
name = randName() name = randName()
end end
ref.name = "NODE_"..name ref.name = "NODE_"..name
ref.connection:broadcast(ref.name) ref.connection:broadcast(ref.name)
end end
node.ServerCode = require("multi.integration.networkManager.serverSide") node.ServerCode = require("multi.integration.networkManager.serverSide")
node.ClientCode = require("multi.integration.networkManager.clientSide") node.ClientCode = require("multi.integration.networkManager.clientSide")
function node.random() function node.random()
return randName(12) return randName(12)
end end
function node:registerWithManager(ip,port) function node:registerWithManager(ip,port)
if self.type ~= "server" then return end if self.type ~= "server" then return end
if not self.manager then if not self.manager then
self.manager = net:newTCPClient(ip,port) self.manager = net:newTCPClient(ip,port)
if not self.manager then if not self.manager then
error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!") error("Unable to connect to the node Manager! Is it running? Perhaps the hostname or port is incorrect!")
end end
end end
thread:newFunction(function() thread:newFunction(function()
thread.hold(function() return self.name end) thread.hold(function() return self.name end)
self.manager:send("!REG_NODE!"..self.name.."|"..net.getLocalIP().."|"..self.connection.port) self.manager:send("!REG_NODE!"..self.name.."|"..net.getLocalIP().."|"..self.connection.port)
end)() end)()
end end
function node:new(host,port,name) function node:new(host,port,name)
local c = {} local c = {}
c.links = {} c.links = {}
setmetatable(c,node) setmetatable(c,node)
if type(host)=="number" or type(host)=="nil" then if type(host)=="number" or type(host)=="nil" then
c.connection = net:newTCPServer(host or cmd.defaultPort) c.connection = net:newTCPServer(host or cmd.defaultPort)
c.connection:enableBinaryMode() c.connection:enableBinaryMode()
c.type = "server" c.type = "server"
c.connection.node = c c.connection.node = c
c.connection.OnDataRecieved(self.ServerCode) c.connection.OnDataRecieved(self.ServerCode)
setName(c) setName(c)
elseif type(host)=="table" and host.Type == "tcp" then elseif type(host)=="table" and host.Type == "tcp" then
c.connection = host c.connection = host
c.connection:enableBinaryMode() c.connection:enableBinaryMode()
c.type = "client" c.type = "client"
c.connection.node = c c.connection.node = c
c.connection.OnDataRecieved(self.ClientCode) c.connection.OnDataRecieved(self.ClientCode)
c.name = "MASTER_NODE" c.name = "MASTER_NODE"
elseif type(host) == "string" and type(port)=="number" then elseif type(host) == "string" and type(port)=="number" then
c.connection = net:newTCPClient(host, port) c.connection = net:newTCPClient(host, port)
c.connection:enableBinaryMode() c.connection:enableBinaryMode()
c.type = "client" c.type = "client"
c.connection.node = c c.connection.node = c
c.connection.OnDataRecieved(self.ClientCode) c.connection.OnDataRecieved(self.ClientCode)
c.name = "MASTER_NODE" c.name = "MASTER_NODE"
else else
error("Invalid arguments!") error("Invalid arguments!")
end end
return c return c
end end
function node:ping() function node:ping()
if self.type ~= "client" then return end if self.type ~= "client" then return end
self:send("!PING!") self:send("!PING!")
return {pong=self.connection.OnDataRecieved} return {pong=self.connection.OnDataRecieved}
end end
function node:send(data) function node:send(data)
if self.type ~= "client" then return end if self.type ~= "client" then return end
self.connection:send(data) self.connection:send(data)
end end
return node return node
+47 -47
View File
@@ -1,48 +1,48 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local cmd = require("multi.integration.networkManager.cmds") local cmd = require("multi.integration.networkManager.cmds")
local net = require("net") local net = require("net")
local bin = require("bin") local bin = require("bin")
local nodes = { -- Testing stuff local nodes = { -- Testing stuff
} }
function multi:newNodeManager(port) function multi:newNodeManager(port)
print("Running node manager on port: "..(port or cmd.defaultManagerPort)) print("Running node manager on port: "..(port or cmd.defaultManagerPort))
local server = net:newTCPServer(port or cmd.defaultManagerPort) local server = net:newTCPServer(port or cmd.defaultManagerPort)
server.OnDataRecieved(function(serv, data, client) server.OnDataRecieved(function(serv, data, client)
local cmd = data:match("!(.+)!") local cmd = data:match("!(.+)!")
data = data:gsub("!"..cmd.."!","") data = data:gsub("!"..cmd.."!","")
if cmd == "NODES" then if cmd == "NODES" then
for i,v in ipairs(nodes) do for i,v in ipairs(nodes) do
-- Sample data -- Sample data
serv:send(client, "!NODE!".. v[1].."|"..v[2].."|"..v[3]) serv:send(client, "!NODE!".. v[1].."|"..v[2].."|"..v[3])
end end
elseif cmd == "REG_NODE" then elseif cmd == "REG_NODE" then
local name, ip, port = data:match("(.-)|(.-)|(.+)") local name, ip, port = data:match("(.-)|(.-)|(.+)")
table.insert(nodes,{name,ip,port}) table.insert(nodes,{name,ip,port})
print("Registering Node:",name, ip, port) print("Registering Node:",name, ip, port)
end end
end) end)
end end
+46 -46
View File
@@ -1,47 +1,47 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local bin, bits = require("bin").init() local bin, bits = require("bin").init()
return function(self,data,client) return function(self,data,client)
local cmd,data = data:match("!(.-)!(.*)") local cmd,data = data:match("!(.-)!(.*)")
--print("SERVER",cmd,data) --print("SERVER",cmd,data)
if cmd == "PING" then if cmd == "PING" then
self:send(client,"!PONG!") self:send(client,"!PONG!")
elseif cmd == "N_THREAD" then elseif cmd == "N_THREAD" then
print(1) print(1)
local dat = bin.new(data) local dat = bin.new(data)
print(2) print(2)
local t = dat:getBlock("t") local t = dat:getBlock("t")
print(3) print(3)
local ret = bin.new() local ret = bin.new()
print(4) print(4)
ret:addBlock{ID = t.id,rets = {t.func(unpack(t.args))}} ret:addBlock{ID = t.id,rets = {t.func(unpack(t.args))}}
print(5) print(5)
print(client,"!RETURNS!"..ret:getData()) print(client,"!RETURNS!"..ret:getData())
self:send(client,"!RETURNS!"..ret:getData()) self:send(client,"!RETURNS!"..ret:getData())
print(6) print(6)
elseif cmd == "CHANNEL" then elseif cmd == "CHANNEL" then
local dat = bin.new(data):getBlock("t") local dat = bin.new(data):getBlock("t")
end end
end end
+22 -22
View File
@@ -1,23 +1,23 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
+26 -26
View File
@@ -1,27 +1,27 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local bin = require("bin") local bin = require("bin")
local utils = {} local utils = {}
-- Will contain data that handles sterilizing and managing data -- Will contain data that handles sterilizing and managing data
return utils return utils
+212 -212
View File
@@ -1,213 +1,213 @@
-- Advanced process management. Mutates the multi namespace -- Advanced process management. Mutates the multi namespace
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local ok, chronos = pcall(require, "chronos") -- hpc local ok, chronos = pcall(require, "chronos") -- hpc
if not ok then chronos = nil end if not ok then chronos = nil end
-- This is an integration, we cannot directly access locals that are in the main file. -- This is an integration, we cannot directly access locals that are in the main file.
local PList = { local PList = {
multi.Priority_Core, multi.Priority_Core,
multi.Priority_Very_High, multi.Priority_Very_High,
multi.Priority_High, multi.Priority_High,
multi.Priority_Above_Normal, multi.Priority_Above_Normal,
multi.Priority_Normal, multi.Priority_Normal,
multi.Priority_Below_Normal, multi.Priority_Below_Normal,
multi.Priority_Low, multi.Priority_Low,
multi.Priority_Very_Low, multi.Priority_Very_Low,
multi.Priority_Idle multi.Priority_Idle
} }
-- Restructered these functions since they rely on local variables from the core library -- Restructered these functions since they rely on local variables from the core library
local mainloop = multi.mainloopRef local mainloop = multi.mainloopRef
local mainloop_p = multi.mainloop_p local mainloop_p = multi.mainloop_p
local uManagerRef = multi.uManagerRef local uManagerRef = multi.uManagerRef
local uManagerRefP = multi.uManagerRefP1 local uManagerRefP = multi.uManagerRefP1
local PROFILE_COUNT = 5 local PROFILE_COUNT = 5
-- self:setCurrentProcess() a bit slower than using the local var, but there isn't another option -- self:setCurrentProcess() a bit slower than using the local var, but there isn't another option
local priorityManager = multi:newProcessor("Priority Manager", true) local priorityManager = multi:newProcessor("Priority Manager", true)
priorityManager.newThread = function() multi.warn("You cannot spawn threads on the priority manager!") end 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 priorityManager.setPriorityScheme = function() multi.warn("You cannot set priority on the priorityManager!") end
local function average(t) local function average(t)
local sum = 0 local sum = 0
for _,v in pairs(t) do for _,v in pairs(t) do
sum = sum + v sum = sum + v
end end
return sum / #t return sum / #t
end end
local function getPriority(obj) local function getPriority(obj)
local avg = average(obj.__profiling) local avg = average(obj.__profiling)
if avg < 0.0002 then if avg < 0.0002 then
return PList[1] return PList[1]
elseif avg < 0.0004 then elseif avg < 0.0004 then
return PList[2] return PList[2]
elseif avg < 0.0008 then elseif avg < 0.0008 then
return PList[3] return PList[3]
elseif avg < 0.001 then elseif avg < 0.001 then
return PList[4] return PList[4]
elseif avg < 0.0025 then elseif avg < 0.0025 then
return PList[5] return PList[5]
elseif avg < 0.005 then elseif avg < 0.005 then
return PList[6] return PList[6]
elseif avg < 0.008 then elseif avg < 0.008 then
return PList[7] return PList[7]
elseif avg < 0.01 then elseif avg < 0.01 then
return PList[8] return PList[8]
else else
return PList[9] return PList[9]
end end
end end
local start, stop local start, stop
priorityManager.uManager = function(self) priorityManager.uManager = function(self)
-- proc.run already checks if the processor is active -- proc.run already checks if the processor is active
self:setCurrentProcess() self:setCurrentProcess()
local Loop=self.Mainloop local Loop=self.Mainloop
local ctask local ctask
for _D=#Loop,1,-1 do for _D=#Loop,1,-1 do
ctask = Loop[_D] ctask = Loop[_D]
ctask:setCurrentTask() ctask:setCurrentTask()
start = chronos.nanotime() start = chronos.nanotime()
if ctask:Act() then if ctask:Act() then
stop = chronos.nanotime() stop = chronos.nanotime()
if ctask.__profiling then if ctask.__profiling then
table.insert(ctask.__profiling, stop - start) table.insert(ctask.__profiling, stop - start)
end end
if ctask.__profiling and #ctask.__profiling == PROFILE_COUNT then if ctask.__profiling and #ctask.__profiling == PROFILE_COUNT then
ctask:setPriority(getPriority(ctask)) ctask:setPriority(getPriority(ctask))
ctask:reallocate(ctask.__restoreProc) ctask:reallocate(ctask.__restoreProc)
ctask.__restoreProc = nil ctask.__restoreProc = nil
ctask.__profiling = nil ctask.__profiling = nil
end end
end end
self:setCurrentProcess() self:setCurrentProcess()
end end
end end
local function processHook(obj, proc) local function processHook(obj, proc)
if obj.Type == multi.registerType("process", "processes") or not(obj.IsAnActor) then return end if obj.Type == multi.registerType("process", "processes") or not(obj.IsAnActor) then return end
obj.__restoreProc = proc obj.__restoreProc = proc
obj.__profiling = {} obj.__profiling = {}
obj:reallocate(priorityManager) obj:reallocate(priorityManager)
end end
local function init() local function init()
local registry = {} local registry = {}
multi.priorityScheme = { multi.priorityScheme = {
RoundRobin = "RoundRobin", RoundRobin = "RoundRobin",
PriorityBased = "PriorityBased", PriorityBased = "PriorityBased",
TimeBased = "TimeBased" TimeBased = "TimeBased"
} }
function multi:setProfilerCount(count) function multi:setProfilerCount(count)
PROFILE_COUNT = count PROFILE_COUNT = count
end end
function multi:recalibrate() function multi:recalibrate()
if self.__processConn then if self.__processConn then
local items = self.Mainloop local items = self.Mainloop
for i,v in pairs(items) do for i,v in pairs(items) do
processHook(v, self) processHook(v, self)
end end
else else
multi.error("Cannot recalibrate the priority if not using Time based mangement!") multi.error("Cannot recalibrate the priority if not using Time based mangement!")
end end
end end
function multi:isRegistredScheme(scheme) function multi:isRegistredScheme(scheme)
return registry[name] ~= nil return registry[name] ~= nil
end end
function multi:getRegisteredScheme(scheme) function multi:getRegisteredScheme(scheme)
return registry[name].mainloop, registry[name].umanager, registry[name].condition return registry[name].mainloop, registry[name].umanager, registry[name].condition
end end
local empty_func = function() return true end local empty_func = function() return true end
function multi:registerScheme(name,options) function multi:registerScheme(name,options)
local mainloop = options.mainloop or multi.error("You must provide a mainloop option when registring a scheme!") 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!") local umanager = options.umanager or multi.error("You must provide a umanager option when registring a scheme!")
if not options.condition then 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!") multi.warn("You might want to use condition when registring a scheme! A function that returns true has been auto generated for you!")
end end
local condition = options.condition or empty_func local condition = options.condition or empty_func
if registry[name] and not registry[name].static then if registry[name] and not registry[name].static then
multi.warn("A scheme named: \"" .. name .. "\" has already been registred, overriting!") multi.warn("A scheme named: \"" .. name .. "\" has already been registred, overriting!")
else else
multi.error("A scheme named: \"" .. name .. "\" has already been registred!") multi.error("A scheme named: \"" .. name .. "\" has already been registred!")
end end
registry[name] = { registry[name] = {
mainloop = mainloop, mainloop = mainloop,
umanager = umanger, umanager = umanger,
condition = condition, condition = condition,
static = options.static or false static = options.static or false
} }
multi.priorityScheme[name] = name multi.priorityScheme[name] = name
return true return true
end end
function multi:setPriorityScheme(scheme) function multi:setPriorityScheme(scheme)
if not self.Type == multi.registerType("process", "processes") or not self.Type == multi.registerType("rootprocess") then 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!") multi.warn("You should only invoke setPriorityScheme on a processor object!")
end end
if scheme == multi.priorityScheme.RoundRobin then if scheme == multi.priorityScheme.RoundRobin then
if self.__processConn then self.OnObjectCreated:Unconnect(self.__processConn) self.__processConn = nil end if self.__processConn then self.OnObjectCreated:Unconnect(self.__processConn) self.__processConn = nil end
self.mainloop = mainloop self.mainloop = mainloop
self.uManager = uManagerRef self.uManager = uManagerRef
elseif scheme == multi.priorityScheme.PriorityBased then elseif scheme == multi.priorityScheme.PriorityBased then
if self.__processConn then self.OnObjectCreated:Unconnect(self.__processConn) self.__processConn = nil end if self.__processConn then self.OnObjectCreated:Unconnect(self.__processConn) self.__processConn = nil end
self.mainloop = mainloop_p self.mainloop = mainloop_p
self.uManager = uManagerRefP self.uManager = uManagerRefP
elseif scheme == multi.priorityScheme.TimeBased then elseif scheme == multi.priorityScheme.TimeBased then
if not chronos then return multi.warn("Unable to use TimeBased Priority without the chronos library!") end 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 if self.__processConn then multi.warn("Already enabled TimeBased Priority!") end
self.__processConn = self.OnObjectCreated(processHook) self.__processConn = self.OnObjectCreated(processHook)
self.mainloop = mainloop_p self.mainloop = mainloop_p
self.uManager = uManagerRefP self.uManager = uManagerRefP
elseif self:isRegistredScheme(scheme) then elseif self:isRegistredScheme(scheme) then
local mainloop, umanager, condition = self:getRegisteredScheme(scheme) local mainloop, umanager, condition = self:getRegisteredScheme(scheme)
if condition() then if condition() then
self.mainloop = mainloop self.mainloop = mainloop
self.uManager = umanager self.uManager = umanager
end end
else else
self.error("Invalid priority scheme selected!") self.error("Invalid priority scheme selected!")
end end
end end
end end
local function init_chronos() local function init_chronos()
-- Let's implement a higher precision clock -- Let's implement a higher precision clock
multi.setClock(chronos.nanotime) -- This is also in .000 format. So a plug and play works. multi.setClock(chronos.nanotime) -- This is also in .000 format. So a plug and play works.
thread:newThread("System Priority Manager", function() thread:newThread("System Priority Manager", function()
while true do while true do
thread.yield() thread.yield()
priorityManager.run() priorityManager.run()
end end
end) end)
end end
if chronos then if chronos then
init_chronos() init_chronos()
else else
multi.warn("In order to have time based priority management, you need to install the chronos library!") multi.warn("In order to have time based priority management, you need to install the chronos library!")
end end
init() init()
+220 -220
View File
@@ -1,221 +1,221 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local GLOBAL, THREAD = multi.integration.GLOBAL, multi.integration.THREAD local GLOBAL, THREAD = multi.integration.GLOBAL, multi.integration.THREAD
local function stripUpValues(func) local function stripUpValues(func)
local dmp = string.dump(func) local dmp = string.dump(func)
if setfenv then if setfenv then
return loadstring(dmp,"IsolatedThread_PesudoThreading") return loadstring(dmp,"IsolatedThread_PesudoThreading")
else else
return load(dmp,"IsolatedThread_PesudoThreading","bt") return load(dmp,"IsolatedThread_PesudoThreading","bt")
end end
end end
function multi:newSystemThreadedQueue(name) function multi:newSystemThreadedQueue(name)
local c = {} local c = {}
c.data = {} c.data = {}
c.Type = multi.registerType("s_queue") c.Type = multi.registerType("s_queue")
function c:push(v) function c:push(v)
table.insert(self.data,v) table.insert(self.data,v)
end end
function c:pop() function c:pop()
return table.remove(self.data,1) return table.remove(self.data,1)
end end
function c:peek() function c:peek()
return self.data[1] return self.data[1]
end end
function c:init() function c:init()
return self return self
end end
function c:Hold(opt) function c:Hold(opt)
if opt.peek then if opt.peek then
return thread.hold(function() return thread.hold(function()
return self:peek() return self:peek()
end) end)
else else
return thread.hold(function() return thread.hold(function()
return self:pop() return self:pop()
end) end)
end end
end end
GLOBAL[name or "_"] = c GLOBAL[name or "_"] = c
return c return c
end end
function multi:newSystemThreadedTable(name) function multi:newSystemThreadedTable(name)
local c = {} local c = {}
c.Type = multi.registerType("s_table") c.Type = multi.registerType("s_table")
function c:init() function c:init()
return self return self
end end
function c:Hold(opt) function c:Hold(opt)
if opt.key then if opt.key then
return thread.hold(function() return thread.hold(function()
return self.tab[opt.key] return self.tab[opt.key]
end) end)
else else
multi.error("Must provide a key to check opt.key = 'key'") multi.error("Must provide a key to check opt.key = 'key'")
end end
end end
GLOBAL[name or "_"] = c GLOBAL[name or "_"] = c
return c return c
end end
local setfenv = multi.isolateFunction local setfenv = multi.isolateFunction
local jqc = 1 local jqc = 1
function multi:newSystemThreadedJobQueue(n) function multi:newSystemThreadedJobQueue(n)
local c = {} local c = {}
c.cores = n or THREAD.getCores() c.cores = n or THREAD.getCores()
c.registerQueue = {} c.registerQueue = {}
c.Type = multi.registerType("s_jobqueue") c.Type = multi.registerType("s_jobqueue")
c.funcs = multi:newSystemThreadedTable("__JobQueue_"..jqc.."_table") c.funcs = multi:newSystemThreadedTable("__JobQueue_"..jqc.."_table")
c.queue = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queue") c.queue = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queue")
c.queueReturn = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueReturn") c.queueReturn = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueReturn")
c.queueAll = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueAll") c.queueAll = multi:newSystemThreadedQueue("__JobQueue_"..jqc.."_queueAll")
c.id = 0 c.id = 0
c.OnJobCompleted = multi:newConnection() c.OnJobCompleted = multi:newConnection()
local allfunc = 0 local allfunc = 0
function c:doToAll(func) function c:doToAll(func)
for i = 1, self.cores do for i = 1, self.cores do
self.queueAll:push({allfunc, func}) self.queueAll:push({allfunc, func})
end end
allfunc = allfunc + 1 allfunc = allfunc + 1
end end
function c:registerFunction(name, func) function c:registerFunction(name, func)
if self.funcs[name] then if self.funcs[name] then
multi.error("A function by the name "..name.." has already been registered!") multi.error("A function by the name "..name.." has already been registered!")
end end
self.funcs[name] = func self.funcs[name] = func
end end
function c:pushJob(name,...) function c:pushJob(name,...)
self.id = self.id + 1 self.id = self.id + 1
self.queue:push{name,self.id,...} self.queue:push{name,self.id,...}
return self.id return self.id
end end
function c:isEmpty() function c:isEmpty()
return queueJob:peek()==nil return queueJob:peek()==nil
end end
local nFunc = 0 local nFunc = 0
function c:newFunction(name,func,holup) -- This registers with the queue function c:newFunction(name,func,holup) -- This registers with the queue
if type(name)=="function" then if type(name)=="function" then
holup = func holup = func
func = name func = name
name = "JQ_Function_"..nFunc name = "JQ_Function_"..nFunc
end end
nFunc = nFunc + 1 nFunc = nFunc + 1
c:registerFunction(name,func) c:registerFunction(name,func)
return thread:newFunction(function(...) return thread:newFunction(function(...)
local id = c:pushJob(name,...) local id = c:pushJob(name,...)
local link local link
local rets local rets
link = c.OnJobCompleted(function(jid,...) link = c.OnJobCompleted(function(jid,...)
if id==jid then if id==jid then
rets = multi.pack(...) rets = multi.pack(...)
end end
end) end)
return thread.hold(function() return thread.hold(function()
if rets then if rets then
return multi.unpack(rets) or multi.NIL return multi.unpack(rets) or multi.NIL
end end
end) end)
end,holup),name end,holup),name
end end
thread:newThread("jobManager",function() thread:newThread("jobManager",function()
while true do while true do
thread.yield() thread.yield()
local dat = c.queueReturn:pop() local dat = c.queueReturn:pop()
if dat then if dat then
c.OnJobCompleted:Fire(multi.unpack(dat)) c.OnJobCompleted:Fire(multi.unpack(dat))
end end
end end
end) end)
for i=1,c.cores do for i=1,c.cores do
multi:newSystemThread("STJQ_"..multi.randomString(8),function(jqc) multi:newSystemThread("STJQ_"..multi.randomString(8),function(jqc)
local GLOBAL, THREAD = require("multi.integration.pseudoManager"):init() local GLOBAL, THREAD = require("multi.integration.pseudoManager"):init()
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local clock = os.clock local clock = os.clock
local funcs = THREAD.waitFor("__JobQueue_"..jqc.."_table") local funcs = THREAD.waitFor("__JobQueue_"..jqc.."_table")
local queue = THREAD.waitFor("__JobQueue_"..jqc.."_queue") local queue = THREAD.waitFor("__JobQueue_"..jqc.."_queue")
local queueReturn = THREAD.waitFor("__JobQueue_"..jqc.."_queueReturn") local queueReturn = THREAD.waitFor("__JobQueue_"..jqc.."_queueReturn")
local queueAll = THREAD.waitFor("__JobQueue_"..jqc.."_queueAll") local queueAll = THREAD.waitFor("__JobQueue_"..jqc.."_queueAll")
local registry = {} local registry = {}
_G["__QR"] = queueReturn _G["__QR"] = queueReturn
setmetatable(_G,{__index = funcs}) setmetatable(_G,{__index = funcs})
thread:newThread("startUp",function() thread:newThread("startUp",function()
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
if all and not registry[all[1]] then if all and not registry[all[1]] then
queueAll:pop()[2]() queueAll:pop()[2]()
end end
end end
end) end)
thread:newThread("runner",function() thread:newThread("runner",function()
thread.sleep(.1) thread.sleep(.1)
while true do while true do
thread.yield() thread.yield()
local all = queueAll:peek() local all = queueAll:peek()
if all and not registry[all[1]] then if all and not registry[all[1]] then
queueAll:pop()[2]() queueAll:pop()[2]()
end end
local dat = thread.hold(queue) local dat = thread.hold(queue)
if dat then if dat then
multi:newThread("JobSubRunner",function() multi:newThread("JobSubRunner",function()
local name = table.remove(dat,1) local name = table.remove(dat,1)
local id = table.remove(dat,1) local id = table.remove(dat,1)
local tab = {multi.isolateFunction(funcs[name],_G)(multi.unpack(dat))} local tab = {multi.isolateFunction(funcs[name],_G)(multi.unpack(dat))}
table.insert(tab,1,id) table.insert(tab,1,id)
queueReturn:push(tab) queueReturn:push(tab)
end) end)
end end
end end
end) end)
multi:mainloop() multi:mainloop()
end, jqc) end, jqc)
end end
function c:Hold(opt) function c:Hold(opt)
return thread.hold(self.OnJobCompleted) return thread.hold(self.OnJobCompleted)
end end
jqc = jqc + 1 jqc = jqc + 1
self:create(c) self:create(c)
return c return c
end end
function multi:newSystemThreadedConnection(name) function multi:newSystemThreadedConnection(name)
local conn = multi:newConnection() local conn = multi:newConnection()
conn.init = function(self) return self end conn.init = function(self) return self end
GLOBAL[name or "_"] = conn GLOBAL[name or "_"] = conn
return conn return conn
end end
require("multi.integration.sharedExtensions") require("multi.integration.sharedExtensions")
+123 -121
View File
@@ -1,121 +1,123 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2020 Ryan Ward Copyright (c) 2020 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
package.path = "?/init.lua;?.lua;" .. package.path package.path = "?/init.lua;?.lua;" .. package.path
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local pseudoProcessor = multi:newProcessor()
if multi.integration then local pseudoProcessor = multi:newProcessor()
return {
init = function() if multi.integration then
return multi.integration.GLOBAL, multi.integration.THREAD return {
end init = function()
} return multi.integration.GLOBAL, multi.integration.THREAD
end end
multi.isMainThread = true }
local activator = require("multi.integration.pseudoManager.threads") end
local GLOBAL, THREAD = activator.init(thread) multi.isMainThread = true
local activator = require("multi.integration.pseudoManager.threads")
_G.THREAD_NAME = "MAIN_THREAD" local GLOBAL, THREAD = activator.init(thread)
_G.THREAD_ID = 0
_G.THREAD_NAME = "MAIN_THREAD"
function multi:canSystemThread() -- We are emulating system threading _G.THREAD_ID = 0
return true
end function multi:canSystemThread() -- We are emulating system threading
return true
function multi:getPlatform() end
return "pesudo"
end function multi:getPlatform()
return "pesudo"
local function split(str) end
local tab = {}
for word in string.gmatch(str, '([^,]+)') do local function split(str)
table.insert(tab,word) local tab = {}
end for word in string.gmatch(str, '([^,]+)') do
return tab table.insert(tab,word)
end end
return tab
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]] end
tab = split(tab)
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]]
local id = 0 tab = split(tab)
function multi:newSystemThread(name, func, ...) local id = 0
local env
env = { function multi:newSystemThread(name, func, ...)
GLOBAL = GLOBAL, local env
THREAD = THREAD, env = {
THREAD_NAME = tostring(name), GLOBAL = GLOBAL,
__THREADNAME__ = tostring(name), THREAD = THREAD,
THREAD_ID = id, THREAD_NAME = tostring(name),
thread = thread, __THREADNAME__ = tostring(name),
multi = multi, 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 for i, v in pairs(_G) do
else if not(env[i]) and not(i == "_G") and not(i == "local_global") then
multi.warn("skipping:",i) env[i] = v
end else
end multi.warn("skipping:",i)
end
if GLOBAL["__env"] then end
for i,v in pairs(GLOBAL["__env"]) do
env[i] = v if GLOBAL["__env"] then
end for i,v in pairs(GLOBAL["__env"]) do
end env[i] = v
end
env._G = env end
local GLOBAL, THREAD = activator.init(thread, env) env._G = env
local th = pseudoProcessor:newISOThread(name, func, env, ...) local GLOBAL, THREAD = activator.init(thread, env)
th.Type = multi.registerType("s_thread", "pseudoThreads")
th.OnError(multi.error) local th = pseudoProcessor:newISOThread(name, func, env, ...)
th.Type = multi.registerType("s_thread", "pseudoThreads")
id = id + 1 th.OnError(multi.error)
return th id = id + 1
end
return th
THREAD.newSystemThread = multi.newSystemThread end
-- 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 THREAD.newSystemThread = multi.newSystemThread
-- System threads as implemented here cannot share memory, but use a message passing system.
function THREAD:newFunction(func,holdme) -- 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
return thread:newFunctionBase(function(...)
return multi:newSystemThread("TempSystemThread",func,...) function THREAD:newFunction(func,holdme)
end, holdme, multi.registerType("s_function", "pseudoFunctions"))() return thread:newFunctionBase(function(...)
end return multi:newSystemThread("TempSystemThread",func,...)
end, holdme, multi.registerType("s_function", "pseudoFunctions"))()
multi.print("Integrated Pesudo Threading!") end
multi.integration = {} -- for module creators
multi.integration.GLOBAL = GLOBAL multi.print("Integrated Pesudo Threading!")
multi.integration.THREAD = THREAD multi.integration = {} -- for module creators
require("multi.integration.pseudoManager.extensions") multi.integration.GLOBAL = GLOBAL
require("multi.integration.sharedExtensions") multi.integration.THREAD = THREAD
return { require("multi.integration.pseudoManager.extensions")
init = function() require("multi.integration.sharedExtensions")
return GLOBAL, THREAD return {
end init = function()
} return GLOBAL, THREAD
end
}
+121 -121
View File
@@ -1,122 +1,122 @@
--[[ --[[
MIT License MIT License
Copyright (c) 2022 Ryan Ward Copyright (c) 2022 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local function getOS() local function getOS()
if package.config:sub(1, 1) == "\\" then if package.config:sub(1, 1) == "\\" then
return "windows" return "windows"
else else
return "unix" return "unix"
end end
end end
local function INIT(thread) local function INIT(thread)
local THREAD = {} local THREAD = {}
local GLOBAL = {} local GLOBAL = {}
THREAD.Priority_Core = 3 THREAD.Priority_Core = 3
THREAD.Priority_High = 2 THREAD.Priority_High = 2
THREAD.Priority_Above_Normal = 1 THREAD.Priority_Above_Normal = 1
THREAD.Priority_Normal = 0 THREAD.Priority_Normal = 0
THREAD.Priority_Below_Normal = -1 THREAD.Priority_Below_Normal = -1
THREAD.Priority_Low = -2 THREAD.Priority_Low = -2
THREAD.Priority_Idle = -3 THREAD.Priority_Idle = -3
function THREAD.set(name, val) function THREAD.set(name, val)
GLOBAL[name] = val GLOBAL[name] = val
end end
function THREAD.get(name) function THREAD.get(name)
return GLOBAL[name] return GLOBAL[name]
end end
function THREAD.waitFor(name) function THREAD.waitFor(name)
return thread.hold(function() return GLOBAL[name] end) return thread.hold(function() return GLOBAL[name] end)
end end
if getOS() == "windows" then if getOS() == "windows" then
THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS")) THREAD.__CORES = tonumber(os.getenv("NUMBER_OF_PROCESSORS"))
else else
THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n")) THREAD.__CORES = tonumber(io.popen("nproc --all"):read("*n"))
end end
function THREAD.getCores() function THREAD.getCores()
return THREAD.__CORES return THREAD.__CORES
end end
function THREAD.getConsole() function THREAD.getConsole()
local c = {} local c = {}
function c.print(...) function c.print(...)
print(...) print(...)
end end
function c.error(err) function c.error(err)
error("ERROR in <"..GLOBAL["$__THREADNAME__"]..">: "..err) error("ERROR in <"..GLOBAL["$__THREADNAME__"]..">: "..err)
end end
return c return c
end end
function THREAD.getThreads() function THREAD.getThreads()
return {}--GLOBAL.__THREADS__ return {}--GLOBAL.__THREADS__
end end
THREAD.pushStatus = thread.pushStatus THREAD.pushStatus = thread.pushStatus
function THREAD.kill() function THREAD.kill()
error("Thread was killed!") error("Thread was killed!")
end end
THREAD.sleep = thread.sleep THREAD.sleep = thread.sleep
THREAD.hold = thread.hold THREAD.hold = thread.hold
THREAD.defer = thread.defer THREAD.defer = thread.defer
function THREAD.setENV(env, name) function THREAD.setENV(env, name)
name = name or "__env" name = name or "__env"
GLOBAL[name] = env GLOBAL[name] = env
end end
function THREAD.getENV(name) function THREAD.getENV(name)
name = name or "__env" name = name or "__env"
return GLOBAL[name] return GLOBAL[name]
end end
function THREAD.exposeENV(name) function THREAD.exposeENV(name)
name = name or "__env" name = name or "__env"
local env = THREAD.getENV(name) local env = THREAD.getENV(name)
for i,v in pairs(env) do for i,v in pairs(env) do
-- This may need to be reworked! -- This may need to be reworked!
local_global[i] = v local_global[i] = v
end end
end end
function THREAD.sync() function THREAD.sync()
thread.sleep(.5) thread.sleep(.5)
end end
return GLOBAL, THREAD return GLOBAL, THREAD
end end
return {init = function(thread, global) return {init = function(thread, global)
return INIT(thread, global) return INIT(thread, global)
end} end}
+336 -336
View File
@@ -1,336 +1,336 @@
--[[ todo finish the targeted job! --[[ todo finish the targeted job!
MIT License MIT License
Copyright (c) 2023 Ryan Ward Copyright (c) 2023 Ryan Ward
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 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 copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
]] ]]
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
-- Returns a handler that allows a user to interact with an object on another thread! -- 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 -- Create on the thread that you want to interact with, send over the handle
function multi:chop(obj) function multi:chop(obj)
if not _G["UIDS"] then if not _G["UIDS"] then
_G["UIDS"] = {} _G["UIDS"] = {}
end end
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local list = {[0] = multi.randomString(12)} local list = {[0] = multi.randomString(12)}
_G[list[0]] = obj _G[list[0]] = obj
for i,v in pairs(obj) do for i,v in pairs(obj) do
if type(v) == "function" or type(v) == "table" and v.Type == multi.registerType("s_function") then if type(v) == "function" or type(v) == "table" and v.Type == multi.registerType("s_function") then
table.insert(list, i) table.insert(list, i)
elseif type(v) == "table" and v.Type == multi.registerType("connector", "connections") then elseif type(v) == "table" and v.Type == multi.registerType("connector", "connections") then
table.insert(list, {i, multi:newProxy(multi:chop(v)):init()}) table.insert(list, {i, multi:newProxy(multi:chop(v)):init()})
end end
end end
return list return list
end end
function multi:newProxy(list) function multi:newProxy(list)
local c = {} local c = {}
c.name = multi.randomString(12) c.name = multi.randomString(12)
c.is_init = false c.is_init = false
local multi, thread = nil, nil local multi, thread = nil, nil
function c:init() function c:init()
local multi, thread = nil, nil local multi, thread = nil, nil
local function copy(obj) local function copy(obj)
if type(obj) ~= 'table' then return obj end if type(obj) ~= 'table' then return obj end
local res = {} local res = {}
for k, v in pairs(obj) do res[copy(k)] = copy(v) end for k, v in pairs(obj) do res[copy(k)] = copy(v) end
return res return res
end end
if not(self.is_init) then if not(self.is_init) then
THREAD.sync() THREAD.sync()
self.is_init = true self.is_init = true
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
self.proxy_link = "PL" .. multi.randomString(12) self.proxy_link = "PL" .. multi.randomString(12)
if multi.integration then if multi.integration then
GLOBAL = multi.integration.GLOBAL GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD THREAD = multi.integration.THREAD
end end
GLOBAL[self.proxy_link] = self GLOBAL[self.proxy_link] = self
local function check() local function check()
return self.send:pop() return self.send:pop()
end end
self.send = multi:newSystemThreadedQueue(self.name.."_S"):init() self.send = multi:newSystemThreadedQueue(self.name.."_S"):init()
self.recv = multi:newSystemThreadedQueue(self.name.."_R"):init() self.recv = multi:newSystemThreadedQueue(self.name.."_R"):init()
self.funcs = list self.funcs = list
self._funcs = copy(list) self._funcs = copy(list)
self.Type = multi.registerType("proxy", "proxies") self.Type = multi.registerType("proxy", "proxies")
self.TID = THREAD_ID self.TID = THREAD_ID
thread:newThread("Proxy_Handler_" .. multi.randomString(4), function() thread:newThread("Proxy_Handler_" .. multi.randomString(4), function()
while true do while true do
local data = thread.hold(check) local data = thread.hold(check)
if data then if data then
-- Let's not hold the main threadloop -- Let's not hold the main threadloop
thread:newThread("Temp_Thread", function() thread:newThread("Temp_Thread", function()
local func = table.remove(data, 1) local func = table.remove(data, 1)
local sref = table.remove(data, 1) local sref = table.remove(data, 1)
local ret local ret
if sref then if sref then
ret = {_G[list[0]][func](_G[list[0]], multi.unpack(data))} ret = {_G[list[0]][func](_G[list[0]], multi.unpack(data))}
else else
ret = {_G[list[0]][func](multi.unpack(data))} ret = {_G[list[0]][func](multi.unpack(data))}
end end
for i = 1,#ret do for i = 1,#ret do
if type(ret[i]) == "table" and ret[i].Type ~= nil and ret[i].Type ~= multi.registerType("proxy", "proxies") then if type(ret[i]) == "table" and ret[i].Type ~= nil and ret[i].Type ~= multi.registerType("proxy", "proxies") then
ret[i] = "\1PARENT_REF" ret[i] = "\1PARENT_REF"
end end
if type(ret[i]) == "table" and getmetatable(ret[i]) then 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! setmetatable(ret[i],nil) -- remove that metatable, we do not need it on the other side!
end end
if ret[i] == _G[list[0]] then if ret[i] == _G[list[0]] then
-- We cannot return itself, that return can contain bad values. -- We cannot return itself, that return can contain bad values.
ret[i] = "\1SELF_REF" ret[i] = "\1SELF_REF"
end end
end end
table.insert(ret, 1, func) table.insert(ret, 1, func)
self.recv:push(ret) self.recv:push(ret)
end) end)
end end
end end
end) end)
return self return self
else else
THREAD.sync() THREAD.sync()
if not self.funcs then return self end if not self.funcs then return self end
local function copy(obj) local function copy(obj)
if type(obj) ~= 'table' then return obj end if type(obj) ~= 'table' then return obj end
local res = {} local res = {}
for k, v in pairs(obj) do res[copy(k)] = copy(v) end for k, v in pairs(obj) do res[copy(k)] = copy(v) end
return res return res
end end
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local me = self local me = self
local funcs = copy(self.funcs) local funcs = copy(self.funcs)
if multi.integration then if multi.integration then
GLOBAL = multi.integration.GLOBAL GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD THREAD = multi.integration.THREAD
end end
self.send = THREAD.waitFor(self.name.."_S"):init() self.send = THREAD.waitFor(self.name.."_S"):init()
self.recv = THREAD.waitFor(self.name.."_R"):init() self.recv = THREAD.waitFor(self.name.."_R"):init()
self.Type = multi.registerType("proxy", "proxies") self.Type = multi.registerType("proxy", "proxies")
for _,v in pairs(funcs) do for _,v in pairs(funcs) do
if type(v) == "table" then if type(v) == "table" then
-- We have a connection -- We have a connection
v[2]:init(proc_name) v[2]:init(proc_name)
self[v[1]] = v[2] self[v[1]] = v[2]
v[2].Parent = self v[2].Parent = self
setmetatable(v[2],getmetatable(multi:newConnection())) setmetatable(v[2],getmetatable(multi:newConnection()))
else else
self[v] = thread:newFunction(function(self,...) self[v] = thread:newFunction(function(self,...)
if self == me then if self == me then
me.send:push({v, true, ...}) me.send:push({v, true, ...})
else else
me.send:push({v, false, ...}) me.send:push({v, false, ...})
end end
return thread.hold(function() return thread.hold(function()
local data = me.recv:peek() local data = me.recv:peek()
if data and data[1] == v then if data and data[1] == v then
me.recv:pop() me.recv:pop()
table.remove(data, 1) table.remove(data, 1)
for i=1,#data do for i=1,#data do
if data[i] == "\1SELF_REF" then if data[i] == "\1SELF_REF" then
data[i] = me data[i] = me
elseif data[i] == "\1PARENT_REF" then elseif data[i] == "\1PARENT_REF" then
data[i] = me.Parent data[i] = me.Parent
end end
end end
return multi.unpack(data) return multi.unpack(data)
end end
end) end)
end, true) end, true)
end end
end end
return self return self
end end
end end
function c:getTransferable() function c:getTransferable()
local cp = {} local cp = {}
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local function copy(obj) local function copy(obj)
if type(obj) ~= 'table' then return obj end if type(obj) ~= 'table' then return obj end
local res = {} local res = {}
for k, v in pairs(obj) do res[copy(k)] = copy(v) end for k, v in pairs(obj) do res[copy(k)] = copy(v) end
return res return res
end end
cp.is_init = true cp.is_init = true
cp.proxy_link = self.proxy_link cp.proxy_link = self.proxy_link
cp.name = self.name cp.name = self.name
cp.funcs = copy(self._funcs) cp.funcs = copy(self._funcs)
cp.init = function(self) cp.init = function(self)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
if multi.integration then if multi.integration then
GLOBAL = multi.integration.GLOBAL GLOBAL = multi.integration.GLOBAL
THREAD = multi.integration.THREAD THREAD = multi.integration.THREAD
end end
local proxy = THREAD.waitFor(self.proxy_link) local proxy = THREAD.waitFor(self.proxy_link)
proxy.funcs = self.funcs proxy.funcs = self.funcs
return proxy:init() return proxy:init()
end end
return cp return cp
end end
self:create(c) self:create(c)
return c return c
end end
local targets = {} local targets = {}
local references = {} local references = {}
local jid = -1 local jid = -1
function multi:newSystemThreadedProcessor(cores) function multi:newSystemThreadedProcessor(cores)
local name = "STP_"..multi.randomString(4) -- set a random name if none was given. 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 autoscale = autoscale or false -- Will scale up the number of cores that the process uses.
local c = {} local c = {}
setmetatable(c,{__index = multi}) setmetatable(c,{__index = multi})
c.Type = multi.registerType("s_process", "s_processes") c.Type = multi.registerType("s_process", "s_processes")
c.threads = {} c.threads = {}
c.cores = cores or 8 c.cores = cores or 8
c.Name = name c.Name = name
c.Mainloop = {} c.Mainloop = {}
c.__count = 0 c.__count = 0
c.processors = {} c.processors = {}
c.proc_list = {} c.proc_list = {}
c.OnObjectCreated = multi:newConnection() c.OnObjectCreated = multi:newConnection()
c.parent = self c.parent = self
c.jobqueue = multi:newSystemThreadedJobQueue(c.cores) c.jobqueue = multi:newSystemThreadedJobQueue(c.cores)
function c:pushJob(ID, name, ...) function c:pushJob(ID, name, ...)
local tq = THREAD.waitFor(self.Name .. "_target_tq_" .. ID):init() local tq = THREAD.waitFor(self.Name .. "_target_tq_" .. ID):init()
tq:push{name, jid, multi.pack(...)} tq:push{name, jid, multi.pack(...)}
jid = jid - 1 jid = jid - 1
return jid + 1 return jid + 1
end end
c.jobqueue:registerFunction("packObj",function(obj) c.jobqueue:registerFunction("packObj",function(obj)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local list = multi:chop(obj) local list = multi:chop(obj)
obj.__link_name = list[0] obj.__link_name = list[0]
local proxy = multi:newProxy(list):init() local proxy = multi:newProxy(list):init()
return proxy return proxy
end) end)
c.spawnThread = c.jobqueue:newFunction("__spawnThread__", function(name, func, ...) c.spawnThread = c.jobqueue:newFunction("__spawnThread__", function(name, func, ...)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local obj = thread:newThread(name, func, ...) local obj = thread:newThread(name, func, ...)
return packObj(obj) return packObj(obj)
end, true) end, true)
c.spawnTask = c.jobqueue:newFunction("__spawnTask__", function(obj, func, ...) c.spawnTask = c.jobqueue:newFunction("__spawnTask__", function(obj, func, ...)
local multi, thread = require("multi"):init() local multi, thread = require("multi"):init()
local obj = multi[obj](multi, func, ...) local obj = multi[obj](multi, func, ...)
return packObj(obj) return packObj(obj)
end, true) end, true)
local implement = { local implement = {
"newLoop", "newLoop",
"newTLoop", "newTLoop",
"newUpdater", "newUpdater",
"newEvent", "newEvent",
"newAlarm", "newAlarm",
"newStep", "newStep",
"newTStep", "newTStep",
"newService" "newService"
} }
for _, method in pairs(implement) do for _, method in pairs(implement) do
c[method] = thread:newFunction(function(self, ...) c[method] = thread:newFunction(function(self, ...)
proxy = self.spawnTask(method, ...) proxy = self.spawnTask(method, ...)
proxy:init() proxy:init()
references[proxy] = self references[proxy] = self
return proxy return proxy
end, true) end, true)
end end
function c:newThread(name, func, ...) function c:newThread(name, func, ...)
proxy = self.spawnThread(name, func, ...):init(self.Name) proxy = self.spawnThread(name, func, ...):init(self.Name)
references[proxy] = self references[proxy] = self
table.insert(self.threads, proxy) table.insert(self.threads, proxy)
return proxy return proxy
end end
function c:newFunction(func, holdme) function c:newFunction(func, holdme)
return self.jobqueue:newFunction(func, holdme) return self.jobqueue:newFunction(func, holdme)
end end
function c:newSharedTable(name) function c:newSharedTable(name)
if not name then multi.error("You must provide a name when creating a table!") end if not name then multi.error("You must provide a name when creating a table!") end
local tbl_name = "TABLE_"..multi.randomString(8) local tbl_name = "TABLE_"..multi.randomString(8)
self.jobqueue:doToAll(function(tbl_name, interaction) self.jobqueue:doToAll(function(tbl_name, interaction)
_G[interaction] = THREAD.waitFor(tbl_name):init() _G[interaction] = THREAD.waitFor(tbl_name):init()
end, tbl_name, name) end, tbl_name, name)
return multi:newSystemThreadedTable(tbl_name):init() return multi:newSystemThreadedTable(tbl_name):init()
end end
function c:getHandler() function c:getHandler()
return function() end -- return empty function return function() end -- return empty function
end end
function c:getThreads() function c:getThreads()
return self.threads return self.threads
end end
function c:getFullName() function c:getFullName()
return self.parent:getFullName() .. "." .. c.Name return self.parent:getFullName() .. "." .. c.Name
end end
function c:getName() function c:getName()
return self.Name return self.Name
end end
function c.run() function c.run()
return self return self
end end
function c.isActive() function c.isActive()
return true return true
end end
function c.Start() function c.Start()
return self return self
end end
function c.Stop() function c.Stop()
return self return self
end end
function c:Destroy() function c:Destroy()
return false return false
end end
return c return c
end end
-1
View File
@@ -1 +0,0 @@
-- Allows the creation of states
+12 -12
View File
@@ -1,13 +1,13 @@
-- We need to detect what enviroment we are running our code in. -- We need to detect what enviroment we are running our code in.
return { return {
init = function() init = function()
if love then if love then
return require("multi.integration.loveManager"):init() return require("multi.integration.loveManager"):init()
else else
if pcall(require,"lanes") then if pcall(require,"lanes") then
return require("multi.integration.lanesManager"):init() return require("multi.integration.lanesManager"):init()
end end
return require("multi.integration.pesudoManager"):init() return require("multi.integration.pesudoManager"):init()
end end
end end
} }
+20 -20
View File
@@ -1,20 +1,20 @@
function love.conf(t) function love.conf(t)
t.identity = nil -- The name of the save directory (string) t.identity = nil -- The name of the save directory (string)
t.version = "12.0" -- The LOVE version this game was made for (string) t.version = "12.0" -- The LOVE version this game was made for (string)
t.console = true -- Attach a console (boolean, Windows only) t.console = true -- Attach a console (boolean, Windows only)
-- t.modules.audio = false -- Enable the audio module (boolean) -- t.modules.audio = false -- Enable the audio module (boolean)
-- t.modules.event = false -- Enable the event module (boolean) -- t.modules.event = false -- Enable the event module (boolean)
-- t.modules.graphics = false -- Enable the graphics module (boolean) -- t.modules.graphics = false -- Enable the graphics module (boolean)
-- t.modules.image = false -- Enable the image module (boolean) -- t.modules.image = false -- Enable the image module (boolean)
-- t.modules.joystick = false -- Enable the joystick module (boolean) -- t.modules.joystick = false -- Enable the joystick module (boolean)
-- t.modules.keyboard = false -- Enable the keyboard module (boolean) -- t.modules.keyboard = false -- Enable the keyboard module (boolean)
-- t.modules.math = false -- Enable the math module (boolean) -- t.modules.math = false -- Enable the math module (boolean)
-- t.modules.mouse = false -- Enable the mouse module (boolean) -- t.modules.mouse = false -- Enable the mouse module (boolean)
-- t.modules.physics = false -- Enable the physics module (boolean) -- t.modules.physics = false -- Enable the physics module (boolean)
-- t.modules.sound = false -- Enable the sound module (boolean) -- t.modules.sound = false -- Enable the sound module (boolean)
-- t.modules.system = true -- Enable the system module (boolean) -- t.modules.system = true -- Enable the system module (boolean)
-- t.modules.timer = true -- Enable the timer module (boolean) -- t.modules.timer = true -- Enable the timer module (boolean)
-- t.modules.window = false -- Enable the window module (boolean) -- t.modules.window = false -- Enable the window module (boolean)
-- t.modules.thread = true -- Enable the thread module (boolean) -- t.modules.thread = true -- Enable the thread module (boolean)
end end
+74 -74
View File
@@ -1,75 +1,75 @@
package.path = "../?/init.lua;../?.lua;"..package.path package.path = "../?/init.lua;../?.lua;"..package.path
local multi, thread = require("multi"):init{print=true, warning = true, error=true} local multi, thread = require("multi"):init{print=true, warning = true, error=true}
local utils = require("multi.integration.loveManager.utils") local utils = require("multi.integration.loveManager.utils")
local people = {1,2,3} local people = {1,2,3}
function dump(o) function dump(o)
if type(o) == 'table' then if type(o) == 'table' then
local s = '{ ' local s = '{ '
for k,v in pairs(o) do for k,v in pairs(o) do
if type(k) ~= 'number' then k = '"'..k..'"' end if type(k) ~= 'number' then k = '"'..k..'"' end
s = s .. '['..k..'] = ' .. dump(v) .. '('..type(v):sub(1,1)..'),' s = s .. '['..k..'] = ' .. dump(v) .. '('..type(v):sub(1,1)..'),'
end end
return s .. '} ' return s .. '} '
else else
return tostring(o) return tostring(o)
end end
end end
local fpeople = utils.pack(people) local fpeople = utils.pack(people)
print("Pack:", dump(fpeople)) print("Pack:", dump(fpeople))
local people = utils.unpack(fpeople) local people = utils.unpack(fpeople)
print("Unpack:", dump(people)) print("Unpack:", dump(people))
print(type(people[3])) print(type(people[3]))
-- GLOBAL, THREAD = require("multi.integration.loveManager"):init() -- GLOBAL, THREAD = require("multi.integration.loveManager"):init()
-- local queue = multi:newSystemThreadedQueue("TestQueue") -- local queue = multi:newSystemThreadedQueue("TestQueue")
-- local tab = multi:newSystemThreadedTable("TestTable") -- local tab = multi:newSystemThreadedTable("TestTable")
-- local test = multi:newSystemThread("Test",function() -- local test = multi:newSystemThread("Test",function()
-- local queue = THREAD.waitFor("TestQueue") -- local queue = THREAD.waitFor("TestQueue")
-- local tab = THREAD.waitFor("TestTable") -- local tab = THREAD.waitFor("TestTable")
-- print("THREAD_ID:",THREAD_ID) -- print("THREAD_ID:",THREAD_ID)
-- queue:push("Did it work?") -- queue:push("Did it work?")
-- tab["Test"] = true -- tab["Test"] = true
-- return 1,2,3 -- return 1,2,3
-- end) -- end)
-- multi:newThread("QueueTest", function() -- multi:newThread("QueueTest", function()
-- print(thread.hold(queue)) -- print(thread.hold(queue))
-- print(thread.hold(tab, {key="Test"})) -- print(thread.hold(tab, {key="Test"}))
-- print("Done!") -- print("Done!")
-- end) -- end)
-- local jq = multi:newSystemThreadedJobQueue(n) -- local jq = multi:newSystemThreadedJobQueue(n)
-- jq:registerFunction("test2",function() -- jq:registerFunction("test2",function()
-- print("This works!") -- print("This works!")
-- end) -- end)
-- jq:registerFunction("test",function(a, b, c) -- jq:registerFunction("test",function(a, b, c)
-- print(a, b+c) -- print(a, b+c)
-- test2() -- test2()
-- return a+b+c -- return a+b+c
-- end) -- end)
-- print("Job:",jq:pushJob("test",1,2,3)) -- print("Job:",jq:pushJob("test",1,2,3))
-- print("Job:",jq:pushJob("test",2,3,4)) -- print("Job:",jq:pushJob("test",2,3,4))
-- print("Job:",jq:pushJob("test",5,6,7)) -- print("Job:",jq:pushJob("test",5,6,7))
-- jq.OnJobCompleted(function(...) -- jq.OnJobCompleted(function(...)
-- print("Job Completed!", ...) -- print("Job Completed!", ...)
-- end) -- end)
-- function love.draw() -- function love.draw()
-- -- -- --
-- end -- end
-- function love.update() -- function love.update()
-- multi:uManager() -- multi:uManager()
-- end -- end
File diff suppressed because it is too large Load Diff
+53 -53
View File
@@ -1,53 +1,53 @@
IsEvent=true IsEvent=true
event={ event={
Active=true, Active=true,
CT=false, CT=false,
tag={}, tag={},
Events={}, Events={},
EventTracker={}, EventTracker={},
Steps={}, 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, 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, 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, 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, updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
addTracker=function(self,varname,var) event.EventTracker[varname]=var end, addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
getTracker=function(self,var) return event.EventTracker[var] end, getTracker=function(self,var) return event.EventTracker[var] end,
removeTracker=function(self,var) event.EventTracker[var]=nil end, removeTracker=function(self,var) event.EventTracker[var]=nil end,
trackerExist=function(self,tag) return event.EventTracker[tag]~=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, 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, 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, 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, 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, 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, Stop=function() event.Active=false end,
OnCreate=function() end, OnCreate=function() end,
OnUpdate=function() end, OnUpdate=function() end,
OnClose=function() end, OnClose=function() end,
getActive=function() return event.tag 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, 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, 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, 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) createStep=function(self,tag,reset,endc)
if not(endc) then endc=false end if not(endc) then endc=false end
if not(reset) then reset=0 end if not(reset) then reset=0 end
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc, 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, 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, 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, Reset=function(self) self.pos=1 end,
Set=function(self,amt) self.pos=amt end, Set=function(self,amt) self.pos=amt end,
Pause=function(self) self.active=false end, Pause=function(self) self.active=false end,
Resume=function(self) self.active=true end, Resume=function(self) self.active=true end,
Stop=function(self) self:Reset() self:Pause() end, Stop=function(self) self:Reset() self:Pause() end,
Start=function(self) self:Resume() end, Start=function(self) self:Resume() end,
End=function(self) self.pos=self.EndAt self.endc=true end, End=function(self) self.pos=self.EndAt self.endc=true end,
} }
table.insert(event.Steps,temp) return temp end, table.insert(event.Steps,temp) return temp end,
stepExist=function(self,tag) stepExist=function(self,tag)
for a_s=1,#event.Steps do for a_s=1,#event.Steps do
if event.Steps[a_s].Name==tag then if event.Steps[a_s].Name==tag then
return true return true
end end
end end
return false return false
end, end,
} }
+55 -55
View File
@@ -1,55 +1,55 @@
IsEvent=true IsEvent=true
event={ event={
Active=true, Active=true,
CT=false, CT=false,
tag={}, tag={},
Events={}, Events={},
EventTracker={}, EventTracker={},
Steps={}, Steps={},
--addAlarm=function(self,tag) end, --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, 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, 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, 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, updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
addTracker=function(self,varname,var) event.EventTracker[varname]=var end, addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
getTracker=function(self,var) return event.EventTracker[var] end, getTracker=function(self,var) return event.EventTracker[var] end,
removeTracker=function(self,var) event.EventTracker[var]=nil end, removeTracker=function(self,var) event.EventTracker[var]=nil end,
trackerExist=function(self,tag) return event.EventTracker[tag]~=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, 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, 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, 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, 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, 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, Stop=function() event.Active=false end,
OnCreate=function() end, OnCreate=function() end,
OnUpdate=function() end, OnUpdate=function() end,
OnClose=function() end, OnClose=function() end,
getActive=function() return event.tag 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, 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, 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, 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, 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) createStep=function(self,tag,reset,endc)
if not(endc) then endc=false end if not(endc) then endc=false end
if not(reset) then reset=0 end if not(reset) then reset=0 end
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc, 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, 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, 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, Reset=function(self) self.pos=1 end,
Set=function(self,amt) self.pos=amt end, Set=function(self,amt) self.pos=amt end,
Pause=function(self) self.active=false end, Pause=function(self) self.active=false end,
Resume=function(self) self.active=true end, Resume=function(self) self.active=true end,
Stop=function(self) self:Reset() self:Pause() end, Stop=function(self) self:Reset() self:Pause() end,
Start=function(self) self:Resume() end, Start=function(self) self:Resume() end,
End=function(self) self.pos=self.EndAt self.endc=true end, End=function(self) self.pos=self.EndAt self.endc=true end,
} }
table.insert(event.Steps,temp) return temp end, table.insert(event.Steps,temp) return temp end,
stepExist=function(self,tag) stepExist=function(self,tag)
for a_s=1,#event.Steps do for a_s=1,#event.Steps do
if event.Steps[a_s].Name==tag then if event.Steps[a_s].Name==tag then
return true return true
end end
end end
return false return false
end, end,
} }
+55 -55
View File
@@ -1,55 +1,55 @@
IsEvent=true IsEvent=true
event={ event={
Active=true, Active=true,
CT=false, CT=false,
tag={}, tag={},
Events={}, Events={},
EventTracker={}, EventTracker={},
Steps={}, Steps={},
--addAlarm=function(self,tag) end, --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, 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, 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, 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, updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
addTracker=function(self,varname,var) event.EventTracker[varname]=var end, addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
getTracker=function(self,var) return event.EventTracker[var] end, getTracker=function(self,var) return event.EventTracker[var] end,
removeTracker=function(self,var) event.EventTracker[var]=nil end, removeTracker=function(self,var) event.EventTracker[var]=nil end,
trackerExist=function(self,tag) return event.EventTracker[tag]~=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, 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, 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, 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, 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, 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, Stop=function() event.Active=false end,
OnCreate=function() end, OnCreate=function() end,
OnUpdate=function() end, OnUpdate=function() end,
OnClose=function() end, OnClose=function() end,
getActive=function() return event.tag 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, 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, 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, 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, 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) createStep=function(self,tag,reset,endc)
if not(endc) then endc=false end if not(endc) then endc=false end
if not(reset) then reset=0 end if not(reset) then reset=0 end
temp={Name=tag,pos=1,endAt=reset,active=true,endc=endc, 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, 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, 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, Reset=function(self) self.pos=1 end,
Set=function(self,amt) self.pos=amt end, Set=function(self,amt) self.pos=amt end,
Pause=function(self) self.active=false end, Pause=function(self) self.active=false end,
Resume=function(self) self.active=true end, Resume=function(self) self.active=true end,
Stop=function(self) self:Reset() self:Pause() end, Stop=function(self) self:Reset() self:Pause() end,
Start=function(self) self:Resume() end, Start=function(self) self:Resume() end,
End=function(self) self.pos=self.EndAt self.endc=true end, End=function(self) self.pos=self.EndAt self.endc=true end,
} }
table.insert(event.Steps,temp) return temp end, table.insert(event.Steps,temp) return temp end,
stepExist=function(self,tag) stepExist=function(self,tag)
for a_s=1,#event.Steps do for a_s=1,#event.Steps do
if event.Steps[a_s].Name==tag then if event.Steps[a_s].Name==tag then
return true return true
end end
end end
return false return false
end, end,
} }
+98 -98
View File
@@ -1,98 +1,98 @@
require("Data/BasicCommands") require("Data/BasicCommands")
IsEvent=true IsEvent=true
event={ event={
Active=true, Active=true,
CT=false, CT=false,
tag={}, tag={},
Events={}, Events={},
EventTracker={}, EventTracker={},
Steps={}, Steps={},
TSteps={}, TSteps={},
LoadOrder="/E/S/U",-- types = ESU,EUS,USE,UES,SEU,SUE LoadOrder="/E/S/U",-- types = ESU,EUS,USE,UES,SEU,SUE
setLoadOrder=function(self,str) event.LoadOrder=string.upper(str) end, 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, 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_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_STEPS=function() for s_g=1,#event.Steps do event.Steps[s_g]:Step() end end,
RUN_UPDATES=function() event.OnUpdate() 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, 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, 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, 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, updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
addTracker=function(self,varname,var) event.EventTracker[varname]=var end, addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
getTracker=function(self,varname) return event.EventTracker[varname] end, getTracker=function(self,varname) return event.EventTracker[varname] end,
removeTracker=function(self,var) event.EventTracker[var]=nil end, removeTracker=function(self,var) event.EventTracker[var]=nil end,
trackerExist=function(self,tag) return event.EventTracker[tag]~=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, 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, 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, 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, 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, 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, Stop=function() event.Active=false end,
OnCreate=function() end, OnCreate=function() end,
OnUpdate=function() end, OnUpdate=function() end,
OnClose=function() end, OnClose=function() end,
getActive=function() return event.tag 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 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, --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, 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, 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) createStep=function(self,tag,reset,skip,endc)
if not(endc) then endc=false end if not(endc) then endc=false end
temp= temp=
{ {
Name=tag, Name=tag,
pos=1, pos=1,
endAt=reset or math.huge, endAt=reset or math.huge,
active=true, active=true,
endc=endc, endc=endc,
skip=skip or 0, skip=skip or 0,
spos=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, 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, 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, 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, Reset=function(self) self.pos=1 end,
Set=function(self,amt) self.pos=amt end, Set=function(self,amt) self.pos=amt end,
Pause=function(self) self.active=false end, Pause=function(self) self.active=false end,
Resume=function(self) self.active=true end, Resume=function(self) self.active=true end,
Stop=function(self) self:Reset() self:Pause() end, Stop=function(self) self:Reset() self:Pause() end,
Start=function(self) self:Resume() end, Start=function(self) self:Resume() end,
End=function(self) self.pos=self.EndAt self.endc=true end, End=function(self) self.pos=self.EndAt self.endc=true end,
} }
table.insert(event.Steps,temp) return temp end, table.insert(event.Steps,temp) return temp end,
createTStep=function(self,tag,reset,timer,endc) createTStep=function(self,tag,reset,timer,endc)
if not(endc) then endc=false end if not(endc) then endc=false end
timer=timer or 1 timer=timer or 1
temp= temp=
{ {
Name=tag, Name=tag,
pos=1, pos=1,
endAt=reset or math.huge, endAt=reset or math.huge,
active=true, active=true,
endc=endc, endc=endc,
skip= 0, skip= 0,
spos=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, 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, 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, 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, Reset=function(self) self.pos=1 end,
Set=function(self,amt) self.pos=amt end, Set=function(self,amt) self.pos=amt end,
Pause=function(self) self.active=false end, Pause=function(self) self.active=false end,
Resume=function(self) self.active=true end, Resume=function(self) self.active=true end,
Stop=function(self) self:Reset() self:Pause() end, Stop=function(self) self:Reset() self:Pause() end,
Start=function(self) self:Resume() end, Start=function(self) self:Resume() end,
End=function(self) self.pos=self.EndAt self.endc=true end, End=function(self) self.pos=self.EndAt self.endc=true end,
} }
event:setAlarm("TStep_"..tag,timer) event:setAlarm("TStep_"..tag,timer)
event:addTracker("_TStep_"..tag,temp) event:addTracker("_TStep_"..tag,temp)
table.insert(event.TSteps,temp) table.insert(event.TSteps,temp)
assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:setAlarm(alarm,"..timer..") end"))() assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:setAlarm(alarm,"..timer..") end"))()
return temp end, return temp end,
stepExist=function(self,tag) stepExist=function(self,tag)
for a_s=1,#event.Steps do for a_s=1,#event.Steps do
if event.Steps[a_s].Name==tag then if event.Steps[a_s].Name==tag then
return true return true
end end
end end
return false return false
end, end,
} }
+203 -203
View File
@@ -1,203 +1,203 @@
function dump(t,indent) function dump(t,indent)
local names = {} local names = {}
if not indent then indent = "" end if not indent then indent = "" end
for n,g in pairs(t) do for n,g in pairs(t) do
table.insert(names,n) table.insert(names,n)
end end
table.sort(names) table.sort(names)
for i,n in pairs(names) do for i,n in pairs(names) do
local v = t[n] local v = t[n]
if type(v) == "table" then if type(v) == "table" then
if(v==t) then -- prevent endless loop if table contains reference to itself if(v==t) then -- prevent endless loop if table contains reference to itself
print(indent..tostring(n)..": <-") print(indent..tostring(n)..": <-")
else else
print(indent..tostring(n)..":") print(indent..tostring(n)..":")
dump(v,indent.." ") dump(v,indent.." ")
end end
else else
if type(v) == "function" then if type(v) == "function" then
print(indent..tostring(n).."()") print(indent..tostring(n).."()")
else else
print(indent..tostring(n)..": "..tostring(v)) print(indent..tostring(n)..": "..tostring(v))
end end
end end
end end
end end
function SetCounter() function SetCounter()
return os.clock() return os.clock()
end end
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
function GetCounter(count) function GetCounter(count)
if count~=nil then if count~=nil then
return os.clock()-count return os.clock()-count
else else
return 0 return 0
end end
end end
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
clock=os.clock clock=os.clock
event={ event={
Active=true, Active=true,
CT=false, CT=false,
tag={}, tag={},
Events={}, Events={},
Alarms={}, Alarms={},
EventTracker={}, EventTracker={},
Steps={}, Steps={},
TSteps={}, TSteps={},
CTask="", CTask="",
LoadOrder="/E/S/A/U", LoadOrder="/E/S/A/U",
UpdateObj= UpdateObj=
{ {
LoadOrder="", LoadOrder="",
Resume=function(self) event.LoadOrder=self.LoadOrder end, Resume=function(self) event.LoadOrder=self.LoadOrder end,
Pause=function(self) self.LoadOrder=event.LoadOrder event.LoadOrder=event.LoadOrder:gsub("/U", "") 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, 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, 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_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_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_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, RUN_ALARMS=function() for i=1,#event.Alarms do event.Alarms[i]:Tick() end end,
--System Used Functions --System Used Functions
Hold=function(self,task) -- as many conditions and times that you want can be used Hold=function(self,task) -- as many conditions and times that you want can be used
local action=__CAction__ local action=__CAction__
action:Pause() action:Pause()
if type(task)=="number" then if type(task)=="number" then
local func=function() end local func=function() end
local alarm=event:newAlarm(task,func,true) local alarm=event:newAlarm(task,func,true)
while alarm.active==true do while alarm.active==true do
event.CManager() event.CManager()
end end
alarm:Destroy() alarm:Destroy()
action:Resume() action:Resume()
elseif type(task)=="string" then elseif type(task)=="string" then
assert(loadstring("while not("..task..") do event.CManager() end"))() assert(loadstring("while not("..task..") do event.CManager() end"))()
action:Resume() action:Resume()
end end
end, end,
newAlarm=function(self,set,func,start) newAlarm=function(self,set,func,start)
if not(start) then timer=0 active=false else timer=clock() active=true end if not(start) then timer=0 active=false else timer=clock() active=true end
if not(func) then func=(function() end) end if not(func) then func=(function() end) end
Alarm= Alarm=
{ {
active=active, active=active,
timer=timer, timer=timer,
set=set or 0, set=set or 0,
func=func, 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, 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, Pause=function(self) self.active=false end,
Set=function(self,amt) self.set=amt self.timer=clock() self:Resume() end, Set=function(self,amt) self.set=amt self.timer=clock() self:Resume() end,
OnRing=function(self,func) self.func=func end, OnRing=function(self,func) self.func=func end,
Ring=function(self) self:func(self) end, Ring=function(self) self:func(self) end,
Reset=function(self) self.timer=clock() self:Resume() end, Reset=function(self) self.timer=clock() self:Resume() end,
Resume=function(self) self.active=true 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, 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) table.insert(event.Alarms,Alarm)
return Alarm return Alarm
end, end,
setAlarm=function(self,tag,set) setAlarm=function(self,tag,set)
if event:eventExist("Alarm_"..tag.."(\""..tag.."\")")==false then if event:eventExist("Alarm_"..tag.."(\""..tag.."\")")==false then
event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]]) event:new("Alarm_"..tag.."(\""..tag.."\")",[[GetCounter(event:getTracker("_Alarm_]]..tag..[["))>=]]..set,[[event:removeAlarm("]]..tag..[[")]])
event:addTracker("_Alarm_"..tag,SetCounter()) 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"))() assert(loadstring("if Alarm_"..tag.."==nil then function Alarm_"..tag.."() print('No function \"Alarm_"..tag.."()\" exists make sure you created it') end end"))()
else else
event:addTracker("_Alarm_"..tag,SetCounter()) event:addTracker("_Alarm_"..tag,SetCounter())
end 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, 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, 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, updateAlarm=function(self,tag,set) event:removeAlarm(tag) event:setAlarm(tag,set) end,
addTracker=function(self,varname,var) event.EventTracker[varname]=var end, addTracker=function(self,varname,var) event.EventTracker[varname]=var end,
getTracker=function(self,varname) return event.EventTracker[varname] end, getTracker=function(self,varname) return event.EventTracker[varname] end,
listTrackers=function(self) return event.EventTracker end, listTrackers=function(self) return event.EventTracker end,
removeTracker=function(self,var) event.EventTracker[var]=nil end, removeTracker=function(self,var) event.EventTracker[var]=nil end,
trackerExist=function(self,tag) return event.EventTracker[tag]~=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, 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, 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, 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, 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, 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, Stop=function() event.Active=false end,
OnCreate=function() end, OnCreate=function() end,
OnUpdate=function() end, OnUpdate=function() end,
OnClose=function() end, OnClose=function() end,
getActive=function() return event.tag 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 event.DO_Order() end event.OnClose() end,
CManager=function() if event.Active==true then event.DO_Order() end 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, 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) createStep=function(self,tag,reset,skip,endc)
if not(endc) then if not(endc) then
endc=false endc=false
end end
temp= temp=
{ {
Name=tag, Name=tag,
pos=1, pos=1,
endAt=reset or math.huge, endAt=reset or math.huge,
active=true, active=true,
endc=endc, endc=endc,
skip=skip or 0, skip=skip or 0,
spos=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, 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, 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, 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, Reset=function(self) self.pos=1 end,
Set=function(self,amt) self.pos=amt end, Set=function(self,amt) self.pos=amt end,
Pause=function(self) self.active=false end, Pause=function(self) self.active=false end,
Resume=function(self) self.active=true end, Resume=function(self) self.active=true end,
Stop=function(self) self:Reset() self:Pause() end, Stop=function(self) self:Reset() self:Pause() end,
Start=function(self) self:Resume() end, Start=function(self) self:Resume() end,
End=function(self) _G.__CAction__=self assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() self:Reset() end, End=function(self) _G.__CAction__=self assert(loadstring("Step_"..self.Name.."_End(__CAction__)"))() self:Reset() end,
} }
table.insert(event.Steps,temp) return temp table.insert(event.Steps,temp) return temp
end, end,
createTStep=function(self,tag,reset,timer,endc) createTStep=function(self,tag,reset,timer,endc)
if not(endc) then if not(endc) then
endc=false endc=false
end end
timer=timer or 1 timer=timer or 1
temp= temp=
{ {
Name=tag, Name=tag,
pos=1, pos=1,
endAt=reset or math.huge, endAt=reset or math.huge,
active=true, active=true,
endc=endc, endc=endc,
skip= 0, skip= 0,
spos=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, 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, 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, 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, Reset=function(self) self.pos=1 end,
Set=function(self,amt) self.pos=amt end, Set=function(self,amt) self.pos=amt end,
Pause=function(self) self.active=false end, Pause=function(self) self.active=false end,
Resume=function(self) self.active=true end, Resume=function(self) self.active=true end,
Stop=function(self) self:Reset() self:Pause() end, Stop=function(self) self:Reset() self:Pause() end,
Start=function(self) self:Resume() end, Start=function(self) self:Resume() end,
End=function(self) self.pos=self.EndAt self.endc=true end, End=function(self) self.pos=self.EndAt self.endc=true end,
} }
event:setAlarm("TStep_"..tag,timer) event:setAlarm("TStep_"..tag,timer)
event:addTracker("_TStep_"..tag,temp) event:addTracker("_TStep_"..tag,temp)
table.insert(event.TSteps,temp) table.insert(event.TSteps,temp)
assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:updateAlarm(alarm,"..timer..") end"))() assert(loadstring("function Alarm_TStep_"..tag.."(alarm) event:getTracker(\"_\"..alarm):Step() event:updateAlarm(alarm,"..timer..") end"))()
return temp return temp
end, end,
stepExist=function(self,tag) stepExist=function(self,tag)
for a_s=1,#event.Steps do for a_s=1,#event.Steps do
if event.Steps[a_s].Name==tag then if event.Steps[a_s].Name==tag then
return true return true
end end
end end
return false return false
end, end,
tstepExist=function(self,tag) tstepExist=function(self,tag)
for a_s=1,#event.TSteps do for a_s=1,#event.TSteps do
if event.TSteps[a_s].Name==tag then if event.TSteps[a_s].Name==tag then
return true return true
end end
end end
return false return false
end, end,
} }
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+365 -365
View File
@@ -1,365 +1,365 @@
multi = {} multi = {}
multi.__index = multi multi.__index = multi
multi.Mainloop={} multi.Mainloop={}
multi.Tasks={} multi.Tasks={}
multi.Tasks2={} multi.Tasks2={}
multi.Garbage={} multi.Garbage={}
multi.Children={} multi.Children={}
multi.Paused={} multi.Paused={}
multi.MasterId=0 multi.MasterId=0
multi.Active=true multi.Active=true
multi.Id=-1 multi.Id=-1
-- System -- System
function multi:newBase(ins) function multi:newBase(ins)
local c = {} local c = {}
setmetatable(c, multi) setmetatable(c, multi)
c.Parent=self c.Parent=self
c.Active=true c.Active=true
c.func={} c.func={}
c.Id=0 c.Id=0
c.Act=function() end c.Act=function() end
if ins then if ins then
table.insert(multi.Mainloop,ins,c) table.insert(multi.Mainloop,ins,c)
else else
table.insert(multi.Mainloop,c) table.insert(multi.Mainloop,c)
end end
multi.MasterId=multi.MasterId+1 multi.MasterId=multi.MasterId+1
return c return c
end end
function multi:reboot(r) function multi:reboot(r)
multi.Mainloop={} multi.Mainloop={}
multi.Tasks={} multi.Tasks={}
multi.Tasks2={} multi.Tasks2={}
multi.Garbage={} multi.Garbage={}
multi.Children={} multi.Children={}
multi.Paused={} multi.Paused={}
multi.MasterId=0 multi.MasterId=0
multi.Active=true multi.Active=true
multi.Id=-1 multi.Id=-1
if r then if r then
for i,v in pairs(_G) do for i,v in pairs(_G) do
if type(i)=="table" then if type(i)=="table" then
if i.Parent and i.Id and i.Act then if i.Parent and i.Id and i.Act then
i={} i={}
end end
end end
end end
end end
end end
--Processor --Processor
function multi.Do_Order() function multi.Do_Order()
for _D=#multi.Mainloop,1,-1 do for _D=#multi.Mainloop,1,-1 do
if multi.Mainloop[_D]~=nil then if multi.Mainloop[_D]~=nil then
multi.Mainloop[_D].Id=_D multi.Mainloop[_D].Id=_D
multi.Mainloop[_D]:Act() multi.Mainloop[_D]:Act()
end end
end end
end end
function multi:benchMark(sec) function multi:benchMark(sec)
local temp=multi:newStep(2) local temp=multi:newStep(2)
temp.CC=0 temp.CC=0
temp:OnStep(function(pos,step) step.CC=step.CC+1 end) temp:OnStep(function(pos,step) step.CC=step.CC+1 end)
local Loud=multi:newAlarm(sec) local Loud=multi:newAlarm(sec)
Loud.Link=temp 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) 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 return Loud
end end
--Helpers --Helpers
function multi:FreeMainEvent() function multi:FreeMainEvent()
self.func={} self.func={}
end end
function multi:isPaused() function multi:isPaused()
return not(self.Active) return not(self.Active)
end end
function multi:Pause(n) function multi:Pause(n)
if not(n) then if not(n) then
self.Active=false self.Active=false
table.remove(multi.Mainloop,self.Id) table.remove(multi.Mainloop,self.Id)
table.insert(multi.Paused,self) table.insert(multi.Paused,self)
else else
self:hold(n) self:hold(n)
end end
end end
function multi:Resume() function multi:Resume()
if self:isPaused() then if self:isPaused() then
self.Active=true self.Active=true
table.remove(multi.Paused,self.Id) table.remove(multi.Paused,self.Id)
table.insert(multi.Mainloop,self) table.insert(multi.Mainloop,self)
end end
end end
function multi:Remove() function multi:Remove()
self:Pause() self:Pause()
self:Destroy() self:Destroy()
end end
function multi:Destroy() function multi:Destroy()
self:Pause() self:Pause()
if self:isPaused() then if self:isPaused() then
for i=1,#multi.Paused do for i=1,#multi.Paused do
if multi.Paused[i]==self then if multi.Paused[i]==self then
table.remove(multi.Paused,i) table.remove(multi.Paused,i)
return return
end end
end end
else else
table.remove(multi.Mainloop,self.Id) table.remove(multi.Mainloop,self.Id)
end end
self.Act=function() end self.Act=function() end
end end
function multi:hold(task) function multi:hold(task)
self:Pause() self:Pause()
if type(task)=="number" then if type(task)=="number" then
local alarm=multi:newAlarm(task) local alarm=multi:newAlarm(task)
while alarm.Active==true do while alarm.Active==true do
if love then if love then
multi.lManager() multi.lManager()
else else
multi.Do_Order() multi.Do_Order()
end end
end end
alarm:Destroy() alarm:Destroy()
self:Resume() self:Resume()
elseif type(task)=="function" then elseif type(task)=="function" then
local env=multi:newEvent(task) local env=multi:newEvent(task)
env:OnEvent(function(envt) envt:Pause() envt:Stop() end) env:OnEvent(function(envt) envt:Pause() envt:Stop() end)
while env.Active do while env.Active do
if love then if love then
multi.lManager() multi.lManager()
else else
multi.Do_Order() multi.Do_Order()
end end
end end
env:Destroy() env:Destroy()
self:Resume() self:Resume()
else else
print("Error Data Type!!!") print("Error Data Type!!!")
end end
end end
function multi:oneTime(func,...) function multi:oneTime(func,...)
for _k=1,#multi.Tasks2 do for _k=1,#multi.Tasks2 do
if multi.Tasks2[_k]==func then if multi.Tasks2[_k]==func then
return false return false
end end
end end
table.insert(multi.Tasks2,func) table.insert(multi.Tasks2,func)
func(...) func(...)
return true return true
end end
--Constructors --Constructors
function multi:newEvent(task) function multi:newEvent(task)
local c=multi:newBase() local c=multi:newBase()
c.Type="Event" c.Type="Event"
c.Task=task or function() end c.Task=task or function() end
function c:Act() function c:Act()
if self.Task(self) and self.Active==true then if self.Task(self) and self.Active==true then
self:Pause() self:Pause()
for _E=1,#self.func do for _E=1,#self.func do
self.func[_E](self) self.func[_E](self)
end end
end end
end end
function c:OnEvent(func) function c:OnEvent(func)
table.insert(self.func,func) table.insert(self.func,func)
end end
return c return c
end end
function multi:newAlarm(set) function multi:newAlarm(set)
local c=multi:newBase() local c=multi:newBase()
c.Type="Alarm" c.Type="Alarm"
c.timer=os.clock() c.timer=os.clock()
c.set=set or 0 c.set=set or 0
function c:Act() function c:Act()
if self.Active==true then if self.Active==true then
if os.clock()-self.timer>=self.set then if os.clock()-self.timer>=self.set then
self:Pause() self:Pause()
for i=1,#self.func do for i=1,#self.func do
self.func[i](self) self.func[i](self)
end end
end end
end end
end end
function c:Reset(n) function c:Reset(n)
if n then self.set=n end if n then self.set=n end
self.timer=os.clock() self.timer=os.clock()
self:Resume() self:Resume()
end end
function c:OnRing(func) function c:OnRing(func)
table.insert(self.func,func) table.insert(self.func,func)
end end
return c return c
end end
function multi:newTask(func) function multi:newTask(func)
table.insert(multi.Tasks,func) table.insert(multi.Tasks,func)
end end
function multi:newLoop() function multi:newLoop()
local c=multi:newBase() local c=multi:newBase()
c.Type="Loop" c.Type="Loop"
function c:Act() function c:Act()
if self.Active==true then if self.Active==true then
for i=1,#self.func do for i=1,#self.func do
self.func[i](os.clock()-multi.Start,self) self.func[i](os.clock()-multi.Start,self)
end end
end end
end end
function c:OnLoop(func) function c:OnLoop(func)
table.insert(self.func,func) table.insert(self.func,func)
end end
return c return c
end end
function multi:newStep(start,reset,count,skip) function multi:newStep(start,reset,count,skip)
local c=multi:newBase() local c=multi:newBase()
think=1 think=1
c.Type="Step" c.Type="Step"
c.pos=start or 1 c.pos=start or 1
c.endAt=reset or math.huge c.endAt=reset or math.huge
c.skip=skip or 0 c.skip=skip or 0
c.spos=0 c.spos=0
c.count=count or 1*think c.count=count or 1*think
c.funcE={} c.funcE={}
c.start=start or 1 c.start=start or 1
if start~=nil and reset~=nil then if start~=nil and reset~=nil then
if start>reset then if start>reset then
think=-1 think=-1
end end
end end
function c:Act() function c:Act()
if self~=nil then if self~=nil then
if self.spos==0 then if self.spos==0 then
if self.Active==true then if self.Active==true then
for i=1,#self.func do for i=1,#self.func do
self.func[i](self.pos,self) self.func[i](self.pos,self)
end end
self.pos=self.pos+self.count self.pos=self.pos+self.count
end end
end end
end end
self.spos=self.spos+1 self.spos=self.spos+1
if self.spos>=self.skip then if self.spos>=self.skip then
self.spos=0 self.spos=0
end end
end end
function c:OnStep(func) function c:OnStep(func)
table.insert(self.func,1,func) table.insert(self.func,1,func)
end end
function c:OnEnd(func) function c:OnEnd(func)
table.insert(self.funcE,func) table.insert(self.funcE,func)
end end
function c:Update(start,reset,count,skip) function c:Update(start,reset,count,skip)
self.start=start or self.start self.start=start or self.start
self.endAt=reset or self.endAt self.endAt=reset or self.endAt
self.skip=skip or self.skip self.skip=skip or self.skip
self.count=count or self.count self.count=count or self.count
self:Resume() self:Resume()
end end
c:OnStep(function(p,s) c:OnStep(function(p,s)
if s.count>0 and s.endAt==p then if s.count>0 and s.endAt==p then
for fe=1,#s.funcE do for fe=1,#s.funcE do
s.funcE[fe](s) s.funcE[fe](s)
end end
s.pos=s.start-1 s.pos=s.start-1
elseif s.count<0 and s.endAt==p then elseif s.count<0 and s.endAt==p then
for fe=1,#s.funcE do for fe=1,#s.funcE do
s.funcE[fe](s) s.funcE[fe](s)
end end
s.pos=s.start-1 s.pos=s.start-1
end end
end) end)
return c return c
end end
function multi:newTStep(start,reset,count,set) function multi:newTStep(start,reset,count,set)
local c=multi:newBase() local c=multi:newBase()
think=1 think=1
c.Type="TStep" c.Type="TStep"
c.start=start or 1 c.start=start or 1
local reset = reset or math.huge local reset = reset or math.huge
c.endAt=reset c.endAt=reset
c.pos=start or 1 c.pos=start or 1
c.skip=skip or 0 c.skip=skip or 0
c.count=count or 1*think c.count=count or 1*think
c.funcE={} c.funcE={}
c.timer=os.clock() c.timer=os.clock()
c.set=set or 1 c.set=set or 1
function c:Update(start,reset,count,set) function c:Update(start,reset,count,set)
self.start=start or self.start self.start=start or self.start
self.pos=start self.pos=start
self.endAt=reset or self.endAt self.endAt=reset or self.endAt
self.set=set or self.set self.set=set or self.set
self.count=count or self.count or 1 self.count=count or self.count or 1
self.timer=os.clock() self.timer=os.clock()
self:Resume() self:Resume()
end end
function c:Act() function c:Act()
if self.Active then if self.Active then
if os.clock()-self.timer>=self.set then if os.clock()-self.timer>=self.set then
self:Reset() self:Reset()
for i=1,#self.func do for i=1,#self.func do
self.func[i](self.pos,self) self.func[i](self.pos,self)
end end
if self.endAt==self.pos then if self.endAt==self.pos then
for fe=1,#self.funcE do for fe=1,#self.funcE do
self.funcE[fe](self) self.funcE[fe](self)
end end
self.pos=self.start-1 self.pos=self.start-1
end end
self.pos=self.pos+self.count self.pos=self.pos+self.count
end end
end end
end end
function c:OnEnd(func) function c:OnEnd(func)
table.insert(self.funcE,func) table.insert(self.funcE,func)
end end
function c:Reset(n) function c:Reset(n)
if n then self.set=n end if n then self.set=n end
self.timer=os.clock() self.timer=os.clock()
self:Resume() self:Resume()
end end
function c:OnStep(func) function c:OnStep(func)
table.insert(self.func,func) table.insert(self.func,func)
end end
return c return c
end end
function multi:inQueue(func) function multi:inQueue(func)
if self.Id==-1 then if self.Id==-1 then
print("Error: Can't queue the multi object") print("Error: Can't queue the multi object")
return return
end end
local c=multi:newBase(self.Id) local c=multi:newBase(self.Id)
self.Id=self.Id-1 self.Id=self.Id-1
c.Type="Queue" c.Type="Queue"
c.Task=func c.Task=func
c.Link=self c.Link=self
function c:Act() function c:Act()
self.Task(self.Link) self.Task(self.Link)
self:Destroy() self:Destroy()
end end
end end
function multi:newTrigger(func) function multi:newTrigger(func)
local c=multi:newBase() local c=multi:newBase()
c.Type="Trigger" c.Type="Trigger"
c.trigfunc=func or function() end c.trigfunc=func or function() end
function c:Fire(...) function c:Fire(...)
self:trigfunc(self,...) self:trigfunc(self,...)
end end
return c return c
end end
--Managers --Managers
function multi:mainloop() function multi:mainloop()
for i=1,#multi.Tasks do for i=1,#multi.Tasks do
multi.Tasks[i]() multi.Tasks[i]()
end end
multi.Start=os.clock() multi.Start=os.clock()
while self.Active do while self.Active do
multi.Do_Order() multi.Do_Order()
end end
end end
function multi._tFunc(dt) function multi._tFunc(dt)
if dt then if dt then
multi.pump=true multi.pump=true
end end
multi.pumpvar=dt multi.pumpvar=dt
multi.Start=os.clock() multi.Start=os.clock()
end end
function multi:uManager(dt) function multi:uManager(dt)
multi:oneTime(multi._tFunc,dt) multi:oneTime(multi._tFunc,dt)
multi.Do_Order() multi.Do_Order()
end 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
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
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
+32 -32
View File
@@ -1,33 +1,33 @@
package = "multi" package = "multi"
version = "1.10.0" version = "1.10.0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.10.0", tag = "v1.10.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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! 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes" "lanes"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+31 -31
View File
@@ -1,32 +1,32 @@
package = "multi" package = "multi"
version = "1.11.0" version = "1.11.0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.11.0", tag = "v1.11.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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) 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes" "lanes"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+29 -29
View File
@@ -1,30 +1,30 @@
package = "multi" package = "multi"
version = "1.8-2" version = "1.8-2"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.8.2", tag = "v1.8.2",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1, < 5.2" "lua >= 5.1, < 5.2"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua" ["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
} }
} }
+29 -29
View File
@@ -1,30 +1,30 @@
package = "multi" package = "multi"
version = "1.8-3" version = "1.8-3"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.8.3", tag = "v1.8.3",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1, < 5.2" "lua >= 5.1, < 5.2"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua" ["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
} }
} }
+29 -29
View File
@@ -1,30 +1,30 @@
package = "multi" package = "multi"
version = "1.8-4" version = "1.8-4"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.8.4", tag = "v1.8.4",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1, < 5.2" "lua >= 5.1, < 5.2"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua" ["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
} }
} }
+29 -29
View File
@@ -1,30 +1,30 @@
package = "multi" package = "multi"
version = "1.8-5" version = "1.8-5"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.8.5", tag = "v1.8.5",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1, < 5.2" "lua >= 5.1, < 5.2"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua" ["multi.integration.shared.shared"] = "multi/integration/shared/shared.lua"
} }
} }
+29 -29
View File
@@ -1,30 +1,30 @@
package = "multi" package = "multi"
version = "1.8-6" version = "1.8-6"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.8.6", tag = "v1.8.6",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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! 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1, < 5.2" "lua >= 5.1, < 5.2"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+30 -30
View File
@@ -1,31 +1,31 @@
package = "multi" package = "multi"
version = "1.9-1" version = "1.9-1"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.9.1", tag = "v1.9.1",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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! 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1, < 5.2" "lua >= 5.1, < 5.2"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+32 -32
View File
@@ -1,33 +1,33 @@
package = "multi" package = "multi"
version = "1.9-2" version = "1.9-2"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.9.2", tag = "v1.9.2",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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! 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes" "lanes"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+32 -32
View File
@@ -1,33 +1,33 @@
package = "multi" package = "multi"
version = "1.9-3" version = "1.9-3"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v1.9.3", tag = "v1.9.3",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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! 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes" "lanes"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
-- Note the required Lua syntax when listing submodules as keys -- Note the required Lua syntax when listing submodules as keys
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.all"] = "multi/all.lua", ["multi.all"] = "multi/all.lua",
["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua", ["multi.compat.backwards[1,5,0]"] = "multi/compat/backwards[1,5,0].lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+31 -31
View File
@@ -1,32 +1,32 @@
package = "multi" package = "multi"
version = "12.0-0" version = "12.0-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v12.0.0", tag = "v12.0.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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) 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes", "lanes",
"lua-net" "lua-net"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.networkManager"] = "multi/integration/networkManager.lua", ["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+31 -31
View File
@@ -1,32 +1,32 @@
package = "multi" package = "multi"
version = "12.2-0" version = "12.2-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v12.2.0", tag = "v12.2.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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) 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes", "lanes",
"lua-net" "lua-net"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.networkManager"] = "multi/integration/networkManager.lua", ["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+30 -30
View File
@@ -1,31 +1,31 @@
package = "multi" package = "multi"
version = "12.2-1" version = "12.2-1"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v12.2.1", tag = "v12.2.1",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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) 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi.init"] = "multi/init.lua", ["multi.init"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.networkManager"] = "multi/integration/networkManager.lua", ["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+30 -30
View File
@@ -1,31 +1,31 @@
package = "multi" package = "multi"
version = "13.0-0" version = "13.0-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v13.0.0", tag = "v13.0.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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) 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.networkManager"] = "multi/integration/networkManager.lua", ["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+30 -30
View File
@@ -1,31 +1,31 @@
package = "multi" package = "multi"
version = "13.1-0" version = "13.1-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v13.1.0", tag = "v13.1.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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) 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.networkManager"] = "multi/integration/networkManager.lua", ["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+34 -34
View File
@@ -1,35 +1,35 @@
package = "multi" package = "multi"
version = "14.0-0" version = "14.0-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v14.0.0", tag = "v14.0.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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) 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua", --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
["multi.integration.shared"] = "multi/integration/shared.lua" ["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+34 -34
View File
@@ -1,35 +1,35 @@
package = "multi" package = "multi"
version = "14.1-0" version = "14.1-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v14.1.0", tag = "v14.1.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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. 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", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"bin", "bin",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua", --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
--["multi.integration.shared"] = "multi/integration/shared.lua" --["multi.integration.shared"] = "multi/integration/shared.lua"
} }
} }
+33 -33
View File
@@ -1,34 +1,34 @@
package = "multi" package = "multi"
version = "14.2-0" version = "14.2-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v14.2.0", tag = "v14.2.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for how to use.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua", --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
} }
} }
+37 -37
View File
@@ -1,38 +1,38 @@
package = "multi" package = "multi"
version = "15.0-0" version = "15.0-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v15.0.0", tag = "v15.0.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for how to use.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.integration.threading"] = "multi/integration/threading.lua", ["multi.integration.threading"] = "multi/integration/threading.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua", ["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua", ["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua", ["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua", --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
} }
} }
+41 -41
View File
@@ -1,42 +1,42 @@
package = "multi" package = "multi"
version = "15.1-0" version = "15.1-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "V15.1.0", tag = "V15.1.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for documentation.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1", "lua >= 5.1",
"lanes", "lanes",
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.compat.love2d"] = "multi/compat/love2d.lua", ["multi.compat.love2d"] = "multi/compat/love2d.lua",
["multi.compat.lovr"] = "multi/compat/lovr.lua", ["multi.compat.lovr"] = "multi/compat/lovr.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
--["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua", --["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua",
--["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua", --["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua",
--["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua", --["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua",
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua", ["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua", ["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua", ["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.threading"] = "multi/integration/threading.lua", ["multi.integration.threading"] = "multi/integration/threading.lua",
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua", --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
} }
} }
+38 -38
View File
@@ -1,39 +1,39 @@
package = "multi" package = "multi"
version = "15.2-0" version = "15.2-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v15.2.0", tag = "v15.2.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for documentation.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1" "lua >= 5.1"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
--["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua", --["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua",
--["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua", --["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua",
--["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua", --["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua",
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua", ["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua", ["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua", ["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.threading"] = "multi/integration/threading.lua", ["multi.integration.threading"] = "multi/integration/threading.lua",
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua", --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
} }
} }
+38 -38
View File
@@ -1,39 +1,39 @@
package = "multi" package = "multi"
version = "15.2-1" version = "15.2-1"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v15.2.1", tag = "v15.2.1",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for documentation.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1" "lua >= 5.1"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "multi/init.lua", ["multi"] = "multi/init.lua",
["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua", ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
--["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua", --["multi.integration.lovrManager"] = "multi/integration/lovrManager/init.lua",
--["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua", --["multi.integration.lovrManager.extensions"] = "multi/integration/lovrManager/extensions.lua",
--["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua", --["multi.integration.lovrManager.threads"] = "multi/integration/lovrManager/threads.lua",
["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua", ["multi.integration.pesudoManager"] = "multi/integration/pesudoManager/init.lua",
["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua", ["multi.integration.pesudoManager.extensions"] = "multi/integration/pesudoManager/extensions.lua",
["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua", ["multi.integration.pesudoManager.threads"] = "multi/integration/pesudoManager/threads.lua",
["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua", ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
["multi.integration.threading"] = "multi/integration/threading.lua", ["multi.integration.threading"] = "multi/integration/threading.lua",
--["multi.integration.networkManager"] = "multi/integration/networkManager.lua", --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
} }
} }
+38 -38
View File
@@ -1,39 +1,39 @@
package = "multi" package = "multi"
version = "15.3-0" version = "15.3-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v15.3.0", tag = "v15.3.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for documentation.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1" "lua >= 5.1"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "init.lua", ["multi"] = "init.lua",
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "integration/loveManager/init.lua", ["multi.integration.loveManager"] = "integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua", --["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua", --["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua", --["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
["multi.integration.pesudoManager"] = "integration/pesudoManager/init.lua", ["multi.integration.pesudoManager"] = "integration/pesudoManager/init.lua",
["multi.integration.pesudoManager.extensions"] = "integration/pesudoManager/extensions.lua", ["multi.integration.pesudoManager.extensions"] = "integration/pesudoManager/extensions.lua",
["multi.integration.pesudoManager.threads"] = "integration/pesudoManager/threads.lua", ["multi.integration.pesudoManager.threads"] = "integration/pesudoManager/threads.lua",
["multi.integration.luvitManager"] = "integration/luvitManager.lua", ["multi.integration.luvitManager"] = "integration/luvitManager.lua",
["multi.integration.threading"] = "integration/threading.lua", ["multi.integration.threading"] = "integration/threading.lua",
--["multi.integration.networkManager"] = "integration/networkManager.lua", --["multi.integration.networkManager"] = "integration/networkManager.lua",
} }
} }
+38 -38
View File
@@ -1,39 +1,39 @@
package = "multi" package = "multi"
version = "15.3-1" version = "15.3-1"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "15.3.1", tag = "15.3.1",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for documentation.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1" "lua >= 5.1"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "init.lua", ["multi"] = "init.lua",
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "integration/loveManager/init.lua", ["multi.integration.loveManager"] = "integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua", --["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua", --["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua", --["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
["multi.integration.pesudoManager"] = "integration/pesudoManager/init.lua", ["multi.integration.pesudoManager"] = "integration/pesudoManager/init.lua",
["multi.integration.pesudoManager.extensions"] = "integration/pesudoManager/extensions.lua", ["multi.integration.pesudoManager.extensions"] = "integration/pesudoManager/extensions.lua",
["multi.integration.pesudoManager.threads"] = "integration/pesudoManager/threads.lua", ["multi.integration.pesudoManager.threads"] = "integration/pesudoManager/threads.lua",
["multi.integration.luvitManager"] = "integration/luvitManager.lua", ["multi.integration.luvitManager"] = "integration/luvitManager.lua",
["multi.integration.threading"] = "integration/threading.lua", ["multi.integration.threading"] = "integration/threading.lua",
--["multi.integration.networkManager"] = "integration/networkManager.lua", --["multi.integration.networkManager"] = "integration/networkManager.lua",
} }
} }
+41 -41
View File
@@ -1,42 +1,42 @@
package = "multi" package = "multi"
version = "16.0-0" version = "16.0-0"
source = { source = {
url = "git://github.com/rayaman/multi.git", url = "git://github.com/rayaman/multi.git",
tag = "v16.0.0", tag = "v16.0.0",
} }
description = { description = {
summary = "Lua Multi tasking library", summary = "Lua Multi tasking library",
detailed = [[ 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). 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. Check github for documentation.
]], ]],
homepage = "https://github.com/rayaman/multi", homepage = "https://github.com/rayaman/multi",
license = "MIT" license = "MIT"
} }
dependencies = { dependencies = {
"lua >= 5.1" "lua >= 5.1"
} }
build = { build = {
type = "builtin", type = "builtin",
modules = { modules = {
["multi"] = "init.lua", ["multi"] = "init.lua",
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua", ["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua", ["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua", ["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
["multi.integration.loveManager"] = "integration/loveManager/init.lua", ["multi.integration.loveManager"] = "integration/loveManager/init.lua",
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua", ["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua", ["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
["multi.integration.loveManager.utils"] = "integration/loveManager/threads.lua", ["multi.integration.loveManager.utils"] = "integration/loveManager/threads.lua",
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua", --["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua", --["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua", --["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
["multi.integration.pseudoManager"] = "integration/pseudoManager/init.lua", ["multi.integration.pseudoManager"] = "integration/pseudoManager/init.lua",
["multi.integration.pseudoManager.extensions"] = "integration/pseudoManager/extensions.lua", ["multi.integration.pseudoManager.extensions"] = "integration/pseudoManager/extensions.lua",
["multi.integration.pseudoManager.threads"] = "integration/pseudoManager/threads.lua", ["multi.integration.pseudoManager.threads"] = "integration/pseudoManager/threads.lua",
["multi.integration.luvitManager"] = "integration/luvitManager.lua", ["multi.integration.luvitManager"] = "integration/luvitManager.lua",
["multi.integration.threading"] = "integration/threading.lua", ["multi.integration.threading"] = "integration/threading.lua",
["multi.integration.sharedExtensions"] = "integration/sharedExtensions/init.lua", ["multi.integration.sharedExtensions"] = "integration/sharedExtensions/init.lua",
["multi.integration.priorityManager"] = "integration/priorityManager/init.lua", ["multi.integration.priorityManager"] = "integration/priorityManager/init.lua",
--["multi.integration.networkManager"] = "integration/networkManager.lua", --["multi.integration.networkManager"] = "integration/networkManager.lua",
} }
} }
-42
View File
@@ -1,42 +0,0 @@
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",
}
}
-42
View File
@@ -1,42 +0,0 @@
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",
}
}
-42
View File
@@ -1,42 +0,0 @@
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",
}
}
+39
View File
@@ -0,0 +1,39 @@
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.window.title = "MultiThreadTest" -- The window title (string)
t.window.icon = nil -- Filepath to an image to use as the window's icon (string)
t.window.width = 1280 -- The window width (number)
t.window.height = 720 -- The window height (number)
t.window.borderless = false -- Remove all border visuals from the window (boolean)
t.window.resizable = true -- Let the window be user-resizable (boolean)
t.window.minwidth = 1 -- Minimum window width if the window is resizable (number)
t.window.minheight = 1 -- Minimum window height if the window is resizable (number)
t.window.fullscreen = false -- Enable fullscreen (boolean)
t.window.fullscreentype = "desktop" -- Standard fullscreen or desktop fullscreen mode (string)
t.window.vsync = false -- Enable vertical sync (boolean)
t.window.fsaa = 2 -- The number of samples to use with multi-sampled antialiasing (number)
t.window.display = 1 -- Index of the monitor to show the window in (number)
t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean)
t.window.srgb = false -- Enable sRGB gamma correction when drawing to the screen (boolean)
t.window.x = nil -- The x-coordinate of the window's position in the specified display (number)
t.window.y = nil -- The y-coordinate of the window's position in the specified display (number)
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 = false -- Enable the system module (boolean)
t.modules.timer = false -- Enable the timer module (boolean)
t.modules.window = false -- Enable the window module (boolean)
t.modules.thread = true -- Enable the thread module (boolean)
end
-244
View File
@@ -1,244 +0,0 @@
--[[
Test suite for multi.lua
Run with: lua multi_test.lua
Requires multi.lua to be in the same directory or on the Lua path.
Compatible with Lua 5.1, 5.2, 5.3, 5.4, and LuaJIT.
]]
package.path = "../?/init.lua;../?.lua;../init.lua;../?.lua;" .. package.path
-- ─────────────────────────────────────────────
-- Minimal test runner
-- ─────────────────────────────────────────────
local passed, failed, skipped = 0, 0, 0
local failures = {}
local function test(name, fn)
local ok, err = pcall(fn)
if ok then
passed = passed + 1
io.write("\x1b[92m ✓\x1b[0m " .. name .. "\n")
else
failed = failed + 1
table.insert(failures, {name = name, err = tostring(err)})
io.write("\x1b[91m ✗\x1b[0m " .. name .. "\n")
io.write(" " .. tostring(err) .. "\n")
end
end
local function skip(name, reason)
skipped = skipped + 1
io.write("\x1b[93m -\x1b[0m " .. name .. " [SKIPPED: " .. (reason or "") .. "]\n")
end
local function section(name)
io.write("\n\x1b[97m── " .. name .. " ──\x1b[0m\n")
end
local function assert_eq(a, b, msg)
if a ~= b then
error((msg or "assert_eq failed") .. ": expected " .. tostring(b) .. ", got " .. tostring(a), 2)
end
end
local function assert_truthy(v, msg)
if not v then
error((msg or "expected truthy value, got falsy") .. ": " .. tostring(v), 2)
end
end
local function assert_falsy(v, msg)
if v then
error((msg or "expected falsy value, got truthy") .. ": " .. tostring(v), 2)
end
end
local function assert_type(v, t, msg)
if type(v) ~= t then
error((msg or "type mismatch") .. ": expected " .. t .. ", got " .. type(v), 2)
end
end
-- ─────────────────────────────────────────────
-- Load the library
-- ─────────────────────────────────────────────
local multi, thread
local ok, err = pcall(function()
multi, thread = require("multi"):init()
end)
if not ok then
io.write("\x1b[91mFATAL: Could not load multi.lua: " .. tostring(err) .. "\x1b[0m\n")
io.write("Make sure multi.lua is in the same directory or on package.path.\n")
os.exit(1)
end
-- Helper: run the scheduler for up to `max_ticks` ticks or until `done()` returns true.
local function run_until(done, max_ticks)
max_ticks = max_ticks or 10000
for _ = 1, max_ticks do
multi:uManager()
if done and done() then return true end
end
return done == nil
end
section("Initialization")
test("lanesManager init returns GLOBAL and THREAD", function()
local GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
assert_type(GLOBAL, "table")
assert_type(THREAD, "table")
end)
test("lanesManager sets integration table", function()
assert_type(multi.integration.GLOBAL, "table")
assert_type(multi.integration.THREAD, "table")
end)
-- initialize once for rest of tests
local GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
-- ─────────────────────────────────────────────
section("SystemThreadedQueue")
test("queue push/pop", function()
local q = multi:newSystemThreadedQueue("testQ1")
q:push(42)
local val = q:pop()
assert_eq(val, 42)
end)
test("queue peek does not remove", function()
local q = multi:newSystemThreadedQueue("testQ2")
q:push("hello")
assert_eq(q:peek(), "hello")
assert_eq(q:pop(), "hello")
end)
test("queue empty returns nil", function()
local q = multi:newSystemThreadedQueue("testQ3")
assert_eq(q:pop(), nil)
end)
-- ─────────────────────────────────────────────
section("SystemThreadedTable")
test("table set/get", function()
local t = multi:newSystemThreadedTable("testT1")
t.foo = "bar"
assert_eq(t.foo, "bar")
end)
test("table overwrite", function()
local t = multi:newSystemThreadedTable("testT2")
t.x = 1
t.x = 2
assert_eq(t.x, 2)
end)
-- ─────────────────────────────────────────────
section("THREAD API")
test("THREAD set/get", function()
THREAD.set("abc", 123)
assert_eq(THREAD.get("abc"), 123)
end)
test("THREAD getCores > 0", function()
assert_truthy(THREAD.getCores() > 0)
end)
-- ─────────────────────────────────────────────
section("SystemThreadedConnection")
test("connection fires event", function()
local conn = multi:newSystemThreadedConnection("conn1"):init()
local received = nil
conn(function(v)
received = v
end)
conn:Fire("ping")
run_until(function()
return received ~= nil
end, 5000)
assert_eq(received, "ping")
end)
-- ─────────────────────────────────────────────
section("SystemThreadedJobQueue")
test("job queue executes function", function()
local jq = multi:newSystemThreadedJobQueue(1)
jq:registerFunction("add", function(a, b)
return a + b
end)
local result = nil
jq.OnJobCompleted(function(_, val)
result = val
end)
jq:pushJob("add", 2, 3)
run_until(function()
return result ~= nil
end, 10000)
assert_eq(result, 5)
end)
-- ─────────────────────────────────────────────
section("JobQueue newFunction")
test("newFunction returns correct result", function()
local jq = multi:newSystemThreadedJobQueue(1)
local fn = jq:newFunction(function(a, b)
return a * b
end,true)
local result = nil
result = fn(3, 4)
run_until(function()
return result ~= nil
end, 10000)
assert_eq(result, 12)
end)
-- ─────────────────────────────────────────────
-- Summary
-- ─────────────────────────────────────────────
section("Results")
io.write("\n")
io.write("Passed: " .. passed .. "\n")
io.write("Failed: " .. failed .. "\n")
io.write("Skipped: " .. skipped .. "\n")
if failed > 0 then
io.write("\nFailures:\n")
for _, f in ipairs(failures) do
io.write(" - " .. f.name .. "\n")
io.write(" " .. f.err .. "\n")
end
os.exit(1)
end
+10
View File
@@ -0,0 +1,10 @@
package.path = "../?/init.lua;../?.lua;"..package.path
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
require("lldebugger").start()
end
GLOBAL, THREAD = require("multi.integration.loveManager"):init()
require("runtests")
require("threadtests")
+1
View File
@@ -0,0 +1 @@
../
-1095
View File
File diff suppressed because it is too large Load Diff
+193
View File
@@ -0,0 +1,193 @@
package.path = "../?/init.lua;../?.lua;./init.lua;./?.lua;"..package.path
local multi, thread = require("multi"):init{print=true,warn=true,error=true}--{priority=true}
local good = false
local proc = multi:newProcessor("Test")
proc.Start()
proc:newAlarm(3):OnRing(function()
good = true
end)
runTest = thread:newFunction(function()
local alarms,tsteps,steps,loops,tloops,updaters,events=false,0,0,0,0,0,false
multi.print("Testing Basic Features. If this fails most other features will probably not work!")
proc:newAlarm(2):OnRing(function(a)
alarms = true
a:Destroy()
end)
proc:newTStep(1,10,1,.1):OnStep(function(t)
tsteps = tsteps + 1
end):OnEnd(function(step)
step:Destroy()
end)
proc:newStep(1,10):OnStep(function(s)
steps = steps + 1
end):OnEnd(function(step)
step:Destroy()
end)
local loop = proc:newLoop(function(l)
loops = loops + 1
end)
proc:newTLoop(function(t)
tloops = tloops + 1
end,.1)
local updater = proc:newUpdater(1):OnUpdate(function()
updaters = updaters + 1
end)
local event = proc:newEvent(function()
return alarms
end)
event.OnEvent(function(evnt)
evnt:Destroy()
events = true
multi.success("Alarms: Ok")
multi.success("Events: Ok")
if tsteps == 10 then multi.success("TSteps: Ok") else multi.error("TSteps: Bad!") end
if steps == 10 then multi.success("Steps: Ok") else multi.error("Steps: Bad!") end
if loops > 100 then multi.success("Loops: Ok") else multi.error("Loops: Bad!") end
if tloops > 10 then multi.success("TLoops: Ok") else multi.error("TLoops: Bad!") end
if updaters > 100 then multi.success("Updaters: Ok") else multi.error("Updaters: Bad!") end
end)
thread.hold(event.OnEvent)
multi.print("Starting Connection and Thread tests!")
func = thread:newFunction(function(count)
multi.print("Starting Status test: ",count)
local a = 0
while true do
a = a + 1
thread.sleep(.1)
thread.pushStatus(a,count)
if a == count then break end
end
return "Done", true, math.random(1,10000)
end)
local ret = func(10)
local ret2 = func(15)
local ret3 = func(20)
local s1,s2,s3 = 0,0,0
ret.OnError(function(...)
multi.error("Func 1:",...)
end)
ret2.OnError(function(...)
multi.error("Func 2:",...)
end)
ret3.OnError(function(...)
multi.error("Func 3:",...)
end)
ret.OnStatus(function(part,whole)
s1 = math.ceil((part/whole)*1000)/10
end)
ret2.OnStatus(function(part,whole)
s2 = math.ceil((part/whole)*1000)/10
end)
ret3.OnStatus(function(part,whole)
s3 = math.ceil((part/whole)*1000)/10
end)
ret.OnReturn(function(...)
multi.success("Done 1",...)
end)
ret2.OnReturn(function(...)
multi.success("Done 2",...)
end)
ret3.OnReturn(function(...)
multi.success("Done 3",...)
end)
local err, timeout = thread.hold(ret.OnReturn * ret2.OnReturn * ret3.OnReturn)
if s1 == 100 and s2 == 100 and s3 == 100 then
multi.success("Threads: All tests Ok")
else
if s1>0 and s2>0 and s3 > 0 then
multi.success("Thread OnStatus: Ok")
else
multi.error("Threads OnStatus or thread.hold(conn) Error!")
end
if timeout then
multi.error("Connection Error!")
else
multi.success("Connection Test 1: Ok")
end
multi.error("Connection holding Error!")
end
conn1 = proc:newConnection()
conn2 = proc:newConnection()
conn3 = proc:newConnection()
local c1,c2,c3,c4 = false,false,false,false
local a = conn1(function()
c1 = true
end)
local b = conn2(function()
c2 = true
end)
local c = conn3(function()
c3 = true
end)
local d = conn3(function()
c4 = true
end)
conn1:Fire()
conn2:Fire()
conn3:Fire()
if c1 and c2 and c3 and c4 then
multi.success("Connection Test 2: Ok")
else
multi.error("Connection Test 2: Error")
end
c3 = false
c4 = false
conn3:Unconnect(d)
conn3:Fire()
if c3 and not(c4) then
multi.success("Connection Test 3: Ok")
else
multi.error("Connection Test 3: Error removing connection")
end
if not love then
local ec = 0
multi.print("Testing pseudo threading")
capture = io.popen("lua tests/threadtests.lua p"):read("*a")
if capture:lower():match("error") then
ec = ec + 1
os.exit(1)
else
io.write(capture)
end
multi.print("Testing lanes threading")
capture = io.popen("lua tests/threadtests.lua l"):read("*a")
if capture:lower():match("error") then
ec = ec + 1
os.exit(1)
else
io.write(capture)
end
os.exit(0)
end
end)
local handle = runTest()
handle.OnError(function(...)
multi.error("Something went wrong with the test!")
print(...)
end)
if not love then
multi:mainloop()
else
local hold = thread:newFunction(function()
thread.hold(handle.OnError + handle.OnReturn)
end, true)
hold()
multi.print("Starting Threading tests!")
end
+298
View File
@@ -0,0 +1,298 @@
package.path = "../?/init.lua;../?.lua;"..package.path
multi, thread = require("multi"):init{print=true,warn=true,debugging=true}
-- for i,v in pairs(thread) do
-- print(i,v)
-- end
-- require("multi.integration.priorityManager")
-- multi.debugging.OnObjectCreated(function(obj, process)
-- multi.print("Created:", obj.Type, "in", process.Type, process:getFullName())
-- end)
-- multi.debugging.OnObjectDestroyed(function(obj, process)
-- multi.print("Destroyed:", obj.Type, "in", process.Type, process:getFullName())
-- end)
-- test = multi:newProcessor("Test")
-- test:setPriorityScheme(multi.priorityScheme.TimeBased)
-- test:newUpdater(10000000):OnUpdate(function()
-- print("Print is slowish")
-- end)
-- print("Running...")
-- local conn1, conn2 = multi:newConnection(), multi:newConnection()
-- conn3 = conn1 + conn2
-- conn1(function()
-- print("Hi 1")
-- end)
-- conn2(function()
-- print("Hi 2")
-- end)
-- conn3(function()
-- print("Hi 3")
-- end)
-- function test(a,b,c)
-- print("I run before all and control if execution should continue!")
-- return a>b
-- end
-- conn4 = test .. conn1
-- conn5 = conn2 .. function() print("I run after it all!") end
-- conn4:Fire(3,2,3)
-- -- This second one won't trigger the Hi's
-- conn4:Fire(1,2,3)
-- conn5(function()
-- print("Test 1")
-- end)
-- conn5(function()
-- print("Test 2")
-- end)
-- conn5(function()
-- print("Test 3")
-- end)
-- conn5:Fire()
-- multi.print("Testing thread:newProcessor()")
-- proc = thread:newProcessor("Test")
-- proc:newLoop(function()
-- multi.print("Running...")
-- thread.sleep(1)
-- end)
-- proc:newThread(function()
-- while true do
-- multi.warn("Everything is a thread in this proc!")
-- thread.sleep(1)
-- end
-- end)
-- proc:newAlarm(5):OnRing(function(a)
-- multi.print(";) Goodbye")
-- a:Destroy()
-- end)
-- local func = thread:newFunction(function()
-- thread.sleep(4)
-- print("Hello!")
-- end)
-- multi:newTLoop(func, 1)
-- multi:mainloop()
-- multi:setTaskDelay(.05)
-- multi:newTask(function()
-- for i = 1, 10 do
-- multi:newTask(function()
-- print("Task "..i)
-- end)
-- end
-- end)
-- local conn = multi:newConnection()
-- conn(function() print("Test 1") end)
-- conn(function() print("Test 2") end)
-- conn(function() print("Test 3") end)
-- conn(function() print("Test 4") end)
-- print("Fire 1")
-- conn:Fire()
-- conn = -conn
-- print("Fire 2")
-- conn:Fire()
-- print(#conn)
-- thread:newThread("Test thread", function()
-- print("Starting thread!")
-- thread.defer(function() -- Runs when the thread finishes execution
-- print("Clean up time!")
-- end)
-- --[[
-- Do lot's of stuff
-- ]]
-- thread.sleep(3)
-- end)
multi:mainloop()
-- local conn1, conn2, conn3 = multi:newConnection(nil,nil,true), multi:newConnection(), multi:newConnection()
-- local link = conn1(function()
-- print("Conn1, first")
-- end)
-- local link2 = conn1(function()
-- print("Conn1, second")
-- end)
-- local link3 = conn1(function()
-- print("Conn1, third")
-- end)
-- local link4 = conn2(function()
-- print("Conn2, first")
-- end)
-- local link5 = conn2(function()
-- print("Conn2, second")
-- end)
-- local link6 = conn2(function()
-- print("Conn2, third")
-- end)
-- print("Links 1-6",link,link2,link3,link4,link5,link6)
-- conn1:Lock(link)
-- print("All conns\n-------------")
-- conn1:Fire()
-- conn2:Fire()
-- conn1:Unlock(link)
-- conn1:Unconnect(link3)
-- conn2:Unconnect(link6)
-- print("All conns Edit\n---------------------")
-- conn1:Fire()
-- conn2:Fire()
-- thread:newThread(function()
-- print("Awaiting status")
-- thread.hold(conn1 + (conn2 * conn3))
-- print("Conn or Conn2 and Conn3")
-- end)
-- multi:newAlarm(1):OnRing(function()
-- print("Conn")
-- conn1:Fire()
-- end)
-- multi:newAlarm(2):OnRing(function()
-- print("Conn2")
-- conn2:Fire()
-- end)
-- multi:newAlarm(3):OnRing(function()
-- print("Conn3")
-- conn3:Fire()
-- os.exit()
-- end)
-- local conn = multi:newSystemThreadedConnection("conn"):init()
-- multi:newSystemThread("Thread_Test_1", function()
-- local multi, thread = require("multi"):init()
-- local conn = GLOBAL["conn"]:init()
-- local console = THREAD.getConsole()
-- conn(function(a,b,c)
-- console.print(THREAD:getName().." was triggered!",a,b,c)
-- end)
-- multi:mainloop()
-- end)
-- multi:newSystemThread("Thread_Test_2", function()
-- local multi, thread = require("multi"):init()
-- local conn = GLOBAL["conn"]:init()
-- local console = THREAD.getConsole()
-- conn(function(a,b,c)
-- console.print(THREAD:getName().." was triggered!",a,b,c)
-- end)
-- multi:newAlarm(2):OnRing(function()
-- console.print("Fire 2!!!")
-- conn:Fire(4,5,6)
-- THREAD.kill()
-- end)
-- multi:mainloop()
-- end)
-- local console = THREAD.getConsole()
-- conn(function(a,b,c)
-- console.print("Mainloop conn got triggered!",a,b,c)
-- end)
-- alarm = multi:newAlarm(1)
-- alarm:OnRing(function()
-- console.print("Fire 1!!!")
-- conn:Fire(1,2,3)
-- end)
-- alarm = multi:newAlarm(3):OnRing(function()
-- multi:newSystemThread("Thread_Test_3",function()
-- local multi, thread = require("multi"):init()
-- local conn = GLOBAL["conn"]:init()
-- local console = THREAD.getConsole()
-- conn(function(a,b,c)
-- console.print(THREAD:getName().." was triggered!",a,b,c)
-- end)
-- multi:newAlarm(4):OnRing(function()
-- console.print("Fire 3!!!")
-- conn:Fire(7,8,9)
-- end)
-- multi:mainloop()
-- end)
-- end)
-- multi:newSystemThread("Thread_Test_4",function()
-- local multi, thread = require("multi"):init()
-- local conn = GLOBAL["conn"]:init()
-- local conn2 = multi:newConnection()
-- local console = THREAD.getConsole()
-- multi:newAlarm(2):OnRing(function()
-- conn2:Fire()
-- end)
-- multi:newThread(function()
-- console.print("Conn Test!")
-- thread.hold(conn + conn2)
-- console.print("It held!")
-- end)
-- multi:mainloop()
-- end)
-- multi:mainloop()
--[[
newFunction function: 0x00fad170
waitFor function: 0x00fad0c8
request function: 0x00fa4f10
newThread function: 0x00fad1b8
--__threads table: 0x00fa4dc8
defer function: 0x00fa4f98
isThread function: 0x00facd40
holdFor function: 0x00fa5058
yield function: 0x00faccf8
hold function: 0x00fa51a0
chain function: 0x00fa5180
__CORES 32
newISOThread function: 0x00fad250
newFunctionBase function: 0x00fad128
requests table: 0x00fa4e68
newProcessor function: 0x00fad190
exec function: 0x00fa50e8
pushStatus function: 0x00fad108
kill function: 0x00faccd8
get function: 0x00fad0a8
set function: 0x00fad088
getCores function: 0x00facd60
skip function: 0x00faccb0
--_Requests function: 0x00fa50a0
getRunningThread function: 0x00fa4fb8
holdWithin function: 0x00facc80
sleep function: 0x00fa4df0
]]
+1 -1
View File
@@ -1,4 +1,4 @@
package.path = "../?/init.lua;../?.lua;../init.lua;../?.lua;" .. package.path package.path = "D:/VSCWorkspace/?/init.lua;D:/VSCWorkspace/?.lua;"..package.path
package.cpath = "C:/luaInstalls/lua5.4/lib/lua/5.4/?/core.dll;" .. package.cpath package.cpath = "C:/luaInstalls/lua5.4/lib/lua/5.4/?/core.dll;" .. package.cpath
multi, thread = require("multi"):init{error=true,warning=true,print=true, priority=true} multi, thread = require("multi"):init{error=true,warning=true,print=true, priority=true}
proc = multi:newProcessor("Thread Test",true) proc = multi:newProcessor("Thread Test",true)
File diff suppressed because it is too large Load Diff