diff --git a/changes.md b/changes.md index 2abab4b..83aa0d0 100644 --- a/changes.md +++ b/changes.md @@ -5,6 +5,11 @@ Table of contents [Update 14.3.0 - The art of faking it](#update-1430---the-art-of-faking-it)
[Update 14.2.0 - Bloatware Removed](#update-1420---bloatware-removed)
[Update 14.1.0 - A whole new world of possibilities](#update-1410---a-whole-new-world-of-possibilities)
[Update 14.0.0 - Consistency, Additions and Stability](#update-1400---consistency-additions-and-stability)
[Update 13.1.0 - Bug fixes and features added](#update-1310---bug-fixes-and-features-added)
[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)
[Update 12.2.2 - Time for some more bug fixes!](#update-1222---time-for-some-more-bug-fixes)
[Update 12.2.1 - Time for some bug fixes!](#update-1221---time-for-some-bug-fixes)
[Update 12.2.0 - The chains of binding](#update-1220---the-chains-of-binding)
[Update 12.1.0 - Threads just can't hold on anymore](#update-1210---threads-just-cant-hold-on-anymore)
[Update: 12.0.0 - Big update (Lots of additions some changes)](#update-1200---big-update-lots-of-additions-some-changes)
[Update: 1.11.1 - Small Clarification on Love](#update-1111---small-clarification-on-love)
[Update: 1.11.0](#update-1110)
[Update: 1.10.0](#update-1100)
[Update: 1.9.2](#update-192)
[Update: 1.9.1 - Threads can now argue](#update-191---threads-can-now-argue)
[Update: 1.9.0](#update-190)
[Update: 1.8.7](#update-187)
[Update: 1.8.6](#update-186)
[Update: 1.8.5](#update-185)
[Update: 1.8.4](#update-184)
[Update: 1.8.3 - Mainloop recieves some needed overhauling](#update-183---mainloop-recieves-some-needed-overhauling)
[Update: 1.8.2](#update-182)
[Update: 1.8.1](#update-181)
[Update: 1.7.6](#update-176)
[Update: 1.7.5](#update-175)
[Update: 1.7.4](#update-174)
[Update: 1.7.3](#update-173)
[Update: 1.7.2](#update-172)
[Update: 1.7.1 - Bug Fixes Only](#update-171---bug-fixes-only)
[Update: 1.7.0 - Threading the systems](#update-170---threading-the-systems)
[Update: 1.6.0](#update-160)
[Update: 1.5.0](#update-150)
[Update: 1.4.1 (4/10/2017) - First Public release of the library](#update-141-4102017---first-public-release-of-the-library)
[Update: 1.4.0 (3/20/2017)](#update-140-3202017)
[Update: 1.3.0 (1/29/2017)](#update-130-1292017)
[Update: 1.2.0 (12.31.2016)](#update-120-12312016)
[Update: 1.1.0](#update-110)
[Update: 1.0.0](#update-100)
[Update: 0.6.3](#update-063)
[Update: 0.6.2](#update-062)
[Update: 0.6.1-6](#update-061-6)
[Update: 0.5.1-6](#update-051-6)
[Update: 0.4.1](#update-041)
[Update: 0.3.0 - The update that started it all](#update-030---the-update-that-started-it-all)
[Update: EventManager 2.0.0](#update-eventmanager-200)
[Update: EventManager 1.2.0](#update-eventmanager-120)
[Update: EventManager 1.1.0](#update-eventmanager-110)
[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)
[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different) # Update 14.3.0 - The art of faking it +14.3.1 +--- +- Fixed issue with threads +- Added ISOThreads (WIP) was pushed was planned on being part of 15.0.0 + Full Update Showcase --- ```lua diff --git a/multi/init.lua b/multi/init.lua index 8c98580..7fe3f0d 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -30,7 +30,7 @@ if not _G["$multi"] then _G["$multi"] = {multi=multi,thread=thread} end -multi.Version = "14.3.0" +multi.Version = "14.3.1" multi.stage = "stable" multi.Name = "multi.root" multi.Mainloop = {} @@ -1072,13 +1072,21 @@ function thread:newFunction(func,holdme) return temp end end +-- A cross version way to set enviroments, not the same as fenv though +function multi.setEnv(func,env) + local f = string.dump(func) + local chunk = load(f,"env","bt",env) + return chunk +end + function multi:newThread(name,func,...) multi.OnLoad:Fire() local func = func or name if type(name) == "function" then name = "Thread#"..threadCount end - local env = {} + local c={} + local env = {self=c} setmetatable(env,{ __index = Gref, __newindex = function(t,k,v) @@ -1090,7 +1098,117 @@ function multi:newThread(name,func,...) end }) setfenv(func,env) + c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil} + c.startArgs = {...} + c.ref={} + c.Name=name + c.thread=coroutine.create(func) + c.sleep=1 + c.Type="thread" + c.TID = threadid + c.firstRunDone=false + c.timer=multi:newTimer() + c._isPaused = false + c.returns = {} + c.OnError = multi:newConnection(true,nil,true) + c.OnDeath = multi:newConnection(true,nil,true) + function c:isPaused() + return self._isPaused + end + local resumed = false + function c:Pause() + if not self._isPaused then + thread.request(self,"exec",function() + thread.hold(function() + return resumed + end) + resumed = false + self._isPaused = false + end) + self._isPaused = true + end + return self + end + function c:Resume() + resumed = true + return self + end + function c:Kill() + thread.request(self,"kill") + return self + end + c.Destroy = c.Kill + function c.ref:send(name,val) + ret=coroutine.yield({Name=name,Value=val}) + end + function c.ref:get(name) + return self.Globals[name] + end + function c.ref:kill() + dRef[1] = "_kill_" + dRef[2] = "I Was killed by You!" + err = coroutine.yield(dRef) + if err then + error("Failed to kill a thread! Exiting...") + end + end + function c.ref:sleep(n) + if type(n)=="function" then + ret=thread.hold(n) + elseif type(n)=="number" then + ret=thread.sleep(tonumber(n) or 0) + else + error("Invalid Type for sleep!") + end + end + function c.ref:syncGlobals(v) + self.Globals=v + end + table.insert(threads,c) + if initT==false then + multi.initThreads() + end + c.creationTime = os.clock() + threadid = threadid + 1 + self:create(c) + return c +end +function multi:newISOThread(name,func,...) + multi.OnLoad:Fire() + local func = func or name + if type(name) == "function" then + name = "Thread#"..threadCount + end + local env = { + thread = thread, + multi = multi, + coroutine = coroutine, + debug = debug, + io = io, + math = math, + os = os, + package = package, + string = string, + table = table, + utf8 = utf8 + } + for i,v in pairs(_G) do + if tostring(v):match("builtin") then + env[i]=v + end + end + setmetatable(env,{ + __newindex = function(t,k,v) + if type(v)=="function" then + rawset(t,k,thread:newFunction(v)) + else + Gref[k]=v + end + end + }) + local func = multi.setEnv(func,env) local c={} + env.self = c c.TempRets = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil} c.startArgs = {...} c.ref={} @@ -1255,9 +1373,11 @@ function multi.initThreads(justThreads) multi.scheduler:OnLoop(function(self) for i=#threads,1,-1 do if threads[i].isError then - threads[i].OnError:Fire(threads[i],unpack(threads[i].TempRets)) - multi.setType(threads[i],multi.DestroyedObj) - table.remove(threads,i) + if coroutine.status(threads[i].thread)=="dead" then + threads[i].OnError:Fire(threads[i],unpack(threads[i].TempRets)) + multi.setType(threads[i],multi.DestroyedObj) + table.remove(threads,i) + end end if threads[i] and not threads[i].__started then if coroutine.running() ~= threads[i].thread then