Events
Signals are essentially messages send by a network component to computers that listen to the component. This means every computer first has to listen to the network components from which he wants to receive signals from.
A signal has a type and various associated values.
The combination of a signal and the sender from which the signal originated from is also known as event.
Event Filters
Event Filters are a new lua type that allow you to store a signal match condition and match signals against it.
This allows you to more easily filter for specific signals/events.
Matching
You can then use the matches(eventName, sender, …) member function, to easily match the return values of an event.pull() call against the conditions.
Construction
To construct a new EventFilter you have to use the global event.filter(table) function.
You can then provide various optional fields in the table to specify on what you want to check.
-
event : string|string[]The event name has to match the given single string or has to be contained within the given array of strings. -
sender : Object|Object[]The sender of the signals has to be the given single sender or must be one of the senders in the given array. -
`values : table<string,any> A table with string keys and any value as value. For every table entry, the signal must have a parameter with the same name and the parameter value has to match the givne table value associated with the key.
Operator Overloading
The struct overloads a bunch of Lua operators allowing you to create more complex conditions.
-
+|-OROperators -
&* -ANDOperators -
-~-NOTOperators
Example
local f1 = event.filter{sender=someSender, event="SomeEvent", values={someParameterName="someExpectedValue"}}
local f2 = event.fitler{sender=someOtherSender}
local f3 = f1 * f2 -- an AND link (both filters have to match)
local f4 = f1 + f2 -- an OR link (one of the filters has to match)
local f5 = -f1 -- an negation link (the filter is not allowed to match)
local f5 = f3 + f4 * f5 -- you can essentially express complex conditions this way
while true do
local e = {event.pull()}
if f1:matches(table.unpack(e)) then
print("The event matches f1")
end
if f5:matches(table.unpack(e)) then
print("The event matches the complex filter f5")
end
end
Event Duplication & Handling
Events only get processed when you call event.pull() which pulls a signal from the Singal Queue.
That means when you want to use these new features, you have to let them be processed by looping and calling event.pull().
To make this easier when you dont need the low level access event.pull() provides (and further stuff like, main yielding and custom task scheduling),
there is an helper function event.loop() which is the equivalent to:
while true do
local e = event.pull(0)
future.run()
if not e then
computer.skip()
end
end
Event Listeners
You can globally register Event Listeners.
These are functions associated with an event filter.
When the computer pulls a signal, it will check if the event matches the event filter. If this is the case, it will create a a new task based on the function you passed to the registration, and as function parameters you get the event parameters.
To register an Event Listener you have to use the global event.registerListener(EventListener, function) function.
local btn = ...
local switch = ...
event.registerListener({sender=btn}, function(event, sender, p1, p2, ...)
print("Event1: ", event, sender, p1, p2, ...)
end)
event.registerListener(event.filter{sender=switch} + event.filter{State=true}, function()
print("Event2")
end)
event.loop()
Event One-Shots
You can also create futures that resolve only once a signal that matches the given event filter is matched.
This essentially allows you to easily halt program execution and wait for user input. The future it self will return the event parameters.
You can use the event.waitFor(EventFilter) → Future function to create such future.
local okbtn = ...
local cancelbtn = ...
print("Are you sure you want to continue?")
local ok, cancel = future.first(event.waitFor{sender=okbtn}, event.waitFor{sender=cancelbtn})
if ok then
print("Then lets continue!")
else
print("Cancel the continuation...")
end
Event Queues
Event Queues allow you to record and filter events that occur in its life-time.
You can create an Event Queue using the global event.queue(EventFilter) → EventQueu function.
The queue will from then on record all events that occur and that match the given filter.
|
Its always best to use a filter that lets through as few events as your actually need. For memory and performance reasons. The queue is hard limited to 250 entries. |
You can then use the pull([timeout]) and waitFor(EventFilter) member functions.
These functions operate similar to their global counter parts, but instead of operating on the global event system, these here operate on the event queue.
|
Its important to mention that |
The pull function is essentially a shorthand for the following function:
function queue:pull(timeout)
local _, e = future.first(self:waitFor{}, future.sleep(timeout)):await()
if e then
return table.unpack(e)
end
end