Skip to content

Instantly share code, notes, and snippets.

@pkaminski
Created March 24, 2021 12:43
Show Gist options
  • Save pkaminski/21f7dd3534b9de381d12a6eb1b14e1fc to your computer and use it in GitHub Desktop.
Save pkaminski/21f7dd3534b9de381d12a6eb1b14e1fc to your computer and use it in GitHub Desktop.
import {_Entity, Component, ComponentConstructor, PropType, Types, World} from 'ecsy';
type BuiltinPropTypes =
typeof Number | typeof Boolean | typeof String | typeof Array | typeof Object; // you can add more
interface Typed<T, D> {
type: PropType<T, D>;
}
interface PropOptions<T, D> {
type: PropType<T, D> | Typed<T, D> | BuiltinPropTypes;
default?: D;
}
const BUILTINS_MAP = new Map<BuiltinPropTypes, PropType<any, any>>([
[Number, Types.Number],
[Boolean, Types.Boolean],
[String, Types.String],
[Array, Types.Array],
[Object, Types.Ref],
[Vector2, Vector2Type]
]);
export function prop<T, D>(
practicalOptions: PropOptions<T, D> | PropType<T, D> | Typed<T, D> | BuiltinPropTypes
) {
return function(target: any, name: string): void {
if (target.constructor.schema === Component.schema) target.constructor.schema = {};
const options: PropOptions<T, D> =
'type' in practicalOptions ? practicalOptions : {type: practicalOptions};
options.type =
BUILTINS_MAP.get(options.type as BuiltinPropTypes) ??
('type' in options.type ? options.type.type : options.type);
target.constructor.schema[name] = options;
};
}
const components: ComponentConstructor<Component<any>>[] = [];
export function component(constructor: ComponentConstructor<Component<any>>): void {
components.push(constructor);
}
export function registerAllComponents(world: World): void {
for (const comp of components) world.registerComponent(comp);
}
declare module 'ecsy' {
interface Entity { // eslint-disable-line @typescript-eslint/no-unused-vars
get<C extends Component<any>>(
this: Entity, type: ComponentConstructor<C>, includeRemoved?: boolean): Readonly<C>;
mutate<C extends Component<any>>(this: Entity, type: ComponentConstructor<C>): C;
}
}
_Entity.prototype.get = function get<C extends Component<any>>(
this: _Entity, type: ComponentConstructor<C>, includeRemoved?: boolean
): Readonly<C> {
// Don't check if the component exists and throw an exception since it would likely just slow
// things down, and we'll crash pretty soon if the component isn't there anyway.
return this.getComponent(type, includeRemoved)!;
};
_Entity.prototype.mutate = function mutate<C extends Component<any>>(
this: _Entity, type: ComponentConstructor<C>
): C {
// Don't check if the component exists and throw an exception since it would likely just slow
// things down, and we'll crash pretty soon if the component isn't there anyway.
return this.getMutableComponent(type)!;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment