Bus Tutorial
This tutorial will show you how to use a Bus (or EventEmitter).
A bus (event handler/event dispatcher) provides methods to assign and emit events.
Usage
To create your own bus use the provided service:
[info] Your
Window
andApplication
instances extends the EventEmitter. So you can use this as your bus(es), but please consider using event names with a namespace, ex:mynamespace:event-name
to avoid conflicting with internal events.
// Basic usage
const bus = core.make("meeseOS/event-emitter");
bus.on("greet", (who) => console.log(`Hello ${who}!`));
bus.emit("greeet", "world");
// To register a subscriber that only fires once
bus.once("greet", (who) => console.log(`Hello ${who}! But only once`));
// To unregister an event
const event = () => console.log("My event");
bus.on("foo", event);
bus.off("foo", event);
// To unregister all events
bus.off("foo");
Advanced Example
In this example, we'll set up a centralized event bus that handles our application features.
This bus will also proxy events to windows and handle inter-window-communication.
It also uses a window factory to share the bus:
// A simple helper function for creating a DOM Element in the form
// of a button. Attaches an click event via the callback.
const createButton = (label, callback) => {
const button = document.createElement("button");
button.appendChild(document.createTextNode(label))
button.addEventListener("click", callback);
return button;
};
// Renders window with a button to spawn another window.
// Listens for the "greet" event on the window that is proxied via our bus
const mainWindow = bus => props => ($content, win) => {
const button = createButton("Create a new Window", () => {
bus.emit("create-window", "other", {
title: "New Window"
}, {
foo: "bar"
});
});
win.on("custom/greet", () => {
$content.appendChild(document.createTextNode("Other window said hello"));
});
$content.appendChild(button);
};
// Renders another window with a button to signal "kill-application"
// and another for "greet-main-window".
const otherWindow = bus => props => ($content, win) => {
// Custom properties passed on
console.log(props.foo); // => "bar"
const button1 = createButton("Kill application", () => {
bus.emit("kill-application");
});
const button2 = createButton("Greet Main Window", () => {
bus.emit("greet-main-window");
});
$content.appendChild(button1);
$content.appendChild(button2);
};
// A window factory that takes a name and spawns
// the corresponding window in a map.
const windowFactory = (proc, bus) => {
const windows = {
main: mainWindow(bus),
other: otherWindow(bus)
};
return (name, options = {}, props = {}) => {
// Assign some static options to our main window
if (name === "main") {
Object.assign(options, {
id: "MainWindow",
title: "Main Window"
});
}
const renderer = windows[name](props);
proc.createWindow(options)
.render(renderer);
};
};
// Your application code.
// This is where we set up a bus for sentralized event handling.
const register = (core, args, options, metadata) => {
const proc = core.make("meeseOS/application", { args, options, metadata });
const bus = core.make("meeseOS/event-emitter", "SomeOptionalBusName");
const factory = windowFactory(proc, bus);
// Proxy the "greet" event onto the main window if found.
// Notice a namespace is used, as not to conflict with internal events.
bus.on("greet-main-window", (...args) => {
const mainWindow = proc.windows
.find(win => win.id === "MainWindow");
if (mainWindow) {
mainWindow.emit("custom/greet", ...args);
}
});
// Signal to kill our application
bus.on("kill-application", () => {
proc.destroy();
});
// Signal for creating another window by name
bus.on("create-window", (name, options, props) => {
factory(name, options, props);
});
// Immediately emit a create window event to spawn main window
bus.emit("create-window", "main");
// We want to remove our bus when application is destroyed
proc.on("destroy", () => bus.destroy());
return proc;
};
// The package manager registration call
meeseOS.make("meeseOS/packages")
.register("MyApplication", register);
MeeseOS Web Desktop - © Aaron Meese <aaronjmeese@gmail.com>