Coroutine manager
#1
Posted 01 September 2015 - 10:13 PM
#2
Posted 01 September 2015 - 10:24 PM
Step 2: Make the Multishell API (Study this until you know what everything does - and why)
Step 3: Customize.
#3
Posted 01 September 2015 - 11:05 PM
I can't figure out how to pause a coroutine, and I can't figure out how to 'dedicate' a window to a coroutine per say, but I hear it can be done
#4
Posted 01 September 2015 - 11:20 PM
You can dedicate a window to a coroutine the same way the window API does it. Basically just term.redirect() to that window before resuming said coroutine.
#5
Posted 01 September 2015 - 11:32 PM
#6
Posted 01 September 2015 - 11:46 PM
os.pullEvent() pretty much just calls coroutine.yeild, and it isn't from Lua, its a CC function.
You can also pass an argument to coroutine.yeild - This is usually interpreted as the 'filter' - What the coroutine wants, or the event its looking for.
So a coroutine's job is to yeild when its done, and is waiting for something to happen.
A coroutine manager needs to pass the appropriate events to the correct coroutine, such as input events to the coroutine 'in focus' (And should respect the 'filter' from a coroutine)
The coroutine manager keeps calling coroutine.resume on its coroutines, passing event data as arguements, until all coroutines have ended ( 'coroutine.status( coroutineName )' will return "dead", meaning the function returned, or finished )
Here's a great example/tutorial:
http://www.lua.org/pil/9.1.html
Someone please correct me if I got anything wrong
#8
Posted 02 September 2015 - 12:07 AM
#9
Posted 02 September 2015 - 12:19 AM
Creeper9207, on 02 September 2015 - 12:07 AM, said:
You cannot. A function must call coroutine.yeild at some point, otherwise it will be stopped by CC after 10 or 15 seconds for hogging the Lua VM
(There isn't a true multitasking system in Lua, only one function may run at a time. Yes, this includes all computers on the server)
Edited by HPWebcamAble, 02 September 2015 - 12:19 AM.
#10
Posted 02 September 2015 - 02:17 AM
shell.run()
coroutine.yield()
end
^How do i make it pause before the file ends
And you can have a function that never ends
while true do
sleep(1)
end
#11
Posted 02 September 2015 - 02:34 AM
Creeper9207, on 02 September 2015 - 02:17 AM, said:
shell.run()
coroutine.yield()
end
^How do i make it pause before the file ends
In this function, this is how it would go down:
- Coroutine manager starts the function
- shell.run() returns false
- the function returns control to the coroutine manager (when it calls 'coroutine.yeild()')
- In general, the coroutine manager yeilds as well, until an event is triggered (say, a 'mouse_click')
- If there are no other coroutines to worry about, the manager simply passes the event 'mouse_click' (and its arguments)
- Since the function doesn't assign the result to a variable, it simply ends, returning control to the manager (and its state becomes 'dead')
- The manager discards the function, as it is now finished
Creeper9207, on 02 September 2015 - 02:17 AM, said:
while true do
sleep(1)
end
- Coroutine manager starts the function
- Calls 'sleep(1)' which starts a timer and then returns control to the coroutine manager
- The coroutine manager waits for an event. If its a timer, it is passed to the function.
- The while loop begins again - sleep(1) is called
- From 2
For example, if the coroutine manager was part of an OS, the user might close the program. The coroutine manager discards the function, therefore no longer resuming it.
Usually, the coroutine manager is the Parallel API, I believe it is called when the computer starts and runs rednet and the shell API or something like that.
#12
Posted 02 September 2015 - 02:52 AM
Reason i'm so buggy about it, I don't want to release my os without multitasking in it
#13
Posted 02 September 2015 - 03:02 AM
Normally, you resume your coroutine as soon as you have an event of the sort it requested when it yielded. Pausing an arbitrary bit of code for an arbitrary amount of time adds an extra condition: you have to get the right event, and you need to wait for your "unpause" condition.
But multiple events could occur within that timeframe, and so a buffer would be required in order to prevent information loss - as Yami points out, you're better off just withholding user-input based events while always resuming with other event types for the duration of your "pause". That's how multishell does it, for example - if you've got a timer-based clock running in one tab, it'll keep running while you're in another, but it won't receive any key/char/key_up/etc events unless they occur while it's the "active" tab.
#14
Posted 02 September 2015 - 07:41 PM
I perform a simple check to see if the window is active or not, if it is not then I will only pass it certain events, otherwise all events will be stopped and function calls like sleep() will never get their timer return and yield forever.
If you want to see the source code, here is a link (around lines 1534 for the coroutine manager and 837 for the terminal redirect.)
Hope it helps
You'll want to handle "filters", like when you call pullEvent(filter). couroutine.resume returns this filter, so check if it has been passed and store that too, making sure that if a filter is set, ONLY pass the event in the filter to this yield.
This is in the link above at line 1592. FYI, in the source pgCo is the coroutine you are interested in, just ignore messageCo its not finished and might confuse you
*All line numbers are subject to change pretty quick xD
Edited by Hbomb_79, 02 September 2015 - 07:50 PM.
3 user(s) are reading this topic
0 members, 3 guests, 0 anonymous users











