toolkit/devtools/server/actors/common.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/devtools/server/actors/common.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,168 @@
     1.4 +/* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +"use strict";
    1.11 +
    1.12 +/**
    1.13 + * Methods shared between RootActor and BrowserTabActor.
    1.14 + */
    1.15 +
    1.16 +/**
    1.17 + * Populate |this._extraActors| as specified by |aFactories|, reusing whatever
    1.18 + * actors are already there. Add all actors in the final extra actors table to
    1.19 + * |aPool|.
    1.20 + *
    1.21 + * The root actor and the tab actor use this to instantiate actors that other
    1.22 + * parts of the browser have specified with DebuggerServer.addTabActor antd
    1.23 + * DebuggerServer.addGlobalActor.
    1.24 + *
    1.25 + * @param aFactories
    1.26 + *     An object whose own property names are the names of properties to add to
    1.27 + *     some reply packet (say, a tab actor grip or the "listTabs" response
    1.28 + *     form), and whose own property values are actor constructor functions, as
    1.29 + *     documented for addTabActor and addGlobalActor.
    1.30 + *
    1.31 + * @param this
    1.32 + *     The BrowserRootActor or BrowserTabActor with which the new actors will
    1.33 + *     be associated. It should support whatever API the |aFactories|
    1.34 + *     constructor functions might be interested in, as it is passed to them.
    1.35 + *     For the sake of CommonCreateExtraActors itself, it should have at least
    1.36 + *     the following properties:
    1.37 + *
    1.38 + *     - _extraActors
    1.39 + *        An object whose own property names are factory table (and packet)
    1.40 + *        property names, and whose values are no-argument actor constructors,
    1.41 + *        of the sort that one can add to an ActorPool.
    1.42 + *
    1.43 + *     - conn
    1.44 + *        The DebuggerServerConnection in which the new actors will participate.
    1.45 + *
    1.46 + *     - actorID
    1.47 + *        The actor's name, for use as the new actors' parentID.
    1.48 + */
    1.49 +exports.createExtraActors = function createExtraActors(aFactories, aPool) {
    1.50 +  // Walk over global actors added by extensions.
    1.51 +  for (let name in aFactories) {
    1.52 +    let actor = this._extraActors[name];
    1.53 +    if (!actor) {
    1.54 +      actor = aFactories[name].bind(null, this.conn, this);
    1.55 +      actor.prototype = aFactories[name].prototype;
    1.56 +      actor.parentID = this.actorID;
    1.57 +      this._extraActors[name] = actor;
    1.58 +    }
    1.59 +    aPool.addActor(actor);
    1.60 +  }
    1.61 +}
    1.62 +
    1.63 +/**
    1.64 + * Append the extra actors in |this._extraActors|, constructed by a prior call
    1.65 + * to CommonCreateExtraActors, to |aObject|.
    1.66 + *
    1.67 + * @param aObject
    1.68 + *     The object to which the extra actors should be added, under the
    1.69 + *     property names given in the |aFactories| table passed to
    1.70 + *     CommonCreateExtraActors.
    1.71 + *
    1.72 + * @param this
    1.73 + *     The BrowserRootActor or BrowserTabActor whose |_extraActors| table we
    1.74 + *     should use; see above.
    1.75 + */
    1.76 +exports.appendExtraActors = function appendExtraActors(aObject) {
    1.77 +  for (let name in this._extraActors) {
    1.78 +    let actor = this._extraActors[name];
    1.79 +    aObject[name] = actor.actorID;
    1.80 +  }
    1.81 +}
    1.82 +
    1.83 +/**
    1.84 + * Construct an ActorPool.
    1.85 + *
    1.86 + * ActorPools are actorID -> actor mapping and storage.  These are
    1.87 + * used to accumulate and quickly dispose of groups of actors that
    1.88 + * share a lifetime.
    1.89 + */
    1.90 +function ActorPool(aConnection)
    1.91 +{
    1.92 +  this.conn = aConnection;
    1.93 +  this._cleanups = {};
    1.94 +  this._actors = {};
    1.95 +}
    1.96 +
    1.97 +ActorPool.prototype = {
    1.98 +  /**
    1.99 +   * Add an actor to the actor pool.  If the actor doesn't have an ID,
   1.100 +   * allocate one from the connection.
   1.101 +   *
   1.102 +   * @param aActor object
   1.103 +   *        The actor implementation.  If the object has a
   1.104 +   *        'disconnect' property, it will be called when the actor
   1.105 +   *        pool is cleaned up.
   1.106 +   */
   1.107 +  addActor: function AP_addActor(aActor) {
   1.108 +    aActor.conn = this.conn;
   1.109 +    if (!aActor.actorID) {
   1.110 +      let prefix = aActor.actorPrefix;
   1.111 +      if (typeof aActor == "function") {
   1.112 +        // typeName is a convention used with protocol.js-based actors
   1.113 +        prefix = aActor.prototype.actorPrefix || aActor.prototype.typeName;
   1.114 +      }
   1.115 +      aActor.actorID = this.conn.allocID(prefix || undefined);
   1.116 +    }
   1.117 +
   1.118 +    if (aActor.registeredPool) {
   1.119 +      aActor.registeredPool.removeActor(aActor);
   1.120 +    }
   1.121 +    aActor.registeredPool = this;
   1.122 +
   1.123 +    this._actors[aActor.actorID] = aActor;
   1.124 +    if (aActor.disconnect) {
   1.125 +      this._cleanups[aActor.actorID] = aActor;
   1.126 +    }
   1.127 +  },
   1.128 +
   1.129 +  get: function AP_get(aActorID) {
   1.130 +    return this._actors[aActorID];
   1.131 +  },
   1.132 +
   1.133 +  has: function AP_has(aActorID) {
   1.134 +    return aActorID in this._actors;
   1.135 +  },
   1.136 +
   1.137 +  /**
   1.138 +   * Returns true if the pool is empty.
   1.139 +   */
   1.140 +  isEmpty: function AP_isEmpty() {
   1.141 +    return Object.keys(this._actors).length == 0;
   1.142 +  },
   1.143 +
   1.144 +  /**
   1.145 +   * Remove an actor from the actor pool.
   1.146 +   */
   1.147 +  removeActor: function AP_remove(aActor) {
   1.148 +    delete this._actors[aActor.actorID];
   1.149 +    delete this._cleanups[aActor.actorID];
   1.150 +  },
   1.151 +
   1.152 +  /**
   1.153 +   * Match the api expected by the protocol library.
   1.154 +   */
   1.155 +  unmanage: function(aActor) {
   1.156 +    return this.removeActor(aActor);
   1.157 +  },
   1.158 +
   1.159 +  /**
   1.160 +   * Run all actor cleanups.
   1.161 +   */
   1.162 +  cleanup: function AP_cleanup() {
   1.163 +    for each (let actor in this._cleanups) {
   1.164 +      actor.disconnect();
   1.165 +    }
   1.166 +    this._cleanups = {};
   1.167 +  }
   1.168 +}
   1.169 +
   1.170 +exports.ActorPool = ActorPool;
   1.171 +

mercurial