@@ -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
0 commit comments