V15.1.0 #26

Merged
rayaman merged 18 commits from V15.1.0 into master 2021-11-30 21:28:18 -05:00
3 changed files with 215 additions and 85 deletions
Showing only changes of commit 804a117ed0 - Show all commits

View File

@ -3,6 +3,62 @@ Table of contents
---
[Update 15.0.0 - The art of faking it](#update-1500---the-art-of-faking-it)</br>[Update 14.2.0 - Bloatware Removed](#update-1420---bloatware-removed)</br>[Update 14.1.0 - A whole new world of possibilities](#update-1410---a-whole-new-world-of-possibilities)</br>[Update 14.0.0 - Consistency, Additions and Stability](#update-1400---consistency-additions-and-stability)</br>[Update 13.1.0 - Bug fixes and features added](#update-1310---bug-fixes-and-features-added)</br>[Update 13.0.0 - Added some documentation, and some new features too check it out!](#update-1300---added-some-documentation-and-some-new-features-too-check-it-out)</br>[Update 12.2.2 - Time for some more bug fixes!](#update-1222---time-for-some-more-bug-fixes)</br>[Update 12.2.1 - Time for some bug fixes!](#update-1221---time-for-some-bug-fixes)</br>[Update 12.2.0 - The chains of binding](#update-1220---the-chains-of-binding)</br>[Update 12.1.0 - Threads just can't hold on anymore](#update-1210---threads-just-cant-hold-on-anymore)</br>[Update: 12.0.0 - Big update (Lots of additions some changes)](#update-1200---big-update-lots-of-additions-some-changes)</br>[Update: 1.11.1 - Small Clarification on Love](#update-1111---small-clarification-on-love)</br>[Update: 1.11.0](#update-1110)</br>[Update: 1.10.0](#update-1100)</br>[Update: 1.9.2](#update-192)</br>[Update: 1.9.1 - Threads can now argue](#update-191---threads-can-now-argue)</br>[Update: 1.9.0](#update-190)</br>[Update: 1.8.7](#update-187)</br>[Update: 1.8.6](#update-186)</br>[Update: 1.8.5](#update-185)</br>[Update: 1.8.4](#update-184)</br>[Update: 1.8.3 - Mainloop recieves some needed overhauling](#update-183---mainloop-recieves-some-needed-overhauling)</br>[Update: 1.8.2](#update-182)</br>[Update: 1.8.1](#update-181)</br>[Update: 1.7.6](#update-176)</br>[Update: 1.7.5](#update-175)</br>[Update: 1.7.4](#update-174)</br>[Update: 1.7.3](#update-173)</br>[Update: 1.7.2](#update-172)</br>[Update: 1.7.1 - Bug Fixes Only](#update-171---bug-fixes-only)</br>[Update: 1.7.0 - Threading the systems](#update-170---threading-the-systems)</br>[Update: 1.6.0](#update-160)</br>[Update: 1.5.0](#update-150)</br>[Update: 1.4.1 (4/10/2017) - First Public release of the library](#update-141-4102017---first-public-release-of-the-library)</br>[Update: 1.4.0 (3/20/2017)](#update-140-3202017)</br>[Update: 1.3.0 (1/29/2017)](#update-130-1292017)</br>[Update: 1.2.0 (12.31.2016)](#update-120-12312016)</br>[Update: 1.1.0](#update-110)</br>[Update: 1.0.0](#update-100)</br>[Update: 0.6.3](#update-063)</br>[Update: 0.6.2](#update-062)</br>[Update: 0.6.1-6](#update-061-6)</br>[Update: 0.5.1-6](#update-051-6)</br>[Update: 0.4.1](#update-041)</br>[Update: 0.3.0 - The update that started it all](#update-030---the-update-that-started-it-all)</br>[Update: EventManager 2.0.0](#update-eventmanager-200)</br>[Update: EventManager 1.2.0](#update-eventmanager-120)</br>[Update: EventManager 1.1.0](#update-eventmanager-110)</br>[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 15.1.0 -
---
Full Update Showcase
```lua
package.path = "./?/init.lua;"..package.path
multi,thread = require("multi"):init()
test = thread:newFunction(function()
return 1,2,nil,3,4,5,6,7,8,9
end,true)
print(test())
multi:newThread("testing",function()
print("#Test = ",test())
print(thread.hold(function()
print("Hello!")
return false
end,{
interval = 2,
cycles = 3
})) -- End result, 3 attempts within 6 seconds. If still false then timeout
print("held")
end).OnError(function(...)
print(...)
end)
```
Added:
---
Changed:
---
- thread.hold(n,opt) [Ref. Issue](https://github.com/rayaman/multi/issues/24)
- Added option table to thread.hold
| Option | Description |
---|---
| cycles | Number of cycles before timing out |
| sleep | Number of seconds before timing out |
| interval | Time between each poll |
**Note:** cycles and sleep cannot both be used at the same time. Cycles take priority if both are present!
Removed:
---
Fixed:
---
- Threaded functions not returning multiple values [Ref. Issue](https://github.com/rayaman/multi/issues/21)
ToDo
---
# Update 15.0.0 - The art of faking it
Full Update Showcase
---

View File

@ -911,7 +911,7 @@ local threads = thread.__threads
local Gref = _G
multi.GlobalVariables={}
local dFunc = function() return true end
local dRef = {nil,nil,nil}
local dRef = {nil,nil,nil,nil,nil}
thread.requests = {}
function thread.request(t,cmd,...)
thread.requests[t.thread] = {cmd,{...}}
@ -941,11 +941,40 @@ function thread.sleep(n)
dRef[2] = n or 0
return coroutine.yield(dRef)
end
function thread.hold(n)
-- function thread.hold(n)
-- thread._Requests()
-- dRef[1] = "_hold_"
-- dRef[2] = n or dFunc
-- return coroutine.yield(dRef)
-- end
function thread.hold(n,opt)
thread._Requests()
if opt and type(opt)=="table" then
if opt.interval then
dRef[4] = opt.interval
end
if opt.cycles then
dRef[1] = "_holdW_"
dRef[2] = opt.cycles or 1
dRef[3] = n or dFunc
return coroutine.yield(dRef)
elseif opt.sleep then
dRef[1] = "_holdF_"
dRef[2] = opt.sleep
dRef[3] = n or dFunc
return coroutine.yield(dRef)
end
end
if type(n) == "number" then
thread.getRunningThread().lastSleep = clock()
dRef[1] = "_sleep_"
dRef[2] = n or 0
return coroutine.yield(dRef)
else
dRef[1] = "_hold_"
dRef[2] = n or dFunc
return coroutine.yield(dRef)
end
end
function thread.holdFor(sec,n)
thread._Requests()
@ -1041,13 +1070,13 @@ function multi.holdFor(n,func)
end)
end
local function cleanReturns(...)
local n = select("#", ...)
local returns = {...}
local rets = {}
local ind = 0
for i=n,1,-1 do
for i=#returns,1,-1 do
if returns[i] then
ind=i
ind = i
break
end
end
return unpack(returns,1,ind)
@ -1061,7 +1090,7 @@ function thread:newFunction(func,holdme)
if err then
return multi.NIL, err
elseif rets then
return cleanReturns((rets[1] or multi.NIL),rets[2],rets[3],rets[4],rets[5],rets[6],rets[7])
return cleanReturns((rets[1] or multi.NIL),rets[2],rets[3],rets[4],rets[5],rets[6],rets[7],rets[8],rets[9],rets[10],rets[11],rets[12],rets[13],rets[14],rets[15],rets[16])
end
end)
else
@ -1071,7 +1100,7 @@ function thread:newFunction(func,holdme)
if err then
return nil,err
end
return cleanReturns(rets[1],rets[2],rets[3],rets[4],rets[5],rets[6],rets[7])
return cleanReturns(rets[1],rets[2],rets[3],rets[4],rets[5],rets[6],rets[7],rets[8],rets[9],rets[10],rets[11],rets[12],rets[13],rets[14],rets[15],rets[16])
end
end
local t = multi:newThread("TempThread",func,...)
@ -1084,7 +1113,7 @@ function thread:newFunction(func,holdme)
isTFunc = true,
wait = wait,
connect = function(f)
t.OnDeath(function(self,status,...) f(cleanReturns(...)) end)
t.OnDeath(function(self,status,...) f(...) end)
t.OnError(function(self,err) f(err) end)
end
}
@ -1206,8 +1235,8 @@ function multi.initThreads(justThreads)
self.skip=tonumber(n) or 24
end
multi.scheduler.skip=0
local t0,t1,t2,t3,t4,t5,t6
local r1,r2,r3,r4,r5,r6
local t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15
local r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16
local ret,_
local function CheckRets(i)
if threads[i] and not(threads[i].isError) then
@ -1216,7 +1245,7 @@ function multi.initThreads(justThreads)
threads[i].TempRets[1] = ret
return
end
if ret or r1 or r2 or r3 or r4 or r5 or r6 then
if ret or r1 or r2 or r3 or r4 or r5 or r6 or r7 or r8 or r9 or r10 or r11 or r12 or r13 or r14 or r15 or r16 then
threads[i].TempRets[1] = ret
threads[i].TempRets[2] = r1
threads[i].TempRets[3] = r2
@ -1224,6 +1253,16 @@ function multi.initThreads(justThreads)
threads[i].TempRets[5] = r4
threads[i].TempRets[6] = r5
threads[i].TempRets[7] = r6
threads[i].TempRets[8] = r7
threads[i].TempRets[9] = r8
threads[i].TempRets[10] = r9
threads[i].TempRets[11] = r10
threads[i].TempRets[12] = r11
threads[i].TempRets[13] = r12
threads[i].TempRets[14] = r13
threads[i].TempRets[15] = r14
threads[i].TempRets[16] = r15
threads[i].TempRets[17] = r16
end
end
end
@ -1241,7 +1280,7 @@ function multi.initThreads(justThreads)
local function helper(i)
if type(ret)=="table" then
if ret[1]=="_kill_" then
threads[i].OnDeath:Fire(threads[i],"killed",ret,r1,r2,r3,r4,r5,r6)
threads[i].OnDeath:Fire(threads[i],"killed",ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16)
multi.setType(threads[i],multi.DestroyedObj)
table.remove(threads,i)
ret = nil
@ -1262,6 +1301,8 @@ function multi.initThreads(justThreads)
threads[i].func = ret[2]
threads[i].task = "hold"
threads[i].__ready = false
threads[i].interval = ret[4] or 0
threads[i].intervalR = clock()
ret = nil
elseif ret[1]=="_holdF_" then
holdconn(3)
@ -1270,6 +1311,8 @@ function multi.initThreads(justThreads)
threads[i].task = "holdF"
threads[i].time = clock()
threads[i].__ready = false
threads[i].interval = ret[4] or 0
threads[i].intervalR = clock()
ret = nil
elseif ret[1]=="_holdW_" then
holdconn(3)
@ -1279,6 +1322,8 @@ function multi.initThreads(justThreads)
threads[i].task = "holdW"
threads[i].time = clock()
threads[i].__ready = false
threads[i].interval = ret[4] or 0
threads[i].intervalR = clock()
ret = nil
end
end
@ -1295,7 +1340,7 @@ function multi.initThreads(justThreads)
end
if threads[i] and not threads[i].__started then
if coroutine.running() ~= threads[i].thread then
_,ret,r1,r2,r3,r4,r5,r6=coroutine.resume(threads[i].thread,unpack(threads[i].startArgs))
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=coroutine.resume(threads[i].thread,unpack(threads[i].startArgs))
end
threads[i].__started = true
helper(i)
@ -1306,7 +1351,7 @@ function multi.initThreads(justThreads)
end
if threads[i] and coroutine.status(threads[i].thread)=="dead" then
local t = threads[i].TempRets or {}
threads[i].OnDeath:Fire(threads[i],"ended",t[1],t[2],t[3],t[4],t[5],t[6],t[7])
threads[i].OnDeath:Fire(threads[i],"ended",t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15],t[16])
multi.setType(threads[i],multi.DestroyedObj)
table.remove(threads,i)
elseif threads[i] and threads[i].task == "skip" then
@ -1316,7 +1361,8 @@ function multi.initThreads(justThreads)
threads[i].__ready = true
end
elseif threads[i] and threads[i].task == "hold" then
t0,t1,t2,t3,t4,t5,t6 = threads[i].func()
if clock() - threads[i].intervalR>=threads[i].interval then
t0,t1,t2,t3,t4,t5,t6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16 = threads[i].func()
if t0 then
if t0==multi.NIL then
t0 = nil
@ -1324,13 +1370,16 @@ function multi.initThreads(justThreads)
threads[i].task = ""
threads[i].__ready = true
end
threads[i].intervalR = clock()
end
elseif threads[i] and threads[i].task == "sleep" then
if clock() - threads[i].time>=threads[i].sec then
threads[i].task = ""
threads[i].__ready = true
end
elseif threads[i] and threads[i].task == "holdF" then
t0,t1,t2,t3,t4,t5,t6 = threads[i].func()
if clock() - threads[i].intervalR>=threads[i].interval then
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = threads[i].func()
if t0 then
threads[i].task = ""
threads[i].__ready = true
@ -1340,9 +1389,13 @@ function multi.initThreads(justThreads)
t0 = nil
t1 = "TIMEOUT"
end
threads[i].intervalR = clock()
end
elseif threads[i] and threads[i].task == "holdW" then
if clock() - threads[i].intervalR>=threads[i].interval then
threads[i].pos = threads[i].pos + 1
t0,t1,t2,t3,t4,t5,t6 = threads[i].func()
print(threads[i].pos,threads[i].count)
t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 = threads[i].func()
if t0 then
threads[i].task = ""
threads[i].__ready = true
@ -1352,11 +1405,13 @@ function multi.initThreads(justThreads)
t0 = nil
t1 = "TIMEOUT"
end
threads[i].intervalR = clock()
end
end
if threads[i] and threads[i].__ready then
threads[i].__ready = false
if coroutine.running() ~= threads[i].thread then
_,ret,r1,r2,r3,r4,r5,r6=coroutine.resume(threads[i].thread,t0,t1,t2,t3,t4,t5,t6)
_,ret,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16=coroutine.resume(threads[i].thread,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15)
CheckRets(i)
end
end

