1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | (function( define ){
|
14 | define( function(){
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | var l8 = (this && this.l8) || require( "l8/lib/l8.js")
|
21 | var Pattern = require( "matches").pattern
|
22 | var SocketIo = require( "socket.io")
|
23 | var SocketIoClient = require( "socket.io-client")
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | this.__defineGetter__( "de", l8.getDebugFlag)
|
30 | var bug = l8.bug
|
31 | var mand = l8.mand
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | var Registry = {}
|
40 | var RegistryIds = {}
|
41 |
|
42 | function Actor( name, delegate ){
|
43 | this.name = name
|
44 | this.task = null
|
45 | this.queue = l8.queue()
|
46 | this.backlog = []
|
47 | this.pattern = null
|
48 | this.delegate = null
|
49 | this.stage = null
|
50 | var previous = null
|
51 | if( (name[name.length - 1] != ".")
|
52 | && (previous = this.lookup( name))
|
53 | ){
|
54 | previous.task.cancel()
|
55 | }
|
56 | this.name = this.register( name, this)
|
57 | return this
|
58 | }
|
59 | var ProtoActor = Actor.prototype
|
60 |
|
61 | ProtoActor.toString = ProtoActor.toLabel
|
62 | = function(){ return "Actor/" + this.name }
|
63 |
|
64 | ProtoActor.register = function( name, object ){
|
65 | if( !name ){ name = "." }
|
66 | var dot = name.lastIndexOf( ".")
|
67 | if( dot === -1 ){
|
68 | Registry[name] = object
|
69 | return name
|
70 | }
|
71 | var prefix = name.substr( 0, dot )
|
72 | var suffix = name.substring( dot + 1)
|
73 | if( suffix ){
|
74 | Registry[name] = object
|
75 | return name
|
76 | }
|
77 | var id = RegistryIds[prefix] || 0
|
78 | name += id++
|
79 | RegistryIds[prefix] = id
|
80 | Registry[name] = object
|
81 | return name
|
82 | }
|
83 |
|
84 | ProtoActor.lookup = function( name, remove ){
|
85 | var obj = Registry[name]
|
86 | if( obj && remove ){
|
87 | delete Registry[name]
|
88 | }
|
89 | return obj
|
90 | }
|
91 |
|
92 | var SetPatternMatchOutcome
|
93 |
|
94 | ProtoActor.match = function( msg, delegate ){
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | var that = this
|
113 | var callback = msg.caller
|
114 | var callback_called = false
|
115 | if( callback ){
|
116 |
|
117 | if( that.caller )return false
|
118 |
|
119 | callback = msg.callback
|
120 | if( !callback ){
|
121 | var true_cb = function( err, rslt ){
|
122 | try{
|
123 | if( callback_called ){
|
124 | return
|
125 | var error = new Error( "duplicate reply of " + that)
|
126 | error.message = msg
|
127 | throw error
|
128 | }
|
129 | callback_called = true
|
130 | msg.caller( err, rslt)
|
131 | }catch( e ){
|
132 | l8.trace( "!!! callback failure in " + this, e)
|
133 | }
|
134 | }
|
135 | msg.callback = callback = function( err, rslt ){
|
136 | if( rslt && rslt.then ){
|
137 | rslt.then(
|
138 | function( ok ){ true_cb( 0, ok) },
|
139 | function( ko ){ true_cb( ko) }
|
140 | )
|
141 | }else{
|
142 | true_cb( err, rslt)
|
143 | }
|
144 | }
|
145 | }
|
146 | that.caller = callback
|
147 | }
|
148 |
|
149 | this.stage = msg.remote
|
150 | if( this.stage ){
|
151 | de&&bug( "local actor " + this + " handles message from " + this.stage)
|
152 | }
|
153 |
|
154 | var rslt
|
155 | var err = null
|
156 |
|
157 | if( delegate ){
|
158 | try{
|
159 | rslt = delegate.match( msg.message, msg.remote, msg.callback, this)
|
160 | }catch( e ){
|
161 | err = e
|
162 | if( err === l8.continueError )return false
|
163 | }
|
164 | }else{
|
165 | SetPatternMatchOutcome = function( e, r ){
|
166 | err = e
|
167 | rslt = r
|
168 | }
|
169 | try{
|
170 | this.pattern.apply( this, msg.message)
|
171 | }catch( e ){
|
172 | return false
|
173 | }
|
174 | if( err === l8.continueEvent )return false
|
175 | }
|
176 | if( callback && callback === that.caller ){
|
177 | that.caller = null
|
178 | if( err ){
|
179 | callback( err)
|
180 | }else if( rslt || typeof rslt !== 'undefined' ){
|
181 | callback( 0, rslt)
|
182 | }
|
183 | }
|
184 | return true
|
185 | }
|
186 |
|
187 | ProtoActor.pick = function( delegate ){
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 | var list = this.backlog
|
194 | var len = list.length
|
195 | if( !len )return false
|
196 | var empty = false
|
197 | var found = false
|
198 | var msg
|
199 |
|
200 | while( true ){
|
201 |
|
202 | for( var ii ; ii < len ; ii++ ){
|
203 |
|
204 | if( !(msg = list[ii]) )continue;
|
205 |
|
206 | empty = false
|
207 | if( !this.match( msg, delegate) )continue
|
208 | found = true
|
209 | list[ii] = null
|
210 | break
|
211 | }
|
212 |
|
213 | if( !found )break
|
214 | found = false
|
215 | }
|
216 |
|
217 | if( empty ){
|
218 | this.backlog = []
|
219 | }
|
220 | return found
|
221 | }
|
222 |
|
223 | ProtoActor.act = function( delegate, after, timeout, loop ){
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 | var that = this
|
233 | l8.repeat( function(){
|
234 |
|
235 | this.step( function(){
|
236 | if( that.pick( delegate) ){
|
237 | if( loop )this.continue
|
238 | this.break
|
239 | }
|
240 |
|
241 | }).step( function(){
|
242 | if( timeout == 0 && that.queue.empty ){
|
243 | if( after ){
|
244 | after.call( that)
|
245 | }
|
246 | this.continue
|
247 | }
|
248 | that.queue.get()
|
249 |
|
250 | }).step( function( msg ){
|
251 | if( !that.match( msg, delegate) ){
|
252 | de&&bug( "backlog")
|
253 | that.backlog.push( msg)
|
254 | }
|
255 | if( !loop ) this.break
|
256 | })
|
257 | })
|
258 | .failure( function( e ){
|
259 | l8.trace( "Actor: " + that, "Unexpected error", e)
|
260 | })
|
261 | }
|
262 |
|
263 | ProtoActor.__defineGetter__( "callback" , function(){
|
264 | var caller = this.caller
|
265 | this.caller = null
|
266 | return caller
|
267 | })
|
268 |
|
269 | ProtoActor.receive = function( pattern, options ){
|
270 |
|
271 |
|
272 | var previous_pattern = this.pattern
|
273 | var that = this
|
274 | if( !options ){
|
275 | options = {}
|
276 | }
|
277 | this.task._task( function(){
|
278 | this.defer( function(){ that.pattern = previous_pattern})
|
279 | var after = options.after || pattern.after
|
280 | var timeout = options.timeout || pattern.timeout
|
281 | var loop = options.loop || pattern.loop
|
282 |
|
283 | if( pattern.match ){
|
284 | return that.act( pattern, after, timeout, loop)
|
285 | }else if( pattern.delegate ){
|
286 | return that.act( pattern.delegate, after, timeout, loop)
|
287 | }
|
288 | delete pattern.after
|
289 | delete pattern.timeout
|
290 | delete pattern.loop
|
291 |
|
292 | for( var attr in pattern ){
|
293 | if( attr === 'after' ){
|
294 | after = pattern[attr]
|
295 | continue
|
296 | }
|
297 | if( attr === 'timeout' ){
|
298 | timeout = pattern[attr]
|
299 | continue
|
300 | }
|
301 | pattern[attr] = (function( block){
|
302 | return function(){
|
303 | var rslt
|
304 | var err = null
|
305 | try{
|
306 | rslt = block.apply( this, arguments)
|
307 | }catch( e ){
|
308 | err = e
|
309 | }
|
310 | SetPatternMatchOutcome( err, rslt)
|
311 | }
|
312 | })( pattern[attr])
|
313 | }
|
314 | that.pattern = Pattern( pattern)
|
315 | that.act( null, after, timeout, loop)
|
316 | })
|
317 | }
|
318 |
|
319 | ProtoActor.become = function( pattern, options ){
|
320 | return this.receive( pattern, (options || {}).loop = true)
|
321 | }
|
322 |
|
323 | ProtoActor.send = function( message, caller ){
|
324 |
|
325 |
|
326 |
|
327 |
|
328 | var promise = null
|
329 | if( !caller ){
|
330 | promise = l8.promise()
|
331 | caller = function( err, rslt ){
|
332 | if( err ){
|
333 | promise.reject( err)
|
334 | }else{
|
335 | promise.resolve( rslt)
|
336 | }
|
337 | }
|
338 | }
|
339 | var r = this.queue.tryPut( message.remote ? message : {message:message})
|
340 | if( !r ){
|
341 | caller( "Invalid send() on " + this)
|
342 | }else{
|
343 | caller( null, r)
|
344 | }
|
345 | return promise
|
346 | }
|
347 |
|
348 | ProtoActor.call = function( message, caller ){
|
349 |
|
350 |
|
351 |
|
352 | var promise = null
|
353 | if( !caller ){
|
354 | promise = l8.promise()
|
355 | caller = function( err, rslt ){
|
356 | if( err ){
|
357 | promise.reject( err)
|
358 | }else{
|
359 | promise.resolve( rslt)
|
360 | }
|
361 | }
|
362 | }
|
363 | if( message.remote ){
|
364 | message.caller = caller
|
365 | }else{
|
366 | message = {caller:caller,message:message}
|
367 | }
|
368 | var r = this.queue.tryPut( message)
|
369 | if( !r ){
|
370 | caller( "Invalid call() on " + this)
|
371 | }
|
372 | return promise
|
373 | }
|
374 |
|
375 | function MakeActorConstructor( name, pattern ){
|
376 | return function(){
|
377 | de&&bug( "create actor " + name)
|
378 | var act = new Actor( name)
|
379 | function byebye(){
|
380 | act.queue.close()
|
381 |
|
382 | if( ProtoActor.lookup( name) === act ){
|
383 | ProtoActor.register( name, null)
|
384 | }
|
385 | }
|
386 | var task = l8._spawn( function(){
|
387 | task.var( "actor", act)
|
388 | task.step( function(){ act.receive( pattern, {loop:true}) })
|
389 | task.step( function(){ byebye(); task.join() })
|
390 | task.final( function(){ byebye() })
|
391 | })
|
392 | return act.task = task
|
393 | }
|
394 | }
|
395 |
|
396 |
|
397 |
|
398 |
|
399 |
|
400 |
|
401 |
|
402 |
|
403 |
|
404 |
|
405 |
|
406 |
|
407 | function Role( delegate ){
|
408 | this.delegate = delegate
|
409 | var options = (delegate.options && delegate.options()) || {}
|
410 | this.name = options.name
|
411 | this.async = options.async
|
412 | this.task = options.task
|
413 | this.actor = null
|
414 | this.stage = null
|
415 | this.role = this
|
416 | }
|
417 | var ProtoRole = Role.prototype
|
418 |
|
419 | function MakeRole( delegate ){
|
420 | return new Role( delegate )
|
421 | }
|
422 |
|
423 | ProtoRole.match = function( msg, remote, callback, actor ){
|
424 | var that = this
|
425 | MakeRole.current = that
|
426 | that.actor = actor
|
427 | that.stage = remote
|
428 | that.callback = callback
|
429 | var verb = msg[0]
|
430 | function apply(){
|
431 | var target = that
|
432 | if( that.delegate != that ){
|
433 | target = that.delegate
|
434 | target.actor = actor
|
435 | target.stage = remote
|
436 | target.callback = callback
|
437 | target.role = that
|
438 | }
|
439 | var target_method = target[verb]
|
440 | if( target_method ){
|
441 | msg.shift()
|
442 | }else{
|
443 | target_method = target["catch"]
|
444 | }
|
445 | return target_method.apply( target, msg)
|
446 | }
|
447 | if( !callback ){
|
448 | if( !actor.task ){
|
449 | return apply()
|
450 | }
|
451 | actor.task._spawn( function(){
|
452 | return apply()
|
453 | })
|
454 | return
|
455 | }
|
456 | if( that.task ){
|
457 | that.task._spawn( function(){
|
458 | l8.step( function(){ return apply() })
|
459 | l8.final( function( err, rslt ){
|
460 | try{
|
461 | if( !callback )return
|
462 | callback( err, rslt)
|
463 | }catch( e ){
|
464 | l8.trace( "!!! unexpected callback error in " + actor, e)
|
465 | }
|
466 | })
|
467 | })
|
468 | return
|
469 | }
|
470 | var rslt
|
471 | try{
|
472 | rslt = apply()
|
473 | if( !callback )return
|
474 | if( typeof rslt === 'undefined' )return
|
475 | if( rslt && rslt.then ){
|
476 | rslt.then(
|
477 | function( ok ){
|
478 | callback( null, ok)
|
479 | },
|
480 | function( ko ){
|
481 | callback( ko)
|
482 | }
|
483 | )
|
484 | return
|
485 | }
|
486 | try{
|
487 | callback( null, rslt)
|
488 | }catch( e ){
|
489 | l8.trace( "!!! unexpected callback error in " + actor, e)
|
490 | }
|
491 | }catch( err ){
|
492 | try{
|
493 | if( !callback )return
|
494 | callback( err)
|
495 | }catch( e ){
|
496 | l8.trace( "!!! unexpected callback error in " + actor, e)
|
497 | }
|
498 | }
|
499 | return
|
500 | }
|
501 |
|
502 |
|
503 |
|
504 |
|
505 |
|
506 |
|
507 |
|
508 | var LocalStage = null
|
509 | var AllStages = {}
|
510 | var AllCalls = {}
|
511 | var NextCallbackId = 1
|
512 | var NextClientId = 1
|
513 |
|
514 | function Stage( name, address, not_lazy ){
|
515 | this.name = name
|
516 | var promise
|
517 | this.promise = promise = l8.promise()
|
518 | this.disconnected = l8.promise()
|
519 | this.address = address
|
520 | this.isLocal = typeof address !== 'string'
|
521 | this.lazy = !not_lazy && !this.isLocal
|
522 | this.resources = {}
|
523 | AllStages[name] = this
|
524 | var that = this
|
525 |
|
526 | if( this.isLocal ){
|
527 | AllStages["local"] = this
|
528 | LocalStage = this
|
529 |
|
530 | if( l8.server ){
|
531 | this.listenSocket = null
|
532 | this.allConnection = {}
|
533 |
|
534 | try{
|
535 | this.listenSocket = SocketIo.listen(
|
536 | address || parseInt( process.env.PORT),
|
537 | {"log level":1}
|
538 | )
|
539 | }catch( e ){
|
540 | l8.trace( "Cannot listen for socket.io")
|
541 | promise.reject()
|
542 | }
|
543 | promise.resolve( that)
|
544 | this.listenSocket.sockets.on( 'connection', function( connection ){
|
545 | var client_id = "client:" + NextClientId++
|
546 | de&&bug( "new connection, " + client_id)
|
547 | var stage = MakeStage( client_id, client_id)
|
548 | stage.connection = connection
|
549 | stage.promise.resolve( connection)
|
550 | stage.setConnectionHandlers()
|
551 | connection.on( 'message', function( msg ){
|
552 | de&&bug( ["'send' from " + client_id].concat( msg))
|
553 | })
|
554 | connection.on( 'ack', function( msg ){
|
555 | de&&bug( ["'ack' from " + client_id].concat( msg))
|
556 | })
|
557 | })
|
558 | }
|
559 |
|
560 | }else{
|
561 | if( !this.lazy ){
|
562 | this.connect()
|
563 | }
|
564 | }
|
565 | return this
|
566 | }
|
567 |
|
568 | var ProtoStage = Stage.prototype
|
569 |
|
570 | ProtoStage.toString = ProtoStage.toLabel
|
571 | = function(){ return "Stage/" + this.name }
|
572 |
|
573 | ProtoStage.connect = function(){
|
574 | var that = this
|
575 | var promise = this.promise
|
576 | if( !this.lazy || this.isLocal )return this
|
577 | this.lazy = false
|
578 |
|
579 | var address = this.address
|
580 | if( address.substr( 0, 7) === "client:" )return this
|
581 | var url
|
582 | var unix
|
583 | var node
|
584 | if( address.substr( 0, 7) === "http://" ){
|
585 | url = address
|
586 | }else if( address.substr( 0, 8) === "https://" ){
|
587 | url = address
|
588 | }else if( address.sibstr( 0, 5) === "node:" ){
|
589 | node = address
|
590 | }else{
|
591 | cmd = address
|
592 | }
|
593 |
|
594 | if( url ){
|
595 | var connection = SocketIoClient.connect( this.address, {})
|
596 |
|
597 | this.connection = connection
|
598 | that.setConnectionHandlers()
|
599 | connection.on( 'connect', function(){
|
600 | that.promise.resolve( connection)
|
601 | })
|
602 | connection.on( 'connect_failed', function(){
|
603 | that.connection = null
|
604 | AllStages[that.name] = null
|
605 | that.promise.reject( 'connect_failed')
|
606 | that.disconnected.resolve()
|
607 | })
|
608 |
|
609 | }else if( node ){
|
610 | throw Error( "not supported local l8 stage " + node)
|
611 |
|
612 | }else if( unix ){
|
613 | throw Error( "not supported local l8 stage " + unix)
|
614 |
|
615 | }else{
|
616 | throw Error( "not supported local l8 stage " + address)
|
617 | }
|
618 | return this
|
619 | }
|
620 |
|
621 | ProtoStage.setConnectionHandlers = function(){
|
622 | var that = this
|
623 | var conn = this.connection
|
624 | conn.on( 'send', function( msg ){
|
625 | de&&bug( ["'send' from " + that].concat( msg))
|
626 | var actor = ProtoActor.lookup( msg.name)
|
627 | if( !actor ){
|
628 | de&&bug( "'send' message for unknown " + msg.name + " actor")
|
629 | return
|
630 | }
|
631 | actor.send( {remote:that,message:msg.send})
|
632 | })
|
633 | conn.on( 'call', function( msg ){
|
634 | de&&bug( ["'call' from " + that].concat( msg))
|
635 | var actor = ProtoActor.lookup( msg.name)
|
636 | if( !actor ){
|
637 | de&&bug( "'call' message for unknown " + msg.name + " actor")
|
638 | conn.emit( "ack", [msg.caller, "bad actor"])
|
639 | return
|
640 | }
|
641 | actor.call(
|
642 | {remote:that,message:msg.call},
|
643 | function( err, rslt ){
|
644 | conn.emit( "ack", [msg.caller, err, rslt])
|
645 | }
|
646 | )
|
647 | })
|
648 | conn.on( 'ack', function( msg ){
|
649 | de&&bug( ["'ack' from " + that].concat( msg))
|
650 | var cb_id = msg[0]
|
651 | var err = msg[1]
|
652 | var rslt = msg[2]
|
653 | if( err ){
|
654 | AllCalls[cb_id].reject( err)
|
655 | }else{
|
656 | AllCalls[cb_id].resolve( rslt)
|
657 | }
|
658 | delete AllCalls[cb_id]
|
659 | })
|
660 | conn.on( 'disconnect', function( msg ){
|
661 | de&&bug( ["'disconnect' from " + that].concat( msg))
|
662 | that.promise.reject()
|
663 | that.promise = l8.promise()
|
664 | that.promise.reject()
|
665 | that.disconnected.resolve()
|
666 | delete AllStages[that.name]
|
667 | })
|
668 | }
|
669 |
|
670 | ProtoStage.then = function( ok, ko ){
|
671 | return this.connect().promise.then( ok, ko)
|
672 | }
|
673 |
|
674 | ProtoStage.defer = function( cb ){
|
675 | var that = this
|
676 | this.disconnected.then( function(){ cb.call( l8, that) })
|
677 | }
|
678 |
|
679 | ProtoStage.get = function( id ){
|
680 | return this.resources[id]
|
681 | }
|
682 |
|
683 | ProtoStage.set = function( id, value ){
|
684 | return this.resources[id] = value
|
685 | }
|
686 |
|
687 | function MakeStage( name, address, not_lazy ){
|
688 |
|
689 | if( !LocalStage && name !== "local" ){
|
690 | new Stage( name || "local")
|
691 | }
|
692 |
|
693 | var stage = AllStages[name || "local"]
|
694 | if( stage && (!address || stage.address === address) )return stage
|
695 |
|
696 | if( !address && LocalStage && LocalStage.name === "local" ){
|
697 | LocalStage.name = name
|
698 | AllStages[name] = LocalStage
|
699 | return LocalStage
|
700 | }
|
701 |
|
702 | if( name !== 'local' && !address )throw new Error( "Missing address for remote l8 stage")
|
703 | var stage = new Stage( name, address, not_lazy)
|
704 | return stage
|
705 | }
|
706 |
|
707 |
|
708 |
|
709 |
|
710 |
|
711 |
|
712 |
|
713 | var AllProxyActors = {}
|
714 |
|
715 | function ProxyActor( name, stage, address ){
|
716 | if( stage ){
|
717 | if( address ){
|
718 | stage = MakeStage( stage, address)
|
719 | }else if( (typeof stage === 'string') && (stage.indexOf( "://") !== -1) ){
|
720 | stage = MakeStage( name, stage)
|
721 | }
|
722 | }
|
723 | this.stage = stage || LocalStage
|
724 | this.name = name
|
725 | var stage_name = this.stage.name
|
726 | AllProxyActors[stage_name + "/" + name] = this
|
727 | return this
|
728 | }
|
729 |
|
730 | var ProtoProxyActor = ProxyActor.prototype
|
731 |
|
732 | function MakeProxyActor( name, stage, address ){
|
733 | if( !LocalStage ){
|
734 | new Stage( "local")
|
735 | }
|
736 | if( !stage ){ stage = LocalStage }
|
737 | var proxy = AllProxyActors[stage.name + "/" + name]
|
738 | if( proxy && proxy.stage === stage) return proxy
|
739 | return new ProxyActor( name, stage, address)
|
740 | }
|
741 |
|
742 | ProtoProxyActor.toString = ProtoProxyActor.toLabel
|
743 | = function(){ return "Proxy/" + this.stage.name + "/" + this.name }
|
744 |
|
745 | ProtoProxyActor.send = function( args ){
|
746 | var that = this
|
747 | var promise = l8.promise()
|
748 | this.stage.then(
|
749 | function( conn ){
|
750 | if( that.stage.isLocal ){
|
751 | de&&bug( "local 'send' on " + that)
|
752 | var actor = ProtoActor.lookup( that.name)
|
753 | try{
|
754 | actor.send.call( actor, args, l8.noop)
|
755 | promise.resolve( that)
|
756 | }catch( err ){
|
757 | promise.reject( err)
|
758 | }
|
759 | return
|
760 | }
|
761 | try{
|
762 | de&&bug( "'send' on " + that)
|
763 | conn.emit( "send", {name:that.name,send:args})
|
764 | promise.resolve( that)
|
765 | }catch( err ){
|
766 | promise.reject( err)
|
767 | }
|
768 | },
|
769 | function( ko ){
|
770 | l8.trace( "Could not 'send', unavailable stage " + this.stage)
|
771 | promise.reject( ko)
|
772 | }
|
773 | )
|
774 | return promise
|
775 | }
|
776 |
|
777 | ProtoProxyActor.call = function( args, caller ){
|
778 | var that = this
|
779 | var promise = l8.promise()
|
780 | if( caller ){
|
781 | promise.then(
|
782 | function( ok ){ caller( null, ok) },
|
783 | function( ko ){ caller( ko) }
|
784 | )
|
785 | }
|
786 | this.stage.then(
|
787 | function( conn ){
|
788 | if( that.stage.isLocal ){
|
789 | de&&bug( "local 'call' on " + that)
|
790 | var actor = ProtoActor.lookup( that.name)
|
791 | actor.call(
|
792 | args,
|
793 | function( err, rslt ){
|
794 | if( err ){
|
795 | promise.reject( err)
|
796 | }else{
|
797 | promise.resolve( rslt)
|
798 | }
|
799 | }
|
800 | )
|
801 | return
|
802 | }
|
803 | var cb_id = NextCallbackId++
|
804 | AllCalls[cb_id] = promise
|
805 | de&&bug( "'call' on " + that.stage)
|
806 | conn.emit( "call", {name:that.name,call:args,caller:cb_id})
|
807 | },
|
808 | function( err ){ promise.reject( err) }
|
809 | )
|
810 | return promise
|
811 | }
|
812 |
|
813 |
|
814 |
|
815 |
|
816 |
|
817 | function Campaign( name ){
|
818 | this.name = name
|
819 | this.allServerStages = {}
|
820 | }
|
821 | var ProtoCampaign = Campaign.prototype
|
822 |
|
823 | ProtoCampaign.register = function( Stage ){
|
824 | this.allServerStages[Stage.name] = Stage
|
825 | }
|
826 |
|
827 | ProtoCampaign.deregister = function( Stage ){
|
828 | this.allServerStages[Stage.name] = null
|
829 | }
|
830 |
|
831 | ProtoCampaign.lookup = function( name ){
|
832 | return this.allServerStages[name]
|
833 | }
|
834 |
|
835 |
|
836 |
|
837 |
|
838 |
|
839 |
|
840 | l8.Actor = MakeActorConstructor
|
841 | l8.Actor.lookup = ProtoActor.lookup
|
842 | l8.Actor.all = Registry
|
843 | l8.proto.__defineGetter__( "actor", function(){ return this.get( "actor")})
|
844 | l8.Role = Role
|
845 | l8.role = MakeRole
|
846 | l8.stage = MakeStage
|
847 | l8.proxy = MakeProxyActor
|
848 |
|
849 |
|
850 |
|
851 |
|
852 |
|
853 |
|
854 |
|
855 | return l8
|
856 | }) })(
|
857 | typeof define == 'function' && define.amd
|
858 | ? define
|
859 | : function( factory ){
|
860 | typeof exports === 'object'
|
861 | ? (module.exports = factory())
|
862 | : (this.l8 = factory());
|
863 | }
|
864 | );
|
865 |
|