From ea6f007cc60f430b121aba1607aace5ac849806f Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Fri, 2 Jun 2017 13:39:05 -0400 Subject: [PATCH] Added more examples Added: - Processes - Queuer - Threads - Functions Fixed: some bugs --- README.md | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 218 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 34c0a2b..556557e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ alarm:OnRing(function(a) end) multi:mainloop() -- the main loop of the program, multi:umanager() exists as well to allow intergration in other loops Ex: love2d love.update function. More on this binding in the wiki! ``` -The library is module so you only need to require what you need. Because of this the global enviroment is altered
+The library is modular so you only need to require what you need to. Because of this, the global enviroment is altered
There are many useful objects that you can use
Check out the wiki for detailed usage, but here are the objects:
@@ -366,15 +366,223 @@ Low: 971 Steps in 3 second(s)!
Notice: Even though I started each bench at the same time the order that they finished differed the order is likely to vary on your machine as well!
+# Processes +A process allows you to group the Actor objects within a controlable interface +```lua +require("multi.all") +proc=multi:newProcess() -- takes an optional file as an argument, but for this example we aren't going to use that +-- a process works just like the multi object! +b=0 +loop=proc:newTLoop(function(self) + a=a+1 + proc:Pause() -- pauses the cpu cycler for this processor! Individual objects are not paused, however because they aren't getting cpu time they act as if they were paused +end,.1) +updater=proc:newUpdater(multi.Priority_Idle) -- priority can be used in skip arguments as well to manage priority without enabling it! +updater:OnUpdate(function(self) + b=b+1 +end) +a=0 -- a counter +loop2=proc:newLoop(function(dt,self) + print("Lets Go!") + self:hold(3) -- this will keep this object from doing anything! Note: You can only have one hold active at a time! Multiple are possible, but results may not be as they seem see * for how hold works + -- Within a process using hold will keep it alive until the hold is satisified! + print("Done being held for 1 second") + self:hold(function() return a>10 end) + print("A is now: "..a.." b is also: "..b) + self:Destroy() + self.Parent:Pause() -- lets say you don't have the reference to the process! + os.exit() +end) +-- Notice this is now being created on the multi namespace +event=multi:newEvent(function() return os.clock()>=1 end) +event:OnEvent(function(self) + proc:Resume() + self:Destroy() +end) +proc:Start() +multi:mainloop() +``` +# Output +Lets Go!
+Done being held for 1 second
+A is now: 29 b is also: 479
-# TODO -- Process#
-- Queuer#
-- Thread*
-- Trigger**
-- Task
-- Job
-- Function
-- Watcher***
+**Hold: This method works as follows** +```lua +function multi:hold(task) + self:Pause() -- pause the current object + self.held=true -- set held + if type(task)=='number' then -- a sleep cmd + local timer=multi:newTimer() + timer:Start() + while timer:Get() +Ring ring!!!
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+Done
+# Actual Output +Done
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+Ring ring!!!
+ +# Threads +These fix the hold problem that you get with regular objects, and they work exactly the same! They even have some extra features that make them really useful.
+```lua +_require=require -- lets play with the require method a bit +function require(path) + path=path:gsub("%*","all") + _require(path) +end +require("multi.*") -- now I can use that lovely * symbol to require everything +test=multi:newThreadedProcess("main") -- you can thread processors and all Actors see note for a list of actors you can thread! +test2=multi:newThreadedProcess("main2") +count=0 +test:newLoop(function(dt,self) + count=count+1 + thread.sleep(.01) +end) +test2:newLoop(function(dt,self) + print("Hello!") + thread.sleep(1) -- sleep for some time +end) +-- threads take a name object then the rest as normal +step=multi:newThreadedTStep("step",1,10) +step:OnStep(function(p,self) + print("step",p) + thread.skip(21) -- skip n cycles +end) +step:OnEnd(function() + print("Killing thread!") + thread.kill() -- kill the thread +end) +loop=multi:newThreadedLoop("loop",function(dt,self) + print(dt) + thread.sleep(1.1) +end) +loop2=multi:newThreadedLoop("loop",function(dt,self) + print(dt) + thread.hold(function() return count>=100 end) + print("Count is "..count) + os.exit() +end) +alarm=multi:newThreadedAlarm("alarm",1) +alarm:OnRing(function(self) + print("Ring") + self:Reset() +end) +multi:mainloop() +``` +# Output +Ring
+0.992
+0.992
+Hello!
+step 1
+step 2
+Hello!
+Ring
+2.092
+step 3
+Hello!
+Ring
+Count is 100
+# Threadable Actors +- Alarms +- Events +- Loop/TLoop +- Process +- Step/TStep + +# Functions +If you ever wanted to pause a function then great now you can +The uses of the Function object allows one to have a method that can run free in a sense +```lua +require("multi.all") +func=multi:newFunction(function(self,arg1,arg2,...) + self:Pause() + return arg1 +end) +print(func("Hello")) +print(func("Hello2")) -- returns PAUSED allows for the calling of functions that should only be called once. returns PAUSED instantly if paused +func:Resume() +print(func("Hello3")) +``` +# Output +Hello
+PAUSED
+Hello3
+ +# TODO (In order of importance) - Write the wiki stuff +- Write multi:newThreadedUpdater(name,skip) - Test for unknown bugs +**Don't find these useful tbh, I will document them eventually though** +- Document Triggers
+- Document Tasks
+- Document Jobs
+- Document Watcher