103
test.lua
View File

@ -2,50 +2,69 @@ package.path = "./?/init.lua;"..package.path
multi,thread = require("multi"):init()
--GLOBAL,THREAD = require("multi.integration.threading"):init() -- Auto detects your enviroment and uses what's available
local sandcount = 0
function multi:newProcessor(name)
local c = {}
setmetatable(c,{__index = self})
local multi,thread = require("multi"):init() -- We need to capture the t in thread
local name = name or "Processor_"..sandcount
sandcount = sandcount + 1
c.Mainloop = {}
c.Type = "process"
c.Active = false
c.OnError = multi:newConnection()
c.process = self:newThread(name,function()
while true do
thread.hold(function()
return sandbox.Active
end)
c:uManager()
end
end).OnError(c.OnError)
function c.Start()
c.Active = true
end
function c.Stop()
c.Active = false
end
return c
end
sandbox = multi:newProcessor()
sandbox:newTLoop(function()
print("testing...")
end,1)
test2 = multi:newTLoop(function()
print("testing2...")
end,1)
sandbox:newThread("Test Thread",function()
while true do
thread.sleep(1)
print("Thread Test...")
end
test = thread:newFunction(function()
return 1,2,nil,3,4,5,6,7,8,9
end,true)
print(test())
multi:newThread("testing",function()
print("#Test = ",test())
print(thread.hold(function()
print("Hello!")
return false
end,{
interval = 2,
cycles = 3
})) -- End result, 3 attempts within 6 seconds. If still false then timeout
print("held")
end).OnError(function(...)
print(...)
end)
sandbox.Start()
-- local sandcount = 0
-- function multi:newProcessor(name)
-- local c = {}
-- setmetatable(c,{__index = self})
-- local multi,thread = require("multi"):init() -- We need to capture the t in thread
-- local name = name or "Processor_"..sandcount
-- sandcount = sandcount + 1
-- c.Mainloop = {}
-- c.Type = "process"
-- c.Active = false
-- c.OnError = multi:newConnection()
-- c.process = self:newThread(name,function()
-- while true do
-- thread.hold(function()
-- return sandbox.Active
-- end)
-- c:uManager()
-- end
-- end).OnError(c.OnError)
-- function c.Start()
-- c.Active = true
-- end
-- function c.Stop()
-- c.Active = false
-- end
-- return c
-- end
-- sandbox = multi:newProcessor()
-- sandbox:newTLoop(function()
-- print("testing...")
-- end,1)
-- test2 = multi:newTLoop(function()
-- print("testing2...")
-- end,1)
-- sandbox:newThread("Test Thread",function()
-- while true do
-- thread.sleep(1)
-- print("Thread Test...")
-- end
-- end)
-- sandbox.Start()
multi:mainloop()