Events and Event Processing
NeuroKernel OS is an event based system. Everything is handled via event flows between modules. Because of this, NeuroKernel has a very specialized event mechanism. Events are handled via special purpose event listeners. IEventListener
and IDataListener
are the two widely used general purpose event handler interfaces used by the system. There are also other listeners for the specific purposes such as IServiceListener
and IPortListener
. It is important to understand this event system before writing any NeuroKernel applications. This event model used is very well known by many Java and JavaScript developers.
1. Event Pipeline
When an event sent to an event dispatcher, it processes the event and calls a event multicaster to announce the event to the listeners. Each task has an event pipeline that is controlled by the task container. Events are served to their destinations by their type and event properties if any special treatment needed. Task container will dispose an event if the destination of the event object is not know or unavailable. In the below example, slider value is read by an action listener of a button. When this button is pushed and released, an action event is created and delivered to the application that hosts this button. Task container looks for the button and dispatches the event to the button component. In the last step, button component receives the event and after processing it calls the registered event listeners.
import com.neurokernel.client.*; import com.neurokernel.client.constants.*; public class EventListenerExample extends NApplication { @Override public void main(int argc, String[] argv) { NFrame mainFrame = getMainFrame(); NGridLayout gridLayout=mainFrame.getLayout(); gridLayout.setSize(2,1); NSlider slider = new NSlider(mainFrame, Orientation.HORIZONTAL, 0, 255, 0); new NButton(mainFrame,"Get Value").addListener(event -> NMessageDialog.showInfo(mainFrame, slider.getValue()), NEventTypes.ACTION); mainFrame.setTitle("Listener/Observer Example"); mainFrame.show(20,20); } }
As you see, and general purpose event listener is used for this example. Event pipeline does not care about the type of the event, it is sent to the destination in raw form packaged in a NEvent
object.
2. Observers
UI controls also offer another listener type called observer. Observer's only purpose is to get the current value of the UI control. It is possible to write bean frameworks based on the observer features of the UI controls. All UI controls in NeuroKernel implement IObserver
interface by default.
import com.neurokernel.client.*; public class EventListenerExample extends NApplication { @Override public void main(int argc, String[] argv) { NFrame mainFrame = getMainFrame(); NGridLayout gridLayout=mainFrame.getLayout(); gridLayout.setSize(3,1); NTextField textfield = new NTextField(mainFrame); NSlider slider = new NSlider(mainFrame, Orientation.HORIZONTAL, 0, 255, 0); slider.addObserver(textfield); new NButton(mainFrame,"Get Value").addListener(event -> NMessageDialog.showInfo(mainFrame, slider.getValue()), NEventTypes.ACTION); mainFrame.setTitle("Listener/Observer Example"); mainFrame.show(20,20); } }
3. Data listeners
Data listeners are used widely along with event listeners to fetch the data resulting from a system call. They are used mostly by calls to the kernel modules. The response object includes all the information about the incoming data package. The API reference manual gives details about the data to be read for each data listener passed to a method that calls a system interface.
import com.neurokernel.client.*; import com.neurokernel.system.io.*; import com.neurokernel.client.adapter.IActionListener; public class DataListenerExample extends NApplication { @Override public void main(int argc, String[] argv) { NFrame mainFrame = getMainFrame(); new NButton(mainFrame,"Get Date").addListener((IActionListener) e -> { NFile myFile = new NFile("/myfile.txt"); IFileSystem fileSystem=myFile.getFileSystem(getSystem()); fileSystem.exists(myFile, response -> { if(response.hasError()) NMessageDialog.showError(mainFrame,"File does not exists"); else NMessageDialog.showInfo(mainFrame,"File exists"); }); }); setVisible("IDataListener Interface"); } }