refactor(WebWorker): Abstract message passing and serialization to UIMessageBroker

closes #3703

Closes #3815
This commit is contained in:
Jason Teplitz
2015-08-21 16:55:50 -07:00
parent aeef19e2a6
commit 21f60c5dce
22 changed files with 319 additions and 248 deletions

View File

@ -1,6 +1,6 @@
import {Injectable} from 'angular2/di';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {Serializer} from 'angular2/src/web_workers/shared/serializer';
import {Serializer, PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
import {
RenderViewRef,
RenderFragmentRef,
@ -8,120 +8,68 @@ import {
Renderer
} from 'angular2/src/render/api';
import {WebWorkerElementRef} from 'angular2/src/web_workers/shared/api';
import {EventEmitter, ObservableWrapper, PromiseWrapper, Promise} from 'angular2/src/facade/async';
import {EVENT_CHANNEL, RENDERER_CHANNEL} from 'angular2/src/web_workers/shared/messaging_api';
import {ReceivedMessage} from 'angular2/src/web_workers/ui/impl';
import {BaseException, Type} from 'angular2/src/facade/lang';
import {bind} from './bind';
import {EventDispatcher} from 'angular2/src/web_workers/ui/event_dispatcher';
import {
RenderViewWithFragmentsStore
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
import {ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/service_message_broker';
@Injectable()
export class MessageBasedRenderer {
constructor(private _bus: MessageBus, private _serializer: Serializer,
constructor(brokerFactory: ServiceMessageBrokerFactory, private _bus: MessageBus,
private _serializer: Serializer,
private _renderViewWithFragmentsStore: RenderViewWithFragmentsStore,
private _renderer: Renderer) {
var source = _bus.from(RENDERER_CHANNEL);
ObservableWrapper.subscribe(source,
(message: StringMap<string, any>) => this._handleMessage(message));
var broker = brokerFactory.createMessageBroker(RENDERER_CHANNEL);
broker.registerMethod("createRootHostView",
[RenderProtoViewRef, PRIMITIVE, PRIMITIVE, PRIMITIVE],
bind(this._createRootHostView, this));
broker.registerMethod("createView", [RenderProtoViewRef, PRIMITIVE, PRIMITIVE],
bind(this._createView, this));
broker.registerMethod("destroyView", [RenderViewRef],
bind(this._renderer.destroyView, this._renderer));
broker.registerMethod("attachFragmentAfterFragment", [RenderFragmentRef, RenderFragmentRef],
bind(this._renderer.attachFragmentAfterFragment, this._renderer));
broker.registerMethod("attachFragmentAfterElement", [WebWorkerElementRef, RenderFragmentRef],
bind(this._renderer.attachFragmentAfterElement, this._renderer));
broker.registerMethod("detachFragment", [RenderFragmentRef],
bind(this._renderer.detachFragment, this._renderer));
broker.registerMethod("hydrateView", [RenderViewRef],
bind(this._renderer.hydrateView, this._renderer));
broker.registerMethod("dehydrateView", [RenderViewRef],
bind(this._renderer.dehydrateView, this._renderer));
broker.registerMethod("setText", [RenderViewRef, PRIMITIVE, PRIMITIVE],
bind(this._renderer.setText, this._renderer));
broker.registerMethod("setElementProperty", [WebWorkerElementRef, PRIMITIVE, PRIMITIVE],
bind(this._renderer.setElementProperty, this._renderer));
broker.registerMethod("setElementAttribute", [WebWorkerElementRef, PRIMITIVE, PRIMITIVE],
bind(this._renderer.setElementAttribute, this._renderer));
broker.registerMethod("setElementClass", [WebWorkerElementRef, PRIMITIVE, PRIMITIVE],
bind(this._renderer.setElementClass, this._renderer));
broker.registerMethod("setElementStyle", [WebWorkerElementRef, PRIMITIVE, PRIMITIVE],
bind(this._renderer.setElementStyle, this._renderer));
broker.registerMethod("invokeElementMethod", [WebWorkerElementRef, PRIMITIVE, PRIMITIVE],
bind(this._renderer.invokeElementMethod, this._renderer));
broker.registerMethod("setEventDispatcher", [RenderViewRef],
bind(this._setEventDispatcher, this));
}
private _createViewHelper(args: List<any>, method) {
var hostProtoView = this._serializer.deserialize(args[0], RenderProtoViewRef);
var fragmentCount = args[1];
var startIndex, renderViewWithFragments;
if (method == "createView") {
startIndex = args[2];
renderViewWithFragments = this._renderer.createView(hostProtoView, fragmentCount);
} else {
var selector = args[2];
startIndex = args[3];
renderViewWithFragments =
this._renderer.createRootHostView(hostProtoView, fragmentCount, selector);
}
private _createRootHostView(ref: RenderProtoViewRef, fragmentCount: number, selector: string,
startIndex: number) {
var renderViewWithFragments = this._renderer.createRootHostView(ref, fragmentCount, selector);
this._renderViewWithFragmentsStore.store(renderViewWithFragments, startIndex);
}
private _createView(ref: RenderProtoViewRef, fragmentCount: number, startIndex: number) {
var renderViewWithFragments = this._renderer.createView(ref, fragmentCount);
this._renderViewWithFragmentsStore.store(renderViewWithFragments, startIndex);
}
private _handleMessage(map: StringMap<string, any>): void {
var data = new ReceivedMessage(map);
var args = data.args;
switch (data.method) {
case "createRootHostView":
case "createView":
this._createViewHelper(args, data.method);
break;
case "destroyView":
var viewRef = this._serializer.deserialize(args[0], RenderViewRef);
this._renderer.destroyView(viewRef);
break;
case "attachFragmentAfterFragment":
var previousFragment = this._serializer.deserialize(args[0], RenderFragmentRef);
var fragment = this._serializer.deserialize(args[1], RenderFragmentRef);
this._renderer.attachFragmentAfterFragment(previousFragment, fragment);
break;
case "attachFragmentAfterElement":
var element = this._serializer.deserialize(args[0], WebWorkerElementRef);
var fragment = this._serializer.deserialize(args[1], RenderFragmentRef);
this._renderer.attachFragmentAfterElement(element, fragment);
break;
case "detachFragment":
var fragment = this._serializer.deserialize(args[0], RenderFragmentRef);
this._renderer.detachFragment(fragment);
break;
case "hydrateView":
var viewRef = this._serializer.deserialize(args[0], RenderViewRef);
this._renderer.hydrateView(viewRef);
break;
case "dehydrateView":
var viewRef = this._serializer.deserialize(args[0], RenderViewRef);
this._renderer.dehydrateView(viewRef);
break;
case "setText":
var viewRef = this._serializer.deserialize(args[0], RenderViewRef);
var textNodeIndex = args[1];
var text = args[2];
this._renderer.setText(viewRef, textNodeIndex, text);
break;
case "setElementProperty":
var elementRef = this._serializer.deserialize(args[0], WebWorkerElementRef);
var propName = args[1];
var propValue = args[2];
this._renderer.setElementProperty(elementRef, propName, propValue);
break;
case "setElementAttribute":
var elementRef = this._serializer.deserialize(args[0], WebWorkerElementRef);
var attributeName = args[1];
var attributeValue = args[2];
this._renderer.setElementAttribute(elementRef, attributeName, attributeValue);
break;
case "setElementClass":
var elementRef = this._serializer.deserialize(args[0], WebWorkerElementRef);
var className = args[1];
var isAdd = args[2];
this._renderer.setElementClass(elementRef, className, isAdd);
break;
case "setElementStyle":
var elementRef = this._serializer.deserialize(args[0], WebWorkerElementRef);
var styleName = args[1];
var styleValue = args[2];
this._renderer.setElementStyle(elementRef, styleName, styleValue);
break;
case "invokeElementMethod":
var elementRef = this._serializer.deserialize(args[0], WebWorkerElementRef);
var methodName = args[1];
var methodArgs = args[2];
this._renderer.invokeElementMethod(elementRef, methodName, methodArgs);
break;
case "setEventDispatcher":
var viewRef = this._serializer.deserialize(args[0], RenderViewRef);
var dispatcher =
new EventDispatcher(viewRef, this._bus.to(EVENT_CHANNEL), this._serializer);
this._renderer.setEventDispatcher(viewRef, dispatcher);
break;
default:
throw new BaseException("Not Implemented");
}
private _setEventDispatcher(viewRef: RenderViewRef) {
var dispatcher = new EventDispatcher(viewRef, this._bus.to(EVENT_CHANNEL), this._serializer);
this._renderer.setEventDispatcher(viewRef, dispatcher);
}
}