Skip to content

Commit 989923c

Browse files
committed
Improve addons loading with consumes/provides
1 parent 2415960 commit 989923c

6 files changed

Lines changed: 126 additions & 13 deletions

File tree

addons/editor/addon-built.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

addons/editor/client.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,9 @@ define([
108108

109109
// Open base tabs
110110
commands.run("files.open");
111+
112+
// Return globals
113+
return {
114+
'ace': ace
115+
};
111116
});

addons/editor/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"url": "http://samypesse.fr"
1212
},
1313
"client": {
14-
"main": "client"
14+
"main": "client",
15+
"provides": [
16+
"ace"
17+
]
1518
}
1619
}

client/build.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,8 @@ exports.config = {
6767
},
6868
'args': {
6969
'version': pkg.version
70+
},
71+
'options': {
72+
7073
}
7174
};

client/collections/addons.js

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ define([
1111
loader: "getInstalled",
1212
loaderArgs: [],
1313
}, hr.Collection.prototype.defaults),
14+
15+
// Constructor
16+
initialize: function() {
17+
Addons.__super__.initialize.apply(this, arguments);
18+
19+
this.resolved = {};
20+
this.provides = {};
21+
22+
return this;
23+
},
1424

1525
// Get installed addons
1626
getInstalled: function(options) {
@@ -70,11 +80,92 @@ define([
7080
});
7181
},
7282

83+
// Extract from engineer, order addons for loading
84+
checkCycles: function() {
85+
var that = this;
86+
var plugins = this.map(function(addon, index) {
87+
return {
88+
name: addon.get("name"),
89+
provides: addon.get("client.provides", []).concat(),
90+
consumes: addon.get("client.consumes", []).concat(),
91+
i: index
92+
};
93+
});
94+
95+
var changed = true;
96+
var sorted = [];
97+
98+
while(plugins.length && changed) {
99+
changed = false;
100+
101+
plugins.concat().forEach(function(plugin) {
102+
var consumes = plugin.consumes.concat();
103+
104+
var resolvedAll = true;
105+
for (var i=0; i<consumes.length; i++) {
106+
var service = consumes[i];
107+
if (!that.resolved[service]) {
108+
resolvedAll = false;
109+
} else {
110+
plugin.consumes.splice(plugin.consumes.indexOf(service), 1);
111+
}
112+
}
113+
114+
if (!resolvedAll)
115+
return;
116+
117+
plugins.splice(plugins.indexOf(plugin), 1);
118+
plugin.provides.forEach(function(service) {
119+
that.resolved[service] = true;
120+
});
121+
sorted.push(that.models[plugin.i]);
122+
changed = true;
123+
});
124+
}
125+
126+
if (plugins.length) {
127+
var unresolved = {};
128+
plugins.forEach(function(plugin) {
129+
delete plugin.config;
130+
plugin.consumes.forEach(function(name) {
131+
if (unresolved[name] == false)
132+
return;
133+
if (!unresolved[name])
134+
unresolved[name] = [];
135+
unresolved[name].push(plugin.name);
136+
});
137+
plugin.provides.forEach(function(name) {
138+
unresolved[name] = false;
139+
});
140+
});
141+
142+
Object.keys(unresolved).forEach(function(name) {
143+
if (unresolved[name] == false)
144+
delete unresolved[name];
145+
});
146+
147+
console.error("Could not resolve dependencies of these plugins:", plugins);
148+
console.error("Resolved services:", Object.keys(resolved));
149+
console.error("Missing services:", unresolved);
150+
throw new Error("Could not resolve dependencies");
151+
}
152+
153+
return sorted;
154+
},
155+
73156
// Load all this addons collection
157+
// similar loading to engineer
74158
loadAll: function() {
75-
return Q.all(this.map(function(addon) {
76-
return addon.load();
77-
}));
159+
var that = this;
160+
var addons = this.checkCycles();
161+
162+
return _.reduce(addons, function(d, addon) {
163+
return d.then(function() {
164+
return addon.load({}, _.pick(that.provides, addon.get("client.consumes", [])));
165+
}).then(function(provides) {
166+
_.extend(that.provides, provides || {});
167+
});
168+
}, Q({}));
78169
}
79170
});
80171

client/models/addon.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ define([
3232
},
3333

3434
// Load the addon
35-
load: function() {
35+
load: function(config, imports) {
3636
var context, main, addonRequireConfig,
3737
addonRequire, that = this
3838
var d = Q.defer();
@@ -68,14 +68,25 @@ define([
6868
base: "/addons/"+this.get("name")+"/templates"
6969
});
7070

71-
// Load main module
72-
addonRequire([main], function() {
71+
// Register addons
72+
var register = function(err, globals) {
73+
if (err) {
74+
that.set("state", "error");
75+
d.reject(err);
76+
return;
77+
}
7378
that.set("state", "loaded");
74-
d.resolve();
75-
}, function(err) {
76-
that.set("state", "error");
77-
d.reject(err);
78-
});
79+
d.resolve(globals);
80+
};
81+
82+
// Load main module
83+
addonRequire([main], function(globals) {
84+
if (_.isFunction(globals)) {
85+
globals(config, imports, register);
86+
} else {
87+
register(null, globals);
88+
}
89+
}, register);
7990

8091
return d.promise;
8192
}

0 commit comments

Comments
 (0)