-
Notifications
You must be signed in to change notification settings - Fork 4
/
ComponentRepository.ts
184 lines (169 loc) · 5.96 KB
/
ComponentRepository.ts
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import { Component } from './Component';
import {Is} from '../misc/Is';
import { EntityRepository } from './EntityRepository';
import {Config} from './Config';
import {ComponentTID, ComponentSID, EntityUID} from '../../types/CommonTypes';
/**
* The class that generates and manages all kinds of components.
*/
export class ComponentRepository {
private static __component_sid_count_map: Map<ComponentTID, number> =
new Map();
private static __components: Map<ComponentTID, Array<Component>> = new Map(); // index of array Is ComponentSID
static __componentClasses: Map<ComponentTID, typeof Component> = new Map();
constructor() {}
/**
* Registers the class object of the component.
* @param componentClass A class object of the component.
*/
public static registerComponentClass(componentClass: typeof Component) {
const thisClass = ComponentRepository;
thisClass.__componentClasses.set(
componentClass.componentTID,
componentClass
);
}
/**
* deregister the component.
* @param componentTID A componentTID
*/
public static deregisterComponentClass(componentTID: ComponentTID) {
const thisClass = ComponentRepository;
thisClass.__componentClasses.delete(componentTID);
}
/**
* Gets the class object of the component corresponding to specified ComponentTID.
* @param componentTid The componentTID to get the class object.
*/
public static getComponentClass(componentTid: ComponentTID) {
return this.__componentClasses.get(componentTid);
}
/**
* Creates an instance of the component for the entity.
* @param componentTid The componentTID to create the instance.
* @param entityUid The entityUID of the entity.
* @param entityRepository the reference of the entityRepository.
*/
public static createComponent(
componentTid: ComponentTID,
entityUid: EntityUID,
entityRepository: EntityRepository
) {
const thisClass = ComponentRepository;
const componentClass = thisClass.__componentClasses.get(componentTid);
if (Is.exist(componentClass)) {
// Update __component_sid_count_map
let component_sid_count =
this.__component_sid_count_map.get(componentTid);
if (Is.not.exist(component_sid_count)) {
this.__component_sid_count_map.set(componentTid, 0);
component_sid_count = Component.invalidComponentSID;
}
this.__component_sid_count_map.set(componentTid, ++component_sid_count!);
// create the component
const component = new componentClass(
entityUid,
component_sid_count!,
entityRepository
) as Component;
// register the component
if (!this.__components.has(componentTid)) {
this.__components.set(componentTid, []);
}
const array = this.__components.get(componentTid);
array![component.componentSID] = component;
return component;
} else {
throw new Error('The Component Class object is invalid.');
}
}
/**
* Get the instance of the component corresponding to the component class and componentSID.
* @param componentClass The class object to get the component.
* @param componentSid The componentSID to get the component.
*/
public static getComponent(
componentClass: typeof Component,
componentSid: ComponentSID
) {
return this.getComponentFromComponentTID(
componentClass.componentTID,
componentSid
);
}
/**
* Get the instance of the component corresponding to the componentTID and componentSID.
* @param componentTid The componentTID to get the component.
* @param componentSid The componentSID to get the component.
*/
public static getComponentFromComponentTID(
componentTid: ComponentTID,
componentSid: ComponentSID
) {
const map = this.__components.get(componentTid);
if (map != null) {
const component = map[componentSid];
if (component != null) {
return map[componentSid];
} else {
return undefined;
}
}
return undefined;
}
/**
* @internal
* Gets an array of components corresponding to the class object of the component.
* @param componentClass The class object of the component.
*/
public static _getComponents(
componentClass: typeof Component
): Array<Component> | undefined {
const components = this.__components.get(componentClass.componentTID);
return components?.filter(component => component._isAlive);
}
/**
* @internal
* Gets an array of components corresponding to the class object of the component (dead components included).
* @param componentClass The class object of the component.
*/
public static _getComponentsIncludingDead(
componentClass: typeof Component
): Array<Component> | undefined {
const components = this.__components.get(componentClass.componentTID);
return components;
}
public static getMemoryBeginIndex(componentTid: ComponentTID) {
let memoryBeginIndex = 0;
for (let i = 0; i < componentTid; i++) {
const componentClass = ComponentRepository.__componentClasses.get(i);
if (componentClass != null) {
const sizeOfComponent = (componentClass as any).sizeOfThisComponent;
const maxEntityNumber = Config.maxEntityNumber;
memoryBeginIndex += sizeOfComponent * maxEntityNumber;
}
}
return memoryBeginIndex;
}
/**
* Gets an array of components corresponding to the class object of the component.
* @param componentType The class object of the component.
*/
public static getComponentsWithType(
componentType: typeof Component
): Array<Component> {
const components = this.__components.get(componentType.componentTID);
if (components == null) {
return [];
}
return components.filter(component => component._isAlive);
}
/**
* Gets all componentTIDs.
*/
public static getComponentTIDs(): Array<ComponentTID> {
const componentTids = Array.from(this.__components.keys());
componentTids.sort((a, b) => a - b);
return componentTids;
}
}