koota 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +337 -0
- package/dist/chunk-AQ5VUG5P.js +17 -0
- package/dist/index.cjs +1266 -0
- package/dist/index.d.cts +39 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +1226 -0
- package/dist/react.cjs +111 -0
- package/dist/react.d.cts +19 -0
- package/dist/react.d.ts +19 -0
- package/dist/react.js +82 -0
- package/dist/world-BRz2NI5_.d.cts +229 -0
- package/dist/world-BRz2NI5_.d.ts +229 -0
- package/package.json +59 -0
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/react.ts
|
|
21
|
+
var react_exports = {};
|
|
22
|
+
__export(react_exports, {
|
|
23
|
+
WorldProvider: () => WorldProvider,
|
|
24
|
+
createActions: () => createActions,
|
|
25
|
+
useObserve: () => useObserve,
|
|
26
|
+
useQuery: () => useQuery,
|
|
27
|
+
useWorld: () => useWorld
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(react_exports);
|
|
30
|
+
|
|
31
|
+
// ../react/src/query/use-query.ts
|
|
32
|
+
var import_react3 = require("react");
|
|
33
|
+
|
|
34
|
+
// ../react/src/world/use-world.ts
|
|
35
|
+
var import_react2 = require("react");
|
|
36
|
+
|
|
37
|
+
// ../react/src/world/world-context.ts
|
|
38
|
+
var import_react = require("react");
|
|
39
|
+
var WorldContext = (0, import_react.createContext)(null);
|
|
40
|
+
|
|
41
|
+
// ../react/src/world/use-world.ts
|
|
42
|
+
function useWorld() {
|
|
43
|
+
const world = (0, import_react2.useContext)(WorldContext);
|
|
44
|
+
if (!world) throw new Error("Koota ECS: Hooks can only be used within the World component!");
|
|
45
|
+
return world;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ../react/src/query/use-query.ts
|
|
49
|
+
function useQuery(...parameters) {
|
|
50
|
+
const world = useWorld();
|
|
51
|
+
const [entities, setEntities] = (0, import_react3.useState)([]);
|
|
52
|
+
(0, import_react3.useEffect)(() => {
|
|
53
|
+
const unsubAdd = world.onAdd(parameters, (entity) => {
|
|
54
|
+
setEntities((v) => [...v, entity]);
|
|
55
|
+
});
|
|
56
|
+
const unsubRemove = world.onRemove(parameters, (entity) => {
|
|
57
|
+
setEntities((v) => v.filter((e) => e !== entity));
|
|
58
|
+
});
|
|
59
|
+
return () => {
|
|
60
|
+
unsubAdd();
|
|
61
|
+
unsubRemove();
|
|
62
|
+
};
|
|
63
|
+
}, [world, parameters]);
|
|
64
|
+
return entities;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ../react/src/world/world-provider.tsx
|
|
68
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
69
|
+
function WorldProvider({ children, world }) {
|
|
70
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WorldContext.Provider, { value: world, children });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ../react/src/actions/create-actions.ts
|
|
74
|
+
function createActions(actionSet) {
|
|
75
|
+
return Object.assign(
|
|
76
|
+
() => {
|
|
77
|
+
const world = useWorld();
|
|
78
|
+
return actionSet(world);
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
get: (world) => actionSet(world)
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ../react/src/trait/use-observe.tsx
|
|
87
|
+
var import_react4 = require("react");
|
|
88
|
+
function useObserve(entity, trait) {
|
|
89
|
+
const world = useWorld();
|
|
90
|
+
const [value, setValue] = (0, import_react4.useState)(() => {
|
|
91
|
+
if (entity.has(trait)) return entity.get(trait);
|
|
92
|
+
return void 0;
|
|
93
|
+
});
|
|
94
|
+
(0, import_react4.useEffect)(() => {
|
|
95
|
+
const unsub = world.onChange(trait, (e) => {
|
|
96
|
+
if (e === entity) setValue(e.get(trait));
|
|
97
|
+
});
|
|
98
|
+
return () => {
|
|
99
|
+
unsub();
|
|
100
|
+
};
|
|
101
|
+
}, [entity, trait]);
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
WorldProvider,
|
|
107
|
+
createActions,
|
|
108
|
+
useObserve,
|
|
109
|
+
useQuery,
|
|
110
|
+
useWorld
|
|
111
|
+
});
|
package/dist/react.d.cts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Q as QueryParameter, W as World, T as Trait, j as Entity, d as TraitInstanceFromSchema, E as ExtractSchema } from './world-BRz2NI5_.cjs';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
declare function useQuery(...parameters: QueryParameter[]): number[];
|
|
5
|
+
|
|
6
|
+
declare function WorldProvider({ children, world }: {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
world: World;
|
|
9
|
+
}): react_jsx_runtime.JSX.Element;
|
|
10
|
+
|
|
11
|
+
declare function useWorld(): World;
|
|
12
|
+
|
|
13
|
+
declare function createActions<T extends Record<string, (...args: any[]) => any>>(actionSet: (world: World) => T): (() => T) & {
|
|
14
|
+
get: (world: World) => T;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare function useObserve<T extends Trait>(entity: Entity, trait: T): TraitInstanceFromSchema<ExtractSchema<T>> | undefined;
|
|
18
|
+
|
|
19
|
+
export { WorldProvider, createActions, useObserve, useQuery, useWorld };
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Q as QueryParameter, W as World, T as Trait, j as Entity, d as TraitInstanceFromSchema, E as ExtractSchema } from './world-BRz2NI5_.js';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
declare function useQuery(...parameters: QueryParameter[]): number[];
|
|
5
|
+
|
|
6
|
+
declare function WorldProvider({ children, world }: {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
world: World;
|
|
9
|
+
}): react_jsx_runtime.JSX.Element;
|
|
10
|
+
|
|
11
|
+
declare function useWorld(): World;
|
|
12
|
+
|
|
13
|
+
declare function createActions<T extends Record<string, (...args: any[]) => any>>(actionSet: (world: World) => T): (() => T) & {
|
|
14
|
+
get: (world: World) => T;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare function useObserve<T extends Trait>(entity: Entity, trait: T): TraitInstanceFromSchema<ExtractSchema<T>> | undefined;
|
|
18
|
+
|
|
19
|
+
export { WorldProvider, createActions, useObserve, useQuery, useWorld };
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import "./chunk-AQ5VUG5P.js";
|
|
2
|
+
|
|
3
|
+
// ../react/src/query/use-query.ts
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
|
|
6
|
+
// ../react/src/world/use-world.ts
|
|
7
|
+
import { useContext } from "react";
|
|
8
|
+
|
|
9
|
+
// ../react/src/world/world-context.ts
|
|
10
|
+
import { createContext } from "react";
|
|
11
|
+
var WorldContext = createContext(null);
|
|
12
|
+
|
|
13
|
+
// ../react/src/world/use-world.ts
|
|
14
|
+
function useWorld() {
|
|
15
|
+
const world = useContext(WorldContext);
|
|
16
|
+
if (!world) throw new Error("Koota ECS: Hooks can only be used within the World component!");
|
|
17
|
+
return world;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ../react/src/query/use-query.ts
|
|
21
|
+
function useQuery(...parameters) {
|
|
22
|
+
const world = useWorld();
|
|
23
|
+
const [entities, setEntities] = useState([]);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const unsubAdd = world.onAdd(parameters, (entity) => {
|
|
26
|
+
setEntities((v) => [...v, entity]);
|
|
27
|
+
});
|
|
28
|
+
const unsubRemove = world.onRemove(parameters, (entity) => {
|
|
29
|
+
setEntities((v) => v.filter((e) => e !== entity));
|
|
30
|
+
});
|
|
31
|
+
return () => {
|
|
32
|
+
unsubAdd();
|
|
33
|
+
unsubRemove();
|
|
34
|
+
};
|
|
35
|
+
}, [world, parameters]);
|
|
36
|
+
return entities;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ../react/src/world/world-provider.tsx
|
|
40
|
+
import { jsx } from "react/jsx-runtime";
|
|
41
|
+
function WorldProvider({ children, world }) {
|
|
42
|
+
return /* @__PURE__ */ jsx(WorldContext.Provider, { value: world, children });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ../react/src/actions/create-actions.ts
|
|
46
|
+
function createActions(actionSet) {
|
|
47
|
+
return Object.assign(
|
|
48
|
+
() => {
|
|
49
|
+
const world = useWorld();
|
|
50
|
+
return actionSet(world);
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
get: (world) => actionSet(world)
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ../react/src/trait/use-observe.tsx
|
|
59
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
60
|
+
function useObserve(entity, trait) {
|
|
61
|
+
const world = useWorld();
|
|
62
|
+
const [value, setValue] = useState2(() => {
|
|
63
|
+
if (entity.has(trait)) return entity.get(trait);
|
|
64
|
+
return void 0;
|
|
65
|
+
});
|
|
66
|
+
useEffect2(() => {
|
|
67
|
+
const unsub = world.onChange(trait, (e) => {
|
|
68
|
+
if (e === entity) setValue(e.get(trait));
|
|
69
|
+
});
|
|
70
|
+
return () => {
|
|
71
|
+
unsub();
|
|
72
|
+
};
|
|
73
|
+
}, [entity, trait]);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
WorldProvider,
|
|
78
|
+
createActions,
|
|
79
|
+
useObserve,
|
|
80
|
+
useQuery,
|
|
81
|
+
useWorld
|
|
82
|
+
};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
declare const $internal: unique symbol;
|
|
2
|
+
|
|
3
|
+
type RelationTarget = number | string;
|
|
4
|
+
type Relation<T> = T & {
|
|
5
|
+
[$internal]: {
|
|
6
|
+
pairsMap: Map<number | string, T>;
|
|
7
|
+
createTrait: () => T;
|
|
8
|
+
exclusive: boolean;
|
|
9
|
+
autoRemoveTarget: boolean;
|
|
10
|
+
};
|
|
11
|
+
} & ((target: RelationTarget) => T);
|
|
12
|
+
|
|
13
|
+
type IsEmpty<T> = T extends Record<string, never> ? true : false;
|
|
14
|
+
|
|
15
|
+
type Trait<TSchema extends Schema = any, TStore = Store<TSchema>, TTag extends boolean = IsEmpty<TSchema>> = {
|
|
16
|
+
schema: TSchema;
|
|
17
|
+
[$internal]: {
|
|
18
|
+
set: (index: number, store: TStore, values: Partial<TraitInstanceFromSchema<TSchema>>) => void;
|
|
19
|
+
fastSet: (index: number, store: TStore, values: Partial<TraitInstanceFromSchema<TSchema>>) => void;
|
|
20
|
+
fastSetWithChangeDetection: (index: number, store: TStore, values: Partial<TraitInstanceFromSchema<TSchema>>) => boolean;
|
|
21
|
+
get: (index: number, store: TStore) => TraitInstanceFromSchema<TSchema>;
|
|
22
|
+
stores: TStore[];
|
|
23
|
+
id: number;
|
|
24
|
+
createStore: () => TStore;
|
|
25
|
+
isPairTrait: boolean;
|
|
26
|
+
relation: Relation<any> | null;
|
|
27
|
+
pairTarget: RelationTarget | null;
|
|
28
|
+
isTag: TTag;
|
|
29
|
+
};
|
|
30
|
+
} & ((params: Partial<TraitInstanceFromSchema<TSchema>>) => [Trait<TSchema, TStore>, Partial<TSchema>]);
|
|
31
|
+
type TraitTuple<T extends Trait = Trait> = [
|
|
32
|
+
T,
|
|
33
|
+
T extends Trait<infer S, any> ? Partial<TraitInstanceFromSchema<S>> : never
|
|
34
|
+
];
|
|
35
|
+
type ConfigurableTrait<T extends Trait = Trait> = T | TraitTuple<T>;
|
|
36
|
+
type TraitInstanceFromSchema<T extends Schema> = {
|
|
37
|
+
[P in keyof T]: T[P] extends (...args: any[]) => any ? ReturnType<T[P]> : T[P];
|
|
38
|
+
};
|
|
39
|
+
type TraitInstance<T extends Trait> = {
|
|
40
|
+
[P in keyof T['schema']]: T['schema'][P] extends (...args: any[]) => any ? ReturnType<T['schema'][P]> : T['schema'][P];
|
|
41
|
+
};
|
|
42
|
+
type Schema = {
|
|
43
|
+
[key: string]: number | string | boolean | any[] | object | null | undefined;
|
|
44
|
+
};
|
|
45
|
+
type Store<T extends Schema = any> = {
|
|
46
|
+
[P in keyof T]: T[P] extends (...args: any[]) => any ? ReturnType<T[P]>[] : T[P][];
|
|
47
|
+
};
|
|
48
|
+
type Norm<T extends Schema> = {
|
|
49
|
+
[K in keyof T]: T[K] extends boolean ? boolean : T[K];
|
|
50
|
+
};
|
|
51
|
+
type TraitSnapshot<T extends Trait> = T extends Trait<infer S, any> ? TraitInstanceFromSchema<S> : never;
|
|
52
|
+
type ExtractSchema<T extends Trait> = T extends Trait<infer S, any> ? S : never;
|
|
53
|
+
type ExtractStore<T extends Trait> = T extends Trait<any, infer S> ? S : never;
|
|
54
|
+
type ExtractStores<T extends [Trait, ...Trait[]]> = T extends [infer C] ? C extends Trait<any, Store<any>> ? ExtractStore<C> : never : {
|
|
55
|
+
[K in keyof T]: ExtractStore<T[K]>;
|
|
56
|
+
};
|
|
57
|
+
type IsTag<T extends Trait> = T extends Trait<any, any, infer Tag> ? Tag : false;
|
|
58
|
+
|
|
59
|
+
type Entity = number & {
|
|
60
|
+
add: (...traits: ConfigurableTrait[]) => void;
|
|
61
|
+
remove: (...traits: Trait[]) => void;
|
|
62
|
+
has: (trait: Trait) => boolean;
|
|
63
|
+
destroy: () => void;
|
|
64
|
+
changed: (trait: Trait) => void;
|
|
65
|
+
set: <T extends Trait>(trait: T, value: Partial<TraitInstanceFromSchema<ExtractSchema<T>>>, flagChanged?: boolean) => void;
|
|
66
|
+
get: <T extends Trait>(trait: T) => TraitInstanceFromSchema<ExtractSchema<T>>;
|
|
67
|
+
targetFor: <T>(relation: Relation<T>) => Entity | undefined;
|
|
68
|
+
targetsFor: <T>(relation: Relation<T>) => Entity[];
|
|
69
|
+
id: () => number;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type EntityIndex = {
|
|
73
|
+
/** The number of currently alive entities. */
|
|
74
|
+
aliveCount: number;
|
|
75
|
+
/** Array of packed entities, densely packed. */
|
|
76
|
+
dense: Entity[];
|
|
77
|
+
/** Sparse array mapping entity IDs to their index in the dense array. */
|
|
78
|
+
sparse: number[];
|
|
79
|
+
/** The highest entity ID that has been assigned. */
|
|
80
|
+
maxId: number;
|
|
81
|
+
/** The current world ID. */
|
|
82
|
+
worldId: number;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
declare class SparseSet {
|
|
86
|
+
#private;
|
|
87
|
+
has(val: number): boolean;
|
|
88
|
+
add(val: number): void;
|
|
89
|
+
remove(val: number): void;
|
|
90
|
+
clear(): void;
|
|
91
|
+
sort(): void;
|
|
92
|
+
getIndex(val: number): number;
|
|
93
|
+
get dense(): number[];
|
|
94
|
+
get sparse(): number[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
declare class ModifierData<TTrait extends Trait[] = Trait[], TType extends string = string> {
|
|
98
|
+
type: TType;
|
|
99
|
+
id: number;
|
|
100
|
+
traits: TTrait;
|
|
101
|
+
traitIds: number[];
|
|
102
|
+
constructor(type: TType, id: number, traits: TTrait);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
type QueryModifier = (...components: Trait[]) => ModifierData;
|
|
106
|
+
type QueryParameter = Trait | ReturnType<QueryModifier>;
|
|
107
|
+
type QuerySubscriber = (entity: Entity) => void;
|
|
108
|
+
type QueryResultOptions = {
|
|
109
|
+
passive?: boolean;
|
|
110
|
+
};
|
|
111
|
+
type QueryResult<T extends QueryParameter[]> = readonly Entity[] & {
|
|
112
|
+
updateEach: (callback: (state: SnapshotFromParameters<T>, entity: Entity, index: number) => void, options?: QueryResultOptions) => QueryResult<T>;
|
|
113
|
+
useStores: (callback: (stores: StoresFromParameters<T>, entities: readonly Entity[]) => void) => QueryResult<T>;
|
|
114
|
+
select<U extends QueryParameter[]>(...params: U): QueryResult<U>;
|
|
115
|
+
};
|
|
116
|
+
type UnwrapModifierData<T> = T extends ModifierData<infer C> ? C : never;
|
|
117
|
+
type StoresFromParameters<T extends QueryParameter[]> = T extends [infer First, ...infer Rest] ? [
|
|
118
|
+
...(First extends Trait ? [ExtractStore<First>] : First extends ModifierData<any> ? StoresFromParameters<UnwrapModifierData<First>> : []),
|
|
119
|
+
...(Rest extends QueryParameter[] ? StoresFromParameters<Rest> : [])
|
|
120
|
+
] : [];
|
|
121
|
+
type SnapshotFromParameters<T extends QueryParameter[]> = T extends [
|
|
122
|
+
infer First,
|
|
123
|
+
...infer Rest
|
|
124
|
+
] ? [
|
|
125
|
+
...(First extends Trait ? IsTag<First> extends false ? [TraitSnapshot<First>] : [] : First extends ModifierData<any> ? IsNotModifier<First> extends true ? [] : SnapshotFromParameters<UnwrapModifierData<First>> : []),
|
|
126
|
+
...(Rest extends QueryParameter[] ? SnapshotFromParameters<Rest> : [])
|
|
127
|
+
] : [];
|
|
128
|
+
type IsNotModifier<T> = T extends ModifierData<any, infer TType> ? TType extends 'not' ? true : false : false;
|
|
129
|
+
|
|
130
|
+
declare class Query {
|
|
131
|
+
world: World;
|
|
132
|
+
parameters: QueryParameter[];
|
|
133
|
+
hash: string;
|
|
134
|
+
traits: Trait[];
|
|
135
|
+
traitData: {
|
|
136
|
+
required: TraitData[];
|
|
137
|
+
forbidden: TraitData[];
|
|
138
|
+
or: TraitData[];
|
|
139
|
+
added: TraitData[];
|
|
140
|
+
removed: TraitData[];
|
|
141
|
+
changed: TraitData[];
|
|
142
|
+
all: TraitData[];
|
|
143
|
+
};
|
|
144
|
+
bitmasks: {
|
|
145
|
+
required: number;
|
|
146
|
+
forbidden: number;
|
|
147
|
+
or: number;
|
|
148
|
+
added: number;
|
|
149
|
+
removed: number;
|
|
150
|
+
changed: number;
|
|
151
|
+
addedTracker: number[];
|
|
152
|
+
removedTracker: number[];
|
|
153
|
+
changedTracker: number[];
|
|
154
|
+
}[];
|
|
155
|
+
generations: number[];
|
|
156
|
+
entities: SparseSet;
|
|
157
|
+
isTracking: boolean;
|
|
158
|
+
hasChangedModifiers: boolean;
|
|
159
|
+
toRemove: SparseSet;
|
|
160
|
+
addSubscriptions: Set<QuerySubscriber>;
|
|
161
|
+
removeSubscriptions: Set<QuerySubscriber>;
|
|
162
|
+
constructor(world: World, parameters?: QueryParameter[]);
|
|
163
|
+
run(world: World): Entity[];
|
|
164
|
+
add(entity: Entity): void;
|
|
165
|
+
remove(world: World, entity: Entity): void;
|
|
166
|
+
check(world: World, entity: Entity, event?: {
|
|
167
|
+
type: 'add' | 'remove' | 'change';
|
|
168
|
+
traitData: TraitData;
|
|
169
|
+
}): boolean;
|
|
170
|
+
commitRemovals(world: World): void;
|
|
171
|
+
resetTrackingBitmasks(eid: number): void;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
declare class TraitData<T extends Trait = Trait, S extends Schema = ExtractSchema<T>> {
|
|
175
|
+
generationId: number;
|
|
176
|
+
bitflag: number;
|
|
177
|
+
trait: Trait;
|
|
178
|
+
store: Store<S>;
|
|
179
|
+
queries: Set<Query>;
|
|
180
|
+
notQueries: Set<Query>;
|
|
181
|
+
schema: S;
|
|
182
|
+
changedSubscriptions: Set<(entity: Entity) => void>;
|
|
183
|
+
constructor(world: World, trait: T);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
declare class World {
|
|
187
|
+
#private;
|
|
188
|
+
[$internal]: {
|
|
189
|
+
entityIndex: EntityIndex;
|
|
190
|
+
entityMasks: number[][];
|
|
191
|
+
entityTraits: Map<number, Set<Trait>>;
|
|
192
|
+
bitflag: number;
|
|
193
|
+
traitData: Map<Trait, TraitData<Trait, any>>;
|
|
194
|
+
queries: Set<Query>;
|
|
195
|
+
queriesHashMap: Map<string, Query>;
|
|
196
|
+
notQueries: Set<Query>;
|
|
197
|
+
dirtyQueries: Set<Query>;
|
|
198
|
+
relationTargetEntities: Set<RelationTarget>;
|
|
199
|
+
dirtyMasks: Map<number, number[][]>;
|
|
200
|
+
trackingSnapshots: Map<number, number[][]>;
|
|
201
|
+
changedMasks: Map<number, number[][]>;
|
|
202
|
+
worldEntity: Entity;
|
|
203
|
+
};
|
|
204
|
+
get id(): number;
|
|
205
|
+
get isInitialized(): boolean;
|
|
206
|
+
get entities(): Entity[];
|
|
207
|
+
traits: Set<Trait>;
|
|
208
|
+
constructor(...traits: ConfigurableTrait[]);
|
|
209
|
+
init(...traits: ConfigurableTrait[]): void;
|
|
210
|
+
spawn(...traits: ConfigurableTrait[]): Entity;
|
|
211
|
+
has(entity: Entity): boolean;
|
|
212
|
+
has(trait: Trait): boolean;
|
|
213
|
+
add(...traits: ConfigurableTrait[]): void;
|
|
214
|
+
remove(...traits: Trait[]): void;
|
|
215
|
+
get<T extends Trait>(trait: T): TraitInstanceFromSchema<ExtractSchema<T>>;
|
|
216
|
+
set<T extends Trait>(trait: T, value: Partial<TraitInstanceFromSchema<ExtractSchema<T>>>): void;
|
|
217
|
+
destroy(): void;
|
|
218
|
+
reset(): void;
|
|
219
|
+
query<T extends QueryParameter[]>(key: string): QueryResult<T>;
|
|
220
|
+
query<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
|
|
221
|
+
queryFirst(key: string): Entity | undefined;
|
|
222
|
+
queryFirst(...parameters: QueryParameter[]): Entity | undefined;
|
|
223
|
+
onAdd(parameters: QueryParameter[], callback: (entity: Entity) => void): () => boolean;
|
|
224
|
+
onRemove(parameters: QueryParameter[], callback: (entity: Entity) => void): () => boolean;
|
|
225
|
+
onChange(trait: Trait, callback: (entity: Entity) => void): () => boolean;
|
|
226
|
+
}
|
|
227
|
+
declare function createWorld(...traits: ConfigurableTrait[]): World;
|
|
228
|
+
|
|
229
|
+
export { $internal as $, type ConfigurableTrait as C, type ExtractSchema as E, type IsTag as I, ModifierData as M, type Norm as N, type QueryParameter as Q, type Relation as R, type Schema as S, type Trait as T, World as W, type RelationTarget as a, type TraitTuple as b, createWorld as c, type TraitInstanceFromSchema as d, type TraitInstance as e, type Store as f, type TraitSnapshot as g, type ExtractStore as h, type ExtractStores as i, type Entity as j, type QueryModifier as k, type QuerySubscriber as l, type QueryResultOptions as m, type QueryResult as n, type StoresFromParameters as o, type SnapshotFromParameters as p, type IsNotModifier as q };
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
declare const $internal: unique symbol;
|
|
2
|
+
|
|
3
|
+
type RelationTarget = number | string;
|
|
4
|
+
type Relation<T> = T & {
|
|
5
|
+
[$internal]: {
|
|
6
|
+
pairsMap: Map<number | string, T>;
|
|
7
|
+
createTrait: () => T;
|
|
8
|
+
exclusive: boolean;
|
|
9
|
+
autoRemoveTarget: boolean;
|
|
10
|
+
};
|
|
11
|
+
} & ((target: RelationTarget) => T);
|
|
12
|
+
|
|
13
|
+
type IsEmpty<T> = T extends Record<string, never> ? true : false;
|
|
14
|
+
|
|
15
|
+
type Trait<TSchema extends Schema = any, TStore = Store<TSchema>, TTag extends boolean = IsEmpty<TSchema>> = {
|
|
16
|
+
schema: TSchema;
|
|
17
|
+
[$internal]: {
|
|
18
|
+
set: (index: number, store: TStore, values: Partial<TraitInstanceFromSchema<TSchema>>) => void;
|
|
19
|
+
fastSet: (index: number, store: TStore, values: Partial<TraitInstanceFromSchema<TSchema>>) => void;
|
|
20
|
+
fastSetWithChangeDetection: (index: number, store: TStore, values: Partial<TraitInstanceFromSchema<TSchema>>) => boolean;
|
|
21
|
+
get: (index: number, store: TStore) => TraitInstanceFromSchema<TSchema>;
|
|
22
|
+
stores: TStore[];
|
|
23
|
+
id: number;
|
|
24
|
+
createStore: () => TStore;
|
|
25
|
+
isPairTrait: boolean;
|
|
26
|
+
relation: Relation<any> | null;
|
|
27
|
+
pairTarget: RelationTarget | null;
|
|
28
|
+
isTag: TTag;
|
|
29
|
+
};
|
|
30
|
+
} & ((params: Partial<TraitInstanceFromSchema<TSchema>>) => [Trait<TSchema, TStore>, Partial<TSchema>]);
|
|
31
|
+
type TraitTuple<T extends Trait = Trait> = [
|
|
32
|
+
T,
|
|
33
|
+
T extends Trait<infer S, any> ? Partial<TraitInstanceFromSchema<S>> : never
|
|
34
|
+
];
|
|
35
|
+
type ConfigurableTrait<T extends Trait = Trait> = T | TraitTuple<T>;
|
|
36
|
+
type TraitInstanceFromSchema<T extends Schema> = {
|
|
37
|
+
[P in keyof T]: T[P] extends (...args: any[]) => any ? ReturnType<T[P]> : T[P];
|
|
38
|
+
};
|
|
39
|
+
type TraitInstance<T extends Trait> = {
|
|
40
|
+
[P in keyof T['schema']]: T['schema'][P] extends (...args: any[]) => any ? ReturnType<T['schema'][P]> : T['schema'][P];
|
|
41
|
+
};
|
|
42
|
+
type Schema = {
|
|
43
|
+
[key: string]: number | string | boolean | any[] | object | null | undefined;
|
|
44
|
+
};
|
|
45
|
+
type Store<T extends Schema = any> = {
|
|
46
|
+
[P in keyof T]: T[P] extends (...args: any[]) => any ? ReturnType<T[P]>[] : T[P][];
|
|
47
|
+
};
|
|
48
|
+
type Norm<T extends Schema> = {
|
|
49
|
+
[K in keyof T]: T[K] extends boolean ? boolean : T[K];
|
|
50
|
+
};
|
|
51
|
+
type TraitSnapshot<T extends Trait> = T extends Trait<infer S, any> ? TraitInstanceFromSchema<S> : never;
|
|
52
|
+
type ExtractSchema<T extends Trait> = T extends Trait<infer S, any> ? S : never;
|
|
53
|
+
type ExtractStore<T extends Trait> = T extends Trait<any, infer S> ? S : never;
|
|
54
|
+
type ExtractStores<T extends [Trait, ...Trait[]]> = T extends [infer C] ? C extends Trait<any, Store<any>> ? ExtractStore<C> : never : {
|
|
55
|
+
[K in keyof T]: ExtractStore<T[K]>;
|
|
56
|
+
};
|
|
57
|
+
type IsTag<T extends Trait> = T extends Trait<any, any, infer Tag> ? Tag : false;
|
|
58
|
+
|
|
59
|
+
type Entity = number & {
|
|
60
|
+
add: (...traits: ConfigurableTrait[]) => void;
|
|
61
|
+
remove: (...traits: Trait[]) => void;
|
|
62
|
+
has: (trait: Trait) => boolean;
|
|
63
|
+
destroy: () => void;
|
|
64
|
+
changed: (trait: Trait) => void;
|
|
65
|
+
set: <T extends Trait>(trait: T, value: Partial<TraitInstanceFromSchema<ExtractSchema<T>>>, flagChanged?: boolean) => void;
|
|
66
|
+
get: <T extends Trait>(trait: T) => TraitInstanceFromSchema<ExtractSchema<T>>;
|
|
67
|
+
targetFor: <T>(relation: Relation<T>) => Entity | undefined;
|
|
68
|
+
targetsFor: <T>(relation: Relation<T>) => Entity[];
|
|
69
|
+
id: () => number;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type EntityIndex = {
|
|
73
|
+
/** The number of currently alive entities. */
|
|
74
|
+
aliveCount: number;
|
|
75
|
+
/** Array of packed entities, densely packed. */
|
|
76
|
+
dense: Entity[];
|
|
77
|
+
/** Sparse array mapping entity IDs to their index in the dense array. */
|
|
78
|
+
sparse: number[];
|
|
79
|
+
/** The highest entity ID that has been assigned. */
|
|
80
|
+
maxId: number;
|
|
81
|
+
/** The current world ID. */
|
|
82
|
+
worldId: number;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
declare class SparseSet {
|
|
86
|
+
#private;
|
|
87
|
+
has(val: number): boolean;
|
|
88
|
+
add(val: number): void;
|
|
89
|
+
remove(val: number): void;
|
|
90
|
+
clear(): void;
|
|
91
|
+
sort(): void;
|
|
92
|
+
getIndex(val: number): number;
|
|
93
|
+
get dense(): number[];
|
|
94
|
+
get sparse(): number[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
declare class ModifierData<TTrait extends Trait[] = Trait[], TType extends string = string> {
|
|
98
|
+
type: TType;
|
|
99
|
+
id: number;
|
|
100
|
+
traits: TTrait;
|
|
101
|
+
traitIds: number[];
|
|
102
|
+
constructor(type: TType, id: number, traits: TTrait);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
type QueryModifier = (...components: Trait[]) => ModifierData;
|
|
106
|
+
type QueryParameter = Trait | ReturnType<QueryModifier>;
|
|
107
|
+
type QuerySubscriber = (entity: Entity) => void;
|
|
108
|
+
type QueryResultOptions = {
|
|
109
|
+
passive?: boolean;
|
|
110
|
+
};
|
|
111
|
+
type QueryResult<T extends QueryParameter[]> = readonly Entity[] & {
|
|
112
|
+
updateEach: (callback: (state: SnapshotFromParameters<T>, entity: Entity, index: number) => void, options?: QueryResultOptions) => QueryResult<T>;
|
|
113
|
+
useStores: (callback: (stores: StoresFromParameters<T>, entities: readonly Entity[]) => void) => QueryResult<T>;
|
|
114
|
+
select<U extends QueryParameter[]>(...params: U): QueryResult<U>;
|
|
115
|
+
};
|
|
116
|
+
type UnwrapModifierData<T> = T extends ModifierData<infer C> ? C : never;
|
|
117
|
+
type StoresFromParameters<T extends QueryParameter[]> = T extends [infer First, ...infer Rest] ? [
|
|
118
|
+
...(First extends Trait ? [ExtractStore<First>] : First extends ModifierData<any> ? StoresFromParameters<UnwrapModifierData<First>> : []),
|
|
119
|
+
...(Rest extends QueryParameter[] ? StoresFromParameters<Rest> : [])
|
|
120
|
+
] : [];
|
|
121
|
+
type SnapshotFromParameters<T extends QueryParameter[]> = T extends [
|
|
122
|
+
infer First,
|
|
123
|
+
...infer Rest
|
|
124
|
+
] ? [
|
|
125
|
+
...(First extends Trait ? IsTag<First> extends false ? [TraitSnapshot<First>] : [] : First extends ModifierData<any> ? IsNotModifier<First> extends true ? [] : SnapshotFromParameters<UnwrapModifierData<First>> : []),
|
|
126
|
+
...(Rest extends QueryParameter[] ? SnapshotFromParameters<Rest> : [])
|
|
127
|
+
] : [];
|
|
128
|
+
type IsNotModifier<T> = T extends ModifierData<any, infer TType> ? TType extends 'not' ? true : false : false;
|
|
129
|
+
|
|
130
|
+
declare class Query {
|
|
131
|
+
world: World;
|
|
132
|
+
parameters: QueryParameter[];
|
|
133
|
+
hash: string;
|
|
134
|
+
traits: Trait[];
|
|
135
|
+
traitData: {
|
|
136
|
+
required: TraitData[];
|
|
137
|
+
forbidden: TraitData[];
|
|
138
|
+
or: TraitData[];
|
|
139
|
+
added: TraitData[];
|
|
140
|
+
removed: TraitData[];
|
|
141
|
+
changed: TraitData[];
|
|
142
|
+
all: TraitData[];
|
|
143
|
+
};
|
|
144
|
+
bitmasks: {
|
|
145
|
+
required: number;
|
|
146
|
+
forbidden: number;
|
|
147
|
+
or: number;
|
|
148
|
+
added: number;
|
|
149
|
+
removed: number;
|
|
150
|
+
changed: number;
|
|
151
|
+
addedTracker: number[];
|
|
152
|
+
removedTracker: number[];
|
|
153
|
+
changedTracker: number[];
|
|
154
|
+
}[];
|
|
155
|
+
generations: number[];
|
|
156
|
+
entities: SparseSet;
|
|
157
|
+
isTracking: boolean;
|
|
158
|
+
hasChangedModifiers: boolean;
|
|
159
|
+
toRemove: SparseSet;
|
|
160
|
+
addSubscriptions: Set<QuerySubscriber>;
|
|
161
|
+
removeSubscriptions: Set<QuerySubscriber>;
|
|
162
|
+
constructor(world: World, parameters?: QueryParameter[]);
|
|
163
|
+
run(world: World): Entity[];
|
|
164
|
+
add(entity: Entity): void;
|
|
165
|
+
remove(world: World, entity: Entity): void;
|
|
166
|
+
check(world: World, entity: Entity, event?: {
|
|
167
|
+
type: 'add' | 'remove' | 'change';
|
|
168
|
+
traitData: TraitData;
|
|
169
|
+
}): boolean;
|
|
170
|
+
commitRemovals(world: World): void;
|
|
171
|
+
resetTrackingBitmasks(eid: number): void;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
declare class TraitData<T extends Trait = Trait, S extends Schema = ExtractSchema<T>> {
|
|
175
|
+
generationId: number;
|
|
176
|
+
bitflag: number;
|
|
177
|
+
trait: Trait;
|
|
178
|
+
store: Store<S>;
|
|
179
|
+
queries: Set<Query>;
|
|
180
|
+
notQueries: Set<Query>;
|
|
181
|
+
schema: S;
|
|
182
|
+
changedSubscriptions: Set<(entity: Entity) => void>;
|
|
183
|
+
constructor(world: World, trait: T);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
declare class World {
|
|
187
|
+
#private;
|
|
188
|
+
[$internal]: {
|
|
189
|
+
entityIndex: EntityIndex;
|
|
190
|
+
entityMasks: number[][];
|
|
191
|
+
entityTraits: Map<number, Set<Trait>>;
|
|
192
|
+
bitflag: number;
|
|
193
|
+
traitData: Map<Trait, TraitData<Trait, any>>;
|
|
194
|
+
queries: Set<Query>;
|
|
195
|
+
queriesHashMap: Map<string, Query>;
|
|
196
|
+
notQueries: Set<Query>;
|
|
197
|
+
dirtyQueries: Set<Query>;
|
|
198
|
+
relationTargetEntities: Set<RelationTarget>;
|
|
199
|
+
dirtyMasks: Map<number, number[][]>;
|
|
200
|
+
trackingSnapshots: Map<number, number[][]>;
|
|
201
|
+
changedMasks: Map<number, number[][]>;
|
|
202
|
+
worldEntity: Entity;
|
|
203
|
+
};
|
|
204
|
+
get id(): number;
|
|
205
|
+
get isInitialized(): boolean;
|
|
206
|
+
get entities(): Entity[];
|
|
207
|
+
traits: Set<Trait>;
|
|
208
|
+
constructor(...traits: ConfigurableTrait[]);
|
|
209
|
+
init(...traits: ConfigurableTrait[]): void;
|
|
210
|
+
spawn(...traits: ConfigurableTrait[]): Entity;
|
|
211
|
+
has(entity: Entity): boolean;
|
|
212
|
+
has(trait: Trait): boolean;
|
|
213
|
+
add(...traits: ConfigurableTrait[]): void;
|
|
214
|
+
remove(...traits: Trait[]): void;
|
|
215
|
+
get<T extends Trait>(trait: T): TraitInstanceFromSchema<ExtractSchema<T>>;
|
|
216
|
+
set<T extends Trait>(trait: T, value: Partial<TraitInstanceFromSchema<ExtractSchema<T>>>): void;
|
|
217
|
+
destroy(): void;
|
|
218
|
+
reset(): void;
|
|
219
|
+
query<T extends QueryParameter[]>(key: string): QueryResult<T>;
|
|
220
|
+
query<T extends QueryParameter[]>(...parameters: T): QueryResult<T>;
|
|
221
|
+
queryFirst(key: string): Entity | undefined;
|
|
222
|
+
queryFirst(...parameters: QueryParameter[]): Entity | undefined;
|
|
223
|
+
onAdd(parameters: QueryParameter[], callback: (entity: Entity) => void): () => boolean;
|
|
224
|
+
onRemove(parameters: QueryParameter[], callback: (entity: Entity) => void): () => boolean;
|
|
225
|
+
onChange(trait: Trait, callback: (entity: Entity) => void): () => boolean;
|
|
226
|
+
}
|
|
227
|
+
declare function createWorld(...traits: ConfigurableTrait[]): World;
|
|
228
|
+
|
|
229
|
+
export { $internal as $, type ConfigurableTrait as C, type ExtractSchema as E, type IsTag as I, ModifierData as M, type Norm as N, type QueryParameter as Q, type Relation as R, type Schema as S, type Trait as T, World as W, type RelationTarget as a, type TraitTuple as b, createWorld as c, type TraitInstanceFromSchema as d, type TraitInstance as e, type Store as f, type TraitSnapshot as g, type ExtractStore as h, type ExtractStores as i, type Entity as j, type QueryModifier as k, type QuerySubscriber as l, type QueryResultOptions as m, type QueryResult as n, type StoresFromParameters as o, type SnapshotFromParameters as p, type IsNotModifier as q };
|