diff --git a/README.md b/README.md index ebb8641..d53e19c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Multi Version: 15.2.1 +# Multi Version: 15.3.0 Connecting the dots **Key Changes** - Bug fix @@ -16,8 +16,9 @@ Progress is being made in [v15.3.0](https://github.com/rayaman/multi/tree/v15.3. INSTALLING ---------- Link to optional dependencies: -[lanes](https://github.com/LuaLanes/lanes) -[love2d](https://love2d.org/) +- [lanes](https://github.com/LuaLanes/lanes) + +- [love2d](https://love2d.org/) To install copy the multi folder into your environment and you are good to go
If you want to use the system threads, then you'll need to install lanes or love2d game engine! diff --git a/changes.md b/changes.md index 2539005..d6cef4f 100644 --- a/changes.md +++ b/changes.md @@ -4,8 +4,118 @@ Table of contents [Update 15.2.1 - Bug fix](#update-1521---bug-fix)
[Update 15.2.0 - Upgrade Complete](#update-1520---upgrade-complete)
[Update 15.1.0 - Hold the thread!](#update-1510---hold-the-thread)
[Update 15.0.0 - The art of faking it](#update-1500---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 15.3.0 - A world of connection + +Full Update Showcase +```lua +multi, thread = require("multi"):init{print=true} +GLOBAL, THREAD = require("multi.integration.lanesManager"):init() + +local conn = multi:newSystemThreadedConnection("conn"):init() + +multi:newSystemThread("Thread_Test_1",function() + local multi, thread = require("multi"):init() + local conn = GLOBAL["conn"]:init() + conn(function() + print(THREAD:getName().." was triggered!") + end) + multi:mainloop() +end) + +multi:newSystemThread("Thread_Test_2",function() + local multi, thread = require("multi"):init() + local conn = GLOBAL["conn"]:init() + conn(function(a,b,c) + print(THREAD:getName().." was triggered!",a,b,c) + end) + multi:newAlarm(2):OnRing(function() + print("Fire 2!!!") + conn:Fire(4,5,6) + THREAD.kill() + end) + + multi:mainloop() +end) + +conn(function(a,b,c) + print("Mainloop conn got triggered!",a,b,c) +end) + +alarm = multi:newAlarm(1) +alarm:OnRing(function() + 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() + conn(function(a,b,c) + print(THREAD:getName().." was triggered!",a,b,c) + end) + multi:newAlarm(2):OnRing(function() + 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() + multi:newAlarm(2):OnRing(function() + conn2:Fire() + end) + multi:newThread(function() + print("Conn Test!") + thread.hold(conn + conn2) + print("It held!") + end) + multi:mainloop() +end) + +multi:mainloop() +``` + +Added +--- +- `multi:newSystemThreadedConnection()` + + Allows one to trigger connection events across threads. Works like how any connection would work. Supports all of the features, can even be `added` with non SystemThreadedConnections as demonstrated in the full showcase. +- `multi:newConnection():SetHelper(func)` + + Sets the helper function that the connection object uses when creating connection links. + +- `multi.ForEach(table, callback_function)` + + Loops through the table and calls callback_function with each element of the array. + +- If a name is not supplied when creating threads; a name is randomly generated. Unless sending through an established channel/queue you might not be able to easily init the object. + +Changed +--- +- `Connection:[connect, hasConnections, getConnection]` changed to be `Connection:[Connect, HasConnections, getConnections]`. This was done in an attempt to follow a consistent naming scheme. The old methods still will work to prevent old code breaking. + +Removed +--- +- Connection objects methods removed: + - holdUT(), HoldUT() -- With the way `thread.hold(conn)` interacts with connections this method was no longer needed. To emulate this use `multi.hold(conn)`. `multi.hold()` is able to emulate what `thread.hold()` outside of a thread, albeit with some drawbacks. + +Fixed +--- +- SystemThreaded Objects variables weren't consistent. + +ToDo +--- + +- Work on network parallelism (I am really excited to start working on this. Not because it will have much use, but because it seems like a cool addition/project to work on. I just need time to actually do work on stuff) + # Update 15.2.1 - Bug fix Fixed issue #41 +--- # Update 15.2.0 - Upgrade Complete diff --git a/makeENV.lua b/makeENV.lua index acb6fc0..d312349 100644 --- a/makeENV.lua +++ b/makeENV.lua @@ -1,9 +1,9 @@ commands = [[ -mkdir luajit && python -m hererocks -j 2.1.0-beta3 -r latest --patch --compat all ./luajit && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi -mkdir lua5.1 && python -m hererocks -l 5.1 -r latest --patch --compat all ./lua5.1 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi -mkdir lua5.2 && python -m hererocks -l 5.2 -r latest --patch --compat all ./lua5.2 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi -mkdir lua5.3 && python -m hererocks -l 5.3 -r latest --patch --compat all ./lua5.3 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi -mkdir lua5.4 && python -m hererocks -l 5.4 -r latest --patch --compat all ./lua5.4 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi +mkdir luajit && python -m hererocks -j 2.1.0-beta3 -r latest --patch --compat all ./luajit && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes +mkdir lua5.1 && python -m hererocks -l 5.1 -r latest --patch --compat all ./lua5.1 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes +mkdir lua5.2 && python -m hererocks -l 5.2 -r latest --patch --compat all ./lua5.2 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes +mkdir lua5.3 && python -m hererocks -l 5.3 -r latest --patch --compat all ./lua5.3 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes +mkdir lua5.4 && python -m hererocks -l 5.4 -r latest --patch --compat all ./lua5.4 && set "PATH=G:\VSCWorkspace\multi\luajit\bin;%PATH%" && lua -v && luarocks install multi && luarocks install lanes ]] function string.split (inputstr, sep) local sep = sep or "\n" diff --git a/multi/init.lua b/multi/init.lua index 976170a..3d1d006 100644 --- a/multi/init.lua +++ b/multi/init.lua @@ -58,15 +58,15 @@ multi.Priority_Very_Low = 16384 multi.Priority_Idle = 65536 multi.PriorityResolve = { - [1]="Core", - [4]="Very High", - [16]="High", - [64]="Above Normal", - [256]="Normal", - [1024]="Below Normal", - [4096]="Low", - [16384]="Very Low", - [65536]="Idle", + [1] = "Core", + [4] = "Very High", + [16] = "High", + [64] = "Above Normal", + [256] = "Normal", + [1024] = "Below Normal", + [4096] = "Low", + [16384] = "Very Low", + [65536] = "Idle", } local PList = {multi.Priority_Core,multi.Priority_Very_High,multi.Priority_High,multi.Priority_Above_Normal,multi.Priority_Normal,multi.Priority_Below_Normal,multi.Priority_Low,multi.Priority_Very_Low,multi.Priority_Idle} @@ -121,19 +121,20 @@ function multi:newConnection(protect,func,kill) local lock = false c.callback = func c.Parent=self + setmetatable(c,{__call=function(self,...) local t = ... if type(t)=="table" then for i,v in pairs(t) do if v==self then - local ref = self:connect(select(2,...)) + local ref = self:Connect(select(2,...)) ref.root_link = select(1,...) return ref end end - return self:connect(...) + return self:Connect(...) else - return self:connect(...) + return self:Connect(...) end end, __add = function(c1,c2) @@ -159,32 +160,18 @@ function multi:newConnection(protect,func,kill) end) return cn end}) + c.Type='connector' c.func={} c.ID=0 local protect=protect or false local connections={} c.FC=0 + function c:hasConnections() return #call_funcs~=0 end - function c:holdUT(n) - local n=n or 0 - self.waiting=true - local count=0 - local id=self:connect(function() - count = count + 1 - if n<=count then - self.waiting=false - end - end) - repeat - self.Parent:uManager() - until self.waiting==false - id:Destroy() - return self - end - c.HoldUT=c.holdUT + function c:getConnection(name,ignore) if ignore then return connections[name] or CRef @@ -192,14 +179,17 @@ function multi:newConnection(protect,func,kill) return connections[name] or self end end + function c:Lock() lock = true return self end + function c:Unlock() lock = false return self end + if protect then function c:Fire(...) if lock then return end @@ -213,6 +203,7 @@ function multi:newConnection(protect,func,kill) end else function c:Fire(...) + if lock then return end for i=#call_funcs,1,-1 do call_funcs[i](...) if kill then @@ -221,48 +212,56 @@ function multi:newConnection(protect,func,kill) end end end + local fast = {} function c:getConnections() return call_funcs end + function c:fastMode() function self:Fire(...) for i=1,#fast do fast[i](...) end end - function self:connect(func) + function self:Connect(func) table.insert(fast,func) end end + function c:Bind(t) local temp = call_funcs call_funcs=t return temp end + function c:Remove() local temp = call_funcs call_funcs={} return temp end + local function conn_helper(self,func,name,num) self.ID=self.ID+1 + if num then table.insert(call_funcs,num,func) else table.insert(call_funcs,1,func) end + local temp = { func=func, Type="connector_link", Parent=self, connect = function(s,...) - return self:connect(...) + return self:Connect(...) end } + setmetatable(temp,{ __call=function(s,...) - return self:connect(...) + return self:Connect(...) end, __index = function(t,k) if rawget(t,"root_link") then @@ -277,17 +276,11 @@ function multi:newConnection(protect,func,kill) rawset(t,k,v) end, }) + function temp:Fire(...) - if lock then return end - if protect then - local t=pcall(call_funcs,...) - if t then - return t - end - else - return call_funcs(...) - end + return call_funcs(...) end + function temp:Destroy() for i=#call_funcs,1,-1 do if call_funcs[i]~=nil then @@ -299,15 +292,19 @@ function multi:newConnection(protect,func,kill) end end end + if name then connections[name]=temp end + if self.callback then self.callback(temp) end + return temp end - function c:connect(...)--func,name,num + + function c:Connect(...)--func,name,num local tab = {...} local funcs={} for i=1,#tab do @@ -325,8 +322,15 @@ function multi:newConnection(protect,func,kill) return conn_helper(self,tab[1],tab[2],tab[3]) end end - c.Connect=c.connect + + function c:SetHelper(func) + conn_helper = func + end + + c.connect=c.Connect c.GetConnection=c.getConnection + c.HasConnections = c.hasConnections + c.GetConnection = c.getConnection if not(ignoreconn) then multi:create(c) end @@ -1249,9 +1253,8 @@ local startme_len = 0 function thread:newThread(name,func,...) multi.OnLoad:Fire() -- This was done incase a threaded function was called before mainloop/uManager was called local func = func or name - - if type(name) == "function" then - name = "Thread#"..threadCount + if func == name then + name = name or multi.randomString(16) end local c={nil,nil,nil,nil,nil,nil,nil} local env = {self=c} @@ -2050,14 +2053,14 @@ function multi.print(...) end end -multi.GetType=multi.getType -multi.IsPaused=multi.isPaused -multi.IsActive=multi.isActive -multi.Reallocate=multi.Reallocate -multi.ConnectFinal=multi.connectFinal -multi.ResetTime=multi.SetTime -multi.IsDone=multi.isDone -multi.SetName = multi.setName +multi.GetType = multi.getType +multi.IsPaused = multi.isPaused +multi.IsActive = multi.isActive +multi.Reallocate = multi.Reallocate +multi.ConnectFinal = multi.connectFinal +multi.ResetTime = multi.SetTime +multi.IsDone = multi.isDone +multi.SetName = multi.setName -- Special Events local _os = os.exit diff --git a/multi/integration/lanesManager/extensions.lua b/multi/integration/lanesManager/extensions.lua index ad6c5cf..fdf9f9a 100644 --- a/multi/integration/lanesManager/extensions.lua +++ b/multi/integration/lanesManager/extensions.lua @@ -231,6 +231,12 @@ function multi:newSystemThreadedConnection(name) ping:Resume() end,false) + local function fire(...) + for _, link in pairs(c.links) do + link:push {c.TRIG, {...}} + end + end + thread:newThread("STC_SUB_MAN"..name,function() local item while true do @@ -246,11 +252,11 @@ function multi:newSystemThreadedConnection(name) end) c.links[#c.links+1] = item[2] elseif item[1] == c.TRIG then - c:Fire(unpack(item[2])) + fire(unpack(item[2])) c.proxy_conn:Fire(unpack(item[2])) end end - end).OnError(print) + end) --- ^^^ This will only exist in the init thread function c:Fire(...) @@ -259,7 +265,7 @@ function multi:newSystemThreadedConnection(name) for _, link in pairs(self.links) do link:push {self.TRIG, args} end - --c.proxy_conn:Fire(...) + self.proxy_conn:Fire(...) else self.subscribe:push {self.TRIG, args} end @@ -295,7 +301,7 @@ function multi:newSystemThreadedConnection(name) -- This shouldn't be the case end end - end).OnError(print) + end) return self end diff --git a/multi/integration/lanesManager/init.lua b/multi/integration/lanesManager/init.lua index 57f507e..26ac65c 100644 --- a/multi/integration/lanesManager/init.lua +++ b/multi/integration/lanesManager/init.lua @@ -50,7 +50,7 @@ local __SleepingLinda = lanes.linda() -- handles sleeping stuff local __ConsoleLinda = lanes.linda() -- handles console stuff local __StatusLinda = lanes.linda() -- handles pushstatus for stfunctions -local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda, __SleepingLinda, __StatusLinda) +local GLOBAL,THREAD = require("multi.integration.lanesManager.threads").init(__GlobalLinda, __SleepingLinda, __StatusLinda, __ConsoleLinda) local count = 1 local started = false local livingThreads = {} @@ -62,6 +62,7 @@ function THREAD:newFunction(func,holdme) end function multi:newSystemThread(name, func, ...) + local name = name or multi.randomString(16) multi.InitSystemThreadErrorHandler() local rand = math.random(1, 10000000) local return_linda = lanes.linda() diff --git a/multi/integration/lanesManager/threads.lua b/multi/integration/lanesManager/threads.lua index 56b2340..f1b8da1 100644 --- a/multi/integration/lanesManager/threads.lua +++ b/multi/integration/lanesManager/threads.lua @@ -29,7 +29,7 @@ local function getOS() end end -local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda) +local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda, __Console) local THREAD = {} THREAD.Priority_Core = 3 THREAD.Priority_High = 2 @@ -70,7 +70,7 @@ local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda) function THREAD.getConsole() local c = {} - c.queue = _Console + c.queue = __Console function c.print(...) c.queue:send("Q", {...}) end @@ -137,6 +137,6 @@ local function INIT(__GlobalLinda, __SleepingLinda, __StatusLinda) return GLOBAL, THREAD end -return {init = function(g,s,st) - return INIT(g,s,st) +return {init = function(g,s,st,c) + return INIT(g,s,st,c) end} \ No newline at end of file diff --git a/multi/integration/loveManager/extensions.lua b/multi/integration/loveManager/extensions.lua index ad8339e..3eb1a7a 100644 --- a/multi/integration/loveManager/extensions.lua +++ b/multi/integration/loveManager/extensions.lua @@ -27,6 +27,7 @@ local multi, thread = require("multi").init() GLOBAL = multi.integration.GLOBAL THREAD = multi.integration.THREAD function multi:newSystemThreadedQueue(name) + local name = name or multi.randomString(16) local c = {} c.Name = name local fRef = {"func",nil} @@ -64,10 +65,11 @@ function multi:newSystemThreadedQueue(name) return c end function multi:newSystemThreadedTable(name) + local name = name or multi.randomString(16) local c = {} - c.name = name + c.Name = name function c:init() - return THREAD.createTable(self.name) + return THREAD.createTable(self.Name) end THREAD.package(name,c) return c @@ -440,7 +442,12 @@ function multi:newSystemThreadedConnection(name) end,{sleep=3}) if not res then - self.links = remove(self.links, pings) + for i=1,#links do + if links[i] == link then + table.remove(links,i,link) + break + end + end else link:pop() end @@ -458,6 +465,12 @@ function multi:newSystemThreadedConnection(name) ping:Resume() end,false) + local function fire(...) + for _, link in pairs(c.links) do + link:push {c.TRIG, {...}} + end + end + thread:newThread("STC_SUB_MAN"..name,function() local item while true do @@ -473,7 +486,7 @@ function multi:newSystemThreadedConnection(name) end) c.links[#c.links+1] = item[2] elseif item[1] == c.TRIG then - c:Fire(unpack(item[2])) + fire(unpack(item[2])) c.proxy_conn:Fire(unpack(item[2])) end end @@ -486,6 +499,7 @@ function multi:newSystemThreadedConnection(name) for _, link in pairs(self.links) do link:push {self.TRIG, args} end + self.proxy_conn:Fire(...) else self.subscribe:push {self.TRIG, args} end @@ -497,6 +511,7 @@ function multi:newSystemThreadedConnection(name) self.proxy_conn = multi:newConnection() local mt = getmetatable(self.proxy_conn) setmetatable(self, {__index = self.proxy_conn, __call = function(t,func) self.proxy_conn(func) end, __add = mt.__add}) + if self.CID == THREAD.getID() then return self end thread:newThread("STC_CONN_MAN"..name,function() local item local link_self_ref = multi:newSystemThreadedQueue() @@ -524,7 +539,7 @@ function multi:newSystemThreadedConnection(name) return self end - GLOBAL[name] = c + THREAD.package(name,c) return c end \ No newline at end of file diff --git a/multi/integration/lovrManager/extensions.lua b/multi/integration/lovrManager/extensions.lua index 7032b1d..b2082da 100644 --- a/multi/integration/lovrManager/extensions.lua +++ b/multi/integration/lovrManager/extensions.lua @@ -25,6 +25,7 @@ local multi, thread = require("multi").init() GLOBAL = multi.integration.GLOBAL THREAD = multi.integration.THREAD function multi:newSystemThreadedQueue(name) + local name = name or multi.randomString(16) local c = {} c.Name = name local fRef = {"func",nil} @@ -62,10 +63,11 @@ function multi:newSystemThreadedQueue(name) return c end function multi:newSystemThreadedTable(name) + local name = name or multi.randomString(16) local c = {} - c.name = name + c.Name = name function c:init() - return THREAD.createTable(self.name) + return THREAD.createTable(self.Name) end THREAD.package(name,c) return c diff --git a/test.lua b/test.lua index b77857a..aacb05f 100644 --- a/test.lua +++ b/test.lua @@ -9,8 +9,8 @@ multi:newSystemThread("Thread_Test_1",function() local multi, thread = require("multi"):init() local conn = GLOBAL["conn"]:init() local console = THREAD.getConsole() - conn(function() - console.print(THREAD:getName().." was triggered!") + conn(function(a,b,c) + console.print(THREAD:getName().." was triggered!",a,b,c) end) multi:mainloop() end) @@ -22,22 +22,22 @@ multi:newSystemThread("Thread_Test_2",function() conn(function(a,b,c) console.print(THREAD:getName().." was triggered!",a,b,c) end) - multi:newAlarm(3):OnRing(function() + multi:newAlarm(2):OnRing(function() console.print("Fire 2!!!") conn:Fire(4,5,6) - --THREAD.kill() + THREAD.kill() end) multi:mainloop() end) - +local console = THREAD.getConsole() conn(function(a,b,c) - print("Mainloop conn got triggered!",a,b,c) + console.print("Mainloop conn got triggered!",a,b,c) end) alarm = multi:newAlarm(1) alarm:OnRing(function() - print("Fire 1!!!") + console.print("Fire 1!!!") conn:Fire(1,2,3) end) diff --git a/test2.lua b/test2.lua new file mode 100644 index 0000000..5603708 --- /dev/null +++ b/test2.lua @@ -0,0 +1,33 @@ +function difference(a, b) + local ai = {} + local r = {} + local rr = {} + for k,v in pairs(a) do r[k] = v; ai[v]=true end + for k,v in pairs(b) do + if ai[v]==nil then table.insert(rr,r[k]) end + end + return rr +end +function remove(a, b) + local ai = {} + local r = {} + for k,v in pairs(a) do ai[v]=true end + for k,v in pairs(b) do + if ai[v]==nil then table.insert(r,a[k]) end + end + return r +end + +function printtab(tab,msg) + print(msg or "TABLE") + for i,v in pairs(tab) do + print(i, v) + end + print("") +end + +local tab1 = {1,2,3,4,5} +local tab2 = {3,4,5,6,7} +tab1 = remove(tab1,tab2) +printtab(tab1, "Table 1") +printtab(tab2, "Table 2")