"
50 | ],
51 | "license": "MIT",
52 | "bugs": {
53 | "url": "https://github.com/RobotlegsJS/RobotlegsJS-Pixi/issues"
54 | },
55 | "homepage": "https://github.com/RobotlegsJS/RobotlegsJS-Pixi#readme",
56 | "files": [
57 | "definitions",
58 | "lib"
59 | ],
60 | "directories": {
61 | "lib": "./lib"
62 | },
63 | "dependencies": {
64 | "@robotlegsjs/core": "^2.0.0",
65 | "tslib": "^1.11.1"
66 | },
67 | "peerDependencies": {
68 | "pixi.js": "^5.0.0",
69 | "reflect-metadata": "^0.1.13"
70 | },
71 | "devDependencies": {
72 | "@types/bluebird": "^3.5.30",
73 | "@types/chai": "^4.2.11",
74 | "@types/mocha": "^7.0.2",
75 | "@types/sinon": "^7.5.2",
76 | "@types/webpack-env": "^1.15.1",
77 | "bluebird": "^3.7.2",
78 | "browserify-versionify": "^1.0.6",
79 | "chai": "^4.2.0",
80 | "clean-webpack-plugin": "^3.0.0",
81 | "copy-webpack-plugin": "^5.1.1",
82 | "es6-map": "^0.1.5",
83 | "es6-symbol": "^3.1.3",
84 | "glslify": "^7.0.0",
85 | "html-webpack-plugin": "^3.2.0",
86 | "imports-loader": "^0.8.0",
87 | "istanbul-instrumenter-loader": "^3.0.1",
88 | "karma": "^4.4.1",
89 | "karma-chrome-launcher": "^3.1.0",
90 | "karma-coverage-istanbul-reporter": "^2.1.1",
91 | "karma-es6-shim": "^1.0.0",
92 | "karma-mocha": "^1.3.0",
93 | "karma-mocha-reporter": "^2.2.5",
94 | "karma-sinon-chai": "^2.0.2",
95 | "karma-sourcemap-loader": "^0.3.7",
96 | "karma-sourcemap-writer": "^0.1.2",
97 | "karma-webpack": "^4.0.2",
98 | "mocha": "^7.1.0",
99 | "pixi.js": "^5.2.1",
100 | "prettier": "^1.19.1",
101 | "publish-please": "^5.5.1",
102 | "puppeteer": "^2.1.1",
103 | "reflect-metadata": "^0.1.13",
104 | "rimraf": "^3.0.2",
105 | "sinon": "^9.0.1",
106 | "sinon-chai": "^3.5.0",
107 | "terser-webpack-plugin": "^2.3.5",
108 | "ts-loader": "^6.2.1",
109 | "ts-node": "^8.6.2",
110 | "tslint": "^6.1.0",
111 | "tslint-config-prettier": "^1.18.0",
112 | "typescript": "^3.8.3",
113 | "webpack": "^4.42.0",
114 | "webpack-cli": "^3.3.11",
115 | "webpack-dev-server": "^3.10.3",
116 | "webpack-simple-progress-plugin": "^0.0.4"
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | // ContextView
9 | export { IContextView } from "./robotlegs/bender/extensions/contextView/api/IContextView";
10 | export { ContextView } from "./robotlegs/bender/extensions/contextView/impl/ContextView";
11 | export { ContextViewListenerConfig } from "./robotlegs/bender/extensions/contextView/impl/ContextViewListenerConfig";
12 | export { ContextViewExtension } from "./robotlegs/bender/extensions/contextView/ContextViewExtension";
13 |
14 | // MediatorMap
15 | export { IMediator } from "./robotlegs/bender/extensions/mediatorMap/api/IMediator";
16 | export { IMediatorMap } from "./robotlegs/bender/extensions/mediatorMap/api/IMediatorMap";
17 | export { IMediatorMapping } from "./robotlegs/bender/extensions/mediatorMap/api/IMediatorMapping";
18 | export { Mediator } from "./robotlegs/bender/extensions/mediatorMap/impl/Mediator";
19 | export { MediatorMapExtension } from "./robotlegs/bender/extensions/mediatorMap/MediatorMapExtension";
20 |
21 | // ViewManager
22 | export { IViewHandler } from "./robotlegs/bender/extensions/viewManager/api/IViewHandler";
23 | export { IViewManager } from "./robotlegs/bender/extensions/viewManager/api/IViewManager";
24 | export { ManualStageObserverExtension } from "./robotlegs/bender/extensions/viewManager/ManualStageObserverExtension";
25 | export { StageCrawlerExtension } from "./robotlegs/bender/extensions/viewManager/StageCrawlerExtension";
26 | export { StageObserverExtension } from "./robotlegs/bender/extensions/viewManager/StageObserverExtension";
27 | export { ViewManagerExtension } from "./robotlegs/bender/extensions/viewManager/ViewManagerExtension";
28 |
29 | /**
30 | * Bundles
31 | */
32 | export { PixiBundle } from "./robotlegs/bender/bundles/pixi/PixiBundle";
33 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/bundles/pixi/PixiBundle.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IBundle, IContext, ILogger, instanceOfType } from "@robotlegsjs/core";
9 |
10 | import { IContextView } from "../../extensions/contextView/api/IContextView";
11 | import { ContextView } from "../../extensions/contextView/impl/ContextView";
12 | import { ContextViewListenerConfig } from "../../extensions/contextView/impl/ContextViewListenerConfig";
13 |
14 | import { ContextViewExtension } from "../../extensions/contextView/ContextViewExtension";
15 | import { MediatorMapExtension } from "../../extensions/mediatorMap/MediatorMapExtension";
16 | import { StageCrawlerExtension } from "../../extensions/viewManager/StageCrawlerExtension";
17 | import { StageObserverExtension } from "../../extensions/viewManager/StageObserverExtension";
18 | import { ViewManagerExtension } from "../../extensions/viewManager/ViewManagerExtension";
19 |
20 | /**
21 | * For that Classic Robotlegs flavour
22 | *
23 | * This bundle installs a number of extensions commonly used
24 | * in typical Robotlegs applications and modules.
25 | */
26 | export class PixiBundle implements IBundle {
27 | /*============================================================================*/
28 | /* Private Properties */
29 | /*============================================================================*/
30 |
31 | private _context: IContext;
32 | private _logger: ILogger;
33 |
34 | /*============================================================================*/
35 | /* Public Functions */
36 | /*============================================================================*/
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public extend(context: IContext): void {
42 | this._context = context;
43 | this._logger = context.getLogger(this);
44 |
45 | this._context.install(
46 | ContextViewExtension,
47 | ViewManagerExtension,
48 | StageObserverExtension,
49 | MediatorMapExtension,
50 | StageCrawlerExtension
51 | );
52 |
53 | this._context.addConfigHandler(instanceOfType(ContextView), this.handleContextView.bind(this));
54 | this._context.whenInitializing(this.whenInitializing.bind(this));
55 | this._context.afterDestroying(this.afterDestroying.bind(this));
56 | }
57 |
58 | /*============================================================================*/
59 | /* Private Functions */
60 | /*============================================================================*/
61 |
62 | private handleContextView(): void {
63 | this._context.configure(ContextViewListenerConfig);
64 | }
65 |
66 | private whenInitializing(): void {
67 | if (!this._context.injector.isBound(IContextView)) {
68 | this._logger.error("PixiBundle requires IContextView.");
69 | }
70 | }
71 |
72 | private afterDestroying(): void {
73 | this._context = null;
74 | this._logger = null;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/contextView/ContextViewExtension.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { instanceOfType, IContext, IExtension, IInjector, ILogger } from "@robotlegsjs/core";
9 |
10 | import { IContextView } from "./api/IContextView";
11 | import { ContextView } from "./impl/ContextView";
12 |
13 | import { applyPixiPatch } from "./pixiPatch/pixi-patch";
14 |
15 | /**
16 | * This Extension waits for a ContextView to be added as a configuration
17 | * and maps it into the context's injector.
18 | *
19 | * It should be installed before context initialization.
20 | */
21 | export class ContextViewExtension implements IExtension {
22 | /*============================================================================*/
23 | /* Private Properties */
24 | /*============================================================================*/
25 |
26 | private _injector: IInjector;
27 |
28 | private _logger: ILogger;
29 |
30 | /*============================================================================*/
31 | /* Public Functions */
32 | /*============================================================================*/
33 |
34 | /**
35 | * @inheritDoc
36 | */
37 | public extend(context: IContext): void {
38 | this._injector = context.injector;
39 | this._logger = context.getLogger(this);
40 | context.beforeInitializing(this.beforeInitializing.bind(this));
41 | context.addConfigHandler(instanceOfType(ContextView), this.handleContextView.bind(this));
42 | }
43 |
44 | /*============================================================================*/
45 | /* Private Functions */
46 | /*============================================================================*/
47 |
48 | private handleContextView(contextView: IContextView): void {
49 | if (this._injector.isBound(IContextView)) {
50 | this._logger.warn("A contextView has already been installed, ignoring {0}", [contextView.view]);
51 | } else {
52 | this._logger.debug("Mapping {0} as contextView", [contextView.view]);
53 |
54 | applyPixiPatch(contextView.view);
55 |
56 | this._injector.bind(IContextView).toConstantValue(contextView);
57 | }
58 | }
59 |
60 | private beforeInitializing(): void {
61 | if (!this._injector.isBound(IContextView)) {
62 | this._logger.error("A ContextView must be installed if you install the ContextViewExtension.");
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/contextView/api/IContextView.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | export let IContextView = Symbol("IContextView");
11 | export interface IContextView {
12 | view: Container;
13 | }
14 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/contextView/impl/ContextView.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | import { IConfig } from "@robotlegsjs/core";
11 |
12 | import { IContextView } from "../api/IContextView";
13 |
14 | /**
15 | * The Context View represents the root Container for a Context
16 | */
17 | export class ContextView implements IContextView, IConfig {
18 | private _view: Container;
19 |
20 | /*============================================================================*/
21 | /* Constructor */
22 | /*============================================================================*/
23 |
24 | /**
25 | * The Context View represents the root Container for a Context
26 | * @param view The root Container for this Context
27 | */
28 | constructor(view: Container) {
29 | if (view !== null && view !== undefined) {
30 | this._view = view;
31 | } else {
32 | throw new Error("View can't be null or undefined");
33 | }
34 | }
35 |
36 | /*============================================================================*/
37 | /* Public Properties */
38 | /*============================================================================*/
39 |
40 | /**
41 | *
42 | */
43 | public configure(): void {}
44 |
45 | /**
46 | * The root Container for this Context
47 | */
48 | public get view(): Container {
49 | return this._view;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/contextView/impl/ContextViewListenerConfig.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject, IConfig } from "@robotlegsjs/core";
9 |
10 | import { IContextView } from "../api/IContextView";
11 | import { IViewManager } from "../../viewManager/api/IViewManager";
12 |
13 | /**
14 | * This configuration file adds the ContextView to the viewManager.
15 | *
16 | * It requires that the ViewManagerExtension, ContextViewExtension
17 | * and a ContextView have been installed.
18 | */
19 | @injectable()
20 | export class ContextViewListenerConfig implements IConfig {
21 | /*============================================================================*/
22 | /* Public Properties */
23 | /*============================================================================*/
24 |
25 | private _contextView: IContextView;
26 |
27 | private _viewManager: IViewManager;
28 |
29 | /*============================================================================*/
30 | /* Public Functions */
31 | /*============================================================================*/
32 |
33 | constructor(@inject(IContextView) contextView: IContextView, @inject(IViewManager) viewManager: IViewManager) {
34 | this._contextView = contextView;
35 | this._viewManager = viewManager;
36 | }
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public configure(): void {
42 | // Adds the Context View to the View Manager at startup
43 | this._viewManager.addContainer(this._contextView.view);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/contextView/pixiPatch/contains-patch.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | /**
9 | * Patch PIXI.Container class to add implementation of contains method.
10 | */
11 |
12 | import { Container, DisplayObject } from "pixi.js";
13 |
14 | const ContainerMixin = {
15 | /**
16 | * Determines whether the specified child object is a child of the Container instance or the instance itself.
17 | * The search includes the entire display list including this Container instance.
18 | * Grandchildren, great-grandchildren, and so on each return true.
19 | *
20 | * @param child The child object to test.
21 | *
22 | * @return true if the child object is a child of the Container or the Container itself; otherwise false.
23 | *
24 | * @see {@link https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html#contains()}
25 | */
26 | contains(this: Container, child: DisplayObject): boolean {
27 | let found: boolean = false;
28 | if (this === child || this.children.indexOf(child) >= 0) {
29 | found = true;
30 | } else {
31 | for (let c of this.children) {
32 | if (c instanceof Container && c.contains(child)) {
33 | found = true;
34 | break;
35 | }
36 | }
37 | }
38 | return found;
39 | }
40 | };
41 |
42 | Object.assign(Container.prototype, ContainerMixin);
43 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/contextView/pixiPatch/eventemitter3-patch.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | /**
9 | * Patch PIXI event handling.
10 | *
11 | * - Proxy PIXI events to be compatible with EventDispatcher
12 | * - Implements event bubbling on `dispatchEvent` when `bubbles` is true.
13 | */
14 |
15 | import { DisplayObject, utils } from "pixi.js";
16 | import EventEmitter = utils.EventEmitter;
17 | import { IEvent } from "@robotlegsjs/core";
18 |
19 | const EventDispatcherMixin = {
20 | addEventListener(this: EventEmitter, type: string | symbol, listener: Function, context?: any): void {
21 | this.on(type, listener, context);
22 | },
23 |
24 | hasEventListener(this: EventEmitter, type: string | symbol, listener?: Function): boolean {
25 | return this.listenerCount(type) > 0;
26 | },
27 |
28 | removeEventListener(this: EventEmitter, type: string | symbol, listener?: Function, context?: any, once?: boolean): void {
29 | this.off(type, listener, context, once);
30 | },
31 |
32 | willTrigger(type: string | symbol): boolean {
33 | return this.hasEventListener(type);
34 | },
35 |
36 | dispatchEvent(this: EventEmitter, event: IEvent): void {
37 | event.target = this;
38 |
39 | let currentTarget = this;
40 | do {
41 | event.currentTarget = currentTarget;
42 | event.currentTarget.emit(event.type, event);
43 | currentTarget = (currentTarget as DisplayObject).parent;
44 | } while (currentTarget && event.bubbles);
45 | }
46 | };
47 |
48 | Object.assign(DisplayObject.prototype, EventDispatcherMixin);
49 | Object.assign(EventEmitter.prototype, EventDispatcherMixin);
50 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/contextView/pixiPatch/pixi-patch.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | /**
9 | * Patch PIXI to:
10 | * - emit "added"/"removed" events on stage
11 | * - implement PIXI.Container.contains method
12 | */
13 |
14 | import "./eventemitter3-patch";
15 | import "./contains-patch";
16 |
17 | import PIXI = require("pixi.js");
18 |
19 | function isConnectedToStage(stage: PIXI.Container, object: PIXI.DisplayObject): boolean {
20 | if (object === stage) {
21 | return true;
22 | } else if (object.parent) {
23 | return isConnectedToStage(stage, object.parent);
24 | } else {
25 | return false;
26 | }
27 | }
28 |
29 | function emitAddedEvent(stage: PIXI.Container, target: PIXI.DisplayObject): void {
30 | stage.emit("added", { target });
31 |
32 | if (target instanceof PIXI.Container) {
33 | target.children.forEach(child => emitAddedEvent(stage, child));
34 | }
35 | }
36 |
37 | function emitRemovedEvent(stage: PIXI.Container, target: PIXI.DisplayObject): void {
38 | stage.emit("removed", { target });
39 |
40 | if (target instanceof PIXI.Container) {
41 | target.children.forEach(child => emitRemovedEvent(stage, child));
42 | }
43 | }
44 |
45 | export function applyPixiPatch(stage: PIXI.Container) {
46 | let addChild = PIXI.Container.prototype.addChild;
47 | let addChildAt = PIXI.Container.prototype.addChildAt;
48 | let removeChild = PIXI.Container.prototype.removeChild;
49 | let removeChildren = PIXI.Container.prototype.removeChildren;
50 | let removeChildAt = PIXI.Container.prototype.removeChildAt;
51 |
52 | PIXI.Container.prototype.addChild = function patchedAddChild(/*...children: T*/): T[0] {
53 | for (let i = 0, len = arguments.length; i < len; i++) {
54 | const object = arguments[i];
55 | addChild.call(this, object);
56 |
57 | if (isConnectedToStage(stage, object)) {
58 | emitAddedEvent(stage, object);
59 | }
60 | }
61 | return arguments[0];
62 | };
63 |
64 | PIXI.Container.prototype.addChildAt = function patchedAddChildAt(child: T, index: number): T {
65 | addChildAt.call(this, child, index);
66 |
67 | if (isConnectedToStage(stage, child)) {
68 | emitAddedEvent(stage, child);
69 | }
70 |
71 | return child;
72 | };
73 |
74 | PIXI.Container.prototype.removeChild = function patchedRemoveChild(/*...children: T*/): T[0] {
75 | for (let i = 0, len = arguments.length; i < len; i++) {
76 | const object = arguments[i];
77 | if (isConnectedToStage(stage, object)) {
78 | emitRemovedEvent(stage, object);
79 | }
80 |
81 | removeChild.call(this, object);
82 | }
83 |
84 | return arguments[0];
85 | };
86 |
87 | PIXI.Container.prototype.removeChildren = function patchedRemoveChildren(
88 | beginIndex: number = 0,
89 | endIndex?: number
90 | ): T[] {
91 | let removedChildren = removeChildren.call(this, beginIndex, endIndex);
92 |
93 | if (isConnectedToStage(stage, this) && removedChildren.length) {
94 | for (let child of removedChildren) {
95 | emitRemovedEvent(stage, child);
96 | }
97 | }
98 |
99 | return removedChildren;
100 | };
101 |
102 | PIXI.Container.prototype.removeChildAt = function patchedRemoveChildAt(
103 | index: number
104 | ): T {
105 | let child = removeChildAt.call(this, index);
106 |
107 | if (isConnectedToStage(stage, this) && child) {
108 | emitRemovedEvent(stage, child);
109 | }
110 |
111 | return child;
112 | };
113 | }
114 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/MediatorMapExtension.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IContext, IExtension, IInjector } from "@robotlegsjs/core";
9 |
10 | import { IMediatorMap } from "./api/IMediatorMap";
11 | import { MediatorMap } from "./impl/MediatorMap";
12 |
13 | import { IViewManager } from "../viewManager/api/IViewManager";
14 |
15 | /**
16 | * This extension installs a shared IMediatorMap into the context
17 | */
18 | export class MediatorMapExtension implements IExtension {
19 | /*============================================================================*/
20 | /* Private Properties */
21 | /*============================================================================*/
22 |
23 | private _injector: IInjector;
24 |
25 | private _mediatorMap: MediatorMap;
26 |
27 | private _viewManager: IViewManager;
28 |
29 | /*============================================================================*/
30 | /* Public Functions */
31 | /*============================================================================*/
32 |
33 | /**
34 | * @inheritDoc
35 | */
36 | public extend(context: IContext): void {
37 | context
38 | .beforeInitializing(this.beforeInitializing.bind(this))
39 | .beforeDestroying(this.beforeDestroying.bind(this))
40 | .whenDestroying(this.whenDestroying.bind(this));
41 | this._injector = context.injector;
42 | this._injector
43 | .bind(IMediatorMap)
44 | .to(MediatorMap)
45 | .inSingletonScope();
46 | }
47 |
48 | /*============================================================================*/
49 | /* Private Functions */
50 | /*============================================================================*/
51 |
52 | private beforeInitializing(): void {
53 | this._mediatorMap = this._injector.get(IMediatorMap);
54 |
55 | if (this._injector.isBound(IViewManager)) {
56 | this._viewManager = this._injector.get(IViewManager);
57 | this._viewManager.addViewHandler(this._mediatorMap);
58 | }
59 | }
60 |
61 | private beforeDestroying(): void {
62 | this._mediatorMap.unmediateAll();
63 |
64 | if (this._injector.isBound(IViewManager)) {
65 | this._viewManager = this._injector.get(IViewManager);
66 | this._viewManager.removeViewHandler(this._mediatorMap);
67 | }
68 | }
69 |
70 | private whenDestroying(): void {
71 | if (this._injector.isBound(IMediatorMap)) {
72 | this._injector.unbind(IMediatorMap);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/api/IMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | /**
9 | * Optional Mediator interface
10 | */
11 | export interface IMediator {
12 | /**
13 | * Initializes the mediator. This is run automatically by the mediatorMap when a mediator is created.
14 | * Normally the initialize function is where you would add handlers using the eventMap.
15 | */
16 | initialize(): void;
17 |
18 | /**
19 | * Destroys the mediator. This is run automatically by the mediatorMap when a mediator is destroyed.
20 | * You should clean up any handlers that were added directly (eventMap handlers will be cleaned up automatically).
21 | */
22 | destroy(): void;
23 | }
24 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/api/IMediatorMap.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IClass, ITypeMatcher } from "@robotlegsjs/core";
9 |
10 | import { IMediatorMapper } from "../dsl/IMediatorMapper";
11 | import { IMediatorUnmapper } from "../dsl/IMediatorUnmapper";
12 |
13 | /**
14 | * The Mediator Map allows you to bind Mediators to objects
15 | */
16 | export let IMediatorMap = Symbol("IMediatorMap");
17 | export interface IMediatorMap {
18 | /**
19 | * Maps a matcher that will be tested against incoming items to be handled.
20 | * @param matcher The type or package matcher specifying the rules for matching.
21 | * @return the mapper so that you can continue the mapping.
22 | */
23 | mapMatcher(matcher: ITypeMatcher): IMediatorMapper;
24 |
25 | /**
26 | * Maps a type that will be tested against incoming items to be handled.
27 | * Under the hood this will create a TypeMatcher for this type.
28 | * @param type The class or interface to be matched against.
29 | * @return the mapper so that you can continue the mapping.
30 | */
31 | map(type: IClass): IMediatorMapper;
32 |
33 | /**
34 | * Removes a mapping that was made against a matcher.
35 | * No error will be thrown if there isn't a mapping to remove.
36 | * @param matcher The type or package matcher specifying the rules for matching.
37 | * @return the unmapper so that you can continue the unmapping.
38 | */
39 | unmapMatcher(matcher: ITypeMatcher): IMediatorUnmapper;
40 |
41 | /**
42 | * Removes a mapping that was made against a type.
43 | * No error will be thrown if there isn't a mapping to remove.
44 | * @param type The class or interface to be matched against.
45 | * @return the unmapper so that you can continue the unmapping.
46 | */
47 | unmap(type: IClass): IMediatorUnmapper;
48 |
49 | /**
50 | * Mediates an item directly. If the item matches any mapped matchers or types then it will be mediated according to those mappings.
51 | * @param item The item to create mediators for.
52 | */
53 | mediate(item: any): void;
54 |
55 | /**
56 | * Removes the mediators for an item if there are any.
57 | * @param item The item to remove mediators for.
58 | */
59 | unmediate(item: any): void;
60 |
61 | /**
62 | * Removes all mediators
63 | */
64 | unmediateAll(): void;
65 | }
66 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/api/IMediatorMapping.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IClass, ITypeFilter } from "@robotlegsjs/core";
9 |
10 | /**
11 | * Represents a Mediator mapping
12 | */
13 | export interface IMediatorMapping {
14 | /**
15 | * The matcher for this mapping
16 | */
17 | matcher: ITypeFilter;
18 |
19 | /**
20 | * The concrete mediator class
21 | */
22 | mediatorClass: IClass;
23 |
24 | /**
25 | * A list of guards to check before allowing mediator creation
26 | */
27 | guards: any[];
28 |
29 | /**
30 | * A list of hooks to run before creating a mediator
31 | */
32 | hooks: any[];
33 |
34 | /**
35 | * Should the mediator be removed when the mediated item looses scope?
36 | */
37 | autoRemoveEnabled: boolean;
38 | }
39 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/dsl/IMediatorConfigurator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | /**
9 | * Configures a mediator mapping
10 | */
11 | export interface IMediatorConfigurator {
12 | /**
13 | * Guards to check before allowing a mediator to be created
14 | * @param guards Guards
15 | * @return Self
16 | */
17 | withGuards(...guards: any[]): IMediatorConfigurator;
18 |
19 | /**
20 | * Hooks to run before a mediator is created
21 | * @param hooks Hooks
22 | * @return Self
23 | */
24 | withHooks(...hooks: any[]): IMediatorConfigurator;
25 |
26 | /**
27 | * Should the mediator be removed when the mediated item looses scope?
28 | *
29 | * Usually this would be when the mediated item is a Display Object
30 | * and it leaves the stage.
31 | *
32 | * @param value Boolean
33 | * @return Self
34 | */
35 | autoRemove(value: boolean): IMediatorConfigurator;
36 | }
37 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/dsl/IMediatorMapper.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IClass } from "@robotlegsjs/core";
9 |
10 | import { IMediatorConfigurator } from "./IMediatorConfigurator";
11 |
12 | /**
13 | * Maps a matcher to a concrete Mediator class
14 | */
15 | export interface IMediatorMapper {
16 | /**
17 | * Maps a matcher to a concrete Mediator class
18 | * @param mediatorClass The concrete mediator class
19 | * @return Mapping configurator
20 | */
21 | toMediator(mediatorClass: IClass): IMediatorConfigurator;
22 | }
23 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/dsl/IMediatorUnmapper.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IClass } from "@robotlegsjs/core";
9 |
10 | /**
11 | * Unmaps a Mediator
12 | */
13 | export interface IMediatorUnmapper {
14 | /**
15 | * Unmaps a mediator from this matcher
16 | * @param mediatorClass Mediator to unmap
17 | */
18 | fromMediator(mediatorClass: IClass): void;
19 |
20 | /**
21 | * Unmaps all mediator mappings for this matcher
22 | */
23 | fromAll(): void;
24 | }
25 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorManager.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { DisplayObject } from "pixi.js";
9 |
10 | import { IMediatorMapping } from "../api/IMediatorMapping";
11 | import { MediatorFactory } from "./MediatorFactory";
12 |
13 | /**
14 | * @private
15 | */
16 | export class MediatorManager {
17 | /*============================================================================*/
18 | /* Private Properties */
19 | /*============================================================================*/
20 |
21 | private _factory: MediatorFactory;
22 |
23 | /*============================================================================*/
24 | /* Constructor */
25 | /*============================================================================*/
26 |
27 | /**
28 | * @private
29 | */
30 | constructor(factory: MediatorFactory) {
31 | this._factory = factory;
32 | }
33 |
34 | /*============================================================================*/
35 | /* Public Functions */
36 | /*============================================================================*/
37 |
38 | /**
39 | * @private
40 | */
41 | public addMediator(mediator: any, item: any, mapping: IMediatorMapping): void {
42 | // Watch Display Object for removal
43 | if (item instanceof DisplayObject && mapping.autoRemoveEnabled) {
44 | (item)._onRemovedFromStage = this.onRemovedFromStage.bind(this, item);
45 | item.on("removed", (item)._onRemovedFromStage, this);
46 | }
47 |
48 | // Synchronize with item life-cycle
49 | this.initializeMediator(mediator, item);
50 | }
51 |
52 | /**
53 | * @private
54 | */
55 | public removeMediator(mediator: any, item: any, mapping: IMediatorMapping): void {
56 | if (item instanceof DisplayObject) {
57 | item.off("removed", (item)._onRemovedFromStage);
58 | }
59 |
60 | this.destroyMediator(mediator);
61 | }
62 |
63 | /*============================================================================*/
64 | /* Private Functions */
65 | /*============================================================================*/
66 |
67 | private onRemovedFromStage(displayObject: any, fromContainer: any): void {
68 | this._factory.removeMediators(displayObject);
69 | }
70 |
71 | private initializeMediator(mediator: any, mediatedItem: any): void {
72 | if ("preInitialize" in mediator) {
73 | mediator.preInitialize();
74 | }
75 |
76 | if ("view" in mediator) {
77 | mediator.view = mediatedItem;
78 | }
79 |
80 | if ("initialize" in mediator) {
81 | mediator.initialize();
82 | }
83 |
84 | if ("postInitialize" in mediator) {
85 | mediator.postInitialize();
86 | }
87 | }
88 |
89 | private destroyMediator(mediator: any): void {
90 | if ("preDestroy" in mediator) {
91 | mediator.preDestroy();
92 | }
93 |
94 | if ("destroy" in mediator) {
95 | mediator.destroy();
96 | }
97 |
98 | if ("view" in mediator) {
99 | mediator.view = null;
100 | }
101 |
102 | if ("postDestroy" in mediator) {
103 | mediator.postDestroy();
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMap.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { DisplayObject } from "pixi.js";
9 |
10 | import { injectable, inject, IClass, IContext, ILogger, ITypeMatcher, TypeMatcher } from "@robotlegsjs/core";
11 |
12 | import { IMediatorMap } from "../api/IMediatorMap";
13 | import { IMediatorMapper } from "../dsl/IMediatorMapper";
14 | import { IMediatorUnmapper } from "../dsl/IMediatorUnmapper";
15 |
16 | import { IViewHandler } from "../../viewManager/api/IViewHandler";
17 |
18 | import { MediatorFactory } from "./MediatorFactory";
19 | import { MediatorViewHandler } from "./MediatorViewHandler";
20 | import { NullMediatorUnmapper } from "./NullMediatorUnmapper";
21 | import { MediatorMapper } from "./MediatorMapper";
22 |
23 | /**
24 | * @private
25 | */
26 | @injectable()
27 | export class MediatorMap implements IMediatorMap, IViewHandler {
28 | /*============================================================================*/
29 | /* Private Properties */
30 | /*============================================================================*/
31 |
32 | private _mappers: Map = new Map();
33 |
34 | private _logger: ILogger;
35 |
36 | private _factory: MediatorFactory;
37 |
38 | private _viewHandler: MediatorViewHandler;
39 |
40 | private NULL_UNMAPPER: IMediatorUnmapper = new NullMediatorUnmapper();
41 |
42 | /*============================================================================*/
43 | /* Constructor */
44 | /*============================================================================*/
45 |
46 | /**
47 | * @private
48 | */
49 | constructor(@inject(IContext) context: IContext) {
50 | this._logger = context.getLogger(this);
51 | this._factory = new MediatorFactory(context.injector);
52 | this._viewHandler = new MediatorViewHandler(this._factory);
53 | }
54 |
55 | /*============================================================================*/
56 | /* Public Functions */
57 | /*============================================================================*/
58 |
59 | /**
60 | * @inheritDoc
61 | */
62 | public mapMatcher(matcher: ITypeMatcher): IMediatorMapper {
63 | const desc = matcher.createTypeFilter().descriptor;
64 | let mapper = this._mappers.get(desc);
65 |
66 | if (mapper) {
67 | return mapper;
68 | }
69 |
70 | mapper = this.createMapper(matcher);
71 | this._mappers.set(desc, mapper);
72 | return mapper;
73 | }
74 |
75 | /**
76 | * @inheritDoc
77 | */
78 | public map(type: IClass): IMediatorMapper {
79 | return this.mapMatcher(new TypeMatcher().allOf(type));
80 | }
81 |
82 | /**
83 | * @inheritDoc
84 | */
85 | public unmapMatcher(matcher: ITypeMatcher): IMediatorUnmapper {
86 | return this._mappers.get(matcher.createTypeFilter().descriptor) || this.NULL_UNMAPPER;
87 | }
88 |
89 | /**
90 | * @inheritDoc
91 | */
92 | public unmap(type: IClass): IMediatorUnmapper {
93 | return this.unmapMatcher(new TypeMatcher().allOf(type));
94 | }
95 |
96 | /**
97 | * @inheritDoc
98 | */
99 | public handleView(view: DisplayObject, type: IClass): void {
100 | this._viewHandler.handleView(view, type);
101 | }
102 |
103 | /**
104 | * @inheritDoc
105 | */
106 | public mediate(item: any): void {
107 | this._viewHandler.handleItem(item, >item.constructor);
108 | }
109 |
110 | /**
111 | * @inheritDoc
112 | */
113 | public unmediate(item: any): void {
114 | this._factory.removeMediators(item);
115 | }
116 |
117 | /**
118 | * @inheritDoc
119 | */
120 | public unmediateAll(): void {
121 | this._factory.removeAllMediators();
122 | }
123 |
124 | /*============================================================================*/
125 | /* Private Functions */
126 | /*============================================================================*/
127 |
128 | private createMapper(matcher: ITypeMatcher): MediatorMapper {
129 | return new MediatorMapper(matcher.createTypeFilter(), this._viewHandler, this._logger);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMapper.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IClass, ILogger, ITypeFilter } from "@robotlegsjs/core";
9 |
10 | import { IMediatorMapping } from "../api/IMediatorMapping";
11 | import { IMediatorConfigurator } from "../dsl/IMediatorConfigurator";
12 | import { IMediatorMapper } from "../dsl/IMediatorMapper";
13 | import { IMediatorUnmapper } from "../dsl/IMediatorUnmapper";
14 |
15 | import { MediatorViewHandler } from "./MediatorViewHandler";
16 | import { MediatorMapping } from "./MediatorMapping";
17 |
18 | /**
19 | * @private
20 | */
21 | export class MediatorMapper implements IMediatorMapper, IMediatorUnmapper {
22 | /*============================================================================*/
23 | /* Private Properties */
24 | /*============================================================================*/
25 |
26 | private _mappings: Map, IMediatorMapping> = new Map, IMediatorMapping>();
27 |
28 | private _typeFilter: ITypeFilter;
29 |
30 | private _handler: MediatorViewHandler;
31 |
32 | private _logger: ILogger;
33 |
34 | /*============================================================================*/
35 | /* Constructor */
36 | /*============================================================================*/
37 |
38 | /**
39 | * @private
40 | */
41 | constructor(typeFilter: ITypeFilter, handler: MediatorViewHandler, logger?: ILogger) {
42 | this._typeFilter = typeFilter;
43 | this._handler = handler;
44 | this._logger = logger;
45 | }
46 |
47 | /*============================================================================*/
48 | /* Public Functions */
49 | /*============================================================================*/
50 |
51 | /**
52 | * @inheritDoc
53 | */
54 | public toMediator(mediatorClass: IClass): IMediatorConfigurator {
55 | const mapping: IMediatorMapping = this._mappings.get(mediatorClass);
56 | return mapping ? this.overwriteMapping(mapping) : this.createMapping(mediatorClass);
57 | }
58 |
59 | /**
60 | * @inheritDoc
61 | */
62 | public fromMediator(mediatorClass: IClass): void {
63 | const mapping: IMediatorMapping = this._mappings.get(mediatorClass);
64 |
65 | if (mapping) {
66 | this.deleteMapping(mapping);
67 | }
68 | }
69 |
70 | /**
71 | * @inheritDoc
72 | */
73 | public fromAll(): void {
74 | this._mappings.forEach(this.deleteMapping, this);
75 | }
76 |
77 | /*============================================================================*/
78 | /* Private Functions */
79 | /*============================================================================*/
80 |
81 | private createMapping(mediatorClass: IClass): MediatorMapping {
82 | let mapping: MediatorMapping = new MediatorMapping(this._typeFilter, mediatorClass);
83 | this._handler.addMapping(mapping);
84 | this._mappings.set(mediatorClass, mapping);
85 |
86 | if (this._logger) {
87 | this._logger.debug("{0} mapped to {1}", [this._typeFilter, mapping]);
88 | }
89 |
90 | return mapping;
91 | }
92 |
93 | private deleteMapping(mapping: IMediatorMapping): void {
94 | this._handler.removeMapping(mapping);
95 | this._mappings.delete(mapping.mediatorClass);
96 |
97 | if (this._logger) {
98 | this._logger.debug("{0} unmapped from {1}", [this._typeFilter, mapping]);
99 | }
100 | }
101 |
102 | private overwriteMapping(mapping: IMediatorMapping): IMediatorConfigurator {
103 | if (this._logger) {
104 | this._logger.warn(
105 | "{0} already mapped to {1}\n" +
106 | 'If you have overridden this mapping intentionally you can use "unmap()" ' +
107 | "prior to your replacement mapping in order to avoid seeing this message.\n",
108 | [this._typeFilter, mapping]
109 | );
110 | }
111 | this.deleteMapping(mapping);
112 | return this.createMapping(mapping.mediatorClass);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMapping.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IClass, ITypeFilter } from "@robotlegsjs/core";
9 |
10 | import { IMediatorMapping } from "../api/IMediatorMapping";
11 | import { IMediatorConfigurator } from "../dsl/IMediatorConfigurator";
12 |
13 | /**
14 | * @private
15 | */
16 | export class MediatorMapping implements IMediatorMapping, IMediatorConfigurator {
17 | /*============================================================================*/
18 | /* Public Properties */
19 | /*============================================================================*/
20 |
21 | private _matcher: ITypeFilter;
22 |
23 | /**
24 | * @inheritDoc
25 | */
26 | public get matcher(): ITypeFilter {
27 | return this._matcher;
28 | }
29 |
30 | private _mediatorClass: IClass;
31 |
32 | /**
33 | * @inheritDoc
34 | */
35 | public get mediatorClass(): IClass {
36 | return this._mediatorClass;
37 | }
38 |
39 | private _guards: any[] = [];
40 |
41 | /**
42 | * @inheritDoc
43 | */
44 | public get guards(): any[] {
45 | return this._guards;
46 | }
47 |
48 | private _hooks: any[] = [];
49 |
50 | /**
51 | * @inheritDoc
52 | */
53 | public get hooks(): any[] {
54 | return this._hooks;
55 | }
56 |
57 | private _autoRemoveEnabled: boolean = true;
58 |
59 | /**
60 | * @inheritDoc
61 | */
62 | public get autoRemoveEnabled(): boolean {
63 | return this._autoRemoveEnabled;
64 | }
65 |
66 | /*============================================================================*/
67 | /* Constructor */
68 | /*============================================================================*/
69 |
70 | /**
71 | * @private
72 | */
73 | constructor(matcher: ITypeFilter, mediatorClass: IClass) {
74 | this._matcher = matcher;
75 | this._mediatorClass = mediatorClass;
76 | }
77 |
78 | /*============================================================================*/
79 | /* Public Functions */
80 | /*============================================================================*/
81 |
82 | /**
83 | * @inheritDoc
84 | */
85 | public withGuards(...guards: any[]): IMediatorConfigurator {
86 | this._guards = this._guards.concat.apply(this._guards, guards);
87 | return this;
88 | }
89 |
90 | /**
91 | * @inheritDoc
92 | */
93 | public withHooks(...hooks: any[]): IMediatorConfigurator {
94 | this._hooks = this._hooks.concat.apply(this._hooks, hooks);
95 | return this;
96 | }
97 |
98 | /**
99 | * @inheritDoc
100 | */
101 | public autoRemove(value: boolean = true): IMediatorConfigurator {
102 | this._autoRemoveEnabled = value;
103 | return this;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/impl/MediatorViewHandler.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { DisplayObject } from "pixi.js";
9 |
10 | import { IClass } from "@robotlegsjs/core";
11 |
12 | import { IMediatorMapping } from "../api/IMediatorMapping";
13 | import { IViewHandler } from "../../viewManager/api/IViewHandler";
14 |
15 | import { MediatorFactory } from "./MediatorFactory";
16 |
17 | /**
18 | * @private
19 | */
20 | export class MediatorViewHandler implements IViewHandler {
21 | /*============================================================================*/
22 | /* Private Properties */
23 | /*============================================================================*/
24 |
25 | private _mappings: IMediatorMapping[] = [];
26 |
27 | private _knownMappings: Map, IMediatorMapping[] | boolean> = new Map, IMediatorMapping[]>();
28 |
29 | private _factory: MediatorFactory;
30 |
31 | /*============================================================================*/
32 | /* Constructor */
33 | /*============================================================================*/
34 |
35 | /**
36 | * @private
37 | */
38 | constructor(factory: MediatorFactory) {
39 | this._factory = factory;
40 | }
41 |
42 | /*============================================================================*/
43 | /* Public Functions */
44 | /*============================================================================*/
45 |
46 | /**
47 | * @private
48 | */
49 | public addMapping(mapping: IMediatorMapping): void {
50 | let index: number = this._mappings.indexOf(mapping);
51 | if (index > -1) {
52 | return;
53 | }
54 | this._mappings.push(mapping);
55 | this._knownMappings.clear();
56 | }
57 |
58 | /**
59 | * @private
60 | */
61 | public removeMapping(mapping: IMediatorMapping): void {
62 | let index: number = this._mappings.indexOf(mapping);
63 | if (index === -1) {
64 | return;
65 | }
66 | this._mappings.splice(index, 1);
67 | this._knownMappings.clear();
68 | }
69 |
70 | /**
71 | * @private
72 | */
73 | public handleView(view: DisplayObject, type: IClass): void {
74 | let interestedMappings = this.getInterestedMappingsFor(view, type);
75 | if (interestedMappings) {
76 | this._factory.createMediators(view, type, interestedMappings);
77 | }
78 | }
79 |
80 | /**
81 | * @private
82 | */
83 | public handleItem(item: any, type: IClass): void {
84 | let interestedMappings = this.getInterestedMappingsFor(item, type);
85 | if (interestedMappings) {
86 | this._factory.createMediators(item, type, interestedMappings);
87 | }
88 | }
89 |
90 | /*============================================================================*/
91 | /* Private Functions */
92 | /*============================================================================*/
93 |
94 | private getInterestedMappingsFor(item: any, type: IClass): IMediatorMapping[] {
95 | // we've seen this type before and nobody was interested
96 | if (this._knownMappings.get(type) === false) {
97 | return null;
98 | }
99 |
100 | // we haven't seen this type before
101 | if (this._knownMappings.get(type) === undefined) {
102 | this._knownMappings.set(type, false);
103 |
104 | this._mappings.forEach((mapping: IMediatorMapping) => {
105 | if (mapping.matcher.matches(item)) {
106 | if (!this._knownMappings.get(type)) {
107 | this._knownMappings.set(type, []);
108 | }
109 | (this._knownMappings.get(type) as IMediatorMapping[]).push(mapping);
110 | }
111 | });
112 | // nobody cares, let's get out of here
113 | if (this._knownMappings.get(type) === false) {
114 | return null;
115 | }
116 | }
117 |
118 | // these mappings really do care
119 | return this._knownMappings.get(type) as IMediatorMapping[];
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/mediatorMap/impl/NullMediatorUnmapper.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IClass } from "@robotlegsjs/core";
9 |
10 | import { IMediatorUnmapper } from "../dsl/IMediatorUnmapper";
11 |
12 | /**
13 | * @private
14 | */
15 | export class NullMediatorUnmapper implements IMediatorUnmapper {
16 | /*============================================================================*/
17 | /* Public Functions */
18 | /*============================================================================*/
19 |
20 | /**
21 | * @private
22 | */
23 | public fromMediator(mediatorClass: IClass): void {}
24 |
25 | /**
26 | * @private
27 | */
28 | public fromAll(): void {}
29 | }
30 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/ManualStageObserverExtension.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IContext, IExtension, IInjector, ILogger } from "@robotlegsjs/core";
9 |
10 | import { ContainerRegistry } from "./impl/ContainerRegistry";
11 | import { ManualStageObserver } from "./impl/ManualStageObserver";
12 |
13 | let installCount: number = 0;
14 |
15 | /**
16 | * This extension install a manual Stage Observer
17 | */
18 | export class ManualStageObserverExtension implements IExtension {
19 | /*============================================================================*/
20 | /* Private Static Properties */
21 | /*============================================================================*/
22 |
23 | // Really? Yes, there can be only one.
24 | private static _manualStageObserver: ManualStageObserver;
25 |
26 | /*============================================================================*/
27 | /* Private Properties */
28 | /*============================================================================*/
29 |
30 | private _injector: IInjector;
31 |
32 | private _logger: ILogger;
33 |
34 | /*============================================================================*/
35 | /* Public Functions */
36 | /*============================================================================*/
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public extend(context: IContext): void {
42 | context.whenInitializing(this.whenInitializing.bind(this));
43 | context.whenDestroying(this.whenDestroying.bind(this));
44 | installCount++;
45 | this._injector = context.injector;
46 | this._logger = context.getLogger(this);
47 | }
48 |
49 | /*============================================================================*/
50 | /* Private Functions */
51 | /*============================================================================*/
52 |
53 | private whenInitializing(): void {
54 | // Hark, an actual Singleton!
55 | if (!ManualStageObserverExtension._manualStageObserver) {
56 | let containerRegistry: ContainerRegistry = this._injector.get(ContainerRegistry);
57 | this._logger.debug("Creating genuine ManualStageObserver Singleton");
58 | ManualStageObserverExtension._manualStageObserver = new ManualStageObserver(containerRegistry);
59 | }
60 | }
61 |
62 | private whenDestroying(): void {
63 | installCount--;
64 | if (installCount === 0) {
65 | this._logger.debug("Destroying genuine ManualStageObserver Singleton");
66 | ManualStageObserverExtension._manualStageObserver.destroy();
67 | ManualStageObserverExtension._manualStageObserver = null;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/StageCrawlerExtension.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | import { IContext, IExtension, IInjector, ILogger } from "@robotlegsjs/core";
11 |
12 | import { IContextView } from "../contextView/api/IContextView";
13 |
14 | import { IViewManager } from "./api/IViewManager";
15 | import { ContainerBinding } from "./impl/ContainerBinding";
16 | import { ContainerRegistry } from "./impl/ContainerRegistry";
17 | import { StageCrawler } from "./impl/StageCrawler";
18 |
19 | /**
20 | * View Handlers (like the MediatorMap) handle views as they land on stage.
21 | *
22 | * This extension checks for views that might already be on the stage
23 | * after context initialization and ensures that those views are handled.
24 | */
25 | export class StageCrawlerExtension implements IExtension {
26 | /*============================================================================*/
27 | /* Private Properties */
28 | /*============================================================================*/
29 |
30 | private _logger: ILogger;
31 |
32 | private _injector: IInjector;
33 |
34 | private _containerRegistry: ContainerRegistry;
35 |
36 | /*============================================================================*/
37 | /* Public Functions */
38 | /*============================================================================*/
39 |
40 | /**
41 | * @inheritDoc
42 | */
43 | public extend(context: IContext): void {
44 | this._injector = context.injector;
45 | this._logger = context.getLogger(this);
46 | context.afterInitializing(this.afterInitializing.bind(this));
47 | }
48 |
49 | /*============================================================================*/
50 | /* Private Functions */
51 | /*============================================================================*/
52 |
53 | private afterInitializing(): void {
54 | this._containerRegistry = this._injector.get(ContainerRegistry);
55 | this._injector.isBound(IViewManager) ? this.scanViewManagedContainers() : this.scanContextView();
56 | }
57 |
58 | private scanViewManagedContainers(): void {
59 | this._logger.debug("ViewManager is installed. Checking for managed containers...");
60 | let viewManager: IViewManager = this._injector.get(IViewManager);
61 | viewManager.containers.forEach((container: Container) => {
62 | this.scanContainer(container);
63 | });
64 | }
65 |
66 | private scanContextView(): void {
67 | if (this._injector.isBound(IContextView)) {
68 | this._logger.debug("ViewManager is not installed. Checking the ContextView...");
69 | let contextView: IContextView = this._injector.get(IContextView);
70 | this.scanContainer(contextView.view);
71 | } else {
72 | this._logger.error("A ContextView must be installed if you install the StageCrawlerExtension.");
73 | }
74 | }
75 |
76 | private scanContainer(container: Container): void {
77 | let binding: ContainerBinding = this._containerRegistry.getBinding(container);
78 | this._logger.debug("StageCrawler scanning container {0} ...", [container]);
79 | new StageCrawler(binding).scan(container);
80 | this._logger.debug("StageCrawler finished scanning {0}", [container]);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/StageObserverExtension.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IContext, IExtension, IInjector, ILogger } from "@robotlegsjs/core";
9 |
10 | import { ContainerRegistry } from "./impl/ContainerRegistry";
11 | import { StageObserver } from "./impl/StageObserver";
12 |
13 | let installCount: number = 0;
14 |
15 | /**
16 | * This extension install an automatic Stage Observer
17 | */
18 | export class StageObserverExtension implements IExtension {
19 | /*============================================================================*/
20 | /* Private Static Properties */
21 | /*============================================================================*/
22 |
23 | // Really? Yes, there can be only one.
24 | private static _stageObserver: StageObserver = null;
25 |
26 | /*============================================================================*/
27 | /* Private Properties */
28 | /*============================================================================*/
29 |
30 | private _injector: IInjector;
31 |
32 | private _logger: ILogger;
33 |
34 | /*============================================================================*/
35 | /* Public Functions */
36 | /*============================================================================*/
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public extend(context: IContext): void {
42 | context.whenInitializing(this.whenInitializing.bind(this));
43 | context.whenDestroying(this.whenDestroying.bind(this));
44 | installCount++;
45 | this._injector = context.injector;
46 | this._logger = context.getLogger(this);
47 | }
48 |
49 | /*============================================================================*/
50 | /* Private Functions */
51 | /*============================================================================*/
52 |
53 | private whenInitializing(): void {
54 | // Hark, an actual Singleton!
55 | if (!StageObserverExtension._stageObserver) {
56 | let containerRegistry: ContainerRegistry = this._injector.get(ContainerRegistry);
57 | this._logger.debug("Creating genuine StageObserver Singleton");
58 | StageObserverExtension._stageObserver = new StageObserver(containerRegistry);
59 | }
60 | }
61 |
62 | private whenDestroying(): void {
63 | installCount--;
64 | if (installCount === 0) {
65 | this._logger.debug("Destroying genuine StageObserver Singleton");
66 | StageObserverExtension._stageObserver.destroy();
67 | StageObserverExtension._stageObserver = null;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/ViewManagerExtension.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { IContext, IExtension, IInjector } from "@robotlegsjs/core";
9 |
10 | import { IViewManager } from "../viewManager/api/IViewManager";
11 | import { ViewManager } from "../viewManager/impl/ViewManager";
12 |
13 | import { ContainerRegistry } from "./impl/ContainerRegistry";
14 |
15 | /**
16 | * This extension install a View Manager into the context
17 | */
18 | export class ViewManagerExtension implements IExtension {
19 | /*============================================================================*/
20 | /* Private Static Properties */
21 | /*============================================================================*/
22 |
23 | // Really? Yes, there can be only one.
24 | private static _containerRegistry: ContainerRegistry;
25 |
26 | /*============================================================================*/
27 | /* Private Properties */
28 | /*============================================================================*/
29 |
30 | private _injector: IInjector;
31 |
32 | private _viewManager: IViewManager;
33 |
34 | /*============================================================================*/
35 | /* Public Functions */
36 | /*============================================================================*/
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public extend(context: IContext): void {
42 | context.whenInitializing(this.whenInitializing.bind(this));
43 | context.whenDestroying(this.whenDestroying.bind(this));
44 |
45 | this._injector = context.injector;
46 |
47 | // Just one Container Registry
48 | ViewManagerExtension._containerRegistry = ViewManagerExtension._containerRegistry || new ContainerRegistry();
49 | this._injector.bind(ContainerRegistry).toConstantValue(ViewManagerExtension._containerRegistry);
50 |
51 | // But you get your own View Manager
52 | this._injector
53 | .bind(IViewManager)
54 | .to(ViewManager)
55 | .inSingletonScope();
56 | }
57 |
58 | /*============================================================================*/
59 | /* Private Functions */
60 | /*============================================================================*/
61 |
62 | private whenInitializing(): void {
63 | this._viewManager = this._injector.get(IViewManager);
64 | }
65 |
66 | private whenDestroying(): void {
67 | this._viewManager.removeAllHandlers();
68 | this._injector.unbind(IViewManager);
69 | this._injector.unbind(ContainerRegistry);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/api/IViewHandler.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { DisplayObject } from "pixi.js";
9 |
10 | import { IClass } from "@robotlegsjs/core";
11 |
12 | /**
13 | * View handler contract
14 | */
15 | export interface IViewHandler {
16 | /**
17 | * View handler method
18 | * @param view The view instance to handle
19 | * @param type The class of the view instance
20 | */
21 | handleView(view: DisplayObject, type: IClass): void;
22 | }
23 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/api/IViewManager.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | import { IEventDispatcher } from "@robotlegsjs/core";
11 | import { IViewHandler } from "./IViewHandler";
12 |
13 | /*[Event(name="containerAdd", type="robotlegs.bender.extensions.viewManager.impl.ViewManagerEvent")]*/
14 | /*[Event(name="containerRemove", type="robotlegs.bender.extensions.viewManager.impl.ViewManagerEvent")]*/
15 | /*[Event(name="handlerAdd", type="robotlegs.bender.extensions.viewManager.impl.ViewManagerEvent")]*/
16 | /*[Event(name="handlerRemove", type="robotlegs.bender.extensions.viewManager.impl.ViewManagerEvent")]*/
17 |
18 | /**
19 | * The View Manager allows you to add multiple "view root" containers to a context
20 | */
21 | export let IViewManager = Symbol("IViewManager");
22 | export interface IViewManager extends IEventDispatcher {
23 | /**
24 | * A list of currently registered containers
25 | */
26 | containers: Container[];
27 |
28 | /**
29 | * Adds a container as a "view root" into the context
30 | * @param container
31 | */
32 | addContainer(container: Container): void;
33 |
34 | /**
35 | * Removes a container from this context
36 | * @param container
37 | */
38 | removeContainer(container: Container): void;
39 |
40 | /**
41 | * Registers a view handler
42 | * @param handler
43 | */
44 | addViewHandler(handler: IViewHandler): void;
45 |
46 | /**
47 | * Removes a view handler
48 | * @param handler
49 | */
50 | removeViewHandler(handler: IViewHandler): void;
51 |
52 | /**
53 | * Removes all view handlers from this context
54 | */
55 | removeAllHandlers(): void;
56 | }
57 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/ConfigureViewEvent.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Event } from "@robotlegsjs/core";
9 |
10 | import { Container } from "pixi.js";
11 |
12 | /**
13 | * View Configuration Event
14 | * @private
15 | */
16 | export class ConfigureViewEvent extends Event {
17 | /*============================================================================*/
18 | /* Public Static Properties */
19 | /*============================================================================*/
20 |
21 | public static CONFIGURE_VIEW: string = "configureView";
22 |
23 | /*============================================================================*/
24 | /* Public Properties */
25 | /*============================================================================*/
26 |
27 | private _view: Container;
28 |
29 | /**
30 | * The view instance associated with this event
31 | */
32 | public get view(): Container {
33 | return this._view;
34 | }
35 |
36 | /*============================================================================*/
37 | /* Constructor */
38 | /*============================================================================*/
39 |
40 | /**
41 | * Creates a view configuration event
42 | * @param type The event type
43 | * @param view The associated view instance
44 | */
45 | constructor(type: string, view: Container) {
46 | super(type, true);
47 | this._view = view;
48 | }
49 |
50 | /*============================================================================*/
51 | /* Public Functions */
52 | /*============================================================================*/
53 |
54 | /**
55 | * @inheritDoc
56 | */
57 | public clone(): ConfigureViewEvent {
58 | return new ConfigureViewEvent(this.type, this._view);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/ContainerBinding.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container, DisplayObject } from "pixi.js";
9 |
10 | import { IClass, EventDispatcher } from "@robotlegsjs/core";
11 |
12 | import { IViewHandler } from "../api/IViewHandler";
13 |
14 | import { ContainerBindingEvent } from "./ContainerBindingEvent";
15 |
16 | /*[Event(name="bindingEmpty", type="robotlegs.bender.extensions.viewManager.impl.ContainerBindingEvent")]*/
17 | /**
18 | * @private
19 | */
20 | export class ContainerBinding extends EventDispatcher {
21 | /*============================================================================*/
22 | /* Public Properties */
23 | /*============================================================================*/
24 |
25 | private _parent: ContainerBinding;
26 |
27 | /**
28 | * @private
29 | */
30 | public get parent(): ContainerBinding {
31 | return this._parent;
32 | }
33 |
34 | /**
35 | * @private
36 | */
37 | public set parent(value: ContainerBinding) {
38 | this._parent = value;
39 | }
40 |
41 | private _container: Container;
42 |
43 | /**
44 | * @private
45 | */
46 | public get container(): Container {
47 | return this._container;
48 | }
49 |
50 | /*============================================================================*/
51 | /* Private Properties */
52 | /*============================================================================*/
53 |
54 | private _handlers: IViewHandler[] = [];
55 |
56 | /*============================================================================*/
57 | /* Constructor */
58 | /*============================================================================*/
59 |
60 | /**
61 | * @private
62 | */
63 | constructor(container: Container) {
64 | super();
65 | this._container = container;
66 | }
67 |
68 | /*============================================================================*/
69 | /* Public Functions */
70 | /*============================================================================*/
71 |
72 | /**
73 | * @private
74 | */
75 | public addHandler(handler: IViewHandler): void {
76 | if (this._handlers.indexOf(handler) > -1) {
77 | return;
78 | }
79 | this._handlers.push(handler);
80 | }
81 |
82 | /**
83 | * @private
84 | */
85 | public removeHandler(handler: IViewHandler): void {
86 | let index: number = this._handlers.indexOf(handler);
87 | if (index > -1) {
88 | this._handlers.splice(index, 1);
89 | if (this._handlers.length === 0) {
90 | this.dispatchEvent(new ContainerBindingEvent(ContainerBindingEvent.BINDING_EMPTY));
91 | }
92 | }
93 | }
94 |
95 | /**
96 | * @private
97 | */
98 | public handleView(view: DisplayObject, type: IClass): void {
99 | let length: number = this._handlers.length;
100 | for (let i: number = 0; i < length; i++) {
101 | let handler: IViewHandler = this._handlers[i];
102 | handler.handleView(view, type);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/ContainerBindingEvent.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Event } from "@robotlegsjs/core";
9 |
10 | /**
11 | * @private
12 | */
13 | export class ContainerBindingEvent extends Event {
14 | /*============================================================================*/
15 | /* Public Static Properties */
16 | /*============================================================================*/
17 |
18 | public static BINDING_EMPTY: string = "bindingEmpty";
19 |
20 | /*============================================================================*/
21 | /* Constructor */
22 | /*============================================================================*/
23 |
24 | /**
25 | * @private
26 | */
27 | constructor(type: string) {
28 | super(type);
29 | }
30 |
31 | /*============================================================================*/
32 | /* Public Functions */
33 | /*============================================================================*/
34 |
35 | /**
36 | * @inheritDoc
37 | */
38 | public clone(): ContainerBindingEvent {
39 | return new ContainerBindingEvent(this.type);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/ContainerRegistryEvent.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | import { Event } from "@robotlegsjs/core";
11 |
12 | /**
13 | * Container existence event
14 | * @private
15 | */
16 | export class ContainerRegistryEvent extends Event {
17 | /*============================================================================*/
18 | /* Public Static Properties */
19 | /*============================================================================*/
20 |
21 | public static CONTAINER_ADD: string = "containerAdd";
22 |
23 | public static CONTAINER_REMOVE: string = "containerRemove";
24 |
25 | public static ROOT_CONTAINER_ADD: string = "rootContainerAdd";
26 |
27 | public static ROOT_CONTAINER_REMOVE: string = "rootContainerRemove";
28 |
29 | /*============================================================================*/
30 | /* Public Properties */
31 | /*============================================================================*/
32 |
33 | private _container: Container;
34 |
35 | /**
36 | * The container associated with this event
37 | */
38 | public get container(): Container {
39 | return this._container;
40 | }
41 |
42 | /*============================================================================*/
43 | /* Constructor */
44 | /*============================================================================*/
45 |
46 | /**
47 | * Creates a new container existence event
48 | * @param type The event type
49 | * @param container The container associated with this event
50 | */
51 | constructor(type: string, container: Container) {
52 | super(type);
53 | this._container = container;
54 | }
55 |
56 | /*============================================================================*/
57 | /* Public Functions */
58 | /*============================================================================*/
59 |
60 | /**
61 | * @inheritDoc
62 | */
63 | public clone(): ContainerRegistryEvent {
64 | return new ContainerRegistryEvent(this.type, this._container);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/ManualStageObserver.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container, DisplayObject } from "pixi.js";
9 |
10 | import { IClass } from "@robotlegsjs/core";
11 |
12 | import { ContainerRegistryEvent } from "./ContainerRegistryEvent";
13 |
14 | import { ContainerRegistry } from "./ContainerRegistry";
15 | import { ContainerBinding } from "./ContainerBinding";
16 |
17 | import { ConfigureViewEvent } from "./ConfigureViewEvent";
18 |
19 | /**
20 | * @private
21 | */
22 | export class ManualStageObserver {
23 | /*============================================================================*/
24 | /* Private Properties */
25 | /*============================================================================*/
26 |
27 | private _registry: ContainerRegistry;
28 |
29 | /*============================================================================*/
30 | /* Constructor */
31 | /*============================================================================*/
32 |
33 | /**
34 | * @private
35 | */
36 | constructor(containerRegistry: ContainerRegistry) {
37 | this._registry = containerRegistry;
38 |
39 | // We care about all containers (not just roots)
40 | this._registry.addEventListener(ContainerRegistryEvent.CONTAINER_ADD, this.onContainerAdd, this);
41 | this._registry.addEventListener(ContainerRegistryEvent.CONTAINER_REMOVE, this.onContainerRemove, this);
42 |
43 | // We might have arrived late on the scene
44 | this._registry.bindings.forEach((binding: ContainerBinding) => {
45 | this.addContainerListener(binding.container);
46 | });
47 | }
48 |
49 | /*============================================================================*/
50 | /* Public Functions */
51 | /*============================================================================*/
52 |
53 | /**
54 | * @private
55 | */
56 | public destroy(): void {
57 | this._registry.removeEventListener(ContainerRegistryEvent.CONTAINER_ADD, this.onContainerAdd, this);
58 | this._registry.removeEventListener(ContainerRegistryEvent.CONTAINER_REMOVE, this.onContainerRemove, this);
59 |
60 | this._registry.rootBindings.forEach((binding: ContainerBinding) => {
61 | this.removeContainerListener(binding.container);
62 | });
63 | }
64 |
65 | /*============================================================================*/
66 | /* Private Functions */
67 | /*============================================================================*/
68 |
69 | private onContainerAdd(event: ContainerRegistryEvent): void {
70 | this.addContainerListener(event.container);
71 | }
72 |
73 | private onContainerRemove(event: ContainerRegistryEvent): void {
74 | this.removeContainerListener(event.container);
75 | }
76 |
77 | private addContainerListener(container: Container): void {
78 | // We're interested in ALL container bindings
79 | // but just for normal, bubbling events
80 | container.addEventListener(ConfigureViewEvent.CONFIGURE_VIEW, this.onConfigureView, this);
81 | }
82 |
83 | private removeContainerListener(container: Container): void {
84 | container.removeEventListener(ConfigureViewEvent.CONFIGURE_VIEW, this.onConfigureView, this);
85 | }
86 |
87 | private onConfigureView(event: ConfigureViewEvent): void {
88 | // Stop that event!
89 | event.stopPropagation();
90 |
91 | let container: Container = event.currentTarget;
92 | let view: DisplayObject = event.target;
93 | let type: IClass = >view.constructor;
94 | this._registry.getBinding(container).handleView(view, type);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/StageCrawler.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container, DisplayObject } from "pixi.js";
9 |
10 | import { IClass } from "@robotlegsjs/core";
11 |
12 | import { ContainerBinding } from "./ContainerBinding";
13 |
14 | /**
15 | * @private
16 | */
17 | export class StageCrawler {
18 | /*============================================================================*/
19 | /* Private Properties */
20 | /*============================================================================*/
21 |
22 | private _binding: ContainerBinding;
23 |
24 | /*============================================================================*/
25 | /* Constructor */
26 | /*============================================================================*/
27 |
28 | /**
29 | * @private
30 | */
31 | constructor(containerBinding: ContainerBinding) {
32 | this._binding = containerBinding;
33 | }
34 |
35 | /*============================================================================*/
36 | /* Public Functions */
37 | /*============================================================================*/
38 |
39 | /**
40 | * @private
41 | */
42 | public scan(container: Container): void {
43 | this.scanContainer(container);
44 | }
45 |
46 | /*============================================================================*/
47 | /* Private Functions */
48 | /*============================================================================*/
49 |
50 | private scanContainer(container: Container): void {
51 | this.processView(container);
52 |
53 | container.children.forEach(child => {
54 | if (child instanceof Container) {
55 | this.scanContainer(child);
56 | } else {
57 | this.processView(child);
58 | }
59 | });
60 | }
61 |
62 | private processView(view: DisplayObject): void {
63 | this._binding.handleView(view, >view.constructor);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/StageObserver.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | import { IClass, IEvent } from "@robotlegsjs/core";
11 |
12 | import { ContainerBinding } from "./ContainerBinding";
13 | import { ContainerRegistry } from "./ContainerRegistry";
14 | import { ContainerRegistryEvent } from "./ContainerRegistryEvent";
15 |
16 | /**
17 | * @private
18 | */
19 | export class StageObserver {
20 | /*============================================================================*/
21 | /* Private Properties */
22 | /*============================================================================*/
23 |
24 | private _registry: ContainerRegistry;
25 |
26 | /*============================================================================*/
27 | /* Constructor */
28 | /*============================================================================*/
29 |
30 | /**
31 | * @private
32 | */
33 | constructor(containerRegistry: ContainerRegistry) {
34 | this._registry = containerRegistry;
35 |
36 | // We only care about roots
37 | this._registry.addEventListener(ContainerRegistryEvent.ROOT_CONTAINER_ADD, this.onRootContainerAdd, this);
38 | this._registry.addEventListener(ContainerRegistryEvent.ROOT_CONTAINER_REMOVE, this.onRootContainerRemove, this);
39 |
40 | // We might have arrived late on the scene
41 | this._registry.rootBindings.forEach((binding: ContainerBinding) => {
42 | this.addRootListener(binding.container);
43 | });
44 | }
45 |
46 | /*============================================================================*/
47 | /* Public Functions */
48 | /*============================================================================*/
49 |
50 | /**
51 | * @private
52 | */
53 | public destroy(): void {
54 | this._registry.removeEventListener(ContainerRegistryEvent.ROOT_CONTAINER_ADD, this.onRootContainerAdd, this);
55 | this._registry.removeEventListener(ContainerRegistryEvent.ROOT_CONTAINER_REMOVE, this.onRootContainerRemove, this);
56 |
57 | this._registry.rootBindings.forEach((binding: ContainerBinding) => {
58 | this.removeRootListener(binding.container);
59 | });
60 | }
61 |
62 | /*============================================================================*/
63 | /* Private Functions */
64 | /*============================================================================*/
65 |
66 | private onRootContainerAdd(event: ContainerRegistryEvent): void {
67 | this.addRootListener(event.container);
68 | }
69 |
70 | private onRootContainerRemove(event: ContainerRegistryEvent): void {
71 | this.removeRootListener(event.container);
72 | }
73 |
74 | private addRootListener(container: Container): void {
75 | container.addEventListener("added", this.onViewAddedToStage, this);
76 | }
77 |
78 | private removeRootListener(container: Container): void {
79 | container.removeEventListener("added", this.onViewAddedToStage, this);
80 | }
81 |
82 | private onViewAddedToStage(event: IEvent): void {
83 | let view: Container = event.target;
84 | let type: IClass = >view.constructor;
85 |
86 | // Walk upwards from the nearest binding
87 | let binding: ContainerBinding = this._registry.findParentBinding(view);
88 | while (binding) {
89 | binding.handleView(view, type);
90 | binding = binding.parent;
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/robotlegs/bender/extensions/viewManager/impl/ViewManagerEvent.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | import { Event } from "@robotlegsjs/core";
11 |
12 | import { IViewHandler } from "../api/IViewHandler";
13 |
14 | /**
15 | * Container existence event
16 | * @private
17 | */
18 | export class ViewManagerEvent extends Event {
19 | /*============================================================================*/
20 | /* Public Static Properties */
21 | /*============================================================================*/
22 |
23 | public static CONTAINER_ADD: string = "containerAdd";
24 |
25 | public static CONTAINER_REMOVE: string = "containerRemove";
26 |
27 | public static HANDLER_ADD: string = "handlerAdd";
28 |
29 | public static HANDLER_REMOVE: string = "handlerRemove";
30 |
31 | /*============================================================================*/
32 | /* Public Properties */
33 | /*============================================================================*/
34 |
35 | private _container: Container;
36 |
37 | /**
38 | * The container associated with this event
39 | */
40 | public get container(): Container {
41 | return this._container;
42 | }
43 |
44 | private _handler: IViewHandler;
45 |
46 | /**
47 | * The view handler associated with this event
48 | */
49 | public get handler(): IViewHandler {
50 | return this._handler;
51 | }
52 |
53 | /*============================================================================*/
54 | /* Constructor */
55 | /*============================================================================*/
56 |
57 | /**
58 | * Creates a view manager event
59 | * @param type The event type
60 | * @param container The container associated with this event
61 | * @param handler The view handler associated with this event
62 | */
63 | constructor(type: string, container?: Container, handler?: IViewHandler) {
64 | super(type);
65 | this._container = container;
66 | this._handler = handler;
67 | }
68 |
69 | /*============================================================================*/
70 | /* Public Functions */
71 | /*============================================================================*/
72 |
73 | /**
74 | * @inheritDoc
75 | */
76 | public clone(): ViewManagerEvent {
77 | return new ViewManagerEvent(this.type, this._container, this._handler);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/static/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobotlegsJS/RobotlegsJS-Pixi/0606cc590c151d0c67527277ff0d53f481de9289/static/images/loading.gif
--------------------------------------------------------------------------------
/static/images/pixijs-v5-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobotlegsJS/RobotlegsJS-Pixi/0606cc590c151d0c67527277ff0d53f481de9289/static/images/pixijs-v5-logo.png
--------------------------------------------------------------------------------
/static/images/robotlegs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RobotlegsJS/RobotlegsJS-Pixi/0606cc590c151d0c67527277ff0d53f481de9289/static/images/robotlegs.png
--------------------------------------------------------------------------------
/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | RobotlegsJS PixiJS Boilerplate
6 |
7 |
8 |
9 |
10 |
22 |
23 |
24 |
25 |
26 |
27 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/static/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Your Game",
3 | "short_name": "Your Game",
4 | "start_url": "index.html",
5 | "display": "standalone",
6 | "orientation": "landscape",
7 | "icons": [
8 | {
9 | "src": "icon.png",
10 | "sizes": "512x512",
11 | "type": "image/png"
12 | },
13 | {
14 | "src": "launcher-icon-2x.png",
15 | "sizes": "96x96",
16 | "type": "image/png"
17 | },
18 | {
19 | "src": "launcher-icon-3x.png",
20 | "sizes": "144x144",
21 | "type": "image/png"
22 | },
23 | {
24 | "src": "launcher-icon-4x.png",
25 | "sizes": "192x192",
26 | "type": "image/png"
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/static/scripts/cache-polyfill.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2015 Google Inc. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | (function() {
19 | var nativeAddAll = Cache.prototype.addAll;
20 | var userAgent = navigator.userAgent.match(/(Firefox|Chrome)\/(\d+\.)/);
21 |
22 | // Has nice behavior of `var` which everyone hates
23 | if (userAgent) {
24 | var agent = userAgent[1];
25 | var version = parseInt(userAgent[2]);
26 | }
27 |
28 | if (nativeAddAll && (!userAgent || (agent === "Firefox" && version >= 46) || (agent === "Chrome" && version >= 50))) {
29 | return;
30 | }
31 |
32 | Cache.prototype.addAll = function addAll(requests) {
33 | var cache = this;
34 |
35 | // Since DOMExceptions are not constructable:
36 | function NetworkError(message) {
37 | this.name = "NetworkError";
38 | this.code = 19;
39 | this.message = message;
40 | }
41 |
42 | NetworkError.prototype = Object.create(Error.prototype);
43 |
44 | return Promise.resolve()
45 | .then(function() {
46 | if (arguments.length < 1) throw new TypeError();
47 |
48 | // Simulate sequence<(Request or USVString)> binding:
49 | var sequence = [];
50 |
51 | requests = requests.map(function(request) {
52 | if (request instanceof Request) {
53 | return request;
54 | } else {
55 | return String(request); // may throw TypeError
56 | }
57 | });
58 |
59 | return Promise.all(
60 | requests.map(function(request) {
61 | if (typeof request === "string") {
62 | request = new Request(request);
63 | }
64 |
65 | var scheme = new URL(request.url).protocol;
66 |
67 | if (scheme !== "http:" && scheme !== "https:") {
68 | throw new NetworkError("Invalid scheme");
69 | }
70 |
71 | return fetch(request.clone());
72 | })
73 | );
74 | })
75 | .then(function(responses) {
76 | // If some of the responses has not OK-eish status,
77 | // then whole operation should reject
78 | if (
79 | responses.some(function(response) {
80 | return !response.ok;
81 | })
82 | ) {
83 | throw new NetworkError("Incorrect response status");
84 | }
85 |
86 | // TODO: check that requests don't overwrite one another
87 | // (don't think this is possible to polyfill due to opaque responses)
88 | return Promise.all(
89 | responses.map(function(response, i) {
90 | return cache.put(requests[i], response);
91 | })
92 | );
93 | })
94 | .then(function() {
95 | return undefined;
96 | });
97 | };
98 |
99 | Cache.prototype.add = function add(request) {
100 | return this.addAll([request]);
101 | };
102 | })();
103 |
--------------------------------------------------------------------------------
/static/service-worker.js:
--------------------------------------------------------------------------------
1 | importScripts("scripts/cache-polyfill.js");
2 |
3 | var CACHE_VERSION = "app-v1";
4 | var CACHE_FILES = ["index.html"];
5 |
6 | self.addEventListener("install", function(event) {
7 | event.waitUntil(
8 | caches.open(CACHE_VERSION).then(function(cache) {
9 | console.log("Opened cache");
10 | return cache.addAll(CACHE_FILES);
11 | })
12 | );
13 | });
14 |
15 | self.addEventListener("activate", function(event) {
16 | event.waitUntil(
17 | caches.keys().then(function(keys) {
18 | return Promise.all(
19 | keys.map(function(key, i) {
20 | if (key !== CACHE_VERSION) {
21 | return caches.delete(keys[i]);
22 | }
23 | })
24 | );
25 | })
26 | );
27 | });
28 |
29 | self.addEventListener("fetch", function(event) {
30 | event.respondWith(
31 | caches.match(event.request).then(function(res) {
32 | if (res) {
33 | return res;
34 | }
35 | requestBackend(event);
36 | })
37 | );
38 | });
39 |
40 | function requestBackend(event) {
41 | var url = event.request.clone();
42 | return fetch(url).then(function(res) {
43 | //if not a valid response send the error
44 | if (!res || res.status !== 200 || res.type !== "basic") {
45 | return res;
46 | }
47 |
48 | var response = res.clone();
49 |
50 | caches.open(CACHE_VERSION).then(function(cache) {
51 | cache.put(event.request, response);
52 | });
53 |
54 | return res;
55 | });
56 | }
57 |
--------------------------------------------------------------------------------
/static/styles/example.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 960px;
3 | }
4 |
5 | header {
6 | margin-bottom: 1rem;
7 | }
8 |
9 | h1 {
10 | font-weight: 200;
11 | margin-bottom: 1rem;
12 | }
13 |
14 | h1:before {
15 | content: "RobotlegsJS ";
16 | font-weight: bold;
17 | }
18 |
19 | header p {
20 | margin: 0;
21 | padding: 1em;
22 | background: rgba(250, 252, 255, 0.7);
23 | }
24 |
25 | .content,
26 | canvas {
27 | background: white;
28 | }
29 |
30 | .content {
31 | width: 960px;
32 | height: 400px;
33 | overflow: hidden;
34 | }
35 |
36 | .loading {
37 | position: relative;
38 | }
39 |
40 | .loading:after {
41 | content: url("../images/loading.gif");
42 | position: absolute;
43 | left: 50%;
44 | top: 50%;
45 | margin: -13px 0 0 -51px;
46 | opacity: 0.8;
47 | }
48 |
49 | #error {
50 | display: none;
51 | width: 960px;
52 | text-align: left;
53 | padding: 10px;
54 | }
55 |
56 | #mobile {
57 | display: none;
58 | width: 960px;
59 | text-align: left;
60 | padding: 10px;
61 | }
62 |
63 | body.embedded header {
64 | display: none;
65 | }
66 |
67 | body.embedded {
68 | margin: 0;
69 | }
70 |
--------------------------------------------------------------------------------
/static/styles/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 3em auto;
3 | padding: 0;
4 | background-color: #eaebee;
5 | font-family: Arial, Verdana, sans-serif;
6 | font-size: 14px;
7 | font-weight: normal;
8 | color: #333;
9 | line-height: 1.4em;
10 | }
11 |
12 | a:link,
13 | a:visited {
14 | color: #39f;
15 | text-decoration: none;
16 | }
17 |
18 | a:hover {
19 | text-decoration: underline;
20 | }
21 |
22 | h1,
23 | h2 {
24 | color: #fff;
25 | font-size: 1.6em;
26 | margin-bottom: 0;
27 | padding: 1.5em;
28 | padding-bottom: 1.2em;
29 | background: #374252;
30 | }
31 |
32 | h1::after {
33 | display: block;
34 | content: "";
35 | background: url("../images/pixijs-v5-logo.png") no-repeat;
36 | height: 33px;
37 | width: 110px;
38 | margin-top: -0.3em;
39 | float: right;
40 | }
41 |
42 | h1 em {
43 | font-weight: 200;
44 | font-style: normal;
45 | }
46 |
47 | h2 {
48 | font-size: 1.3em;
49 | padding: 1em;
50 | padding-bottom: 0.8em;
51 | }
52 |
53 | h3 {
54 | background: #e0e1e5;
55 | color: #374252;
56 | font-size: 1.25em;
57 | padding: 0.5em;
58 | margin-top: 1.25em;
59 | margin-bottom: -0.5em;
60 | position: relative;
61 | }
62 |
63 | code {
64 | color: black;
65 | background-color: rgba(255, 230, 0, 0.33);
66 | padding: 1px 3px;
67 | font-family: Courier New, Courier, serif;
68 | font-weight: bold;
69 | }
70 |
71 | /**
72 | * For modern browsers
73 | * 1. The space content is one way to avoid an Opera bug when the
74 | * contenteditable attribute is included anywhere else in the document.
75 | * Otherwise it causes space to appear at the top and bottom of elements
76 | * that are clearfixed.
77 | * 2. The use of `table` rather than `block` is only necessary if using
78 | * `:before` to contain the top-margins of child elements.
79 | */
80 | .cf:before,
81 | .cf:after {
82 | content: " "; /* 1 */
83 | display: table; /* 2 */
84 | }
85 |
86 | .cf:after {
87 | clear: both;
88 | }
89 |
90 | /**
91 | * For IE 6/7 only
92 | * Include this rule to trigger hasLayout and contain floats.
93 | */
94 | .cf {
95 | *zoom: 1;
96 | }
97 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | # Robotlegs Testing
2 |
3 | Unit tests are written using Mocha, Chai and Sinon.
--------------------------------------------------------------------------------
/test/entry.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | ///
9 | ///
10 |
11 | import "reflect-metadata";
12 | import "bluebird/js/browser/bluebird";
13 | import "es6-symbol/implement";
14 | import "es6-map/implement";
15 |
--------------------------------------------------------------------------------
/test/index.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | // require all modules ending in ".test.ts" from the
4 | // current directory and all subdirectories
5 | const testsContext = require.context(".", true, /\.test\.ts$/);
6 |
7 | testsContext.keys().forEach(testsContext);
8 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/bundles/pixi/pixiBundle.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Container } from "pixi.js";
13 |
14 | import { IContext, Context, LogLevel } from "@robotlegsjs/core";
15 |
16 | import { IContextView, IMediatorMap, IViewManager, ContextView, PixiBundle } from "../../../../../src";
17 |
18 | import { ContainerRegistry } from "../../../../../src/robotlegs/bender/extensions/viewManager/impl/ContainerRegistry";
19 |
20 | import { CallbackLogTarget } from "../../extensions/contextView/support/CallbackLogTarget";
21 | import { LogParams } from "../../extensions/contextView/support/LogParams";
22 |
23 | describe("PixiBundle", () => {
24 | let context: IContext;
25 |
26 | afterEach(() => {
27 | if (context.initialized) {
28 | context.destroy();
29 | }
30 | context = null;
31 | });
32 |
33 | it("bundle_is_properly_installed_into_context", () => {
34 | context = new Context();
35 | context
36 | .install(PixiBundle)
37 | .configure(new ContextView(new Container()))
38 | .initialize();
39 |
40 | // Verify if all extensions are installed
41 | assert.isTrue(context.injector.isBound(IContextView));
42 | assert.isTrue(context.injector.isBound(ContainerRegistry));
43 | assert.isTrue(context.injector.isBound(IViewManager));
44 | assert.isTrue(context.injector.isBound(IMediatorMap));
45 | });
46 |
47 | it("bundle_logs_an_error_message_when_context_view_is_not_provided", () => {
48 | let errorLogged: boolean = false;
49 | let logTarget: CallbackLogTarget = new CallbackLogTarget((log: LogParams) => {
50 | if (log.source instanceof PixiBundle && log.level === LogLevel.ERROR) {
51 | errorLogged = log.message === "PixiBundle requires IContextView.";
52 | }
53 | });
54 |
55 | context = new Context();
56 | context.addLogTarget(logTarget);
57 | context.install(PixiBundle).initialize();
58 | assert.isTrue(errorLogged);
59 | });
60 | });
61 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/contextView/contextViewExtension.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Container } from "pixi.js";
13 |
14 | import { IContext, Context, LogLevel } from "@robotlegsjs/core";
15 |
16 | import { IContextView, ContextView, ContextViewExtension } from "../../../../../src";
17 |
18 | import { CallbackLogTarget } from "./support/CallbackLogTarget";
19 | import { LogParams } from "./support/LogParams";
20 |
21 | describe("ContextViewExtension", () => {
22 | let context: IContext;
23 |
24 | beforeEach(() => {
25 | context = new Context();
26 | });
27 |
28 | afterEach(() => {
29 | context.destroy();
30 | context = null;
31 | });
32 |
33 | it("installing_after_initialization_throws_error", () => {
34 | function installExtensionAfterInitialization(): void {
35 | context.initialize();
36 | context.install(ContextViewExtension);
37 | }
38 | assert.throws(installExtensionAfterInitialization, Error);
39 | });
40 |
41 | it("contextView_is_mapped", () => {
42 | let container = new Container();
43 | let actual: ContextView = null;
44 | context.install(ContextViewExtension).configure(new ContextView(container));
45 | context.whenInitializing(function(): void {
46 | actual = context.injector.get(IContextView);
47 | });
48 | context.initialize();
49 | assert.equal(actual.view, container);
50 | });
51 |
52 | it("second_displayObjectContainer_is_ignored", () => {
53 | let container = new Container();
54 | let actual: ContextView = null;
55 | let secondContainer = new Container();
56 | context.install(ContextViewExtension).configure(new ContextView(container), new ContextView(secondContainer));
57 | context.whenInitializing(function(): void {
58 | actual = context.injector.get(IContextView);
59 | });
60 | context.initialize();
61 | assert.equal(actual.view, container);
62 | });
63 |
64 | it("extension_logs_error_when_context_initialized_with_no_contextView", () => {
65 | let errorLogged: boolean = false;
66 | let logTarget: CallbackLogTarget = new CallbackLogTarget(function(log: LogParams): void {
67 | if (log.source instanceof ContextViewExtension && log.level === LogLevel.ERROR) {
68 | errorLogged = true;
69 | }
70 | });
71 | context.install(ContextViewExtension);
72 | context.addLogTarget(logTarget);
73 | context.initialize();
74 | assert.isTrue(errorLogged);
75 | });
76 | });
77 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/contextView/impl/contextView.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Container } from "pixi.js";
13 |
14 | import { IContextView, ContextView } from "../../../../../../src";
15 |
16 | describe("ContextView", () => {
17 | let container: Container;
18 | let contextView: IContextView;
19 |
20 | beforeEach(() => {
21 | container = new Container();
22 | contextView = new ContextView(container);
23 | });
24 |
25 | afterEach(() => {
26 | contextView = null;
27 | container = null;
28 | });
29 |
30 | it("container_is_stored", () => {
31 | assert.isNotNull(contextView.view);
32 | assert.equal(contextView.view, container);
33 | });
34 |
35 | it("ContextView_throws_a_error_when_view_is_null", () => {
36 | function inicializeContextViewWithNullView(): void {
37 | contextView = new ContextView(null);
38 | }
39 | assert.throws(inicializeContextViewWithNullView, Error);
40 | });
41 |
42 | it("ContextView_throws_a_error_when_view_is_undefined", () => {
43 | function inicializeContextViewWithUndefinedView(): void {
44 | contextView = new ContextView(undefined);
45 | }
46 | assert.throws(inicializeContextViewWithUndefinedView, Error);
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/contextView/impl/contextViewListenerConfig.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Container } from "pixi.js";
13 |
14 | import { IContextView, ContextView, ContextViewListenerConfig } from "../../../../../../src";
15 |
16 | import { ContainerRegistry } from "../../../../../../src/robotlegs/bender/extensions/viewManager/impl/ContainerRegistry";
17 | import { ViewManager } from "../../../../../../src/robotlegs/bender/extensions/viewManager/impl/ViewManager";
18 |
19 | describe("ContextViewListenerConfig", () => {
20 | let container: Container;
21 | let contextView: IContextView;
22 | let containerRegistry: ContainerRegistry;
23 | let viewManager: ViewManager;
24 | let contextViewListenerConfig: ContextViewListenerConfig;
25 |
26 | beforeEach(() => {
27 | container = new Container();
28 | contextView = new ContextView(container);
29 | containerRegistry = new ContainerRegistry();
30 | viewManager = new ViewManager(containerRegistry);
31 | contextViewListenerConfig = new ContextViewListenerConfig(contextView, viewManager);
32 | });
33 |
34 | afterEach(() => {
35 | contextView = null;
36 | container = null;
37 | containerRegistry = null;
38 | viewManager = null;
39 | contextViewListenerConfig = null;
40 | });
41 |
42 | it("container_is_added_to_view_manager", () => {
43 | contextViewListenerConfig.configure();
44 | assert.deepEqual(viewManager.containers, [container]);
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/contextView/pixiPatch/containsPatch.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Container, DisplayObject } from "pixi.js";
13 |
14 | import "../../../../../../src/robotlegs/bender/extensions/contextView/pixiPatch/pixi-patch";
15 |
16 | describe("ContainsPatch", () => {
17 | let container: Container;
18 |
19 | beforeEach(() => {
20 | container = new Container();
21 | });
22 |
23 | afterEach(() => {
24 | container.removeChildren();
25 | container = null;
26 | });
27 |
28 | it("Container_have_contains_method", () => {
29 | assert.isNotNull(container.contains);
30 | assert.isFunction(container.contains);
31 | });
32 |
33 | it("Container_contains_itself", () => {
34 | assert.isTrue(container.contains(container));
35 | });
36 |
37 | it("Container_contains_direct_child", () => {
38 | let child: DisplayObject = new DisplayObject();
39 |
40 | container.addChild(child);
41 |
42 | assert.isTrue(container.contains(child));
43 | });
44 |
45 | it("Container_contains_direct_children", () => {
46 | let child1: DisplayObject = new DisplayObject();
47 | let child2: DisplayObject = new DisplayObject();
48 | let child3: DisplayObject = new DisplayObject();
49 |
50 | container.addChild(child1);
51 | container.addChild(child2);
52 | container.addChild(child3);
53 |
54 | assert.isTrue(container.contains(child1));
55 | assert.isTrue(container.contains(child2));
56 | assert.isTrue(container.contains(child3));
57 | });
58 |
59 | it("Container_contains_nested_children", () => {
60 | let child1: Container = new Container();
61 | let child2: DisplayObject = new DisplayObject();
62 | let child3: DisplayObject = new DisplayObject();
63 | let grandChild1: Container = new Container();
64 | let grandChild2: DisplayObject = new DisplayObject();
65 | let grandChild3: DisplayObject = new DisplayObject();
66 | let greatGrandChild1: DisplayObject = new DisplayObject();
67 | let greatGrandChild2: DisplayObject = new DisplayObject();
68 | let greatGrandChild3: DisplayObject = new DisplayObject();
69 |
70 | container.addChild(child1);
71 | container.addChild(child2);
72 | container.addChild(child3);
73 |
74 | child1.addChild(grandChild1);
75 | child1.addChild(grandChild2);
76 | child1.addChild(grandChild3);
77 |
78 | grandChild1.addChild(greatGrandChild1);
79 | grandChild1.addChild(greatGrandChild2);
80 | grandChild1.addChild(greatGrandChild3);
81 |
82 | assert.isTrue(container.contains(child1));
83 | assert.isTrue(container.contains(child2));
84 | assert.isTrue(container.contains(child3));
85 |
86 | assert.isTrue(container.contains(grandChild1));
87 | assert.isTrue(container.contains(grandChild2));
88 | assert.isTrue(container.contains(grandChild3));
89 |
90 | assert.isTrue(container.contains(greatGrandChild1));
91 | assert.isTrue(container.contains(greatGrandChild2));
92 | assert.isTrue(container.contains(greatGrandChild3));
93 | });
94 |
95 | it("Container_does_not_contains_ancestors", () => {
96 | let parent: Container = new Container();
97 | let grandParent: Container = new Container();
98 | let greatGrandParent: Container = new Container();
99 |
100 | parent.addChild(container);
101 | grandParent.addChild(parent);
102 | greatGrandParent.addChild(grandParent);
103 |
104 | assert.isFalse(container.contains(parent));
105 | assert.isFalse(container.contains(grandParent));
106 | assert.isFalse(container.contains(greatGrandParent));
107 | });
108 |
109 | it("Container_does_not_contains_same_level_container", () => {
110 | let parent: Container = new Container();
111 | let brother: Container = new Container();
112 | let sister: Container = new Container();
113 |
114 | parent.addChild(container);
115 | parent.addChild(brother);
116 | parent.addChild(sister);
117 |
118 | assert.isFalse(container.contains(parent));
119 | assert.isFalse(container.contains(brother));
120 | assert.isFalse(container.contains(sister));
121 | });
122 | });
123 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/contextView/pixiPatch/eventemitter3Patch.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Container } from "pixi.js";
13 |
14 | import { Event } from "@robotlegsjs/core";
15 |
16 | import "../../../../../../src/robotlegs/bender/extensions/contextView/pixiPatch/eventemitter3-patch";
17 |
18 | describe("EventEmmiter3Patch", () => {
19 | let container: Container;
20 |
21 | beforeEach(() => {
22 | container = new Container();
23 | });
24 |
25 | afterEach(() => {
26 | container = null;
27 | });
28 |
29 | it("DisplayObject_is_a_EventDispatcher", () => {
30 | assert.isNotNull(container.addEventListener);
31 | assert.isFunction(container.addEventListener);
32 | assert.isNotNull(container.hasEventListener);
33 | assert.isFunction(container.hasEventListener);
34 | assert.isNotNull(container.removeEventListener);
35 | assert.isFunction(container.removeEventListener);
36 | assert.isNotNull(container.willTrigger);
37 | assert.isFunction(container.willTrigger);
38 | assert.isNotNull(container.dispatchEvent);
39 | assert.isFunction(container.dispatchEvent);
40 | });
41 |
42 | it("addEventListener_store_listener", () => {
43 | let listener: Function = () => {
44 | // no nothing
45 | return;
46 | };
47 | container.addEventListener("added", listener);
48 | assert.deepEqual(container.listeners("added"), [listener]);
49 | });
50 |
51 | it("hasEventListener_check_if_a_listener_was_added", () => {
52 | let listener: Function = () => {
53 | // no nothing
54 | return;
55 | };
56 | container.addEventListener("added", listener);
57 | assert.isTrue(container.hasEventListener("added", listener));
58 | assert.isFalse(container.hasEventListener("removed"));
59 | });
60 |
61 | it("removeEventListener_remove_a_listener", () => {
62 | let listener: Function = () => {
63 | // no nothing
64 | return;
65 | };
66 | container.addEventListener("added", listener);
67 | container.removeEventListener("added", listener);
68 | assert.isEmpty(container.listeners("added"));
69 | assert.isFalse(container.hasEventListener("added"));
70 | });
71 |
72 | it("willTrigger_ensure_that_a_event_will_be_dispatched", () => {
73 | let listener: Function = () => {
74 | // no nothing
75 | return;
76 | };
77 | container.addEventListener("added", listener);
78 | assert.isTrue(container.willTrigger("added"));
79 | });
80 |
81 | it("dispatchEvent_dispatch_a_event", () => {
82 | let dispatched: boolean = false;
83 | let listener: Function = () => {
84 | dispatched = true;
85 | };
86 | container.addEventListener("added", listener);
87 | container.dispatchEvent(new Event("added"));
88 | assert.isTrue(dispatched);
89 | });
90 |
91 | it("dispatchEvent_dispatch_a_event_with_bubbles", () => {
92 | let dispatched: boolean = false;
93 | let listener: Function = () => {
94 | dispatched = true;
95 | };
96 | let child: Container = new Container();
97 | let grandChild: Container = new Container();
98 | child.addChild(grandChild);
99 | container.addChild(child);
100 | container.addEventListener("test", listener);
101 | grandChild.dispatchEvent(new Event("test", true));
102 | assert.isTrue(dispatched);
103 | });
104 | });
105 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/contextView/support/CallbackLogTarget.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { ILogTarget } from "@robotlegsjs/core";
9 |
10 | import { LogParams } from "./LogParams";
11 |
12 | export class CallbackLogTarget implements ILogTarget {
13 | protected _callback: Function;
14 |
15 | constructor(callback: Function) {
16 | this._callback = callback;
17 | }
18 |
19 | public log(source: any, level: number, timestamp: number, message: string, params: any[]): void {
20 | if (this._callback) {
21 | this._callback(new LogParams(source, level, timestamp, message, params));
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/contextView/support/LogParams.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | export class LogParams {
9 | constructor(public source: any, public level: number, public timestamp: number, public message: string, public params: any[]) {
10 | this.source = source;
11 | this.level = level;
12 | this.timestamp = timestamp;
13 | this.message = message;
14 | this.params = params;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/impl/mediatorMap.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Sprite, Texture } from "pixi.js";
13 |
14 | import { IContext, Context, TypeMatcher } from "@robotlegsjs/core";
15 |
16 | import { IMediatorMapper } from "../../../../../../src/robotlegs/bender/extensions/mediatorMap/dsl/IMediatorMapper";
17 | import { MediatorMap } from "../../../../../../src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMap";
18 | import { MediatorMapper } from "../../../../../../src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMapper";
19 |
20 | describe("MediatorMap", () => {
21 | let context: IContext = null;
22 | let mediatorMap: MediatorMap = null;
23 |
24 | beforeEach(() => {
25 | context = new Context();
26 | mediatorMap = new MediatorMap(context);
27 | });
28 |
29 | afterEach(() => {
30 | if (context.initialized) {
31 | context.destroy();
32 | }
33 |
34 | context = null;
35 | mediatorMap = null;
36 | });
37 |
38 | it("mapMatcher_creates_mapper", () => {
39 | const matcher: TypeMatcher = new TypeMatcher().allOf(Sprite);
40 | assert.instanceOf(mediatorMap.mapMatcher(matcher), MediatorMapper);
41 | });
42 |
43 | it("mapMatcher_to_matching_TypeMatcher_returns_same_mapper", () => {
44 | const matcher1: TypeMatcher = new TypeMatcher().allOf(Sprite);
45 | const matcher2: TypeMatcher = new TypeMatcher().allOf(Sprite);
46 | const mapper1: IMediatorMapper = mediatorMap.mapMatcher(matcher1);
47 | const mapper2: IMediatorMapper = mediatorMap.mapMatcher(matcher2);
48 | assert.equal(mapper1, mapper2);
49 | });
50 |
51 | it("mapMatcher_to_differing_TypeMatcher_returns_different_mapper", () => {
52 | const matcher1: TypeMatcher = new TypeMatcher().allOf(Sprite);
53 | const matcher2: TypeMatcher = new TypeMatcher().allOf(Texture);
54 | const mapper1: IMediatorMapper = mediatorMap.mapMatcher(matcher1);
55 | const mapper2: IMediatorMapper = mediatorMap.mapMatcher(matcher2);
56 | assert.notEqual(mapper1, mapper2);
57 | });
58 |
59 | it("map_creates_mapper", () => {
60 | assert.instanceOf(mediatorMap.map(Sprite), MediatorMapper);
61 | });
62 |
63 | it("map_to_matching_TypeMatcher_returns_same_mapper", () => {
64 | const mapper1: IMediatorMapper = mediatorMap.map(Sprite);
65 | const mapper2: IMediatorMapper = mediatorMap.map(Sprite);
66 | assert.equal(mapper1, mapper2);
67 | });
68 |
69 | it("map_to_differing_TypeMatcher_returns_different_mapper", () => {
70 | const mapper1: IMediatorMapper = mediatorMap.map(Sprite);
71 | const mapper2: IMediatorMapper = mediatorMap.map(Texture);
72 | assert.notEqual(mapper1, mapper2);
73 | });
74 |
75 | it("unmapMatcher_returns_mapper", () => {
76 | const mapper: MediatorMapper = mediatorMap.mapMatcher(new TypeMatcher().allOf(Sprite));
77 | const unmappedMapper: MediatorMapper = mediatorMap.unmapMatcher(new TypeMatcher().allOf(Sprite));
78 | assert.equal(unmappedMapper, mapper);
79 | });
80 |
81 | it("unmap_returns_mapper", () => {
82 | const mapper: MediatorMapper = mediatorMap.map(Sprite);
83 | const unmappedMapper: MediatorMapper = mediatorMap.unmap(Sprite);
84 | assert.equal(unmappedMapper, mapper);
85 | });
86 |
87 | it("robust_to_unmapping_non_existent_mappings", () => {
88 | mediatorMap.unmapMatcher(new TypeMatcher().allOf(Sprite)).fromAll();
89 | });
90 | });
91 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/mediatorMapExtension.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { IContext, Context } from "@robotlegsjs/core";
13 |
14 | import { ViewManagerExtension, MediatorMapExtension, IMediatorMap } from "../../../../../src";
15 |
16 | import { MediatorMap } from "../../../../../src/robotlegs/bender/extensions/mediatorMap/impl/MediatorMap";
17 |
18 | describe("MediatorMapExtension", () => {
19 | let context: IContext;
20 |
21 | beforeEach(() => {
22 | context = new Context();
23 | });
24 |
25 | afterEach(() => {
26 | context.destroy();
27 | context = null;
28 | });
29 |
30 | it("installing_after_initialization_throws_error", () => {
31 | function installExtensionAfterInitialization(): void {
32 | context.initialize();
33 | context.install(MediatorMapExtension);
34 | }
35 | assert.throws(installExtensionAfterInitialization, Error);
36 | });
37 |
38 | it("mediatorMap_is_mapped_into_injector_on_initialize", () => {
39 | let mediatorMap: IMediatorMap = null;
40 | context.install(ViewManagerExtension, MediatorMapExtension);
41 | context.whenInitializing(function(): void {
42 | mediatorMap = context.injector.get(IMediatorMap);
43 | });
44 | context.initialize();
45 | assert.isNotNull(mediatorMap);
46 | assert.instanceOf(mediatorMap, MediatorMap);
47 | });
48 |
49 | it("mediatorMap_is_mapped_into_injector_on_initialize_when_view_manager_is_not_installed", () => {
50 | let mediatorMap: IMediatorMap = null;
51 | context.install(MediatorMapExtension);
52 | context.whenInitializing(function(): void {
53 | mediatorMap = context.injector.get(IMediatorMap);
54 | });
55 | context.initialize();
56 | assert.isNotNull(mediatorMap);
57 | assert.instanceOf(mediatorMap, MediatorMap);
58 | });
59 |
60 | it("mediatorMap_is_unmapped_from_injector_on_destroy", () => {
61 | context.install(ViewManagerExtension, MediatorMapExtension);
62 | context.afterDestroying(function(): void {
63 | assert.isFalse(context.injector.isBound(IMediatorMap));
64 | });
65 | context.initialize();
66 | context.destroy();
67 | });
68 | });
69 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/Alpha50PercentHook.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Sprite } from "pixi.js";
9 |
10 | import { injectable, inject, IHook } from "@robotlegsjs/core";
11 |
12 | @injectable()
13 | export class Alpha50PercentHook implements IHook {
14 | @inject(Sprite)
15 | public view: Sprite;
16 |
17 | public hook(): void {
18 | this.view.alpha = 0.5;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/CallbackHook.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject, named, IHook } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class CallbackHook implements IHook {
12 | private _callback: Function;
13 |
14 | constructor(
15 | @inject("Function")
16 | @named("hookCallback")
17 | callback: Function
18 | ) {
19 | this._callback = callback;
20 | }
21 |
22 | public hook(): void {
23 | if (this._callback) {
24 | this._callback();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/CallbackMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject, named, optional } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class CallbackMediator {
12 | @inject("Function")
13 | @named("executeCallback")
14 | @optional()
15 | public callback: Function;
16 |
17 | public initialize(): void {
18 | if (this.callback) {
19 | this.callback(this);
20 | }
21 | }
22 |
23 | public destroy(): void {}
24 | }
25 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/EmptyMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class EmptyMediator {}
12 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/ExampleDisplayObjectMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject } from "@robotlegsjs/core";
9 |
10 | import { DisplayObject } from "pixi.js";
11 |
12 | import { MediatorWatcher } from "./MediatorWatcher";
13 |
14 | @injectable()
15 | export class ExampleDisplayObjectMediator {
16 | @inject(MediatorWatcher)
17 | public mediatorWatcher: MediatorWatcher;
18 |
19 | @inject(DisplayObject)
20 | public view: DisplayObject;
21 |
22 | public initialize(): void {
23 | this.mediatorWatcher.notify("ExampleDisplayObjectMediator");
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/ExampleMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject } from "@robotlegsjs/core";
9 |
10 | import { Sprite } from "pixi.js";
11 |
12 | import { MediatorWatcher } from "./MediatorWatcher";
13 |
14 | @injectable()
15 | export class ExampleMediator {
16 | @inject(MediatorWatcher)
17 | public mediatorWatcher: MediatorWatcher;
18 |
19 | @inject(Sprite)
20 | public view: Sprite;
21 |
22 | public initialize(): void {
23 | this.mediatorWatcher.notify("ExampleMediator");
24 | }
25 |
26 | public destroy(): void {
27 | this.mediatorWatcher.notify("ExampleMediator destroy");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/ExampleMediator2.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject } from "@robotlegsjs/core";
9 |
10 | import { Sprite } from "pixi.js";
11 |
12 | import { MediatorWatcher } from "./MediatorWatcher";
13 |
14 | @injectable()
15 | export class ExampleMediator2 {
16 | @inject(MediatorWatcher)
17 | public mediatorWatcher: MediatorWatcher;
18 |
19 | @inject(Sprite)
20 | public view: Sprite;
21 |
22 | public initialize(): void {
23 | this.mediatorWatcher.notify("ExampleMediator2");
24 | }
25 |
26 | public destroy(): void {
27 | this.mediatorWatcher.notify("ExampleMediator2 destroy");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/GrumpyGuard.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, IGuard } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class GrumpyGuard implements IGuard {
12 | public approve(): boolean {
13 | return false;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/HappyGuard.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, IGuard } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class HappyGuard implements IGuard {
12 | public approve(): boolean {
13 | return true;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/HookWithMediatorAndViewInjectionReportFunction.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Sprite } from "pixi.js";
9 |
10 | import { injectable, inject, named, IHook } from "@robotlegsjs/core";
11 |
12 | import { RectangleMediator } from "./RectangleMediator";
13 |
14 | @injectable()
15 | export class HookWithMediatorAndViewInjectionReportFunction implements IHook {
16 | @inject(RectangleMediator)
17 | public mediator: RectangleMediator;
18 |
19 | @inject(Sprite)
20 | public view: Sprite;
21 |
22 | @inject("Function")
23 | @named("reportView")
24 | public reportView: Function;
25 |
26 | public hook(): void {
27 | this.reportView(this.view, this.mediator.width, this.mediator.height);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/InjectedMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class InjectedMediator {
12 | @inject(Number)
13 | public number: number;
14 |
15 | public initialize(): void {}
16 |
17 | public destroy(): void {}
18 | }
19 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/LifecycleReportingMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject, named, optional } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class LifecycleReportingMediator {
12 | @inject("Function")
13 | @named("preInitializeCallback")
14 | @optional()
15 | public preInitializeCallback: Function;
16 |
17 | @inject("Function")
18 | @named("initializeCallback")
19 | @optional()
20 | public initializeCallback: Function;
21 |
22 | @inject("Function")
23 | @named("postInitializeCallback")
24 | @optional()
25 | public postInitializeCallback: Function;
26 |
27 | @inject("Function")
28 | @named("preDestroyCallback")
29 | @optional()
30 | public preDestroyCallback: Function;
31 |
32 | @inject("Function")
33 | @named("destroyCallback")
34 | @optional()
35 | public destroyCallback: Function;
36 |
37 | @inject("Function")
38 | @named("postDestroyCallback")
39 | @optional()
40 | public postDestroyCallback: Function;
41 |
42 | public initialized: Boolean = false;
43 |
44 | public destroyed: Boolean = false;
45 |
46 | public view: any = undefined;
47 |
48 | /*============================================================================*/
49 | /* Public Functions */
50 | /*============================================================================*/
51 |
52 | public preInitialize(): void {
53 | if (this.preInitializeCallback) {
54 | this.preInitializeCallback("preInitialize");
55 | }
56 | }
57 |
58 | public initialize(): void {
59 | this.initialized = true;
60 | if (this.initializeCallback) {
61 | this.initializeCallback("initialize");
62 | }
63 | }
64 |
65 | public postInitialize(): void {
66 | if (this.postInitializeCallback) {
67 | this.postInitializeCallback("postInitialize");
68 | }
69 | }
70 |
71 | public preDestroy(): void {
72 | if (this.preDestroyCallback) {
73 | this.preDestroyCallback("preDestroy");
74 | }
75 | }
76 |
77 | public destroy(): void {
78 | this.destroyed = true;
79 | if (this.destroyCallback) {
80 | this.destroyCallback("destroy");
81 | }
82 | }
83 |
84 | public postDestroy(): void {
85 | if (this.postDestroyCallback) {
86 | this.postDestroyCallback("postDestroy");
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/MediatorHook.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Sprite } from "pixi.js";
9 |
10 | import { injectable, inject, named, optional, IHook } from "@robotlegsjs/core";
11 |
12 | import { ViewInjectedMediator } from "./ViewInjectedMediator";
13 |
14 | @injectable()
15 | export class MediatorHook implements IHook {
16 | @inject("Function")
17 | @named("callback")
18 | @optional()
19 | public callback: Function;
20 |
21 | @inject(Sprite)
22 | public mediatedItem: Sprite;
23 |
24 | @inject(ViewInjectedMediator)
25 | public mediator: ViewInjectedMediator;
26 |
27 | public hook(): void {
28 | if (this.callback) {
29 | this.callback(this);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/MediatorWatcher.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class MediatorWatcher {
12 | protected _notifications: string[] = [];
13 |
14 | public get notifications(): string[] {
15 | return this._notifications;
16 | }
17 |
18 | public notify(message: string): void {
19 | this._notifications.push(message);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/NotAView.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class NotAView {
12 | public mediatorName: string;
13 | }
14 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/NotAViewMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject } from "@robotlegsjs/core";
9 |
10 | import { MediatorWatcher } from "./MediatorWatcher";
11 | import { NotAView } from "./NotAView";
12 |
13 | @injectable()
14 | export class NotAViewMediator {
15 | @inject(MediatorWatcher)
16 | public mediatorWatcher: MediatorWatcher;
17 |
18 | @inject(NotAView)
19 | public view: NotAView;
20 |
21 | public initialize(): void {
22 | this.view.mediatorName = "NotAViewMediator";
23 | this.mediatorWatcher.notify("NotAViewMediator");
24 | }
25 |
26 | public destroy(): void {
27 | this.mediatorWatcher.notify("NotAViewMediator destroy");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/NullMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class NullMediator {}
12 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/NullMediator2.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class NullMediator2 {}
12 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/OnlyIfViewHasChildrenGuard.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Sprite } from "pixi.js";
9 |
10 | import { injectable, inject, IGuard } from "@robotlegsjs/core";
11 |
12 | @injectable()
13 | export class OnlyIfViewHasChildrenGuard implements IGuard {
14 | @inject(Sprite)
15 | public view: Sprite;
16 |
17 | public approve(): boolean {
18 | return this.view.children.length > 0;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/RectangleMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject, named } from "@robotlegsjs/core";
9 |
10 | @injectable()
11 | export class RectangleMediator {
12 | @inject(Number)
13 | @named("width")
14 | public width: number;
15 |
16 | @inject(Number)
17 | @named("height")
18 | public height: number;
19 | }
20 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/ViewInjectedAsRequestedMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject } from "@robotlegsjs/core";
9 |
10 | import { DisplayObject } from "pixi.js";
11 |
12 | @injectable()
13 | export class ViewInjectedAsRequestedMediator {
14 | @inject(DisplayObject)
15 | public mediatedItem: DisplayObject;
16 |
17 | public initialize(): void {}
18 |
19 | public destroy(): void {}
20 | }
21 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/mediatorMap/support/ViewInjectedMediator.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { injectable, inject } from "@robotlegsjs/core";
9 |
10 | import { Sprite } from "pixi.js";
11 |
12 | @injectable()
13 | export class ViewInjectedMediator {
14 | @inject(Sprite)
15 | public mediatedItem: Sprite;
16 |
17 | public initialize(): void {}
18 |
19 | public destroy(): void {}
20 | }
21 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/impl/configureViewEvent.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Container } from "pixi.js";
13 |
14 | import { ConfigureViewEvent } from "../../../../../../src/robotlegs/bender/extensions/viewManager/impl/ConfigureViewEvent";
15 |
16 | describe("ConfigureViewEvent", () => {
17 | let container: Container = null;
18 | let event: ConfigureViewEvent = null;
19 |
20 | beforeEach(() => {
21 | container = new Container();
22 | event = new ConfigureViewEvent(ConfigureViewEvent.CONFIGURE_VIEW, container);
23 | });
24 |
25 | afterEach(() => {
26 | container = null;
27 | event = null;
28 | });
29 |
30 | it("ensure_static_properties_will_not_change", () => {
31 | assert.equal(ConfigureViewEvent.CONFIGURE_VIEW, "configureView");
32 | });
33 |
34 | it("type_is_stored", () => {
35 | assert.equal(event.type, ConfigureViewEvent.CONFIGURE_VIEW);
36 | });
37 |
38 | it("view_is_stored", () => {
39 | assert.equal(event.view, container);
40 | });
41 |
42 | it("event_is_cloned", () => {
43 | let clone: ConfigureViewEvent = event.clone();
44 | assert.equal(clone.type, event.type);
45 | assert.equal(clone.view, event.view);
46 | assert.notEqual(clone, event);
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/impl/containerBindingEvent.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { ContainerBindingEvent } from "../../../../../../src/robotlegs/bender/extensions/viewManager/impl/ContainerBindingEvent";
13 |
14 | describe("ContainerBindingEvent", () => {
15 | let event: ContainerBindingEvent = null;
16 |
17 | beforeEach(() => {
18 | event = new ContainerBindingEvent(ContainerBindingEvent.BINDING_EMPTY);
19 | });
20 |
21 | afterEach(() => {
22 | event = null;
23 | });
24 |
25 | it("ensure_static_properties_will_not_change", () => {
26 | assert.equal(ContainerBindingEvent.BINDING_EMPTY, "bindingEmpty");
27 | });
28 |
29 | it("type_is_stored", () => {
30 | assert.equal(event.type, ContainerBindingEvent.BINDING_EMPTY);
31 | });
32 |
33 | it("event_is_cloned", () => {
34 | let clone: ContainerBindingEvent = event.clone();
35 | assert.equal(clone.type, event.type);
36 | assert.notEqual(clone, event);
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/impl/containerRegistryEvent.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Sprite } from "pixi.js";
13 |
14 | import { ContainerRegistryEvent } from "../../../../../../src/robotlegs/bender/extensions/viewManager/impl/ContainerRegistryEvent";
15 |
16 | describe("ContainerRegistryEvent", () => {
17 | let container: Sprite = null;
18 | let event: ContainerRegistryEvent = null;
19 |
20 | beforeEach(() => {
21 | container = new Sprite();
22 | event = new ContainerRegistryEvent(ContainerRegistryEvent.CONTAINER_ADD, container);
23 | });
24 |
25 | afterEach(() => {
26 | container = null;
27 | event = null;
28 | });
29 |
30 | it("ensure_static_properties_will_not_change", () => {
31 | assert.equal(ContainerRegistryEvent.CONTAINER_ADD, "containerAdd");
32 | assert.equal(ContainerRegistryEvent.CONTAINER_REMOVE, "containerRemove");
33 | assert.equal(ContainerRegistryEvent.ROOT_CONTAINER_ADD, "rootContainerAdd");
34 | assert.equal(ContainerRegistryEvent.ROOT_CONTAINER_REMOVE, "rootContainerRemove");
35 | });
36 |
37 | it("type_is_stored", () => {
38 | assert.equal(event.type, ContainerRegistryEvent.CONTAINER_ADD);
39 | });
40 |
41 | it("container_is_stored", () => {
42 | assert.equal(event.container, container);
43 | });
44 |
45 | it("event_is_cloned", () => {
46 | let clone: ContainerRegistryEvent = event.clone();
47 | assert.equal(clone.type, event.type);
48 | assert.equal(clone.container, event.container);
49 | assert.notEqual(clone, event);
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/impl/viewManagerEvent.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { Sprite } from "pixi.js";
13 |
14 | import { IViewHandler } from "../../../../../../src/robotlegs/bender/extensions/viewManager/api/IViewHandler";
15 | import { ViewManagerEvent } from "../../../../../../src/robotlegs/bender/extensions/viewManager/impl/ViewManagerEvent";
16 |
17 | import { CallbackViewHandler } from "../support/CallbackViewHandler";
18 |
19 | describe("ViewManagerEvent", () => {
20 | let container: Sprite = null;
21 | let handler: IViewHandler = null;
22 | let event: ViewManagerEvent = null;
23 |
24 | beforeEach(() => {
25 | container = new Sprite();
26 | handler = new CallbackViewHandler();
27 | event = new ViewManagerEvent(ViewManagerEvent.CONTAINER_ADD, container, handler);
28 | });
29 |
30 | afterEach(() => {
31 | container = null;
32 | handler = null;
33 | event = null;
34 | });
35 |
36 | it("ensure_static_properties_will_not_change", () => {
37 | assert.equal(ViewManagerEvent.CONTAINER_ADD, "containerAdd");
38 | assert.equal(ViewManagerEvent.CONTAINER_REMOVE, "containerRemove");
39 | assert.equal(ViewManagerEvent.HANDLER_ADD, "handlerAdd");
40 | assert.equal(ViewManagerEvent.HANDLER_REMOVE, "handlerRemove");
41 | });
42 |
43 | it("type_is_stored", () => {
44 | assert.equal(event.type, ViewManagerEvent.CONTAINER_ADD);
45 | });
46 |
47 | it("container_is_stored", () => {
48 | assert.equal(event.container, container);
49 | });
50 |
51 | it("handler_is_stored", () => {
52 | assert.equal(event.handler, handler);
53 | });
54 |
55 | it("event_is_cloned", () => {
56 | let clone: ViewManagerEvent = event.clone();
57 | assert.equal(clone.type, event.type);
58 | assert.equal(clone.container, event.container);
59 | assert.equal(clone.handler, event.handler);
60 | assert.notEqual(clone, event);
61 | });
62 | });
63 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/manualStageObserverExtension.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { IContext, Context, LogLevel } from "@robotlegsjs/core";
13 |
14 | import { ManualStageObserverExtension, ViewManagerExtension } from "../../../../../src";
15 |
16 | import { CallbackLogTarget } from "../contextView/support/CallbackLogTarget";
17 | import { LogParams } from "../contextView/support/LogParams";
18 |
19 | describe("ManualStageObserverExtension", () => {
20 | let context: IContext;
21 |
22 | beforeEach(() => {
23 | context = new Context();
24 | });
25 |
26 | afterEach(() => {
27 | context.destroy();
28 | context = null;
29 | });
30 |
31 | it("installing_after_initialization_throws_error", () => {
32 | function installExtensionAfterInitialization(): void {
33 | context.initialize();
34 | context.install(ManualStageObserverExtension);
35 | }
36 | assert.throws(installExtensionAfterInitialization, Error);
37 | });
38 |
39 | it("extension_logs_debug_messages_when_initializing_and_destroying", () => {
40 | let whenInitializingLogged: boolean = false;
41 | let whenDestroyingLogged: boolean = false;
42 | let logTarget: CallbackLogTarget = new CallbackLogTarget((log: LogParams) => {
43 | if (log.source instanceof ManualStageObserverExtension && log.level === LogLevel.DEBUG) {
44 | if (!whenInitializingLogged) {
45 | whenInitializingLogged = log.message === "Creating genuine ManualStageObserver Singleton";
46 | }
47 | if (!whenDestroyingLogged) {
48 | whenDestroyingLogged = log.message === "Destroying genuine ManualStageObserver Singleton";
49 | }
50 | }
51 | });
52 | context.logLevel = LogLevel.DEBUG;
53 | context.install(ViewManagerExtension, ManualStageObserverExtension);
54 | context.addLogTarget(logTarget);
55 | context.initialize();
56 | context.destroy();
57 | assert.isTrue(whenInitializingLogged);
58 | assert.isTrue(whenDestroyingLogged);
59 | });
60 | });
61 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/stageObserverExtension.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { IContext, Context, LogLevel } from "@robotlegsjs/core";
13 |
14 | import { StageObserverExtension, ViewManagerExtension } from "../../../../../src";
15 |
16 | import { CallbackLogTarget } from "../contextView/support/CallbackLogTarget";
17 | import { LogParams } from "../contextView/support/LogParams";
18 |
19 | describe("StageObserverExtension", () => {
20 | let context: IContext;
21 |
22 | beforeEach(() => {
23 | context = new Context();
24 | });
25 |
26 | afterEach(() => {
27 | context.destroy();
28 | context = null;
29 | });
30 |
31 | it("installing_after_initialization_throws_error", () => {
32 | function installExtensionAfterInitialization(): void {
33 | context.initialize();
34 | context.install(StageObserverExtension);
35 | }
36 | assert.throws(installExtensionAfterInitialization, Error);
37 | });
38 |
39 | it("extension_logs_debug_messages_when_initializing_and_destroying", () => {
40 | let whenInitializingLogged: boolean = false;
41 | let whenDestroyingLogged: boolean = false;
42 | let logTarget: CallbackLogTarget = new CallbackLogTarget((log: LogParams) => {
43 | if (log.source instanceof StageObserverExtension && log.level === LogLevel.DEBUG) {
44 | if (!whenInitializingLogged) {
45 | whenInitializingLogged = log.message === "Creating genuine StageObserver Singleton";
46 | }
47 | if (!whenDestroyingLogged) {
48 | whenDestroyingLogged = log.message === "Destroying genuine StageObserver Singleton";
49 | }
50 | }
51 | });
52 | context.logLevel = LogLevel.DEBUG;
53 | context.install(ViewManagerExtension, StageObserverExtension);
54 | context.addLogTarget(logTarget);
55 | context.initialize();
56 | context.destroy();
57 | assert.isTrue(whenInitializingLogged);
58 | assert.isTrue(whenDestroyingLogged);
59 | });
60 | });
61 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/support/CallbackViewHandler.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Container } from "pixi.js";
9 |
10 | import { IClass } from "@robotlegsjs/core";
11 |
12 | import { IViewHandler } from "../../../../../../src/robotlegs/bender/extensions/viewManager/api/IViewHandler";
13 |
14 | /**
15 | * @private
16 | */
17 | export class CallbackViewHandler implements IViewHandler {
18 | private _callback: Function;
19 |
20 | constructor(callback: Function = null) {
21 | this._callback = callback;
22 | }
23 |
24 | public handleView(view: Container, type: IClass): void {
25 | if (this._callback) {
26 | this._callback(view, type);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/support/TreeContainer.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import { Sprite } from "pixi.js";
9 |
10 | /**
11 | * @private
12 | */
13 | export class TreeContainer extends Sprite {
14 | private _treeDepth: number = 0;
15 | private _treeWidth: number = 0;
16 | private _treeChildren: TreeContainer[] = [];
17 |
18 | constructor(treeDetpth: number, treeWidth: number) {
19 | super();
20 |
21 | this._treeDepth = treeDetpth;
22 | this._treeWidth = treeWidth;
23 |
24 | this.populate();
25 | }
26 |
27 | private populate(): void {
28 | if (this._treeDepth > 0) {
29 | for (let i: number = 0; i < this._treeWidth; i++) {
30 | let child: TreeContainer = new TreeContainer(this._treeDepth - 1, this._treeWidth);
31 | this._treeChildren.push(child);
32 | this.addChild(child);
33 | }
34 | }
35 | }
36 |
37 | public get treeChildren(): TreeContainer[] {
38 | return this._treeChildren;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/test/robotlegs/bender/extensions/viewManager/viewManagerExtension.test.ts:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved.
3 | //
4 | // NOTICE: You are permitted to use, modify, and distribute this file
5 | // in accordance with the terms of the license agreement accompanying it.
6 | // ------------------------------------------------------------------------------
7 |
8 | import "../../../../entry";
9 |
10 | import { assert } from "chai";
11 |
12 | import { IContext, Context } from "@robotlegsjs/core";
13 |
14 | import { ViewManagerExtension, IViewManager } from "../../../../../src";
15 |
16 | import { ViewManager } from "../../../../../src/robotlegs/bender/extensions/viewManager/impl/ViewManager";
17 |
18 | describe("ViewManagerExtension", () => {
19 | let context: IContext;
20 |
21 | beforeEach(() => {
22 | context = new Context();
23 | });
24 |
25 | afterEach(() => {
26 | context.destroy();
27 | context = null;
28 | });
29 |
30 | it("installing after initialization throws error", () => {
31 | function installExtensionAfterInitialization(): void {
32 | context.initialize();
33 | context.install(ViewManagerExtension);
34 | }
35 | assert.throws(installExtensionAfterInitialization, Error);
36 | });
37 |
38 | it("viewManager is mapped into injector", () => {
39 | let viewManager: IViewManager = null;
40 | context.install(ViewManagerExtension);
41 | context.whenInitializing(function(): void {
42 | viewManager = context.injector.get(IViewManager);
43 | });
44 | context.initialize();
45 | assert.isNotNull(viewManager);
46 | assert.instanceOf(viewManager, ViewManager);
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.test.json"
3 | }
4 |
--------------------------------------------------------------------------------
/tsconfig.example.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib-example"
5 | },
6 | "include": [
7 | "./src/**/*.ts",
8 | "./example/**/*.ts"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "lib",
4 | "target": "es5",
5 | "lib": ["es7", "dom"],
6 | "types": ["reflect-metadata"],
7 | "sourceMap": true,
8 | "inlineSources": true,
9 | "module": "commonjs",
10 | "moduleResolution": "node",
11 | "experimentalDecorators": true,
12 | "emitDecoratorMetadata": true,
13 | "removeComments": false,
14 | "strict": false,
15 | "noImplicitAny": true,
16 | "strictNullChecks": false,
17 | "noImplicitThis": false,
18 | "alwaysStrict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": false,
21 | "noImplicitReturns": true,
22 | "noFallthroughCasesInSwitch": true
23 | },
24 | "include": [
25 | "./src/**/*.ts"
26 | ],
27 | "files": [
28 | "./definitions/pixi.d.ts"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/tsconfig.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib-test"
5 | },
6 | "include": [
7 | "./src/**/*.ts",
8 | "./test/**/*.ts"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/tslint.example.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "./tslint.json"
4 | ],
5 | "rules": {
6 | "no-reference": false,
7 | "object-literal-sort-keys": false
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "tslint:latest",
4 | "tslint-config-prettier"
5 | ],
6 | "rules": {
7 | "ban-types": [ false ],
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "forin": true,
15 | "label-position": true,
16 | "member-access": true,
17 | "member-ordering": [
18 | true, {
19 | "order": [
20 | "static-field",
21 | "instance-field",
22 | "constructor",
23 | "public-instance-method",
24 | "protected-instance-method",
25 | "private-instance-method"
26 | ]
27 | }
28 | ],
29 | "no-angle-bracket-type-assertion": false,
30 | "no-arg": true,
31 | "no-bitwise": true,
32 | "no-console": [
33 | true,
34 | "debug",
35 | "info",
36 | "time",
37 | "timeEnd",
38 | "trace"
39 | ],
40 | "no-construct": true,
41 | "no-debugger": true,
42 | "no-duplicate-variable": true,
43 | "no-empty": false,
44 | "no-eval": true,
45 | "no-inferrable-types": false,
46 | "no-shadowed-variable": true,
47 | "no-string-literal": true,
48 | "no-switch-case-fall-through": false,
49 | "no-this-assignment": false,
50 | "no-unused-expression": true,
51 | "no-use-before-declare": true,
52 | "no-var-keyword": true,
53 | "object-literal-sort-keys": true,
54 | "ordered-imports": false,
55 | "only-arrow-functions": [ false ],
56 | "prefer-const": false,
57 | "radix":true,
58 | "trailing-comma": [
59 | false
60 | ],
61 | "triple-equals": [
62 | true,
63 | "allow-null-check"
64 | ],
65 | "variable-name": false
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tslint.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "./tslint.json"
4 | ],
5 | "rules": {
6 | "no-implicit-dependencies": [true, "dev"],
7 | "no-reference": false,
8 | "no-submodule-imports": false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require("webpack");
2 | const path = require("path");
3 | const TerserPlugin = require("terser-webpack-plugin");
4 |
5 | module.exports = env => {
6 | if (!env) env = { production: false, karma: false };
7 |
8 | let mode = env.production ? "production" : "development";
9 | let tsconfig = !env.karma ? "tsconfig.json" : "tsconfig.test.json";
10 | let output = env.production ? "dist" : "dist-test";
11 | let filename = env.karma ? "[name].[hash].js" : env.production ? "robotlegs-pixi.min.js" : "robotlegs-pixi.js";
12 |
13 | return {
14 | mode: mode,
15 |
16 | entry: {
17 | main: path.join(__dirname, "src/index.ts")
18 | },
19 |
20 | output: {
21 | path: path.join(__dirname, output),
22 | filename: filename,
23 |
24 | libraryTarget: "var",
25 | library: "RobotlegsJSPixi"
26 | },
27 |
28 | devtool: env.production ? undefined : "inline-source-map",
29 |
30 | module: {
31 | rules: [
32 | {
33 | test: /\.ts$/,
34 | loader: "ts-loader?configFile=" + tsconfig
35 | },
36 | {
37 | test: env.production /* disable this loader for production builds */ ? /^$/ : /^.*(src).*\.ts$/,
38 | loader: "istanbul-instrumenter-loader",
39 | query: {
40 | embedSource: true
41 | },
42 | enforce: "post"
43 | }
44 | ]
45 | },
46 |
47 | plugins: env.production ? [] : [new webpack.SourceMapDevToolPlugin({ test: /\.ts$/i })],
48 |
49 | optimization: env.production
50 | ? {
51 | concatenateModules: true,
52 | minimize: true,
53 | minimizer: [
54 | new TerserPlugin({
55 | cache: true,
56 | parallel: 4,
57 | terserOptions: {
58 | output: {
59 | comments: false
60 | }
61 | }
62 | })
63 | ]
64 | }
65 | : {},
66 | resolve: {
67 | extensions: [".ts", ".js", ".json"]
68 | }
69 | };
70 | };
71 |
--------------------------------------------------------------------------------
/webpack.example.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require("webpack");
2 | const path = require("path");
3 | const HtmlWebpackPlugin = require("html-webpack-plugin");
4 | const SimpleProgressPlugin = require("webpack-simple-progress-plugin");
5 | const CopyPlugin = require("copy-webpack-plugin");
6 | const { CleanWebpackPlugin } = require("clean-webpack-plugin");
7 |
8 | module.exports = options => {
9 | return {
10 | mode: "development",
11 |
12 | entry: {
13 | main: path.resolve("example/index.ts")
14 | },
15 |
16 | output: {
17 | path: __dirname + "/dist",
18 | filename: "game.[hash].js"
19 | },
20 |
21 | devtool: "source-map",
22 |
23 | module: {
24 | rules: [{ test: /\.ts$/, loader: "ts-loader" }]
25 | },
26 |
27 | plugins: [
28 | new CleanWebpackPlugin(),
29 |
30 | new HtmlWebpackPlugin({
31 | template: path.resolve("static/index.html"),
32 | inject: false
33 | }),
34 |
35 | new CopyPlugin([{ from: "static", to: "." }]),
36 |
37 | new SimpleProgressPlugin()
38 | ],
39 |
40 | resolve: {
41 | extensions: [".ts", ".js", ".json"]
42 | },
43 |
44 | devServer: {
45 | host: "0.0.0.0",
46 | contentBase: path.join(__dirname, "static"),
47 | hot: true,
48 | disableHostCheck: true,
49 | inline: false
50 | }
51 | };
52 | };
53 |
--------------------------------------------------------------------------------