Skip to content

Commit

Permalink
Added Executor and commands
Browse files Browse the repository at this point in the history
  • Loading branch information
devpaul committed Nov 11, 2017
1 parent f5c3554 commit fb98200
Show file tree
Hide file tree
Showing 22 changed files with 428 additions and 95 deletions.
38 changes: 28 additions & 10 deletions src/App.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
import { v, w } from '@dojo/widget-core/d';
import { w } from '@dojo/widget-core/d';
import { DNode, WidgetProperties } from '@dojo/widget-core/interfaces';
import { WidgetBase } from '@dojo/widget-core/WidgetBase';
import Controls from './widgets/Controls';
import AssetContainer from './containers/AssetContainer';
import OutsideContainer from './containers/OutsideContainer';
import { ApplicationState } from './context/AppContext';
import { Scene } from 'three';
import SceneContainer from './containers/SceneContainer';

export interface AppProperties extends WidgetProperties {
isLoadingState: boolean;
state: ApplicationState;

initialize(): void;
}

export default class App extends WidgetBase<AppProperties> {
manageState() {
const {
isLoadingState,
state,

initialize
} = this.properties;

if (!isLoadingState && state === ApplicationState.Initial) {
initialize();
}
}

export default class App extends WidgetBase<WidgetProperties> {
protected render(): DNode {
return v('a-scene', [
w(AssetContainer, {}),
w(Controls, {}),
w(OutsideContainer, {}),
]);
this.manageState();

return w(SceneContainer, {});
}
}
28 changes: 28 additions & 0 deletions src/commands/initialize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Executor, { Action } from '../framework/Executor';
import AppContext, { ApplicationState } from '../context/AppContext';
import { ActionType } from '../initialize';
import registerHeightComponent from '../components/heightComponent';

export type InitializeAction = Action<undefined, [ AppContext, Executor ]>;

export default function initialize({ state: [ app, executor ] }: InitializeAction) {
if (app.state !== ApplicationState.Initial) {
throw new Error('Application already initialized');
}

app.isLoadingState = true;

if (!app.initialized.monsters) {
executor.execute(ActionType.LoadMonsters);
}
if (!app.initialized.aframe) {
registerHeightComponent();
app.initialized.aframe = true;
}

if (app.initialized.monsters && app.initialized.aframe) {
executor.execute(ActionType.RandomizeEncounter);
app.isLoadingState = false;
app.state = ApplicationState.Outside;
}
};
9 changes: 9 additions & 0 deletions src/commands/loadMonsters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Executor, { Action } from '../framework/Executor';
import monsters from '../configuration/monsters';

export type LoadMonsterAction = Action<undefined, Executor>;

export default function loadMonsters({ state: executor }: LoadMonsterAction) {
// TODO eventually monsters can come from an async load
executor.execute('loadedMonsters', monsters);
}
10 changes: 10 additions & 0 deletions src/commands/loadedMonsters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Executor, { Action } from '../framework/Executor';
import monsters from '../configuration/monsters';
import AppContext from '../context/AppContext';

export type LoadedMonsterAction = Action<undefined, [ AppContext, Executor ]>;

export default function loadedMonsters({ state: [ app, executor ] }: LoadedMonsterAction) {
app.initialized.monsters = true;
executor.execute('registerMonsters', monsters);
}
8 changes: 8 additions & 0 deletions src/commands/randomizeEncounter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Action } from '../framework/Executor';
import OutsideContext from '../context/OutsideContext';

export type RandomizeEncounterAction = Action<undefined, OutsideContext>;

export default function randomizeEncounter({ state: outsideContext }: RandomizeEncounterAction) {
outsideContext.randomizeEncounter();
};
21 changes: 21 additions & 0 deletions src/commands/registerMonsters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Action } from '../framework/Executor';
import { MonsterConfigurationItem } from '../configuration/monsters';
import OutsideContext from '../context/OutsideContext';
import { throws } from '../util/properties';
import AssetContext from '../context/AssetContext';

export type RegisterMonstersAction = Action<Array<MonsterConfigurationItem>, [ AssetContext, OutsideContext ]>;

export default function registerMonsters({
payload: monsters = throws(),
state: [ appContext, outsideContext ] = throws()
}: RegisterMonstersAction) {
for (let monster of monsters) {
appContext.addObjMtlAssets(monster.name, monster.obj, monster.mtl);
outsideContext.addMonster({
name: monster.name,
heights: monster.heights,
environment: monster.environment
});
}
};
2 changes: 1 addition & 1 deletion src/configuration/monsters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Environment, MonsterDefinition } from '../context/OutsideContext';
import { ObjModelAsset } from '../interfaces';
import { assign } from '@dojo/shim/object';

declare type MonsterConfigurationItem = MonsterDefinition & ObjModelAsset;
export type MonsterConfigurationItem = MonsterDefinition & ObjModelAsset;

