This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
oreillynz's profile picture

Improved event management -> os.getNewEvents()

Started by oreillynz, 17 April 2012 - 09:12 AM
oreillynz #1
Posted 17 April 2012 - 11:12 AM
Proposal

A function that will return a list of events, with the data in table form.
If enabled (os.logEvents(true)), events are added to this table with the tick they occurred.
The table includes the global 'tick' time from the World class (as a raw large number), so speed of events can be measured.
A call to os.getNewEvents() returns this table, and removes all entries to the log (so you always get new events you haven't already seen)


Benefits

You don't miss out on events happening while a turtle is moving, or a function takes longer then 0.05s to complete.
You can measure the differences between ticks, and so can time actions better (as SMP server's tick rates are unreliable)
Fast redstone circuits would no longer 'skip', as a rapidly toggling input does not always line up with os.pullEvent and events can be missed.


Example data

It would be ideal to return something like this….



World Tick          Event ID            Data 
2876583096          redstone            [side="left", type="bundled", state=126, previous=84]
2876583142          timer               [id=5]
2876583142          redstone            [side="right", type="simple", state=true]
2876583142          rednet              [senderID=241, distance=45.4, message="A test message"]
Cloudy #2
Posted 17 April 2012 - 07:06 PM
Events are held in the queue - however you are right that if a turtle is moving it will disregard any events it receives (as the turtle waits for an event to know when it is finished moving). It is possible to run a separate thread using the parallel API which won't miss events when the code is sleeping or a turtle is moving. You should look into that - you could even code your suggestion in Lua by doing this.
oreillynz #3
Posted 18 April 2012 - 12:29 PM
I've had a look at the parallel API, and I don't fully understand how the coroutine.yield function is working. It get's passed a string argument that seems to act as a filter?

Is there any existing code I look at to get an idea where to start? I've been slowly looking over the java sources as well to try and backtrace where it all comes from, but I haven't groked the coroutine process yet.
Cloudy #4
Posted 18 April 2012 - 12:47 PM
Sure - to see how the parallel API works check out the API on the APIs folder in rom. This in turn uses coroutines.

To check out coroutines in general, google "coroutine Lua" and it should bring the official Lua documentation up about it as it is a Lua addition, not a CC addition. I would link you but posting from my phone.
oreillynz #5
Posted 18 April 2012 - 03:41 PM
So far, the lua references I've found on coroutine's don't explain passing an argument to yield.

Are programs yielding back to code from bios.lua (and where?), or is the code an arguement gets passed to in the java classes?

EDIT: Further question
- Won't there still be a problem that if a different function takes longer then a minecraft tick to run (for example, encoding a complex table to send via rednet), the coroutine that pullEvents will never get called regardless?
Cloudy #6
Posted 18 April 2012 - 06:19 PM
Basically, the way ComputerCraft works is like this:

Each Computer and Turtle runs its own coroutine. It yields on a regular basis to receive arguments - e.g. events - from the java code. It does this Lua side by using os.pullEvent from the bios.lua, which yields back to java code. When the Java code detects a change in the redstone state, or someone has pressed a key on the keyboard, or a peripheral decides to send an event, it will pass the event down to the Computer's coroutine. The computer can then do what it likes with it.

These events are stored in a buffer Java side, and passed to the computer sequentially when it yields. Any events that do not happen on the exact tick, get queued and are given next time it yields.
oreillynz #7
Posted 19 April 2012 - 05:42 AM
So I could find and use the lower level calls for events that would normally block, and therefore capture all events even while a turtle is moving? That's useful!

So all's that left of this suggestion is to include a "tick" parameter in events, so we can know (in game time) when an event happened. Everything else can potentially be done with a lua API…
Wolvan #8
Posted 19 April 2012 - 08:42 PM
What don't you understand in parallel? The usage?
Cloudy #9
Posted 20 April 2012 - 12:46 AM
So I could find and use the lower level calls for events that would normally block, and therefore capture all events even while a turtle is moving? That's useful!

So all's that left of this suggestion is to include a "tick" parameter in events, so we can know (in game time) when an event happened. Everything else can potentially be done with a lua API…

One of the os API commands has a number of ticks which a computer has been on for. That would be sufficient enough to timestamp an event.
Wolvan #10
Posted 20 April 2012 - 03:38 PM
Do you mean os.time?