Event loop
Although JavaScript programs are event-driven, the code is executed in a single thread. This is achieved by using an event loop, where asynchronous events are queued and executed in the order they are received.
The default implementation of an event loop is provided by EventLoopFeature
. It is an MFeature that can be added to a Machine to provide
an event loop and requires an MFeature that provides an event queue. The default event queue implementation is provided by EventQueueFeature
.
To allow running code on an event loop tick, a virtual method EventLoopFeature::onEventLoop
can be used. To define the top of the Machine stack,
the EventLoopTerminal
class must be used as the topmost MFeature.
Usage
To use the event loop, the MFeature must be added to the Machine. To start the event loop, use the EventLoopFeature::run
method.
#include <jac/machine.h>
#include <jac/features/eventLoopFeature.h>
#include <jac/features/eventQueueFeature.h>
#include <jac/features/timersFeature.h>
using Machine = jac::ComposeMachine<
jac::MachineBase
jac::EventQueueFeature,
jac::EventLoopFeature,
jac::TimersFeature,
jac::EventLoopTerminal,
>;
Machine machine;
machine.initialize();
machine.eval("setTimeout(() => console.log('Hello, world!'), 1000);", "<stdin>", jac::EvalFlags::Global);
machine.startEventLoop();
The event loop will run indefinitely until the EventLoopFeature::exit
or EventLoopFeature::kill
method is called. The exit
method can
also be called from the JavaScript code by calling the exit
function.
Custom event queue
It is possible to implement a custom event queue MFeature with extended functionality. The MFeature must be thread-safe and must provide the following methods:
template<class Next>
class MyEventQueueFeature : public Next {
public:
/**
* @brief Check the event queue and return the first event
* @param wait Wait for event if no event is available
* @return Event or std::nullopt if no event is available
*/
std::optional<std::function<void()>> getEvent(bool wait);
/**
* @brief Schedule an event to be run
* @param func Function to be run
*/
void scheduleEvent(std::function<void()> func);
/**
* @brief Wake up event loop if it is waiting for events
*/
void notifyEventLoop();
};