toolkit/devtools/server/actors/common.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:ef9835c4c712
1 /* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 "use strict";
8
9 /**
10 * Methods shared between RootActor and BrowserTabActor.
11 */
12
13 /**
14 * Populate |this._extraActors| as specified by |aFactories|, reusing whatever
15 * actors are already there. Add all actors in the final extra actors table to
16 * |aPool|.
17 *
18 * The root actor and the tab actor use this to instantiate actors that other
19 * parts of the browser have specified with DebuggerServer.addTabActor antd
20 * DebuggerServer.addGlobalActor.
21 *
22 * @param aFactories
23 * An object whose own property names are the names of properties to add to
24 * some reply packet (say, a tab actor grip or the "listTabs" response
25 * form), and whose own property values are actor constructor functions, as
26 * documented for addTabActor and addGlobalActor.
27 *
28 * @param this
29 * The BrowserRootActor or BrowserTabActor with which the new actors will
30 * be associated. It should support whatever API the |aFactories|
31 * constructor functions might be interested in, as it is passed to them.
32 * For the sake of CommonCreateExtraActors itself, it should have at least
33 * the following properties:
34 *
35 * - _extraActors
36 * An object whose own property names are factory table (and packet)
37 * property names, and whose values are no-argument actor constructors,
38 * of the sort that one can add to an ActorPool.
39 *
40 * - conn
41 * The DebuggerServerConnection in which the new actors will participate.
42 *
43 * - actorID
44 * The actor's name, for use as the new actors' parentID.
45 */
46 exports.createExtraActors = function createExtraActors(aFactories, aPool) {
47 // Walk over global actors added by extensions.
48 for (let name in aFactories) {
49 let actor = this._extraActors[name];
50 if (!actor) {
51 actor = aFactories[name].bind(null, this.conn, this);
52 actor.prototype = aFactories[name].prototype;
53 actor.parentID = this.actorID;
54 this._extraActors[name] = actor;
55 }
56 aPool.addActor(actor);
57 }
58 }
59
60 /**
61 * Append the extra actors in |this._extraActors|, constructed by a prior call
62 * to CommonCreateExtraActors, to |aObject|.
63 *
64 * @param aObject
65 * The object to which the extra actors should be added, under the
66 * property names given in the |aFactories| table passed to
67 * CommonCreateExtraActors.
68 *
69 * @param this
70 * The BrowserRootActor or BrowserTabActor whose |_extraActors| table we
71 * should use; see above.
72 */
73 exports.appendExtraActors = function appendExtraActors(aObject) {
74 for (let name in this._extraActors) {
75 let actor = this._extraActors[name];
76 aObject[name] = actor.actorID;
77 }
78 }
79
80 /**
81 * Construct an ActorPool.
82 *
83 * ActorPools are actorID -> actor mapping and storage. These are
84 * used to accumulate and quickly dispose of groups of actors that
85 * share a lifetime.
86 */
87 function ActorPool(aConnection)
88 {
89 this.conn = aConnection;
90 this._cleanups = {};
91 this._actors = {};
92 }
93
94 ActorPool.prototype = {
95 /**
96 * Add an actor to the actor pool. If the actor doesn't have an ID,
97 * allocate one from the connection.
98 *
99 * @param aActor object
100 * The actor implementation. If the object has a
101 * 'disconnect' property, it will be called when the actor
102 * pool is cleaned up.
103 */
104 addActor: function AP_addActor(aActor) {
105 aActor.conn = this.conn;
106 if (!aActor.actorID) {
107 let prefix = aActor.actorPrefix;
108 if (typeof aActor == "function") {
109 // typeName is a convention used with protocol.js-based actors
110 prefix = aActor.prototype.actorPrefix || aActor.prototype.typeName;
111 }
112 aActor.actorID = this.conn.allocID(prefix || undefined);
113 }
114
115 if (aActor.registeredPool) {
116 aActor.registeredPool.removeActor(aActor);
117 }
118 aActor.registeredPool = this;
119
120 this._actors[aActor.actorID] = aActor;
121 if (aActor.disconnect) {
122 this._cleanups[aActor.actorID] = aActor;
123 }
124 },
125
126 get: function AP_get(aActorID) {
127 return this._actors[aActorID];
128 },
129
130 has: function AP_has(aActorID) {
131 return aActorID in this._actors;
132 },
133
134 /**
135 * Returns true if the pool is empty.
136 */
137 isEmpty: function AP_isEmpty() {
138 return Object.keys(this._actors).length == 0;
139 },
140
141 /**
142 * Remove an actor from the actor pool.
143 */
144 removeActor: function AP_remove(aActor) {
145 delete this._actors[aActor.actorID];
146 delete this._cleanups[aActor.actorID];
147 },
148
149 /**
150 * Match the api expected by the protocol library.
151 */
152 unmanage: function(aActor) {
153 return this.removeActor(aActor);
154 },
155
156 /**
157 * Run all actor cleanups.
158 */
159 cleanup: function AP_cleanup() {
160 for each (let actor in this._cleanups) {
161 actor.disconnect();
162 }
163 this._cleanups = {};
164 }
165 }
166
167 exports.ActorPool = ActorPool;
168

mercurial