diff --git a/changes.html b/changes.html
index c2c9c0b..06918eb 100644
--- a/changes.html
+++ b/changes.html
@@ -12,220 +12,356 @@
Changes
-Update 13.1.0 Bug fixes and features added
Added:
+Update 14.0.0 Consistency, Additions and Stability
Added:
+- multi.init() — Initlizes the library! Must be called for multiple files to have the same handle. Example below
- thread.holdFor(NUMBER sec, FUNCTION condition) — Works like hold, but timesout when a certain amount of time has passed!
- multi.hold(function or number) — It’s back and better than ever! Normal multi objs without threading will all be halted where threads will still run. If within a thread continue using thread.hold() and thread.sleep()
- thread.holdWithin(NUMBER; cycles,FUNCTION; condition) — Holds until the condition is met! If the number of cycles passed is equal to cycles, hold will return a timeout error
- multi.holdFor(NUMBER; seconds,FUNCTION; condition) — Follows the same rules as multi.hold while mimicing the functionality of thread.holdWithin
Note: when hold has a timeout the first argument will return nil and the second atgument will be TIMEOUT, if not timed out hold will return the values from the conditions - thread objects now have hooks that allow you to interact with it in more refined ways!
— tObj.OnDeath(self,status,returns[…]) — This is a connection that passes a reference to the self, the status, whether or not the thread ended or was killed, and the returns of the thread.
— tObj.OnError(self,error) — returns a reference to self and the error as a string
— Limitations: only 7 returns are possible! This was done because creating and destroying table objects are slow. (The way the scheduler works this would happen every cycle and thats no good) Instead I capture the return values from coroutine.resume into local variables and only allowed it to collect 7 max. - thread.run(function) — Can only be used within a thread, creates another thread that can do work, but automatically returns whatever from the run function — Use thread newfunctions for a more powerful version of thread.run()
- thread:newFunction(FUNCTION; func)
— returns a function that gives you the option to wait or connect to the returns of the function.
— func().wait() — waits for the function to return works both within a thread and outside of one
— func().connect() — connects to the function finishing
— func() — If your function does not return anything you dont have to use wait or connect at all and the function will return instantly. You could also use wait() to hold until the function does it thing
— If the created function encounters an error, it will return nil, the error message! - special variable multi.NIL was added to allow error handling in threaded functions.
— multi.NIL can be used in to force a nil value when using thread.hold() - All functions created in the root of a thread are now converted to threaded functions, which allow for wait and connect features. Note: these functions are local to the function! And are only converted if they aren’t set as local! Otherwise the function
- lanes threads can now have their priority set using: sThread.priority =
— thread.Priority_Core
— thread.Priority_High
— thread.Priority_Above_Normal
— thread.Priority_Normal
— thread.Priority_Below_Normal
— thread.Priority_Low
— thread.Priority_Idle - thread.hold() and multi.hold() now accept connections as an argument. See example below
package.path = "./?/init.lua;"..package.path
+local multi, thread = require("multi"):init()
+conn = multi:newConnection()
+multi:newThread(function()
+ thread.hold(conn)
+ print("Connection Fired!!!")
+end)
+multi:newAlarm(3):OnRing(function()
+ conn:Fire()
+end)
+
thread newFunction
func=thread:newFunction(function(...)
+ print("Function running...")
+ thread.sleep(1)
+ return {1,2,3},"done"
+end)
+multi:newThread("Test",function()
+ func().connect(function(...)
+ print(...)
+ end)
+end)
+
+> Function running...
+> table: 0x008cf340 done nil nil nil nil nil
+
thread newFunction using auto convert
package.path = "./?/init.lua;" .. package.path
+multi, thread = require("multi").init()
+a=5
+multi:newThread("Test",function()
+ function hmm()
+ return "Hello!",2
+ end
+ print(a)
+ a=10
+ print(hmm().wait())
+end)
+multi:newAlarm(3):OnRing(function()
+ print(a)
+end)
+print(hmm)
+multi:mainloop()
+
+> nil
+> 5
+> Hello! 2 nil nil nil nil nil
+> 10
+
Fixed:
+- Connections had a preformance issue where they would create a non function when using connection.getConnection() of a non existing label.
- An internal mismanagement of the threads scheduler was fixed. Now it should be quicker and free of bugs
- Thread error management is the integrations was not properly implemented. This is now fixed
Removed:
+- multi:newWatcher() — No real use
- multi:newCustomObject() — No real use
Changed:
+- Connections connect function can now chain connections
package.path = "./?/init.lua;"..package.path
+ local multi, thread = require("multi").init()
+ test = multi:newConnection()
+ test(function(a)
+ print("test 1",a.Temp)
+ a.Temp = "No!"
+ end,function(a)
+ print("test 2",a.Temp)
+ a.Temp = "Maybe!"
+ end,function(a)
+ print("test 3",a.Temp)
+ end)
+ test:Fire({Temp="Yes!"})
+
+ - Ties in to the new function that has been added multi.init()
local multi, thread = require("multi").init()
+
+ - love/lanesManager system threading integration has been reworked. Faster and cleaner code! Consistant code as well
Note: Using init allows you to get access to the thread handle. This was done because thread was modifying the global space as well as multi. I wanted to not modify the global space anymore.
internally most of your code can stay the same, you only need to change how the library is required. I do toy a bit with the global space, buy I use a variable name that is invalid as a variable name. The variable name is $multi. This is used internally to keep some records and maintain a clean space
Also when using intergrations things now look more consistant.
local multi, thread = require("multi").init()
+local GLOBSL, THREAD = require("multi.integration.lanesManager").init() -- or whichever manager you are using
+local nGLOBAL, nTHREAD = require("multi.intergration.networkManager).inti()
+
Note: You can mix and match integrations together. You can create systemthreads within network threads, and you can also create cotoutine based threads within bothe network and system threads. This gives you quite a bit of flexibility to create something awesome.
Going forward:
+- Finish the rework of the networkManager - It “works”, but there are packet losses that I cannot explain. I do not know what is causing this at all. Ill fix when I figure it out!
- If all goes well, the future will contain quality of code features. I’ll keep an eye out for bugs
Update 13.1.0 Bug fixes and features added
Added:
- Connections:Lock() — Prevents a connection object form being fired
- Connections:Unlock() — Removes the restriction imposed by conn:Lock()
- new fucntions added to the thread namespace
— thread.request(THREAD handle,STRING cmd,VARARGS args) — allows you to push thread requests from outside the running thread! Extremely powerful.
— thread.exec(FUNCTION func) — Allows you to push code to run within the thread execution block! - handle = multi:newThread() — now returns a thread handle to interact with the object outside fo the thread
— handle:Pause()
— handle:Resume()
— handle:Kill()
Fixed:
- Minor bug with multi:newThread() in how names and functions were managed
- Major bug with the system thread handler. Saw healthy threads as dead ones
- Major bug the thread scheduler was seen creating a massive amount of ‘event’ causing memory leaks and hard crashes! This has been fixed by changing how the scheduler opperates.
- newSystemThread()’s returned object now matches both the lanes and love2d in terms of methods that are usable. Error handling of System threads now behave the same across both love and lanes implementations.
- looks like I found a typo, thread.yeild -> thread.yield
Changed:
- getTasksDetails(“t”), the table varaiant, formats threads, and system threads in the same way that tasks are formatted. Please see below for the format of the task details
- TID has been added to multi objects. They count up from 0 and no 2 objects will have the same number
- thread.hold() — As part of the memory leaks that I had to fix thread.hold() is slightly different. This change shouldn’t impact previous code at all, but thread.hold() can not only return at most 7 arguments!
- You should notice some faster code execution from threads, the changes improve preformance of threads greatly. They are now much faster than before!
- multi:threadloop() — No longer runs normal multi objects at all! The new change completely allows the multi objects to be seperated from the thread objects!
- local multi, thread = require(“multi”) — Since coroutine based threading has seen a change to how it works, requring the multi library now returns the namespace for the threading interface as well. For now I will still inject into global the thread namespace, but in release 13.2.0 or 14.0.0 It will be removed!
= 5.1",
+ "bin",
+ "lanes",
+}
+build = {
+ type = "builtin",
+ modules = {
+ ["multi"] = "multi/init.lua",
+ ["multi.compat.love2d"] = "multi/compat/love2d.lua",
+ ["multi.integration.lanesManager"] = "multi/integration/lanesManager/init.lua",
+ ["multi.integration.lanesManager.extensions"] = "multi/integration/lanesManager/extensions.lua",
+ ["multi.integration.lanesManager.threads"] = "multi/integration/lanesManager/threads.lua",
+ ["multi.integration.loveManager"] = "multi/integration/loveManager/init.lua",
+ ["multi.integration.loveManager.extensions"] = "multi/integration/loveManager/extensions.lua",
+ ["multi.integration.loveManager.threads"] = "multi/integration/loveManager/threads.lua",
+ ["multi.integration.luvitManager"] = "multi/integration/luvitManager.lua",
+ --["multi.integration.networkManager"] = "multi/integration/networkManager.lua",
+ ["multi.integration.shared"] = "multi/integration/shared.lua"
+ }
+}
\ No newline at end of file