export const enum MonsterName {
CharDerp = 'charderp',
Expand Down
20 changes: 20 additions & 0 deletions src/containers/AppContainer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Container from '../framework/Container';
import App, { AppProperties } from '../App';
import AppContext from '../context/AppContext';
import { ActionType, State } from '../initialize';
import Executor from '../framework/Executor';

const AppContainer = Container(App, [ State.App, State.Executor ], {
getProperties([ app, executor ]: [ AppContext, Executor ]): AppProperties {
return {
isLoadingState: app.isLoadingState,
state: app.state,

initialize() {
executor.execute(ActionType.Initialize);
}
}
}
});

export default AppContainer;
7 changes: 4 additions & 3 deletions src/containers/AssetContainer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Container from '../framework/Container';
import Assets from '../widgets/Assets';
import AppContext from '../context/AppContext';
import AssetContext from '../context/AssetContext';
import { State } from '../initialize';

const AssetContainer = Container(Assets, 'app-state', {
getProperties(context: AppContext) {
const AssetContainer = Container(Assets, State.Asset, {
getProperties(context: AssetContext) {
return {
assets: context.assets
}
Expand Down
7 changes: 4 additions & 3 deletions src/containers/OutsideContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import Outside, { OutsideProperties } from '../widgets/Outside';
import Container from '../framework/Container';
import { throws } from '../util/properties';
import OutsideContext from '../context/OutsideContext';
import AppContext from '../context/AppContext';
import { State } from '../initialize';
import AssetContext from '../context/AssetContext';

const OutsideContainer = Container(Outside, [ 'outside', 'app-state' ], {
getProperties(payload: [OutsideContext, AppContext]): OutsideProperties {
const OutsideContainer = Container(Outside, [ State.Outside, State.Asset ], {
getProperties(payload: [ OutsideContext, AssetContext ]): OutsideProperties {
const [
outside = throws(),
appContext = throws()
Expand Down
15 changes: 15 additions & 0 deletions src/containers/SceneContainer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Container from '../framework/Container';
import AppContext from '../context/AppContext';
import Scene, { SceneProperties } from '../widgets/Scene';
import { State } from '../initialize';

const SceneContainer = Container(Scene, State.App, {
getProperties(state: AppContext): SceneProperties {
return {
debug: state.debug,
state: state.state
}
}
});

export default SceneContainer;
49 changes: 10 additions & 39 deletions src/context/AppContext.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,19 @@
import { InjectorBase } from '../framework/InjectorBase';

/**
* Application Asset used for loading models, video, and images by A-Frame's <a-asset>
*/
export interface Asset {
id: string;
src: string;
export const enum ApplicationState {
Initial = 'initial',
Outside = 'outside'
}

export default class AppContext extends InjectorBase {
private _assets: Map<string, Asset> = new Map();
debug = true;

/**
* @return a list of all active assets
*/
get assets(): Asset[] {
return Array.from(this._assets.values());
}
initialized = {
aframe: false,
monsters: false
};

/**
* Adds an asset
*/
addAsset(id: string, src: string) {
if (!this._assets.has(id)) {
this._assets.set(id, {
id,
src
});
this.emitInvalidate();
}
}
isLoadingState = false;

/**
* Adds an Obj model asset
*/
addObjMtlAssets(name: string, objSrc: string, mtlSrc?: string) {
this.addAsset(`${ name }-obj`, objSrc);
mtlSrc && this.addAsset(`${ name }-mtl`, mtlSrc);
}

getObjMtlAssets(name: string): { mtl?: Asset, obj?: Asset } {
return {
mtl: this._assets.get(`${ name }-mtl`),
obj: this._assets.get(`${ name }-obj`)
}
}
state: ApplicationState = ApplicationState.Initial;
}
48 changes: 48 additions & 0 deletions src/context/AssetContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { InjectorBase } from '../framework/InjectorBase';

/**
* Application Asset used for loading models, video, and images by A-Frame's <a-asset>
*/
export interface Asset {
id: string;
src: string;
}

export default class AssetContext extends InjectorBase {
private _assets: Map<string, Asset> = new Map();

/**
* @return a list of all active assets
*/
get assets(): Asset[] {
return Array.from(this._assets.values());
}

/**
* Adds an asset
*/
addAsset(id: string, src: string) {
if (!this._assets.has(id)) {
this._assets.set(id, {
id,
src
});
this.emitInvalidate();
}
}

/**
* Adds an Obj model asset
*/
addObjMtlAssets(name: string, objSrc: string, mtlSrc?: string) {
this.addAsset(`${ name }-obj`, objSrc);
mtlSrc && this.addAsset(`${ name }-mtl`, mtlSrc);
}

getObjMtlAssets(name: string): { mtl?: Asset, obj?: Asset } {
return {
mtl: this._assets.get(`${ name }-mtl`),
obj: this._assets.get(`${ name }-obj`)
}
}
}
1 change: 0 additions & 1 deletion src/context/OutsideContext.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { InjectorBase } from '../framework/InjectorBase';
import { ObjModelAsset } from '../interfaces';

interface Monster {
distance: number;
Expand Down
8 changes: 2 additions & 6 deletions src/createDerpymonElement.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { CustomElementDescriptor } from '@dojo/widget-core/customElements';
import App from './App';
import initialize from './initialize';

// Require globals
require('aframe');
require('aframe-environment-component');
import AppContainer from './containers/AppContainer';

export default function createDerpymonElement(): CustomElementDescriptor {
return {
tagName: 'go-derpy',
widgetConstructor: App,
widgetConstructor: AppContainer,
events: [],
properties: [],
initialization() {
Expand Down
Loading

0 comments on commit fb98200

Please sign in to comment.