UNPKG

bugcore

Version:

bugcore is a JavaScript library that provides a foundational architecture for object oriented JS

216 lines (176 loc) 8.38 kB
/* * Copyright (c) 2016 airbug Inc. http://airbug.com * * bugcore may be freely distributed under the MIT license. */ //------------------------------------------------------------------------------- // Annotations //------------------------------------------------------------------------------- //@Export('Publisher') //@Require('Class') //@Require('List') //@Require('Map') //@Require('Obj') //@Require('PublisherMessage') //@Require('PublisherSubscription') //------------------------------------------------------------------------------- // Context //------------------------------------------------------------------------------- require('bugpack').context("*", function(bugpack) { //------------------------------------------------------------------------------- // BugPack //------------------------------------------------------------------------------- var Class = bugpack.require('Class'); var List = bugpack.require('List'); var Map = bugpack.require('Map'); var Obj = bugpack.require('Obj'); var PublisherMessage = bugpack.require('PublisherMessage'); var PublisherSubscription = bugpack.require('PublisherSubscription'); //------------------------------------------------------------------------------- // Declare Class //------------------------------------------------------------------------------- // NOTE BRN: The primary difference between an EventDispatcher and Publisher model is that in an EventDispatcher model // the listener knows which object it is listening to, so it's very understood where the EventListener is receiving // the event from. In a Publisher model, the 'listener' or receiver of a message does not know where the message originated // from. So it is much more anonymous. This model is better for cases where any number of objects can send a message // and you have fewer number of receivers of that message. /** * @class * @extends {Obj} */ var Publisher = Class.extend(Obj, { _name: "Publisher", //------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------- /** * @constructs */ _constructor: function() { this._super(); //------------------------------------------------------------------------------- // Private Properties //------------------------------------------------------------------------------- /** * @private * @type {Map.<string, List.<PublisherSubscription>>} */ this.topicToPublisherSubscriptionListMap = new Map(); }, //------------------------------------------------------------------------------- // Getters and Setters //------------------------------------------------------------------------------- /** * @param {string} topic * @return {number} */ getCount: function(topic) { if (this.topicToPublisherSubscriptionListMap.containsKey(topic)) { var publisherSubscriptionList = this.topicToPublisherSubscriptionListMap.get(topic); return publisherSubscriptionList.getCount(); } return 0; }, //------------------------------------------------------------------------------- // Public Methods //------------------------------------------------------------------------------- /** * @param {string} topic */ clear: function(topic) { this.topicToPublisherSubscriptionListMap.remove(topic); }, /** * */ clearAll: function() { this.topicToPublisherSubscriptionListMap.clear(); this.topicToPublisherSubscriptionListMap = new Map(); }, /** * @param {string} topic * @param {*} data * @return {boolean} */ publish: function(topic, data) { if (this.topicToPublisherSubscriptionListMap.containsKey(topic)) { var message = new PublisherMessage(topic, data); var oneTimeDeliveryPublisherSubscriptionList = new List(); var publisherSubscriptionList = this.topicToPublisherSubscriptionListMap.get(topic); publisherSubscriptionList.forEach(function(publisherSubscription) { publisherSubscription.deliverMessage(message); if (publisherSubscription.isOneTimeDelivery()) { oneTimeDeliveryPublisherSubscriptionList.add(publisherSubscription); } }); var _this = this; oneTimeDeliveryPublisherSubscriptionList.forEach(function(publisherSubscription) { _this.removePublisherSubscription(publisherSubscription); }); return true; } return false; }, /** * Subscribing the same subscriber to the same topic will result in that subscriber being called multiple times. * @param {string} topic * @param {function(string, PublisherMessage)} subscriberFunction * @param {Object} subscriberContext * @return {string} */ subscribe: function(topic, subscriberFunction, subscriberContext) { var publisherSubscription = new PublisherSubscription(topic, subscriberFunction, subscriberContext, false); return this.addPublisherSubscription(publisherSubscription); }, /** * @param {string} topic * @param {function(string, PublisherMessage)} subscriberFunction * @param {Object} subscriberContext * @return {string} */ subscribeOnce: function(topic, subscriberFunction, subscriberContext) { var publisherSubscription = new PublisherSubscription(topic, subscriberFunction, subscriberContext, true); return this.addPublisherSubscription(publisherSubscription); }, /** * @param {string} topic * @param {function(string, PublisherMessage)} subscriberFunction * @param {Object} subscriberContext * @return {boolean} */ unsubscribe: function(topic, subscriberFunction, subscriberContext) { var publisherSubscription = new PublisherSubscription(topic, subscriberFunction, subscriberContext, false); return this.removePublisherSubscription(publisherSubscription); }, //------------------------------------------------------------------------------- // Private Methods //------------------------------------------------------------------------------- /** * @private * @param {PublisherSubscription} publisherSubscription */ addPublisherSubscription: function(publisherSubscription) { var publisherSubscriptionList = this.topicToPublisherSubscriptionListMap.get(publisherSubscription.getTopic()); if (publisherSubscriptionList === undefined) { publisherSubscriptionList = new List(); this.topicToPublisherSubscriptionListMap.put(publisherSubscription.getTopic(), publisherSubscriptionList); } publisherSubscriptionList.add(publisherSubscription); }, /** * @private * @param {PublisherSubscription} publisherSubscription */ removePublisherSubscription: function(publisherSubscription) { var publisherSubscriptionList = this.topicToPublisherSubscriptionListMap.get(publisherSubscription.getTopic()); if (publisherSubscriptionList) { return publisherSubscriptionList.remove(publisherSubscription); } return false; } }); //------------------------------------------------------------------------------- // Exports //------------------------------------------------------------------------------- bugpack.export('Publisher', Publisher); });