@vworlds/vecs 1.0.15 → 1.0.16
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/README.md +249 -119
- package/dist/component.d.ts +52 -76
- package/dist/component.js +60 -45
- package/dist/component.js.map +1 -1
- package/dist/component_meta.d.ts +98 -0
- package/dist/component_meta.js +65 -0
- package/dist/component_meta.js.map +1 -0
- package/dist/dsl.d.ts +46 -34
- package/dist/dsl.js +459 -61
- package/dist/dsl.js.map +1 -1
- package/dist/entity/entity.base.d.ts +57 -0
- package/dist/entity/entity.base.js +81 -0
- package/dist/entity/entity.base.js.map +1 -0
- package/dist/entity/entity.components.d.ts +117 -0
- package/dist/entity/entity.components.js +244 -0
- package/dist/entity/entity.components.js.map +1 -0
- package/dist/entity/entity.d.ts +35 -0
- package/dist/entity/entity.identity.d.ts +8 -0
- package/dist/entity/entity.identity.js +15 -0
- package/dist/entity/entity.identity.js.map +1 -0
- package/dist/entity/entity.js +33 -0
- package/dist/entity/entity.js.map +1 -0
- package/dist/entity/entity.lifecycle.d.ts +12 -0
- package/dist/entity/entity.lifecycle.js +111 -0
- package/dist/entity/entity.lifecycle.js.map +1 -0
- package/dist/entity/entity.queries.d.ts +3 -0
- package/dist/entity/entity.queries.js +33 -0
- package/dist/entity/entity.queries.js.map +1 -0
- package/dist/entity/entity.relationships.d.ts +9 -0
- package/dist/entity/entity.relationships.js +74 -0
- package/dist/entity/entity.relationships.js.map +1 -0
- package/dist/entity/index.d.ts +2 -0
- package/dist/entity/index.js +3 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/filter.d.ts +27 -8
- package/dist/filter.js +33 -18
- package/dist/filter.js.map +1 -1
- package/dist/index.d.ts +13 -5
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/inject.d.ts +80 -0
- package/dist/inject.js +270 -0
- package/dist/inject.js.map +1 -0
- package/dist/module.d.ts +23 -0
- package/dist/module.js +17 -0
- package/dist/module.js.map +1 -0
- package/dist/modules/identity.d.ts +15 -0
- package/dist/modules/identity.js +41 -0
- package/dist/modules/identity.js.map +1 -0
- package/dist/modules/singleton.d.ts +26 -0
- package/dist/modules/singleton.js +41 -0
- package/dist/modules/singleton.js.map +1 -0
- package/dist/package.json +12 -1
- package/dist/phase.d.ts +2 -2
- package/dist/query/index.d.ts +6 -0
- package/dist/query/index.js +5 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/query.00.base.d.ts +23 -0
- package/dist/query/query.00.base.js +77 -0
- package/dist/query/query.00.base.js.map +1 -0
- package/dist/query/query.01.reactive.d.ts +7 -0
- package/dist/query/query.01.reactive.js +58 -0
- package/dist/query/query.01.reactive.js.map +1 -0
- package/dist/query/query.02.lifecycle.d.ts +6 -0
- package/dist/query/query.02.lifecycle.js +63 -0
- package/dist/query/query.02.lifecycle.js.map +1 -0
- package/dist/query/query.03.tracking.d.ts +15 -0
- package/dist/query/query.03.tracking.js +31 -0
- package/dist/query/query.03.tracking.js.map +1 -0
- package/dist/query/query.04.callbacks.d.ts +14 -0
- package/dist/query/query.04.callbacks.js +65 -0
- package/dist/query/query.04.callbacks.js.map +1 -0
- package/dist/query/query.05.updates.d.ts +14 -0
- package/dist/query/query.05.updates.js +81 -0
- package/dist/query/query.05.updates.js.map +1 -0
- package/dist/query/query.06.predicate.d.ts +13 -0
- package/dist/query/query.06.predicate.js +40 -0
- package/dist/query/query.06.predicate.js.map +1 -0
- package/dist/query/query.07.groups.d.ts +41 -0
- package/dist/query/query.07.groups.js +110 -0
- package/dist/query/query.07.groups.js.map +1 -0
- package/dist/query/query.d.ts +53 -0
- package/dist/query/query.js +138 -0
- package/dist/query/query.js.map +1 -0
- package/dist/relationship.d.ts +19 -0
- package/dist/relationship.js +18 -0
- package/dist/relationship.js.map +1 -0
- package/dist/system.d.ts +37 -23
- package/dist/system.js +80 -64
- package/dist/system.js.map +1 -1
- package/dist/terms/all_term.d.ts +32 -0
- package/dist/terms/all_term.js +41 -0
- package/dist/terms/all_term.js.map +1 -0
- package/dist/terms/any_term.d.ts +33 -0
- package/dist/terms/any_term.js +42 -0
- package/dist/terms/any_term.js.map +1 -0
- package/dist/terms/build.d.ts +62 -0
- package/dist/terms/build.js +382 -0
- package/dist/terms/build.js.map +1 -0
- package/dist/terms/component_term.d.ts +37 -0
- package/dist/terms/component_term.js +49 -0
- package/dist/terms/component_term.js.map +1 -0
- package/dist/terms/empty_term.d.ts +6 -0
- package/dist/terms/empty_term.js +12 -0
- package/dist/terms/empty_term.js.map +1 -0
- package/dist/terms/index.d.ts +11 -0
- package/dist/terms/index.js +12 -0
- package/dist/terms/index.js.map +1 -0
- package/dist/terms/not_term.d.ts +35 -0
- package/dist/terms/not_term.js +47 -0
- package/dist/terms/not_term.js.map +1 -0
- package/dist/terms/only_term.d.ts +47 -0
- package/dist/terms/only_term.js +79 -0
- package/dist/terms/only_term.js.map +1 -0
- package/dist/terms/predicate_term.d.ts +80 -0
- package/dist/terms/predicate_term.js +109 -0
- package/dist/terms/predicate_term.js.map +1 -0
- package/dist/terms/target_term.d.ts +43 -0
- package/dist/terms/target_term.js +87 -0
- package/dist/terms/target_term.js.map +1 -0
- package/dist/terms/term.d.ts +94 -0
- package/dist/terms/term.js +202 -0
- package/dist/terms/term.js.map +1 -0
- package/dist/terms/world_term.d.ts +68 -0
- package/dist/terms/world_term.js +99 -0
- package/dist/terms/world_term.js.map +1 -0
- package/dist/timer.js +2 -2
- package/dist/timer.js.map +1 -1
- package/dist/util/array_map.js +12 -0
- package/dist/util/array_map.js.map +1 -1
- package/dist/util/bitset.js +107 -22
- package/dist/util/bitset.js.map +1 -1
- package/dist/util/dense_set.d.ts +1 -0
- package/dist/util/dense_set.js +90 -0
- package/dist/util/dense_set.js.map +1 -0
- package/dist/util/id_pool.d.ts +23 -0
- package/dist/util/id_pool.js +194 -0
- package/dist/util/id_pool.js.map +1 -0
- package/dist/world/index.d.ts +3 -0
- package/dist/world/index.js +3 -0
- package/dist/world/index.js.map +1 -0
- package/dist/world/world.base.d.ts +6 -0
- package/dist/world/world.base.js +21 -0
- package/dist/world/world.base.js.map +1 -0
- package/dist/world/world.components.d.ts +67 -0
- package/dist/world/world.components.js +93 -0
- package/dist/world/world.components.js.map +1 -0
- package/dist/world/world.d.ts +29 -0
- package/dist/world/world.deferred.d.ts +13 -0
- package/dist/world/world.deferred.js +93 -0
- package/dist/world/world.deferred.js.map +1 -0
- package/dist/world/world.entities.d.ts +18 -0
- package/dist/world/world.entities.js +97 -0
- package/dist/world/world.entities.js.map +1 -0
- package/dist/world/world.js +39 -0
- package/dist/world/world.js.map +1 -0
- package/dist/world/world.modules.d.ts +12 -0
- package/dist/world/world.modules.js +21 -0
- package/dist/world/world.modules.js.map +1 -0
- package/dist/world/world.pipeline.d.ts +21 -0
- package/dist/world/world.pipeline.js +105 -0
- package/dist/world/world.pipeline.js.map +1 -0
- package/dist/world/world.pools.d.ts +9 -0
- package/dist/world/world.pools.js +59 -0
- package/dist/world/world.pools.js.map +1 -0
- package/dist/world/world.queries.d.ts +18 -0
- package/dist/world/world.queries.js +101 -0
- package/dist/world/world.queries.js.map +1 -0
- package/dist/world/world.storage.d.ts +7 -0
- package/dist/world/world.storage.js +26 -0
- package/dist/world/world.storage.js.map +1 -0
- package/package.json +12 -1
- package/dist/entity.d.ts +0 -215
- package/dist/entity.js +0 -457
- package/dist/entity.js.map +0 -1
- package/dist/query.d.ts +0 -251
- package/dist/query.js +0 -353
- package/dist/query.js.map +0 -1
- package/dist/world.d.ts +0 -389
- package/dist/world.js +0 -631
- package/dist/world.js.map +0 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Component } from "../component.js";
|
|
2
|
+
import { Entities } from "./world.entities.js";
|
|
3
|
+
const RESERVED_EID = 0;
|
|
4
|
+
export class Components extends Entities {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
/** @internal `true` once {@link start} or {@link disableComponentRegistration} has been called. */
|
|
8
|
+
this._componentRegistrationDisabled = false;
|
|
9
|
+
}
|
|
10
|
+
component(ComponentClassOrName, eid) {
|
|
11
|
+
if (typeof ComponentClassOrName === "string") {
|
|
12
|
+
const entity = this.entity(ComponentClassOrName);
|
|
13
|
+
if (!(entity instanceof Component)) {
|
|
14
|
+
throw new Error(`Entity named '${ComponentClassOrName}' is not a component entity`);
|
|
15
|
+
}
|
|
16
|
+
return entity;
|
|
17
|
+
}
|
|
18
|
+
return this._component(Component, ComponentClassOrName, eid);
|
|
19
|
+
}
|
|
20
|
+
/** Prevent any further calls to {@link component}. */
|
|
21
|
+
disableComponentRegistration() {
|
|
22
|
+
this._componentRegistrationDisabled = true;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Read the singleton data stored on the component entity for `Class`.
|
|
26
|
+
*
|
|
27
|
+
* This is a convenience shorthand for `world.component(Class).get(Class)`.
|
|
28
|
+
* Use it when you store world-global state as a component on the component
|
|
29
|
+
* entity itself (the Singleton pattern).
|
|
30
|
+
*
|
|
31
|
+
* @param Class - Registered component class.
|
|
32
|
+
* @returns The component instance stored on the component entity, or
|
|
33
|
+
* `undefined` when none has been set.
|
|
34
|
+
*/
|
|
35
|
+
get(Class) {
|
|
36
|
+
return this.component(Class).get(Class);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Attach or update the singleton data stored on the component entity for `Class`.
|
|
40
|
+
*
|
|
41
|
+
* Shorthand for `world.component(Class).set(Class, props)`. Stores `props`
|
|
42
|
+
* on the component entity itself so the data can be retrieved globally via
|
|
43
|
+
* {@link get}.
|
|
44
|
+
*
|
|
45
|
+
* @param Class - Registered component class.
|
|
46
|
+
* @param props - Properties to merge onto the component instance.
|
|
47
|
+
* @returns The `Component` entity, for chaining.
|
|
48
|
+
*/
|
|
49
|
+
set(Class, props) {
|
|
50
|
+
return this.component(Class).set(Class, props);
|
|
51
|
+
}
|
|
52
|
+
/** Declare a group of mutually exclusive components. */
|
|
53
|
+
setExclusiveComponents(...components) {
|
|
54
|
+
const metas = components.map((C) => this.entity(C).ownMeta);
|
|
55
|
+
for (let i = 0; i < metas.length; i++) {
|
|
56
|
+
metas[i]._exclusive = metas.filter((_, j) => j !== i);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** @internal Register a component-like entity in the requested id pool. */
|
|
60
|
+
_component(Constructor, ComponentClass, eid, pool = this._componentPool) {
|
|
61
|
+
if (eid === RESERVED_EID) {
|
|
62
|
+
throw new Error(`Component eid ${eid} is reserved`);
|
|
63
|
+
}
|
|
64
|
+
const existingComponent = this._classRegistry.get(ComponentClass);
|
|
65
|
+
if (existingComponent) {
|
|
66
|
+
if (eid === undefined || eid === existingComponent.eid) {
|
|
67
|
+
return existingComponent;
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Component class ${ComponentClass.name} is already registered with eid ${existingComponent.eid}`);
|
|
70
|
+
}
|
|
71
|
+
if (this._componentRegistrationDisabled) {
|
|
72
|
+
throw new Error("World component registration is disabled");
|
|
73
|
+
}
|
|
74
|
+
if (eid === undefined) {
|
|
75
|
+
eid = pool.alloc();
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
if (this._entities.has(eid)) {
|
|
79
|
+
throw new Error(`Entity id ${eid} is already taken`);
|
|
80
|
+
}
|
|
81
|
+
this._reserveEid(eid);
|
|
82
|
+
}
|
|
83
|
+
const component = new Constructor(this, eid, ComponentClass);
|
|
84
|
+
this._entities.set(eid, component);
|
|
85
|
+
this._classRegistry.set(ComponentClass, component);
|
|
86
|
+
// Component-definition entities are first-class entities: notify so any
|
|
87
|
+
// live world-rooted query/term picks them up reactively (reflection),
|
|
88
|
+
// exactly like an ordinary `world.entity()`.
|
|
89
|
+
this._notifyEntityCreated(component);
|
|
90
|
+
return component;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=world.components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.components.js","sourceRoot":"","sources":["../../src/world/world.components.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Pipeline } from "./world.pipeline.js";
|
|
2
|
+
import { type WorldOptions } from "./world.base.js";
|
|
3
|
+
/**
|
|
4
|
+
* The central ECS container. One world per game session.
|
|
5
|
+
*
|
|
6
|
+
* A `World` owns every entity, every registered component class, every
|
|
7
|
+
* registered query / system, and the update pipeline. The typical lifecycle:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Register components** — call {@link component} for every component
|
|
10
|
+
* class you plan to use.
|
|
11
|
+
* 2. **Build the pipeline** — {@link addPhase} for every named phase, then
|
|
12
|
+
* {@link system} / {@link query} for each processor.
|
|
13
|
+
* 3. **Start** — call {@link start} to freeze component registration and
|
|
14
|
+
* distribute systems into their phases.
|
|
15
|
+
* 4. **Run loop** — call {@link runPhase} per phase or {@link progress} for
|
|
16
|
+
* every phase, once per frame.
|
|
17
|
+
*
|
|
18
|
+
* ## Deferred mode
|
|
19
|
+
*
|
|
20
|
+
* The world can be in **deferred mode**, in which case entity mutations
|
|
21
|
+
* (`add` / `attach` / `set` / `remove` / `destroy` / `modified`) are
|
|
22
|
+
* queued instead of applied inline. Systems run inside an automatically
|
|
23
|
+
* deferred scope; user code can wrap arbitrary blocks with
|
|
24
|
+
* {@link beginDefer} / {@link endDefer} or {@link defer}. {@link flush}
|
|
25
|
+
* drains the queue at top level.
|
|
26
|
+
*/
|
|
27
|
+
export declare class World extends Pipeline {
|
|
28
|
+
constructor(options?: WorldOptions);
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Queries } from "./world.queries.js";
|
|
2
|
+
export declare class Deferred extends Queries {
|
|
3
|
+
/** `true` while the world is in deferred mode. */
|
|
4
|
+
get deferred(): boolean;
|
|
5
|
+
/** Enter deferred mode. */
|
|
6
|
+
beginDefer(): void;
|
|
7
|
+
/** Run `fn` inside a deferred scope. */
|
|
8
|
+
defer(fn: () => void): void;
|
|
9
|
+
/** Leave deferred mode and drain at the outermost scope. */
|
|
10
|
+
endDefer(): void;
|
|
11
|
+
/** Build pending queries and drain queued commands at the top level. */
|
|
12
|
+
flush(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Queries } from "./world.queries.js";
|
|
2
|
+
export class Deferred extends Queries {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
/** @internal Single ordered command queue used in deferred mode. */
|
|
6
|
+
this._commandQueue = [];
|
|
7
|
+
/** @internal Nested {@link beginDefer} / {@link endDefer} count. */
|
|
8
|
+
this._deferredDepth = 0;
|
|
9
|
+
/** @internal `true` while {@link _processCommandQueue} is iterating, to avoid re-entrant drains. */
|
|
10
|
+
this._draining = false;
|
|
11
|
+
}
|
|
12
|
+
/** `true` while the world is in deferred mode. */
|
|
13
|
+
get deferred() {
|
|
14
|
+
return this._deferredDepth > 0 || this._draining;
|
|
15
|
+
}
|
|
16
|
+
/** @internal Append a command to the deferred-mode queue. */
|
|
17
|
+
_enqueue(cmd) {
|
|
18
|
+
cmd.source = this._currentSource;
|
|
19
|
+
this._commandQueue.push(cmd);
|
|
20
|
+
}
|
|
21
|
+
/** Enter deferred mode. */
|
|
22
|
+
beginDefer() {
|
|
23
|
+
this._deferredDepth++;
|
|
24
|
+
}
|
|
25
|
+
/** Run `fn` inside a deferred scope. */
|
|
26
|
+
defer(fn) {
|
|
27
|
+
this.beginDefer();
|
|
28
|
+
try {
|
|
29
|
+
fn();
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
this.endDefer();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Leave deferred mode and drain at the outermost scope. */
|
|
36
|
+
endDefer() {
|
|
37
|
+
this._deferredDepth--;
|
|
38
|
+
this.flush();
|
|
39
|
+
}
|
|
40
|
+
/** Build pending queries and drain queued commands at the top level. */
|
|
41
|
+
flush() {
|
|
42
|
+
if (this._deferredDepth === 0) {
|
|
43
|
+
this._buildPendingQueries();
|
|
44
|
+
this._processCommandQueue();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** @internal Run one command's side effects. */
|
|
48
|
+
_executeCommand(cmd) {
|
|
49
|
+
this._routingSource = cmd.source;
|
|
50
|
+
switch (cmd.kind) {
|
|
51
|
+
case 0 /* CommandKind.CreateEntity */:
|
|
52
|
+
this._entities.set(cmd.entity.eid, cmd.entity);
|
|
53
|
+
this._notifyEntityCreated(cmd.entity);
|
|
54
|
+
return;
|
|
55
|
+
case 1 /* CommandKind.Set */:
|
|
56
|
+
cmd.entity._set(cmd.meta, cmd.props);
|
|
57
|
+
return;
|
|
58
|
+
case 2 /* CommandKind.Modified */:
|
|
59
|
+
cmd.entity._modified(cmd.meta);
|
|
60
|
+
return;
|
|
61
|
+
case 3 /* CommandKind.Remove */:
|
|
62
|
+
cmd.entity._remove(cmd.meta);
|
|
63
|
+
return;
|
|
64
|
+
case 4 /* CommandKind.Destroy */:
|
|
65
|
+
cmd.entity._destroy();
|
|
66
|
+
return;
|
|
67
|
+
case 5 /* CommandKind.Attach */:
|
|
68
|
+
cmd.entity._attach(cmd.meta, cmd.component);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** @internal Drain the top-level command queue in arrival order. */
|
|
73
|
+
_processCommandQueue() {
|
|
74
|
+
if (this._draining) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (this._commandQueue.length === 0) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this._draining = true;
|
|
81
|
+
try {
|
|
82
|
+
for (let i = 0; i < this._commandQueue.length; i++) {
|
|
83
|
+
this._executeCommand(this._commandQueue[i]);
|
|
84
|
+
}
|
|
85
|
+
this._commandQueue.length = 0;
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
this._routingSource = undefined;
|
|
89
|
+
this._draining = false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=world.deferred.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.deferred.js","sourceRoot":"","sources":["../../src/world/world.deferred.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ComponentRef } from "../component.js";
|
|
2
|
+
import { Entity } from "../entity/index.js";
|
|
3
|
+
import { Deferred } from "./world.deferred.js";
|
|
4
|
+
import type { World } from "./world.js";
|
|
5
|
+
export declare class Entities extends Deferred {
|
|
6
|
+
/** Return the entity with id `eid`, creating it if it does not yet exist. */
|
|
7
|
+
getOrCreateEntity(this: World, eid: number, onCreateCallback?: (e: Entity) => void): Entity;
|
|
8
|
+
/** Look up an entity by component ref or identity name. */
|
|
9
|
+
getEntity(this: World, ref: ComponentRef | string): Entity | undefined;
|
|
10
|
+
/** Create a new entity with an auto-assigned id. */
|
|
11
|
+
entity(this: World): Entity;
|
|
12
|
+
/** Look up an existing entity by identity name, creating it if absent. */
|
|
13
|
+
entity(this: World, ref: string): Entity;
|
|
14
|
+
/** Look up an existing entity by component ref. */
|
|
15
|
+
entity(this: World, ref: ComponentRef): Entity;
|
|
16
|
+
/** Destroy every entity currently tracked by the world. */
|
|
17
|
+
clearAllEntities(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Entity, Identity } from "../entity/index.js";
|
|
2
|
+
import { Deferred } from "./world.deferred.js";
|
|
3
|
+
const RESERVED_EID = 0;
|
|
4
|
+
export class Entities extends Deferred {
|
|
5
|
+
/** Return the entity with id `eid`, creating it if it does not yet exist. */
|
|
6
|
+
getOrCreateEntity(eid, onCreateCallback) {
|
|
7
|
+
if (eid === RESERVED_EID) {
|
|
8
|
+
throw new Error(`Entity eid ${eid} is reserved`);
|
|
9
|
+
}
|
|
10
|
+
let e = this._entities.get(eid);
|
|
11
|
+
if (!e) {
|
|
12
|
+
this._reserveEid(eid);
|
|
13
|
+
e = new Entity(this, eid);
|
|
14
|
+
this._entities.set(eid, e);
|
|
15
|
+
this._notifyEntityCreated(e);
|
|
16
|
+
if (onCreateCallback) {
|
|
17
|
+
onCreateCallback(e);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return e;
|
|
21
|
+
}
|
|
22
|
+
/** Look up an entity by component ref or identity name. */
|
|
23
|
+
getEntity(ref) {
|
|
24
|
+
if (typeof ref === "string") {
|
|
25
|
+
return this._identityNameIndex.get(ref);
|
|
26
|
+
}
|
|
27
|
+
if (typeof ref === "function") {
|
|
28
|
+
return this._classRegistry.get(ref);
|
|
29
|
+
}
|
|
30
|
+
if (typeof ref === "number") {
|
|
31
|
+
if (ref === RESERVED_EID) {
|
|
32
|
+
throw new Error(`Entity eid ${ref} is reserved`);
|
|
33
|
+
}
|
|
34
|
+
return this._entities.get(ref);
|
|
35
|
+
}
|
|
36
|
+
return ref.world === this && this._entities.get(ref.eid) === ref ? ref : undefined;
|
|
37
|
+
}
|
|
38
|
+
entity(ref) {
|
|
39
|
+
if (ref === undefined) {
|
|
40
|
+
return this._entity(Entity);
|
|
41
|
+
}
|
|
42
|
+
if (typeof ref === "string") {
|
|
43
|
+
let entity = this._identityNameIndex.get(ref);
|
|
44
|
+
if (entity) {
|
|
45
|
+
return entity;
|
|
46
|
+
}
|
|
47
|
+
entity = this._entity(Entity);
|
|
48
|
+
entity.set(Identity, { name: ref });
|
|
49
|
+
return entity;
|
|
50
|
+
}
|
|
51
|
+
const entity = this.getEntity(ref);
|
|
52
|
+
if (entity) {
|
|
53
|
+
return entity;
|
|
54
|
+
}
|
|
55
|
+
if (typeof ref === "function") {
|
|
56
|
+
throw new Error(`unregistered component entity for component class '${ref.name}'`);
|
|
57
|
+
}
|
|
58
|
+
if (typeof ref === "number") {
|
|
59
|
+
throw new Error(`No entity with eid ${ref}`);
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`No entity with eid ${ref.eid}`);
|
|
62
|
+
}
|
|
63
|
+
/** Destroy every entity currently tracked by the world. */
|
|
64
|
+
clearAllEntities() {
|
|
65
|
+
const pending = new Set(this._entities.values());
|
|
66
|
+
while (pending.size > 0) {
|
|
67
|
+
let destroyed = 0;
|
|
68
|
+
for (const entity of [...pending]) {
|
|
69
|
+
const instanceCount = entity.instanceCount();
|
|
70
|
+
if (instanceCount > (entity._get(entity.eid) ? 1 : 0)) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
entity.destroy();
|
|
74
|
+
pending.delete(entity);
|
|
75
|
+
destroyed++;
|
|
76
|
+
}
|
|
77
|
+
if (destroyed === 0) {
|
|
78
|
+
throw new Error("Cannot clear entities because component eids are still in use");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
this.flush();
|
|
82
|
+
}
|
|
83
|
+
/** @internal Create an entity with an id from the entity pool. */
|
|
84
|
+
_entity(Constructor) {
|
|
85
|
+
const eid = this._entityPool.alloc();
|
|
86
|
+
const e = new Constructor(this, eid);
|
|
87
|
+
if (this.deferred) {
|
|
88
|
+
this._enqueue({ kind: 0 /* CommandKind.CreateEntity */, entity: e });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this._entities.set(eid, e);
|
|
92
|
+
this._notifyEntityCreated(e);
|
|
93
|
+
}
|
|
94
|
+
return e;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=world.entities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.entities.js","sourceRoot":"","sources":["../../src/world/world.entities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CleanupPolicy } from "../component_meta.js";
|
|
2
|
+
import { Query } from "../query/index.js";
|
|
3
|
+
import { ChildOf, SilenceSource } from "../relationship.js";
|
|
4
|
+
import { System } from "../system.js";
|
|
5
|
+
import { Pipeline } from "./world.pipeline.js";
|
|
6
|
+
/**
|
|
7
|
+
* The central ECS container. One world per game session.
|
|
8
|
+
*
|
|
9
|
+
* A `World` owns every entity, every registered component class, every
|
|
10
|
+
* registered query / system, and the update pipeline. The typical lifecycle:
|
|
11
|
+
*
|
|
12
|
+
* 1. **Register components** — call {@link component} for every component
|
|
13
|
+
* class you plan to use.
|
|
14
|
+
* 2. **Build the pipeline** — {@link addPhase} for every named phase, then
|
|
15
|
+
* {@link system} / {@link query} for each processor.
|
|
16
|
+
* 3. **Start** — call {@link start} to freeze component registration and
|
|
17
|
+
* distribute systems into their phases.
|
|
18
|
+
* 4. **Run loop** — call {@link runPhase} per phase or {@link progress} for
|
|
19
|
+
* every phase, once per frame.
|
|
20
|
+
*
|
|
21
|
+
* ## Deferred mode
|
|
22
|
+
*
|
|
23
|
+
* The world can be in **deferred mode**, in which case entity mutations
|
|
24
|
+
* (`add` / `attach` / `set` / `remove` / `destroy` / `modified`) are
|
|
25
|
+
* queued instead of applied inline. Systems run inside an automatically
|
|
26
|
+
* deferred scope; user code can wrap arbitrary blocks with
|
|
27
|
+
* {@link beginDefer} / {@link endDefer} or {@link defer}. {@link flush}
|
|
28
|
+
* drains the queue at top level.
|
|
29
|
+
*/
|
|
30
|
+
export class World extends Pipeline {
|
|
31
|
+
constructor(options = {}) {
|
|
32
|
+
super(options);
|
|
33
|
+
this.component(ChildOf).ownMeta.onDeleteTarget = CleanupPolicy.Delete;
|
|
34
|
+
this.component(Query).onRemove((_entity, query) => query.destroy());
|
|
35
|
+
this.component(System).onRemove((_entity, system) => system.destroy());
|
|
36
|
+
this.component(SilenceSource).onRemove((entity) => entity.get(Query)?._clearSilence());
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=world.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.js","sourceRoot":"","sources":["../../src/world/world.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,KAAM,SAAQ,QAAQ;IACjC,YAAmB,UAAwB,EAAE;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC;QACtE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;IACzF,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Entity, type EntityClass } from "../entity/index.js";
|
|
2
|
+
import { Components } from "./world.components.js";
|
|
3
|
+
import type { WorldOptions } from "./world.base.js";
|
|
4
|
+
import type { World } from "./world.js";
|
|
5
|
+
type ModuleEntity = Entity & {
|
|
6
|
+
init(): void;
|
|
7
|
+
};
|
|
8
|
+
export declare class Modules extends Components {
|
|
9
|
+
constructor(options?: WorldOptions);
|
|
10
|
+
module<T extends ModuleEntity>(this: World, ModuleClass: EntityClass<T>, eid?: number): T;
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IdentityModule } from "../modules/identity.js";
|
|
2
|
+
import { SingletonModule } from "../modules/singleton.js";
|
|
3
|
+
import { Components } from "./world.components.js";
|
|
4
|
+
const BUILTIN_MODULES = [IdentityModule, SingletonModule];
|
|
5
|
+
export class Modules extends Components {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
super(options);
|
|
8
|
+
const world = this;
|
|
9
|
+
BUILTIN_MODULES.forEach((mod) => world.module(mod));
|
|
10
|
+
}
|
|
11
|
+
module(ModuleClass, eid) {
|
|
12
|
+
const ComponentClass = ModuleClass;
|
|
13
|
+
const isNew = !this._classRegistry.has(ComponentClass);
|
|
14
|
+
const mod = this._component(ModuleClass, ComponentClass, eid, this._modulePool);
|
|
15
|
+
if (isNew) {
|
|
16
|
+
mod.init();
|
|
17
|
+
}
|
|
18
|
+
return mod;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=world.modules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.modules.js","sourceRoot":"","sources":["../../src/world/world.modules.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAMnD,MAAM,eAAe,GAAgC,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AAEvF,MAAM,OAAO,OAAQ,SAAQ,UAAU;IACrC,YAAmB,UAAwB,EAAE;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,MAAM,KAAK,GAAG,IAAwB,CAAC;QACvC,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IAEM,MAAM,CAAsC,WAA2B,EAAE,GAAY;QAC1F,MAAM,cAAc,GAAG,WAAwC,CAAC;QAChE,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAI,WAAW,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACnF,IAAI,KAAK,EAAE,CAAC;YACV,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IPhase } from "../phase.js";
|
|
2
|
+
import { System } from "../system.js";
|
|
3
|
+
import type { WorldOptions } from "./world.base.js";
|
|
4
|
+
import { Modules } from "./world.modules.js";
|
|
5
|
+
export declare class Pipeline extends Modules {
|
|
6
|
+
constructor(options?: WorldOptions);
|
|
7
|
+
/** Add a named phase to the update pipeline. */
|
|
8
|
+
addPhase(name: string): IPhase;
|
|
9
|
+
/** Open a new frame and evaluate every registered tick source once. */
|
|
10
|
+
beginFrame(delta: number): void;
|
|
11
|
+
/** Close the current frame. */
|
|
12
|
+
endFrame(): void;
|
|
13
|
+
/** Run every phase in the pipeline in registration order. */
|
|
14
|
+
progress(now: number, delta: number): void;
|
|
15
|
+
/** Execute every system in `phase` within the current frame. */
|
|
16
|
+
runPhase(phase: IPhase, now: number, delta: number): void;
|
|
17
|
+
/** Freeze component registration and prepare the world for running. */
|
|
18
|
+
start(): void;
|
|
19
|
+
/** Create and return a new {@link System}, ready for fluent configuration. */
|
|
20
|
+
system(name: string): System;
|
|
21
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Phase } from "../phase.js";
|
|
2
|
+
import { System } from "../system.js";
|
|
3
|
+
import { ALWAYS_TICK_SOURCE } from "../timer.js";
|
|
4
|
+
import { Modules } from "./world.modules.js";
|
|
5
|
+
export class Pipeline extends Modules {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
super(options);
|
|
8
|
+
/** @internal `true` once {@link start} has prepared the phase pipeline. */
|
|
9
|
+
this._started = false;
|
|
10
|
+
/** @internal Phase name -> phase. Insertion-ordered, matches pipeline execution order. */
|
|
11
|
+
this._pipeline = new Map();
|
|
12
|
+
/** @internal World-owned tick sources evaluated once per frame. */
|
|
13
|
+
this._tickSources = new Set();
|
|
14
|
+
/** @internal Monotonic frame id used to memoize tick-source evaluation. */
|
|
15
|
+
this._frameCounter = 0;
|
|
16
|
+
this._tickSources.add(ALWAYS_TICK_SOURCE);
|
|
17
|
+
}
|
|
18
|
+
/** Add a named phase to the update pipeline. */
|
|
19
|
+
addPhase(name) {
|
|
20
|
+
const phase = new Phase(name, this);
|
|
21
|
+
this._pipeline.set(name, phase);
|
|
22
|
+
return phase;
|
|
23
|
+
}
|
|
24
|
+
/** Open a new frame and evaluate every registered tick source once. */
|
|
25
|
+
beginFrame(delta) {
|
|
26
|
+
if (this._frameInProgress) {
|
|
27
|
+
throw new Error("endFrame() not called before beginFrame()");
|
|
28
|
+
}
|
|
29
|
+
this._frameInProgress = true;
|
|
30
|
+
this._frameCounter++;
|
|
31
|
+
this.flush();
|
|
32
|
+
this._tickSources.forEach((t) => t._evalTick(delta, this._frameCounter));
|
|
33
|
+
}
|
|
34
|
+
/** Close the current frame. */
|
|
35
|
+
endFrame() {
|
|
36
|
+
if (!this._frameInProgress) {
|
|
37
|
+
throw new Error("beginFrame() not called before endFrame()");
|
|
38
|
+
}
|
|
39
|
+
this._frameInProgress = false;
|
|
40
|
+
}
|
|
41
|
+
/** Run every phase in the pipeline in registration order. */
|
|
42
|
+
progress(now, delta) {
|
|
43
|
+
this.beginFrame(delta);
|
|
44
|
+
try {
|
|
45
|
+
this._pipeline.forEach((phase) => {
|
|
46
|
+
this.runPhase(phase, now, delta);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
this.endFrame();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Execute every system in `phase` within the current frame. */
|
|
54
|
+
runPhase(phase, now, delta) {
|
|
55
|
+
if (!this._frameInProgress) {
|
|
56
|
+
throw new Error("runPhase() called outside a frame — call beginFrame() first");
|
|
57
|
+
}
|
|
58
|
+
this.flush();
|
|
59
|
+
phase.systems.forEach((s) => {
|
|
60
|
+
s._run(now, delta);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/** Freeze component registration and prepare the world for running. */
|
|
64
|
+
start() {
|
|
65
|
+
this._buildPendingQueries();
|
|
66
|
+
this._componentRegistrationDisabled = true;
|
|
67
|
+
this._started = true;
|
|
68
|
+
this._reindexSystems();
|
|
69
|
+
}
|
|
70
|
+
/** Create and return a new {@link System}, ready for fluent configuration. */
|
|
71
|
+
system(name) {
|
|
72
|
+
if (this._started) {
|
|
73
|
+
throw new Error("systems cannot be added after world start");
|
|
74
|
+
}
|
|
75
|
+
return new System(name, this);
|
|
76
|
+
}
|
|
77
|
+
/** @internal Register a tick source with this world. */
|
|
78
|
+
_registerTickSource(t) {
|
|
79
|
+
this._tickSources.add(t);
|
|
80
|
+
}
|
|
81
|
+
/** @internal Distribute every registered system into its phase's `systems` list. */
|
|
82
|
+
_reindexSystems() {
|
|
83
|
+
let _defaultPhase = this._pipeline.get("update");
|
|
84
|
+
if (!_defaultPhase) {
|
|
85
|
+
_defaultPhase = new Phase("update", this);
|
|
86
|
+
this._pipeline.set(_defaultPhase.name, _defaultPhase);
|
|
87
|
+
}
|
|
88
|
+
const defaultPhase = _defaultPhase;
|
|
89
|
+
this._pipeline.forEach((phase) => {
|
|
90
|
+
phase.systems.length = 0;
|
|
91
|
+
});
|
|
92
|
+
this._queries.forEach((q) => {
|
|
93
|
+
if (!(q instanceof System)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let phase = q._phase;
|
|
97
|
+
if (typeof phase === "string") {
|
|
98
|
+
phase = this._pipeline.get(phase);
|
|
99
|
+
}
|
|
100
|
+
phase = phase || defaultPhase;
|
|
101
|
+
phase.systems.push(q);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=world.pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.pipeline.js","sourceRoot":"","sources":["../../src/world/world.pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type IdPoolConfig } from "../util/id_pool.js";
|
|
2
|
+
import { Base, type WorldOptions } from "./world.base.js";
|
|
3
|
+
export declare const DEFAULT_POOLS: readonly IdPoolConfig[];
|
|
4
|
+
export declare class Pools extends Base {
|
|
5
|
+
constructor(options?: WorldOptions);
|
|
6
|
+
get pools(): ReadonlyArray<IdPoolConfig>;
|
|
7
|
+
/** Return the id that the named pool will allocate next without reserving it. */
|
|
8
|
+
peekNextEid(poolName: string): number;
|
|
9
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { IdPool, validateIdPoolConfigs } from "../util/id_pool.js";
|
|
2
|
+
import { Base } from "./world.base.js";
|
|
3
|
+
const RESERVED_EID = 0;
|
|
4
|
+
export const DEFAULT_POOLS = [
|
|
5
|
+
{ name: "component", min: 1, max: 899 },
|
|
6
|
+
{ name: "module", min: 900, max: 999 },
|
|
7
|
+
{ name: "entity", min: 1000 },
|
|
8
|
+
];
|
|
9
|
+
export class Pools extends Base {
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
super();
|
|
12
|
+
/** @internal Baked id pool configs for this world. */
|
|
13
|
+
this._poolConfigs = [];
|
|
14
|
+
/** @internal Runtime allocators for every configured id range. */
|
|
15
|
+
this._pools = [];
|
|
16
|
+
const idPools = options.idPools ?? DEFAULT_POOLS;
|
|
17
|
+
validateIdPoolConfigs(idPools);
|
|
18
|
+
this._poolConfigs.push(...idPools.map((pool) => ({ ...pool })));
|
|
19
|
+
this._pools.push(...this._poolConfigs.map((pool) => new IdPool(pool.name, pool.min, pool.max)));
|
|
20
|
+
this._cacheNamedPools();
|
|
21
|
+
}
|
|
22
|
+
get pools() {
|
|
23
|
+
return this._poolConfigs.map((pool) => ({ ...pool }));
|
|
24
|
+
}
|
|
25
|
+
/** Return the id that the named pool will allocate next without reserving it. */
|
|
26
|
+
peekNextEid(poolName) {
|
|
27
|
+
return this._poolByName(poolName).peek();
|
|
28
|
+
}
|
|
29
|
+
/** @internal Cache the well-known pools used by hot paths. */
|
|
30
|
+
_cacheNamedPools() {
|
|
31
|
+
this._componentPool = this._poolByName("component");
|
|
32
|
+
this._modulePool = this._poolByName("module");
|
|
33
|
+
this._entityPool = this._poolByName("entity");
|
|
34
|
+
}
|
|
35
|
+
/** @internal Look up a configured id pool by name. */
|
|
36
|
+
_poolByName(name) {
|
|
37
|
+
const pool = this._pools.find((candidate) => candidate.name === name);
|
|
38
|
+
if (!pool) {
|
|
39
|
+
throw new Error(`Unknown id pool '${name}'`);
|
|
40
|
+
}
|
|
41
|
+
return pool;
|
|
42
|
+
}
|
|
43
|
+
/** @internal Return the pool that owns `eid`. */
|
|
44
|
+
_poolFor(eid) {
|
|
45
|
+
if (eid === RESERVED_EID) {
|
|
46
|
+
throw new Error(`Eid ${eid} is reserved`);
|
|
47
|
+
}
|
|
48
|
+
const pool = this._pools.find((candidate) => candidate.owns(eid));
|
|
49
|
+
if (!pool) {
|
|
50
|
+
throw new Error(`No id pool owns eid ${eid}`);
|
|
51
|
+
}
|
|
52
|
+
return pool;
|
|
53
|
+
}
|
|
54
|
+
/** @internal Reserve an externally assigned id in its owning pool. */
|
|
55
|
+
_reserveEid(eid) {
|
|
56
|
+
this._poolFor(eid).reserve(eid);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=world.pools.js.map
|