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
10 changed files with 386 additions and 662 deletions
+28 -19
View File
@@ -1,32 +1,41 @@
name: Lua Unit Tests (Matrix)
name: Build & Run tests Ubuntu
on:
push:
branches: [ main ]
branches: [ master ]
pull_request:
branches: [ main ]
branches: [ master ]
jobs:
test:
runs-on: ubuntu-latest
build:
strategy:
fail-fast: false
matrix:
luaVersion: ["5.1", "5.2", "5.3", "5.4", "luajit-2.1.0-beta3"]
build-type: [Release] # Debug
lua: ["lua 5.1", "lua 5.2", "lua 5.3", "lua 5.4", "luajit 2.1.0-beta3"]
os: ["ubuntu-latest"]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Lua
uses: leafo/gh-actions-lua@v10
- uses: actions/checkout@v2
with:
luaVersion: ${{ matrix.luaVersion }}
submodules: recursive
- name: Verify Lua version
run: lua -v
- uses: actions/setup-python@v2
with:
python-version: '3.10'
- name: Run unit tests
- name: Setup env
run: |
# Replace with your actual test file
lua tests/multi_test.lua
pip install hererocks
hererocks lua-pkg --${{ matrix.lua }} -rlatest
- 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
+9 -8
View File
@@ -1,10 +1,11 @@
# Multi Version: 16.1.0 - The Flow State
# Multi Version: 16.0.0 - Connecting the dots
**Key Changes**
- Updated Processors to have more controlled over scheduled processes
- Forwarding connections
- New Timeout handling
Refer to the [Change Log](https://github.com/rayaman/multi/blob/master/docs/changes.md) for more infromation
- Expanded connection logic
- New integration priorityManager
- Tests for threads
- Consistent behavior between the threading integrations
- Improved love2d threading
- Bug fixes
Found an issue? Please [submit it](https://github.com/rayaman/multi/issues) and someone will look into it!
@@ -12,7 +13,7 @@ My multitasking library for lua. It is a pure lua binding, with exceptions of th
</br>
Progress is being made in [v16.2.0](https://github.com/rayaman/multi/tree/v16.2.0)
Progress is being made in [v16.0.0](https://github.com/rayaman/multi/tree/v16.0.0)
---
</br>
@@ -51,7 +52,7 @@ Planned features/TODO
- [x] ~~Create test suite (In progress, mostly done)~~
- [ ] Network Parallelism rework
Usage: [Check out the documentation for more info](https://github.com/rayaman/multi/blob/master/docs/Documentation.md)
Usage: [Check out the documentation for more info](https://github.com/rayaman/multi/blob/master/Documentation.md)
-----
You can run tests in 2 ways:
+2 -172
View File
@@ -1,9 +1,6 @@
# Changelog
Table of contents
---
[Update 16.2.0 - TimeStamps and UUIDs](#update-1620---timestamps-and-uuids-and-bugfixes)</br>
[Update 16.1.0 - The Flow State](#update-1610---the-flow-state)</br>
[Update 16.0.1 - Bug fix](#update-1601---bug-fix)</br>
[Update 16.0.0 - Connecting the dots](#update-1600---getting-the-priorities-straight)</br>
[Update 15.3.1 - Bug fix](#update-1531---bug-fix)</br>
[Update 15.3.0 - A world of connections](#update-1530---a-world-of-connections)</br>
@@ -61,171 +58,6 @@ Table of contents
[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)</br>
[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different)
# Update 16.2.0 - TimeStamps and UUIDs and bugfixes
Added
---
- threadedfunctions, multiobjs and threads contain new method: `GetCreationTimestamp()` With will return a string formated date time using ISO 8601
Changed
---
- Internal uuid functions to not use bitwise operators
Fixed
---
- [Bitwise operations break lua 5.1/luajit](https://github.com/rayaman/multi/issues/73)
# Update 16.1.0 - The Flow State
Added
---
- `multi.UUID()` generates a uuid7, if chronos is installed that will be used as the initial time seed
- `More control over processors`
- `multi:newProcessor(name, opts, priority)` -- Now accepts a opts table. Old param still works
| Option | Description | Default |
| --- | --- | --- |
| Attach | If true a hook will be attached to the parent process and will run when Start is called or Start is set | false |
| MaxObjects | Maximum number of objects that a processor can spawn | -1 (disabled) |
| MaxThreads | Maximum number of threads that a processor can spawn | -1 (disabled) |
| Start | If true the processor will start instantlly | false |
| Priority | If true the processor will use the priority handler | false |
| TaskDelay | Sets the task delay in seconds between each tasks execution | 0 |
| TashHandler | If false will disable the task feature of a processor | true |
- `proc:newThread()` returns nil, "errorstring" if it was unable to create a thread
- `proc:new[Object]` now returns {unscheduled}, "errorstring", used to just return the {scheduledObject} and no errorstring
- `proc:getMaxThreads()` -- returns the max thread limit
- `proc:setMaxThreads(n)` -- sets the max thread limit
- `proc:getMaxObjects()` -- gets the max object limit
- `proc:setMaxObjects(n)` -- sets the max object limit
- `proc.Status` -- A table that contains all status errors that occured in a process
Example:
```lua
local multi, thread = require("multi"):init()
proc = multi:newProcessor("thread test",{
Start = true,
MaxThreads = 1,
MaxObjects = 1,
Attach = true,
TaskDelay = .1,
Priority = true,
TaskHandler = false
})
print(proc:newThread("testing",function()
while true do
print("STATUS:\n---")
for i,v in ipairs(proc.Status) do
print(i,v)
end
thread.sleep(1)
end
end))
proc:newThread("testing 2",function()
while true do
print("testing 2...")
thread.sleep(1)
end
end)
proc:newThread("testing 3",function()
while true do
print("testing 3...")
thread.sleep(1)
end
end)
proc:newLoop(function()
--
end)
print(proc:newLoop(function()
--
end))
multi:mainloop()
```
- `multi.hasType(typ)` returns true if a type has been registered
- `multi.isMultiObj(obj)` returns true if the object is a multi object
- `multi.forwardConnection(src, dest)` forwards events from one connection to another connection. Doesn't modify anything and both connections are triggered when src is Fired, but not when dest is fired.
- `multi.isTimeout(res)` returns true if the response it gets is a timeout type or a string equal to `multi.TIMEOUT`'s value
- `multi:newTimeout(seconds)` returns a connection that will trigger after a certain amount of time. See example below:
```lua
local multi, thread = require("multi"):init()
data = multi:newConnection()
-- This alarm takes too long... We will timeout
multi:newAlarm(4):OnRing(function()
data:Fire({Type="request"},"data is tasty")
end)
multi:newThread(function()
res, data = thread.hold(data + multi:newTimeout(3)) -- combined connections allow this to work
if multi.isTimeout(res) then
print("We timed out!")
else
print("We got the data:", data)
end
os.exit()
end)
multi:mainloop()
```
- `connection % function` can now modify the arguments of a connection. See above example modified below
```lua
local multi, thread = require("multi"):init()
local data = multi:newAlarm(1).OnRing % function() return {Type="request"}, "data is tasty" end
multi:newThread(function()
res, data = thread.hold(data + multi:newTimeout(3))
if multi.isTimeout(res) then
print("We timed out!")
else
print("We got the data:", data)
end
os.exit()
end)
multi:mainloop()
```
If the alarm takes longer the the timeout: `We timed out!` If the alarm is shorter: `We got the data: data is tasty`
Changed
---
- `multi:newBase(tp,ins,callback)` now accepts a tp param and a callback function. Callback is expected to return true/false, errorstring. If callback is false it will cancel scheduling of an object. If type is set the type of the object will be set.
**Note:** This is all internal functionality
# Update 16.0.1 - Bug fix
Fixed
---
- thread.pushStatus() wasn't properly working when forwarding events from THREAD.pushStatus OnStatus connection. This bug also caused stack overflow errors with the following code
```lua
func = thread:newFunction(function()
for i=1,10 do
thread.sleep(1)
thread.pushStatus(i)
end
end)
func2 = thread:newFunction(function()
local ref = func()
ref.OnStatus(function(num)
-- do stuff with this data
thread.pushStatus(num*2) -- Technically this is not ran within a thread. This is ran outside of a thread inside the thread handler.
end)
end)
local handler = func2()
handler.OnStatus(function(num)
print(num)
end)
multi:mainloop()
```
# Update 16.0.0 - Getting the priorities straight
## Added New Integration: **priorityManager**
@@ -629,15 +461,13 @@ Added
Output:
```
I run before all and control if execution should continue!
I run before all and control if things go!
Hi 3
Hi 1
I run before all and control if execution should continue!
Hi 3
Hi 2
Test 1
Test 2
Test 3
I run after it all!
```
**Note:** Concat of connections does modify internal events on both connections depending on the direction func .. conn or conn .. func See implemention below:
+32 -317
View File
@@ -76,23 +76,17 @@ end
local types = {}
function multi.registerType(typ, p)
if multi["$"..typ:upper():gsub("_","")] then return typ end
multi["$"..typ:upper():gsub("_","")] = typ
if multi[typ:upper():gsub("_","")] then return typ end
multi[typ:upper():gsub("_","")] = typ
table.insert(types, {typ, p or typ})
return typ
end
function multi.hasType(typ)
if multi["$"..typ:upper():gsub("_","")] then
return multi["$"..typ:upper():gsub("_","")]
end
end
function multi.getTypes()
return types
end
multi.Version = "16.2.0"
multi.Version = "16.0.0"
multi.Name = "root"
multi.NIL = {Type="NIL"}
local NIL = multi.NIL
@@ -101,7 +95,7 @@ multi.Children = {}
multi.Active = true
multi.Type = multi.registerType("rootprocess")
multi.LinkedPath = multi
multi.TIMEOUT = multi.registerType("TIMEOUT", "timeouts")
multi.TIMEOUT = "TIMEOUT"
multi.TID = 0
multi.defaultSettings = {}
@@ -191,29 +185,9 @@ function multi.randomString(n)
return str
end
function multi.isMulitObj(obj)
if type(obj)=="table" then
if obj.Type ~= nil then
return multi.hasType(obj.Type) ~= nil
end
end
return false
end
function multi.forwardConnection(src, dest)
if multi.isMulitObj(src) and multi.isMulitObj(dest) then
src(function(...)
dest:Fire(...)
end)
else
multi.error("Cannot forward non-connection objects")
end
end
local optimization_stats = {}
local ignoreconn = true
local empty_func = function() end
function multi:newConnection(protect,func,kill)
local processor = self
local c={}
@@ -247,7 +221,6 @@ function multi:newConnection(protect,func,kill)
for i = #conns, 1, -1 do
obj.rawadd = true
obj(conns[i])
obj.rawadd = false
end
return obj
end,
@@ -257,22 +230,6 @@ function multi:newConnection(protect,func,kill)
obj2(function(...)
cn:Fire(obj1(...))
end)
elseif type(obj1) == "table" and type(obj2) == "function" then
local conns = obj1:Bind({})
for i = 1,#conns do
obj1(function(...)
conns[i](obj2(...))
end)
end
obj1.__connectionAdded = function(conn, func)
obj1:Unconnect(conn)
obj1.rawadd = true
obj1:Connect(function(...)
func(obj2(...))
end)
obj1.rawadd = false
end
return obj1
else
error("Invalid mod!", type(obj1), type(obj2),"Expected function, connection(table)")
end
@@ -320,7 +277,6 @@ function multi:newConnection(protect,func,kill)
end
end)
end
return obj1
elseif type(obj1) == "table" and type(obj2) == "table" then
--
else
@@ -491,7 +447,6 @@ function multi:newConnection(protect,func,kill)
func = function(...)
__CurrentConnectionThread = th
fref(...)
__CurrentConnectionThread = nil
end
end
table.insert(fast, func)
@@ -536,10 +491,6 @@ function multi:newConnection(protect,func,kill)
return temp
end
function c:Get()
return fast
end
function c:Remove()
local temp = fast
fast={}
@@ -602,7 +553,8 @@ end
-- Advance Timer stuff
function multi:SetTime(n)
if not n then n=3 end
local c,err=self:newBase(multi.registerType("timemaster"))
local c=self:newBase()
c.Type=multi.registerType("timemaster")
c.timer=self:newTimer()
c.timer:Start()
c.set=n
@@ -618,7 +570,7 @@ function multi:SetTime(n)
return true
end
end
return self,err
return self
end
function multi:ResolveTimer(...)
@@ -698,25 +650,12 @@ function multi:isDone()
return self.Active~=true
end
local time = os.time
local ok, chronos = pcall(require, "chronos") -- hpc
if ok then
math.randomseed(chronos.nanotime()*100000000)
else
math.randomseed(time())
end
function multi:create(ref)
ref.UID = multi.generate_uuid7()
ref.UID = "U"..multi.randomString(12)
self.OnObjectCreated:Fire(ref, self)
return self
end
function multi:GetCreationTimestamp()
return multi.extract_uuid7_timestamp(self.UID).iso8601
end
function multi:setName(name)
self.Name = name
return self
@@ -724,7 +663,7 @@ end
--Constructors [CORE]
local _tid = 0
function multi:newBase(tp,ins,callback)
function multi:newBase(ins)
if not(self.Type==multi.registerType("rootprocess") or self.Type==multi.registerType("process", "processes")) then multi.error('Can only create an object on multi or an interface obj') return false end
local c = {}
if self.Type==multi.registerType("process", "processes") then
@@ -742,7 +681,6 @@ function multi:newBase(tp,ins,callback)
c.Act=function() end
c.Parent=self
c.creationTime = clock()
c.Type = tp
function c:Pause()
c.Parent.Pause(self)
@@ -754,29 +692,15 @@ function multi:newBase(tp,ins,callback)
return self
end
_tid = _tid + 1 -- Even if the task isn't scheduled, we want to increment this
if type(callback) == "function" then
local res, err = callback(tp)
if not res then
return c, err
end
end
if ins then
table.insert(self.Mainloop,ins,c)
else
table.insert(self.Mainloop,c)
end
_tid = _tid + 1
return c
end
function multi:newTimeout(timeout)
local c={}
c.Type = multi.registerType(multi.TIMEOUT, "timeouts")
return function(self) self:Destroy() return c end % self:newAlarm(timeout).OnRing
end
function multi:newTimer()
local c={}
c.Type=multi.registerType("timer", "timers")
@@ -811,7 +735,8 @@ end
--Core Actors
function multi:newEvent(task, func)
local c,err=self:newBase(multi.registerType("event", "events"))
local c=self:newBase()
c.Type=multi.registerType("event", "events")
local task = task or function() end
function c:Act()
local t = task(self)
@@ -833,11 +758,12 @@ function multi:newEvent(task, func)
self:setPriority("core")
c:setName(c.Type)
self:create(c)
return c,err
return c
end
function multi:newUpdater(skip, func)
local c,err=self:newBase(multi.registerType("updater", "updaters"))
local c=self:newBase()
c.Type=multi.registerType("updater", "updaters")
local pos = 1
local skip = skip or 1
function c:Act()
@@ -858,11 +784,12 @@ function multi:newUpdater(skip, func)
c.OnUpdate(func)
end
self:create(c)
return c,err
return c
end
function multi:newAlarm(set, func)
local c,err=self:newBase(multi.registerType("alarm", "alarms"))
local c=self:newBase()
c.Type=multi.registerType("alarm", "alarms")
c:setPriority("Low")
c.set=set or 0
local count = 0
@@ -898,11 +825,12 @@ function multi:newAlarm(set, func)
end
c:setName(c.Type)
self:create(c)
return c,err
return c
end
function multi:newLoop(func, notime)
local c,err=self:newBase(multi.registerType("loop", "loops"))
local c=self:newBase()
c.Type = multi.registerType("loop", "loops")
local start=clock()
if notime then
function c:Act()
@@ -924,12 +852,13 @@ function multi:newLoop(func, notime)
self:create(c)
c:setName(c.Type)
return c,err
return c
end
function multi:newStep(start,reset,count,skip)
local c,err=self:newBase(multi.registerType("step", "steps"))
local c=self:newBase()
think=1
c.Type=multi.registerType("step", "steps")
c.pos=start or 1
c.endAt=reset or math.huge
c.skip=skip or 0
@@ -983,11 +912,12 @@ function multi:newStep(start,reset,count,skip)
end
c:setName(c.Type)
self:create(c)
return c,err
return c
end
function multi:newTLoop(func, set)
local c,err=self:newBase(multi.registerType("tloop", "tloops"))
local c=self:newBase()
c.Type=multi.registerType("tloop", "tloops")
c.set=set or 0
c.timer=self:newTimer()
c.life=0
@@ -1028,7 +958,7 @@ function multi:newTLoop(func, set)
self:create(c)
return c,err
return c
end
function multi:setTimeout(func, t)
@@ -1148,38 +1078,10 @@ end
local sandcount = 1
function multi:newProcessor(name, opts, priority)
local nothread, attach
if type(opts) ~= "table" then
attach = not opts
nothread = opts -- support old params
end
function multi:newProcessor(name, nothread, priority)
local c = {}
c.Status = {}
setmetatable(c,{__index = multi})
local name = name or "Processor_" .. sandcount
local maxThreads = -1
local maxObjects = -1
local taskhandler = true
rootBase = multi.newBase
local function setStatus(status)
table.insert(c.Status,status)
return status
end
local callback = function(tp)
if maxObjects <0 or #c.Mainloop < maxObjects then
return true
end
return false, setStatus(string.format("Unable to create [%s]: MAX_OBJECTS: '%d' current scheduled objects: '%d'", tp, maxObjects, #c.Mainloop))
end
function c:newBase(tp,ins)
return rootBase(self,tp,ins,callback)
end
sandcount = sandcount + 1
c.Mainloop = {}
c.Type = multi.registerType("process", "processes")
@@ -1195,25 +1097,13 @@ function multi:newProcessor(name, opts, priority)
local boost = 1
local handler
if type(opts) == "table" then
priority = opts.Priority or false
Active = opts.Start or false
maxThreads = opts.MaxThreads or -1
maxObjects = opts.MaxObjects or -1
task_delay = opts.TaskDelay or 0
attach = opts.Attach or false
if opts.TaskHandler == false then -- The default was true
taskhandler = false
end
end
if priority then
handler = c:createPriorityHandler(c)
else
handler = c:createHandler(c)
end
if attach then -- Don't create a loop if we are triggering this manually
if not nothread then -- Don't create a loop if we are triggering this manually
c.process = self:newLoop(function()
if Active then
c:uManager(true)
@@ -1247,11 +1137,8 @@ function multi:newProcessor(name, opts, priority)
end
function c:newThread(name, func,...)
if maxThreads < 0 or (#c.threads+#c.startme < maxThreads) then
return thread.newThread(c, name, func, ...)
end
return nil, setStatus(string.format("Unable to create [thread]: '%s' MAX_THREADS: '%d' current scheduled threads: '%d'",name,maxThreads,#c.threads+#c.startme))
end
function c:newFunction(func, holdme)
return thread:newFunctionBase(function(...)
@@ -1259,24 +1146,6 @@ function multi:newProcessor(name, opts, priority)
end, holdme)()
end
function c:getMaxThreads()
return maxThreads
end
function c:setMaxThreads(n)
maxThreads = n
return c
end
function c:getMaxObjects()
return maxObjects
end
function c:setMaxObjects(n)
maxObjects = n
return c
end
function c:boost(count)
boost = count or 1
if boost > 1 then
@@ -1332,7 +1201,6 @@ function multi:newProcessor(name, opts, priority)
end
end
if taskhandler then
c:newThread("Task Handler", function()
local self = multi:getCurrentProcess()
local function task_holder()
@@ -1349,7 +1217,6 @@ function multi:newProcessor(name, opts, priority)
end
end
end).OnError(multi.error)
end
table.insert(processes,c)
self:create(c)
@@ -1568,16 +1435,13 @@ local function cleanReturns(...)
end
function thread.pushStatus(...)
local t = __CurrentConnectionThread or thread.getRunningThread()
local t = thread.getRunningThread() or __CurrentConnectionThread
t.statusconnector:Fire(...)
end
function thread:newFunctionBase(generator, holdme, TYPE)
return function()
local UID = multi.generate_uuid7()
local tfunc = {
GetCreationTimestamp = function() return multi.extract_uuid7_timestamp(UID).iso8601 end,
}
local tfunc = {}
tfunc.Active = true
function tfunc:Pause()
self.Active = false
@@ -1785,10 +1649,6 @@ function thread:newThread(name, func, ...)
return self._isPaused
end
function c:GetCreationTimestamp()
return multi.extract_uuid7_timestamp(self.UID).iso8601
end
local resumed = false
function c:Pause()
if not self._isPaused then
@@ -2367,13 +2227,6 @@ end
-- UTILS
--------
function multi.isTimeout(res)
if type(res) == "table" then
return res.Type == multi.TIMEOUT
end
return res == multi.TIMEOUT
end
function table.merge(t1, t2)
for k,v in pairs(t2) do
if type(v) == 'table' then
@@ -2656,144 +2509,6 @@ function multi.success(...)
io.write("\x1b[92mSUCCESS:\x1b[0m " .. table.concat(t," ") .. "\n")
end
-- UUID Handling
local function get_timestamp_ms()
-- os.time() gives seconds, we need milliseconds
-- For sub-second precision, we'd need a C extension in real use
-- Here we'll use seconds * 1000 + a pseudo-random millisecond component
local sec = os.time()
return sec * 1000
end
-- Convert number to hex string with specified length
local function to_hex(num, len)
local hex = string.format("%x", num)
return string.rep("0", len - #hex) .. hex
end
-- Generate random hex string of specified length
local function random_hex(len)
local result = ""
for i = 1, len do
result = result .. string.format("%x", math.random(0, 15))
end
return result
end
multi.generate_uuid7 = function()
-- Seed random number generator with current time
math.randomseed(os.time() * os.clock() * 1000000)
-- Get timestamp in milliseconds
local timestamp_ms = get_timestamp_ms()
-- Convert timestamp to 12 hex characters (48 bits)
-- Split into high and low parts
local high = math.floor(timestamp_ms / 16777216) -- Upper 24 bits
local low = timestamp_ms % 16777216 -- Lower 24 bits
local time_high = to_hex(high, 6)
local time_low = to_hex(low, 6)
-- Version and random bits (4 bits version + 12 bits random = 16 bits = 4 hex)
local ver_rand = random_hex(3)
local version_field = "7" .. ver_rand -- Version 7
-- Variant and random bits (2 bits variant + 14 bits random = 16 bits = 4 hex)
local rand_val = math.random(0, 16383) -- 14 bits of random
local variant_field = to_hex(0x8000 + rand_val, 4) -- Set variant bits to 10
-- Remaining random bits (48 bits = 12 hex)
local random_field = random_hex(12)
-- Assemble UUID: xxxxxxxx-xxxx-7xxx-xxxx-xxxxxxxxxxxx
local uuid = string.format("%s%s-%s-%s-%s-%s",
time_high:sub(1, 2),
time_high:sub(3, 6) .. time_low:sub(1, 2),
time_low:sub(3, 6),
version_field,
variant_field,
random_field
)
return uuid
end
local function is_leap(y)
return (y % 4 == 0 and y % 100 ~= 0) or (y % 400 == 0)
end
local function format_date(seconds)
local days = math.floor(seconds / 86400)
local remainder = seconds % 86400
local hours = math.floor(remainder / 3600)
remainder = remainder % 3600
local minutes = math.floor(remainder / 60)
local secs = remainder % 60
-- Calculate year, month, day from days since epoch (1970-01-01)
local year = 1970
local month = 1
local day = 1 + days
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
while true do
local days_in_year = is_leap(year) and 366 or 365
if day <= days_in_year then break end
day = day - days_in_year
year = year + 1
end
while true do
local dim = days_in_month[month]
if month == 2 and is_leap(year) then dim = 29 end
if day <= dim then break end
day = day - dim
month = month + 1
end
return string.format("%04d-%02d-%02d %02d:%02d:%02d",
year, month, day, hours, minutes, secs)
end
multi.extract_uuid7_timestamp = function(uuid_str)
-- Remove hyphens from UUID
local hex = uuid_str:gsub("-", "")
-- Validate length
if #hex ~= 32 then
return nil, "Invalid UUID length"
end
-- Extract first 12 hex characters (48 bits = timestamp in ms)
local timestamp_hex = hex:sub(1, 12)
-- Convert hex to decimal - need to handle large numbers
-- Break into two parts to avoid overflow
local high = tonumber(timestamp_hex:sub(1, 6), 16)
local low = tonumber(timestamp_hex:sub(7, 12), 16)
local timestamp_ms = high * 16777216 + low -- 16^6 = 16777216
if not timestamp_ms then
return nil, "Failed to parse timestamp"
end
-- Convert milliseconds to seconds
local timestamp_sec = math.floor(timestamp_ms / 1000)
local ms_remainder = timestamp_ms % 1000
-- Manual date calculation for large timestamps
local date_str = format_date(timestamp_sec)
return {
milliseconds = timestamp_ms,
seconds = timestamp_sec,
date = date_str,
iso8601 = date_str:gsub(" ", "T") .. string.format(".%03dZ", ms_remainder)
}
end
-- Old things for compatability
multi.GetType = multi.getType
multi.IsPaused = multi.isPaused
-1
View File
@@ -1 +0,0 @@
-- Allows the creation of states
-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",
}
}
-2
View File
@@ -4,8 +4,6 @@ local multi, thread = require("multi"):init{print=true,warn=true,error=true}--{p
local good = false
local proc = multi:newProcessor("Test")
print("Version: "..multi.Version)
proc.Start()
proc:newAlarm(3):OnRing(function()
+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
]]