Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Facility for coordinating communication between components in an event-based
- * manner.
- *
- * <p>
- * Communication is modeled by using signals.
- *
- * A Signal consist of a category and a payload (data). Components can publish
- * signals or subscribe to signals of a certain category. When a signal is
- * published, all components subscribed for the signal's category are notified.
- * </p>
- */
- function EventBus(config) {
- var log = getLogger("EventBus");
- /*
- * A No-Operation function that is used to replace
- * handlers when a subscription is cancelled.
- */
- var noop = function() {};
- /**
- * key: signal category value: list of handlers subscribed for this category.
- */
- var subscribers = {};
- /**
- * Registers a listener for a certain signal.
- *
- * @param category
- * The signal type
- * @param handler
- * The function to be called when a signal is received.
- *
- * @return A Subscription object that can be used
- * to unsubscribe from an event.
- */
- this.subscribe = function(category, handler) {
- //log.info("subscribing", handler, "for", category);
- var handlerList = null;
- if (category in subscribers) {
- handlerList = subscribers[category];
- } else {
- handlerList = [];
- subscribers[category] = handlerList;
- }
- handlerList.push(handler);
- return new Subscription(category, handler);
- };
- /**
- * Publishes a signal by notifying the handlers
- * registered for the category.
- *
- * @return the number of subscribers the signal was sent to.
- */
- this.publish = function(category, data) {
- if (config.debug) {
- log.info("publishing", category, data);
- }
- if (category in subscribers) {
- var subscribersForCategory = subscribers[category];
- for (var i = 0; i < subscribersForCategory.length; i++) {
- subscribersForCategory[i](data);
- }
- return subscribersForCategory.length;
- }
- return 0;
- };
- /**
- * <p>
- * The subscription can be stored und used later by a client to
- * unsubscribe a handler from an event.
- * </p>
- *
- * For convenience, subscriptions can be "chained" by calling the
- * add-method.
- *
- * @returns {Subscription}
- */
- function Subscription(category, handler) {
- var cancelled = false;
- var that = this;
- this.cancel = function() {
- if (cancelled) {
- return;
- }
- log.info("unsubscribing from " + category);
- var handlerList = subscribers[category];
- if (handlerList) {
- for (var i = 0; i < handlerList.length; i++) {
- if (handlerList[i] === handler) {
- handlerList[i] = noop;
- cancelled = true;
- handler = null;
- return;
- }
- }
- }
- // for safety. Make sure the subscription was found and removed.
- throw "handler " + handler + " not subscribed to " + category;
- };
- /**
- * Adds another subscription to this subscription.
- * This is handy, when a client subscribes to multiple categories,
- * and does not want to declare a separate variable for
- * each subscription.
- *
- * <p>
- * If the cancel() is invoked, all "nested" subscriptions are
- * cancelled as well.
- * </p>
- */
- this.add = function(otherSubscription) {
- var original = that.cancel;
- that.cancel = function() {
- otherSubscription.cancel();
- original.cancel();
- };
- };
- }
- /**
- * A facility, that can collect other subscriptions which can than
- * be canceled all-at-once with one call.
- * <p>
- * This is handy, if client code subscribes to multiple categories,
- * or if client code eventually subscribes to a category and does not
- * want to check if the subscription actually did happen upon unsubscribe.
- * </p>
- * Example:
- *
- * <pre>
- * var subscriptions = eventBus.newSubscriptionList();
- *
- * subscriptions.add(eventBus.subscribe('category1', ...);
- * subscriptions.add(eventBus.subscribe('category2', ...);
- *
- * [...]
- *
- * subscriptions.cancel();
- *
- * </pre>
- *
- */
- this.nullSubscription = function() {
- var nullSubscription = {
- // do nothing
- cancel: function() {},
- add: function(otherSubscription) {
- /*
- * As soon as the first "real" subscription is
- * added, replace our own cancel and add-implementation
- * with the real one.
- * All subsequent calls to add() will then be delegated to the
- * real implementation.
- */
- nullSubscription.cancel = otherSubscription.cancel;
- nullSubscription.add = otherSubscription.add;
- }
- };
- return nullSubscription;
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement