summaryrefslogtreecommitdiff
path: root/engine/entities/Entity.ts
blob: 63fb3701e0d9cf66158efb0b214c77ddedecd0a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { EntityNames, Floor, Player } from '.';
import { type Component } from '../components';

const randomId = () =>
  (performance.now() + Math.random() * 10_000_000).toString();

export abstract class Entity {
  public id: string;
  public components: Map<string, Component>;
  public name: string;

  constructor(name: string, id: string = randomId()) {
    this.name = name;
    this.id = id;
    this.components = new Map();
  }

  public addComponent(component: Component) {
    this.components.set(component.name, component);
  }

  public getComponent<T extends Component>(name: string): T {
    if (!this.hasComponent(name)) {
      throw new Error('Entity does not have component ' + name);
    }
    return this.components.get(name) as T;
  }

  public getComponents(): Component[] {
    return Array.from(this.components.values());
  }

  public hasComponent(name: string): boolean {
    return this.components.has(name);
  }

  public static from(entityName: string, id: string, args: any): Entity {
    let entity: Entity;

    switch (entityName) {
      case EntityNames.Player:
        const player = new Player();
        player.setFrom(args);
        entity = player;
        break;
      case EntityNames.Floor:
        const floor = new Floor(args.floorWidth);
        floor.setFrom(args);
        entity = floor;
        break;
      default:
        throw new Error('.from() Entity type not implemented: ' + entityName);
    }

    entity.id = id;
    return entity;
  }

  public abstract setFrom(args: Record<string, any>): void;

  public abstract serialize(): Record<string, any>;
}