123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- goog.provide('goog.pubsub.PubSub');
- goog.require('goog.Disposable');
- goog.require('goog.array');
- goog.require('goog.async.run');
- goog.pubsub.PubSub = function(opt_async) {
- goog.pubsub.PubSub.base(this, 'constructor');
-
- this.key_ = 1;
-
- this.pendingKeys_ = [];
-
- this.publishDepth_ = 0;
-
- this.subscriptions_ = [];
-
- this.topics_ = {};
-
- this.async_ = Boolean(opt_async);
- };
- goog.inherits(goog.pubsub.PubSub, goog.Disposable);
- goog.pubsub.PubSub.prototype.subscribe = function(topic, fn, opt_context) {
- var keys = this.topics_[topic];
- if (!keys) {
-
- keys = this.topics_[topic] = [];
- }
-
- var key = this.key_;
- this.subscriptions_[key] = topic;
- this.subscriptions_[key + 1] = fn;
- this.subscriptions_[key + 2] = opt_context;
- this.key_ = key + 3;
-
- keys.push(key);
-
- return key;
- };
- goog.pubsub.PubSub.prototype.subscribeOnce = function(topic, fn, opt_context) {
-
-
-
- var called = false;
-
- var key = this.subscribe(topic, function(var_args) {
- if (!called) {
- called = true;
-
-
- this.unsubscribeByKey(key);
- fn.apply(opt_context, arguments);
- }
- }, this);
- return key;
- };
- goog.pubsub.PubSub.prototype.unsubscribe = function(topic, fn, opt_context) {
- var keys = this.topics_[topic];
- if (keys) {
-
-
- var subscriptions = this.subscriptions_;
- var key = goog.array.find(keys, function(k) {
- return subscriptions[k + 1] == fn && subscriptions[k + 2] == opt_context;
- });
-
- if (key) {
- return this.unsubscribeByKey(key);
- }
- }
- return false;
- };
- goog.pubsub.PubSub.prototype.unsubscribeByKey = function(key) {
- var topic = this.subscriptions_[key];
- if (topic) {
-
- var keys = this.topics_[topic];
- if (this.publishDepth_ != 0) {
-
-
- this.pendingKeys_.push(key);
- this.subscriptions_[key + 1] = goog.nullFunction;
- } else {
- if (keys) {
- goog.array.remove(keys, key);
- }
- delete this.subscriptions_[key];
- delete this.subscriptions_[key + 1];
- delete this.subscriptions_[key + 2];
- }
- }
- return !!topic;
- };
- goog.pubsub.PubSub.prototype.publish = function(topic, var_args) {
- var keys = this.topics_[topic];
- if (keys) {
-
-
-
-
- var args = new Array(arguments.length - 1);
- for (var i = 1, len = arguments.length; i < len; i++) {
- args[i - 1] = arguments[i];
- }
- if (this.async_) {
-
-
- for (i = 0; i < keys.length; i++) {
- var key = keys[i];
- goog.pubsub.PubSub.runAsync_(
- this.subscriptions_[key + 1], this.subscriptions_[key + 2], args);
- }
- } else {
-
-
-
- this.publishDepth_++;
- try {
-
-
-
-
- for (i = 0, len = keys.length; i < len; i++) {
- var key = keys[i];
- this.subscriptions_[key + 1].apply(
- this.subscriptions_[key + 2], args);
- }
- } finally {
-
-
-
- this.publishDepth_--;
- if (this.pendingKeys_.length > 0 && this.publishDepth_ == 0) {
- var pendingKey;
- while ((pendingKey = this.pendingKeys_.pop())) {
- this.unsubscribeByKey(pendingKey);
- }
- }
- }
- }
-
- return i != 0;
- }
-
- return false;
- };
- goog.pubsub.PubSub.runAsync_ = function(func, context, args) {
- goog.async.run(function() { func.apply(context, args); });
- };
- goog.pubsub.PubSub.prototype.clear = function(opt_topic) {
- if (opt_topic) {
- var keys = this.topics_[opt_topic];
- if (keys) {
- goog.array.forEach(keys, this.unsubscribeByKey, this);
- delete this.topics_[opt_topic];
- }
- } else {
- this.subscriptions_.length = 0;
- this.topics_ = {};
-
-
-
- }
- };
- goog.pubsub.PubSub.prototype.getCount = function(opt_topic) {
- if (opt_topic) {
- var keys = this.topics_[opt_topic];
- return keys ? keys.length : 0;
- }
- var count = 0;
- for (var topic in this.topics_) {
- count += this.getCount(topic);
- }
- return count;
- };
- goog.pubsub.PubSub.prototype.disposeInternal = function() {
- goog.pubsub.PubSub.base(this, 'disposeInternal');
- this.clear();
- this.pendingKeys_.length = 0;
- };
|