Skip to content

Commit 38eb9a6

Browse files
authored
refactor: no-type mode change to IComp (#8)
1 parent f53286b commit 38eb9a6

14 files changed

+473
-404
lines changed

.husky/commit-msg

100644100755
File mode changed.

.husky/pre-commit

100644100755
File mode changed.

src/array-map.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
export class ArrayMap<k extends string | number, v> {
2+
private _name2indexRecord: Record<k, number>;
3+
private _values: v[];
4+
5+
constructor(source?: [k, v][]) {
6+
this._name2indexRecord = Object.create(null) as Record<k, number>;
7+
this._values = [];
8+
if (source != null) {
9+
this._values.length = source.length;
10+
for (let i = 0, len = source.length; i < len; i++) {
11+
let [key, value] = source[i];
12+
this._name2indexRecord[key] = i;
13+
this._values[i] = value;
14+
}
15+
}
16+
}
17+
18+
get(key: k): v | null {
19+
const idx = this.getIndex(key);
20+
if (idx > -1) {
21+
return this._values[idx];
22+
}
23+
return null;
24+
}
25+
26+
getIndex(key: k): number {
27+
return this._name2indexRecord[key] ?? -1;
28+
}
29+
30+
getByIndex(index: number): v | null {
31+
return this._values[index];
32+
}
33+
34+
has(key: k): boolean {
35+
return (this._name2indexRecord[key] ?? -1) > -1;
36+
}
37+
38+
set(key: k, value: v) {
39+
let index = this._name2indexRecord[key];
40+
if (index == null) {
41+
index = this._values.length;
42+
this._name2indexRecord[key] = index;
43+
}
44+
this._values[index] = value;
45+
return index;
46+
}
47+
48+
delete(key: k): [v | null, number] {
49+
const index = this.getIndex(key);
50+
if (index < 0) {
51+
return [null, -1];
52+
}
53+
return [this._values[index], index];
54+
}
55+
56+
clear() {
57+
this._name2indexRecord = Object.create(null);
58+
this._values.length = 0;
59+
}
60+
61+
get values(): v[] {
62+
return Array.from(this._values);
63+
}
64+
65+
get readonlyValues(): readonly v[] {
66+
return this._values;
67+
}
68+
}

src/base.ts

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { ISchema } from "./component-variable";
2+
import type { Domain } from "./domain";
3+
import { compName2ctr } from "./global-record";
4+
import { NULL_NUM } from "./macro";
5+
6+
class ComponentHasNotDecorated extends Error {}
7+
export abstract class IComp {
8+
private _entity?: Entity | null;
9+
get entity() {
10+
return this._entity!;
11+
}
12+
init?(domain: Domain, compIdx: number): void;
13+
update?(domain: Domain, compIdx: number): void;
14+
fixedUpdate?(domain: Domain, compIdx: number): void;
15+
destroy?(domain: Domain, compIdx: number): void;
16+
}
17+
/**
18+
* The unit in a network.It can manager some component.
19+
* It include id and version, plz don't modify then if you are not undersanding!
20+
* It is sealed, PLZ NOT implement!!!
21+
* @example
22+
```js
23+
// Must do decoration
24+
@NetComp
25+
class ViewComponent {
26+
@Param(DataType.bool)
27+
active = false
28+
}
29+
const ent = new Entity();
30+
ent.add(ViewComponent);
31+
ent.has(ViewComponent);
32+
ent.get(ViewComponent);
33+
Domain.ref(ent);
34+
ent.rm(ViewComponent);
35+
```
36+
*/
37+
export class Entity<ProxyObj extends Object = any> {
38+
private _id = NULL_NUM;
39+
get id() {
40+
return this._id;
41+
}
42+
private _version = NULL_NUM;
43+
get version() {
44+
return this._version;
45+
}
46+
static Event = {
47+
REG_ENTITY: "reg-entity",
48+
UNREG_ENTITY: "unreg-entity",
49+
};
50+
51+
$comps = new Proxy<ProxyObj>(this as any, {
52+
get(target: any, p, receiver) {
53+
return target.get(compName2ctr[String(p)]);
54+
},
55+
});
56+
57+
private readonly _compMap: Map<number, IComp | IComp[]>;
58+
private readonly _comps: IComp[];
59+
get comps(): readonly IComp[] {
60+
return this._comps;
61+
}
62+
63+
constructor(..._comps: IComp[]) {
64+
this._comps = _comps;
65+
const map = new Map();
66+
for (let i = 0, len = this._comps.length; i < len; i++) {
67+
let c = this._comps[i] as ISchema & IComp;
68+
c["_entity"] = this;
69+
if (!c.__schema__ || c.__schema__.hash == NULL_NUM) {
70+
throw new ComponentHasNotDecorated(
71+
"Component must use @NetComp"
72+
);
73+
}
74+
const hash = c.__schema__.hash;
75+
if (map.has(hash)) {
76+
map.set(hash, [map.get(hash), c]);
77+
} else {
78+
map.set(hash, c);
79+
}
80+
}
81+
this._compMap = map;
82+
}
83+
84+
toString() {
85+
return `Entity: id=${this._id},version=${this._version}`;
86+
}
87+
88+
get<T extends IComp>(ctr: { new (): T }): T | null {
89+
const schema = ctr.prototype.__schema__;
90+
if (!(schema && schema.name)) {
91+
console.error("Componrnt must use @NetComp");
92+
return null;
93+
}
94+
95+
if (!this._compMap.has(schema.hash)) return null;
96+
const insOrArr = this._compMap.get(schema.hash)!;
97+
if (!Array.isArray(insOrArr)) return insOrArr as T;
98+
return insOrArr[insOrArr.length - 1] as T;
99+
}
100+
101+
mget<T extends IComp>(ctr: { new (): T }): T[] {
102+
const schema = ctr.prototype.__schema__;
103+
if (!(schema && schema.name)) {
104+
console.error("Componrnt must use @NetComp");
105+
return [];
106+
}
107+
108+
return (this._compMap.get(schema.hash) as T[]) ?? [];
109+
}
110+
111+
has(ctr: { new (): any }): boolean {
112+
const schema = ctr.prototype.__schema__;
113+
if (!(schema && schema.name)) {
114+
console.error("Componrnt must use @NetComp");
115+
return false;
116+
}
117+
return this._compMap.has(schema.hash);
118+
}
119+
120+
indexOf(ins: IComp) {
121+
if (ins == null) return -1;
122+
return this._comps.indexOf(ins);
123+
}
124+
125+
private _init(domain: Domain) {
126+
for (let i = 0, len = this._comps.length; i < len; i++) {
127+
const c = this._comps[i];
128+
c.init && c.init(domain, i);
129+
}
130+
}
131+
132+
private _update(domain: Domain) {
133+
for (let i = 0, len = this._comps.length; i < len; i++) {
134+
const c = this._comps[i];
135+
c.update && c.update(domain, i);
136+
}
137+
}
138+
139+
private _fixedUpdate(domain: Domain) {
140+
for (let i = 0, len = this._comps.length; i < len; i++) {
141+
const c = this._comps[i];
142+
c.fixedUpdate && c.fixedUpdate(domain, i);
143+
}
144+
}
145+
146+
private _destroy(domain: Domain) {
147+
for (let i = 0, len = this._comps.length; i < len; i++) {
148+
const c = this._comps[i];
149+
c.destroy && c.destroy(domain, i);
150+
c["_entity"] = null;
151+
}
152+
this._comps.length = 0;
153+
this._compMap.clear();
154+
}
155+
}

src/component-rpc.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import {
2-
ComponentConstructor,
32
DataType,
43
DataTypeVoid,
54
genMethodSchema,
6-
genSchema,
75
getOrCreateScheme,
86
RpcType,
97
} from "./component-schema";
8+
import { hash2RpcName } from "./global-record";
109
import { str as hash } from "./lib/crc-32";
1110

12-
export const hash2RpcName = {} as Record<number, string>;
1311
export class Crc32PropertyKeyHashConflict extends Error {}
1412
export function Rpc<RpcReturnType extends void | DataType = void>(
1513
type: RpcType,

src/component-variable.ts

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { Entity } from "./entity";
2-
import { NULL_NUM, NULL_STR } from "./macro";
31
import { ProtoOf } from "./misc";
42
import { str as hash } from "./lib/crc-32";
53
import { IDataBufferReader, IDatabufferWriter } from "./data/serializable";
@@ -14,6 +12,9 @@ import {
1412
getOrCreateScheme,
1513
SCHEME_KEY,
1614
} from "./component-schema";
15+
import { Domain } from "./domain";
16+
import { IComp } from "./base";
17+
import { hash2compName, compName2ctr } from "./global-record";
1718

1819
class WhyPropertyKeyHasTheSameError extends Error {}
1920
function sortComponentPropertyKey(a: PropSchema, b: PropSchema): number {
@@ -23,11 +24,6 @@ function sortComponentPropertyKey(a: PropSchema, b: PropSchema): number {
2324
return akey > bkey ? 1 : -1;
2425
}
2526

26-
export const hash2compName: Record<number, string> = Object.create(null);
27-
export const compName2ctr: Record<string, { new (): any }> = Object.create(
28-
null
29-
);
30-
3127
export function NetComp(name: string, genSerable = true) {
3228
return function <T>(target: { new (): T }) {
3329
const s = getOrCreateScheme(target.prototype);
@@ -78,8 +74,7 @@ type DataTypeMappingPrimitive = {
7874
[DataType.STRING]: string;
7975
};
8076

81-
export type SchemaClass<T> = T & { [SCHEME_KEY]: Schema };
82-
77+
export type ISchema = { [SCHEME_KEY]: Schema };
8378
export function NetVar<DT extends number, R>(type: DT | { new (): R }) {
8479
return function <PK extends string | symbol>(
8580
t: ProtoOf<Record<PK, DataTypeMappingPrimitive[DT] & R>>,
@@ -116,19 +111,11 @@ export function NetArr<DT extends number, R>(type: DT | { new (): R }) {
116111
};
117112
}
118113

119-
// export type ComponentType
120-
121-
export interface IComponent {
122-
entity: Entity;
123-
index: number;
124-
[SCHEME_KEY]: Readonly<Schema>;
125-
}
126-
127114
export function fixupSerable<T extends Record<string, any>>(target: {
128115
new (): T;
129116
}) {
130117
target.prototype.ser = function (
131-
this: SchemaClass<T>,
118+
this: ISchema & Record<string, any>,
132119
buffer: IDatabufferWriter
133120
) {
134121
const schema = this[SCHEME_KEY];
@@ -186,7 +173,7 @@ export function fixupSerable<T extends Record<string, any>>(target: {
186173
}
187174
};
188175
target.prototype.deser = function (
189-
this: SchemaClass<T>,
176+
this: ISchema & Record<string, any>,
190177
buffer: IDataBufferReader
191178
) {
192179
const schema = this[SCHEME_KEY];
@@ -451,9 +438,15 @@ export function fixedupSerableRpc(prototype: any, schema: Schema) {
451438

452439
const privateName = "__" + name + "__";
453440
prototype[privateName] = prototype[name];
454-
prototype[name] = function (...args: any[]) {
455-
const ent = this.entity as Entity;
456-
const domain = ent.domain!;
441+
prototype[name] = function (
442+
this: IComp & ISchema & Record<string, Function>,
443+
...args: any[]
444+
) {
445+
const domain = Domain.GetByEntity(this.entity);
446+
if (domain == null) {
447+
console.warn("Domain is not valid!");
448+
return;
449+
}
457450
if (domain.type == ms.type) {
458451
this[privateName](...args);
459452
} else {

0 commit comments

Comments
 (0)