Remove decorators in favor of declarative initialization
This commit is contained in:
parent
a1900a4daa
commit
4212952abc
5 changed files with 72 additions and 56 deletions
|
@ -1,40 +1,48 @@
|
|||
import { KeyControl } from "./Keyboard";
|
||||
|
||||
/**
|
||||
* A class decorator for automatically constructing
|
||||
* class instances around elements on page load.
|
||||
*/
|
||||
export function Bind(selector: string) {
|
||||
return (appletType: AppletConstructor) => {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
for(let i = 0; i < elements.length; i++) {
|
||||
const element = elements[i] as HTMLElement;
|
||||
new appletType(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
export interface AppletConstructor {
|
||||
new(element: HTMLElement): any
|
||||
};
|
||||
|
||||
/**
|
||||
* A class decorator for automatically constructing
|
||||
* a KeyControl around a canvas on page load & fetching the render context.
|
||||
*/
|
||||
export function Game(selector: string, tabIndex = -1) {
|
||||
return (gameType: GameConstructor) => {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
for(let i = 0; i < elements.length; i++) {
|
||||
const element = elements[i] as HTMLCanvasElement;
|
||||
if(!(element instanceof HTMLCanvasElement)) continue;
|
||||
|
||||
const cx = element.getContext("2d") as CanvasRenderingContext2D;
|
||||
const keys = new KeyControl(element, tabIndex);
|
||||
|
||||
new gameType(element, cx, keys);
|
||||
}
|
||||
}
|
||||
};
|
||||
export interface GameConstructor {
|
||||
new(canvas: HTMLCanvasElement, cx: CanvasRenderingContext2D, keys: KeyControl): any
|
||||
};
|
||||
|
||||
class Selection {
|
||||
constructor(private elements: HTMLElement[]) {}
|
||||
|
||||
/**
|
||||
* Run a callback for every selected item.
|
||||
*/
|
||||
public forEach(callback: (e: HTMLElement) => {}) {
|
||||
this.elements.forEach(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a callback for selected canvases, with a 2d context & KeyControl established for use.
|
||||
*/
|
||||
public forEachCanvas(callback: (canvas: HTMLCanvasElement, cx: CanvasRenderingContext2D, keys: KeyControl) => {}, tabIndex = -1) {
|
||||
this.elements.forEach(e => {
|
||||
if(e instanceof HTMLCanvasElement) {
|
||||
const cx = e.getContext("2d") as CanvasRenderingContext2D;
|
||||
const keys = new KeyControl(e, tabIndex);
|
||||
|
||||
callback(e, cx, keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an HTML element or list of elements to bind them to behavior.
|
||||
*
|
||||
* @param selector A CSS selector or a literal Element
|
||||
*/
|
||||
export function Select(selector: string): Selection;
|
||||
export function Select(selector: HTMLElement): Selection;
|
||||
export function Select(selector: string | HTMLElement): Selection {
|
||||
if(typeof selector === "string") {
|
||||
const elementList = document.querySelectorAll(selector);
|
||||
const elements: HTMLElement[] = Array.prototype.slice.call(elementList);
|
||||
return new Selection(elements);
|
||||
} else {
|
||||
const elements = [selector];
|
||||
return new Selection(elements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { Bind } from "./Init";
|
||||
import { Select } from "./Init";
|
||||
import { KeyControl, KeyHandler, KeyName } from "./Keyboard";
|
||||
import { Loop } from "./Loop";
|
||||
|
||||
@Bind("#KeyTest")
|
||||
export class Test implements KeyHandler {
|
||||
class Test implements KeyHandler {
|
||||
private keys: KeyControl;
|
||||
|
||||
constructor(public div: HTMLElement) {
|
||||
|
@ -29,8 +28,7 @@ export class Test implements KeyHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@Bind("#LoopTest")
|
||||
export class LoopTest {
|
||||
class LoopTest {
|
||||
frames: number = 0;
|
||||
|
||||
constructor(public div: HTMLElement) {
|
||||
|
@ -45,3 +43,8 @@ export class LoopTest {
|
|||
loop.start();
|
||||
}
|
||||
}
|
||||
|
||||
export function BindDemos(): void {
|
||||
Select("#KeyTest").forEach(e => new Test(e));
|
||||
Select("#LoopTest").forEach(e => new LoopTest(e));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Bind, Game } from "../Applet/Init";
|
||||
import { Select } from "../Applet/Init";
|
||||
import { KeyControl } from "../Applet/Keyboard";
|
||||
import { Loop } from "../Applet/Loop";
|
||||
import { DrawSet, Layer } from "../Applet/Render";
|
||||
|
@ -45,8 +45,7 @@ class TestData extends Data {
|
|||
};
|
||||
}
|
||||
|
||||
@Bind("#EcsJoinTest")
|
||||
export class EcsJoinTest {
|
||||
class EcsJoinTest {
|
||||
constructor(pre: HTMLElement) {
|
||||
const data = new TestData();
|
||||
pre.innerText = JSON.stringify({
|
||||
|
@ -58,8 +57,7 @@ export class EcsJoinTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Bind("#EcsLookupTest")
|
||||
export class EcsLookupTest {
|
||||
class EcsLookupTest {
|
||||
constructor(pre: HTMLElement) {
|
||||
const data = new TestData();
|
||||
const applesMaybeCarrots = Join(data, "apple", "id").map(([apple, id]) => ({
|
||||
|
@ -70,8 +68,7 @@ export class EcsLookupTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Bind("#EcsRemoveTest")
|
||||
export class EcsRemoveTest {
|
||||
class EcsRemoveTest {
|
||||
constructor(pre: HTMLElement) {
|
||||
const data = new TestData();
|
||||
const beforeDelete = Join(data, "apple", "carrot", "id",);
|
||||
|
@ -84,8 +81,7 @@ export class EcsRemoveTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Bind("#EcsCreateTest")
|
||||
export class EcsCreateTest {
|
||||
class EcsCreateTest {
|
||||
constructor(pre: HTMLElement) {
|
||||
const data = new TestData();
|
||||
const beforeCreate = Join(data, "apple", "banana", "carrot", "id");
|
||||
|
@ -103,8 +99,7 @@ export class EcsCreateTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Game("#RenderTest")
|
||||
export class LoopTest {
|
||||
class LoopTest {
|
||||
data = new Data();
|
||||
|
||||
constructor(public canvas: HTMLCanvasElement, cx: CanvasRenderingContext2D, keys: KeyControl) {
|
||||
|
@ -174,3 +169,11 @@ export class LoopTest {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function BindTests(): void {
|
||||
Select("#EcsJoinTest").forEach(e => new EcsJoinTest(e));
|
||||
Select("#EcsLookupTest").forEach(e => new EcsLookupTest(e));
|
||||
Select("#EcsRemoveTest").forEach(e => new EcsRemoveTest(e));
|
||||
Select("#EcsCreateTest").forEach(e => new EcsCreateTest(e));
|
||||
Select("#RenderTest").forEachCanvas((c, cx, keys) => new LoopTest(c, cx, keys));
|
||||
}
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import subscribe from "callbag-subscribe";
|
||||
|
||||
import { Game } from "../Applet/Init";
|
||||
import { KeyControl, KeyName } from "../Applet/Keyboard";
|
||||
import { DrawSet } from "../Applet/Render";
|
||||
import { Location, Polygon, RenderBounds } from "../Ecs/Components";
|
||||
import { Create } from "../Ecs/Data";
|
||||
import {} from "../Ecs/Lockstep";
|
||||
import { RunRenderBounds } from "../Ecs/Renderers";
|
||||
import { LockstepClient } from "../Net/LockstepClient";
|
||||
import { Loopback } from "../Net/LoopbackServer";
|
||||
import { Data, Engine } from "./GameComponents";
|
||||
import { Buttons } from "./Input";
|
||||
|
||||
@Game("#GameCanvas")
|
||||
export class Main extends LockstepClient<KeyName[], Data> {
|
||||
|
||||
buttons = new Buttons();
|
||||
|
|
|
@ -1,2 +1,7 @@
|
|||
import "./Game/Main";
|
||||
import "./Ecs/test";
|
||||
import { Select } from "./Applet/Init";
|
||||
import { BindTests } from "./Ecs/test";
|
||||
import { Main } from "./Game/Main";
|
||||
|
||||
Select("#GameCanvas").forEachCanvas((c, cx, keys) => new Main(c, cx, keys));
|
||||
|
||||
BindTests();
|
||||
|
|
Loading…
Reference in a new issue