murow 0.0.73 → 0.1.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/README.md +15 -1
- package/dist/cjs/core/binary-codec/binary-codec.js +1 -1
- package/dist/cjs/core/clock/clock.js +1 -0
- package/dist/cjs/core/clock/index.js +1 -0
- package/dist/cjs/core/driver/driver.js +1 -1
- package/dist/cjs/core/driver/drivers/immediate.js +1 -1
- package/dist/cjs/core/driver/drivers/raf.js +1 -1
- package/dist/cjs/core/driver/drivers/timeout.js +1 -1
- package/dist/cjs/core/hitbox/hitbox-library.js +1 -0
- package/dist/cjs/core/hitbox/hitbox.js +1 -0
- package/dist/cjs/core/hitbox/index.js +1 -0
- package/dist/cjs/core/hitbox/test.js +1 -0
- package/dist/cjs/core/index.js +1 -1
- package/dist/cjs/core/input/index.js +1 -1
- package/dist/cjs/core/input/mouse-look/index.js +1 -0
- package/dist/cjs/core/input/mouse-look/mouse-look.js +1 -0
- package/dist/cjs/core/input/scroll-zoom/index.js +1 -0
- package/dist/cjs/core/input/scroll-zoom/scroll-zoom.js +1 -0
- package/dist/cjs/core/prediction/prediction.js +1 -1
- package/dist/cjs/core/ray/ray-3d.js +1 -1
- package/dist/cjs/core/raycast/hit-buffer.js +1 -0
- package/dist/cjs/core/raycast/index.js +1 -0
- package/dist/cjs/core/raycast/raycaster.js +1 -0
- package/dist/cjs/core/slot-map/index.js +1 -0
- package/dist/cjs/core/slot-map/slot-map.js +1 -0
- package/dist/cjs/core/state-machine/index.js +1 -0
- package/dist/cjs/core/state-machine/state-machine.js +1 -0
- package/dist/cjs/core/timeline/index.js +1 -0
- package/dist/cjs/core/timeline/timeline.js +1 -0
- package/dist/cjs/ecs/component.js +1 -1
- package/dist/cjs/ecs/system-builder.js +1 -1
- package/dist/cjs/ecs/world.js +1 -1
- package/dist/cjs/game/loop/loop.js +1 -1
- package/dist/cjs/game/loop/ticker-schedule.js +1 -0
- package/dist/cjs/net/adapters/bun-websocket.js +1 -1
- package/dist/cjs/renderer/index.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/concrete.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/index.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/parsers.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/specs.js +1 -1
- package/dist/cjs/renderer/raycast/index.js +1 -0
- package/dist/cjs/renderer/raycast/raycast.js +1 -0
- package/dist/esm/core/binary-codec/binary-codec.js +1 -1
- package/dist/esm/core/clock/clock.js +1 -0
- package/dist/esm/core/clock/index.js +1 -0
- package/dist/esm/core/driver/drivers/immediate.js +1 -1
- package/dist/esm/core/driver/drivers/raf.js +1 -1
- package/dist/esm/core/driver/drivers/timeout.js +1 -1
- package/dist/esm/core/hitbox/hitbox-library.js +1 -0
- package/dist/esm/core/hitbox/hitbox.js +1 -0
- package/dist/esm/core/hitbox/index.js +1 -0
- package/dist/esm/core/hitbox/test.js +1 -0
- package/dist/esm/core/index.js +1 -1
- package/dist/esm/core/input/index.js +1 -1
- package/dist/esm/core/input/mouse-look/index.js +1 -0
- package/dist/esm/core/input/mouse-look/mouse-look.js +1 -0
- package/dist/esm/core/input/scroll-zoom/index.js +1 -0
- package/dist/esm/core/input/scroll-zoom/scroll-zoom.js +1 -0
- package/dist/esm/core/prediction/prediction.js +1 -1
- package/dist/esm/core/ray/ray-3d.js +1 -1
- package/dist/esm/core/raycast/hit-buffer.js +1 -0
- package/dist/esm/core/raycast/index.js +1 -0
- package/dist/esm/core/raycast/raycaster.js +1 -0
- package/dist/esm/core/slot-map/index.js +1 -0
- package/dist/esm/core/slot-map/slot-map.js +1 -0
- package/dist/esm/core/state-machine/index.js +1 -0
- package/dist/esm/core/state-machine/state-machine.js +1 -0
- package/dist/esm/core/timeline/index.js +1 -0
- package/dist/esm/core/timeline/timeline.js +1 -0
- package/dist/esm/ecs/component.js +1 -1
- package/dist/esm/ecs/system-builder.js +1 -1
- package/dist/esm/ecs/world.js +1 -1
- package/dist/esm/game/loop/loop.js +1 -1
- package/dist/esm/game/loop/ticker-schedule.js +1 -0
- package/dist/esm/net/adapters/bun-websocket.js +1 -1
- package/dist/esm/renderer/index.js +1 -1
- package/dist/esm/renderer/prefab-bucket/concrete.js +1 -1
- package/dist/esm/renderer/prefab-bucket/index.js +1 -1
- package/dist/esm/renderer/prefab-bucket/parsers.js +1 -1
- package/dist/esm/renderer/raycast/index.js +1 -0
- package/dist/esm/renderer/raycast/raycast.js +1 -0
- package/dist/netcode/cjs/index.js +1556 -0
- package/dist/netcode/esm/index.js +1534 -0
- package/dist/netcode/types/client/game-client.d.ts +139 -0
- package/dist/netcode/types/client/index.d.ts +1 -0
- package/dist/netcode/types/client/strategies/snapshot-interpolation.d.ts +33 -0
- package/dist/netcode/types/client/strategies/snapshot-interpolation.test.d.ts +1 -0
- package/dist/netcode/types/codec/delta-codec.d.ts +17 -0
- package/dist/netcode/types/codec/delta-codec.test.d.ts +1 -0
- package/dist/netcode/types/codec/index.d.ts +1 -0
- package/dist/netcode/types/components/index.d.ts +1 -0
- package/dist/netcode/types/components/sync-spec.d.ts +49 -0
- package/dist/netcode/types/components/sync-spec.test.d.ts +1 -0
- package/dist/netcode/types/ctx.d.ts +105 -0
- package/dist/netcode/types/ctx.test.d.ts +1 -0
- package/dist/netcode/types/handlers/define-handlers.d.ts +47 -0
- package/dist/netcode/types/handlers/index.d.ts +1 -0
- package/dist/netcode/types/index.d.ts +11 -0
- package/dist/netcode/types/integration.test.d.ts +1 -0
- package/dist/netcode/types/intents/define-intents.d.ts +53 -0
- package/dist/netcode/types/intents/define-intents.test.d.ts +1 -0
- package/dist/netcode/types/intents/index.d.ts +1 -0
- package/dist/netcode/types/network/base.d.ts +120 -0
- package/dist/netcode/types/network/index.d.ts +2 -0
- package/dist/netcode/types/network/transport.d.ts +1 -0
- package/dist/netcode/types/packets/convergence.test.d.ts +1 -0
- package/dist/netcode/types/packets/harness.d.ts +103 -0
- package/dist/netcode/types/packets/index.d.ts +2 -0
- package/dist/netcode/types/packets/intermittent-intents.test.d.ts +1 -0
- package/dist/netcode/types/packets/pathological.test.d.ts +1 -0
- package/dist/netcode/types/packets/peer-interpolation.test.d.ts +1 -0
- package/dist/netcode/types/packets/reordering.test.d.ts +1 -0
- package/dist/netcode/types/packets/virtual-network.d.ts +65 -0
- package/dist/netcode/types/predictions/define-predictions.d.ts +45 -0
- package/dist/netcode/types/predictions/define-predictions.test.d.ts +1 -0
- package/dist/netcode/types/predictions/index.d.ts +1 -0
- package/dist/netcode/types/reconciliation.test.d.ts +1 -0
- package/dist/netcode/types/rpcs/define-rpcs.d.ts +44 -0
- package/dist/netcode/types/rpcs/define-rpcs.test.d.ts +1 -0
- package/dist/netcode/types/rpcs/index.d.ts +1 -0
- package/dist/netcode/types/server/game-server.d.ts +77 -0
- package/dist/netcode/types/server/index.d.ts +2 -0
- package/dist/netcode/types/server/plugins/aoi-grid.d.ts +34 -0
- package/dist/netcode/types/server/plugins/index.d.ts +3 -0
- package/dist/netcode/types/server/plugins/lag-compensation.d.ts +34 -0
- package/dist/netcode/types/server/plugins/plugin.d.ts +24 -0
- package/dist/netcode/types/tick-rate.test.d.ts +1 -0
- package/dist/netcode/types/transports/index.d.ts +1 -0
- package/dist/netcode/types/transports/memory-transport.d.ts +51 -0
- package/dist/netcode/types/types.test.d.ts +1 -0
- package/dist/types/core/binary-codec/binary-codec.d.ts +89 -31
- package/dist/types/core/clock/clock.d.ts +37 -0
- package/dist/types/core/clock/index.d.ts +1 -0
- package/dist/types/core/driver/driver.d.ts +8 -8
- package/dist/types/core/driver/drivers/immediate.d.ts +4 -4
- package/dist/types/core/driver/drivers/raf.d.ts +6 -6
- package/dist/types/core/driver/drivers/timeout.d.ts +4 -4
- package/dist/types/core/hitbox/hitbox-library.d.ts +29 -0
- package/dist/types/core/hitbox/hitbox.d.ts +50 -0
- package/dist/types/core/hitbox/index.d.ts +3 -0
- package/dist/types/core/hitbox/test.d.ts +44 -0
- package/dist/types/core/index.d.ts +6 -0
- package/dist/types/core/input/index.d.ts +2 -0
- package/dist/types/core/input/mouse-look/index.d.ts +1 -0
- package/dist/types/core/input/mouse-look/mouse-look.d.ts +139 -0
- package/dist/types/core/input/scroll-zoom/index.d.ts +1 -0
- package/dist/types/core/input/scroll-zoom/scroll-zoom.d.ts +38 -0
- package/dist/types/core/prediction/prediction.d.ts +35 -58
- package/dist/types/core/ray/ray-3d.d.ts +21 -1
- package/dist/types/core/raycast/hit-buffer.d.ts +43 -0
- package/dist/types/core/raycast/index.d.ts +2 -0
- package/dist/types/core/raycast/raycaster.d.ts +54 -0
- package/dist/types/core/slot-map/index.d.ts +1 -0
- package/dist/types/core/slot-map/slot-map.d.ts +109 -0
- package/dist/types/core/state-machine/index.d.ts +1 -0
- package/dist/types/core/state-machine/state-machine.d.ts +114 -0
- package/dist/types/core/timeline/index.d.ts +1 -0
- package/dist/types/core/timeline/timeline.d.ts +34 -0
- package/dist/types/ecs/component.d.ts +67 -11
- package/dist/types/ecs/entity-handle.d.ts +5 -5
- package/dist/types/ecs/system-builder.d.ts +13 -0
- package/dist/types/ecs/world.d.ts +72 -4
- package/dist/types/game/loop/loop.d.ts +51 -2
- package/dist/types/game/loop/ticker-schedule.d.ts +52 -0
- package/dist/types/net/adapters/bun-websocket.d.ts +19 -3
- package/dist/types/renderer/index.d.ts +1 -0
- package/dist/types/renderer/prefab-bucket/concrete.d.ts +16 -6
- package/dist/types/renderer/prefab-bucket/index.d.ts +11 -7
- package/dist/types/renderer/prefab-bucket/specs.d.ts +10 -0
- package/dist/types/renderer/raycast/index.d.ts +1 -0
- package/dist/types/renderer/raycast/raycast.d.ts +24 -0
- package/dist/types/renderer/types.d.ts +1 -0
- package/dist/webgpu/cjs/index.js +1897 -592
- package/dist/webgpu/esm/index.js +1889 -578
- package/dist/webgpu/types/2d/raycast.d.ts +45 -0
- package/dist/webgpu/types/2d/renderer.d.ts +11 -0
- package/dist/webgpu/types/2d/sprite-accessor.d.ts +3 -1
- package/dist/webgpu/types/3d/hitbox.d.ts +32 -0
- package/dist/webgpu/types/3d/lights.d.ts +113 -0
- package/dist/webgpu/types/3d/lights.test.d.ts +1 -0
- package/dist/webgpu/types/3d/raycast.d.ts +44 -0
- package/dist/webgpu/types/3d/renderer.d.ts +88 -1
- package/dist/webgpu/types/3d/shader.d.ts +88 -5
- package/dist/webgpu/types/core/types.d.ts +55 -0
- package/dist/webgpu/types/geometry/geometry-builder.d.ts +1 -4
- package/dist/webgpu/types/index.d.ts +1 -0
- package/dist/webgpu/types/shaders/utils.d.ts +24 -0
- package/package.json +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const e=1;class s{constructor(t){this.update=t;this.last=performance.now();this.running=!1;this.loop=()=>{if(!this.running)return;const t=performance.now(),o=(t-this.last)/1e3;this.last=t,this.update(o),setTimeout(this.loop,e)}}start(){this.running=!0,this.last=performance.now(),this.loop()}stop(){this.running=!1}}export{s as TimeoutDriver};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class n{constructor(e){this.mode=e;this.names=[];this.boxes=[];this.index=new Map}add(e,t){if(this.index.has(e))throw new Error(`Hitbox '${e}' already registered`);return this.index.set(e,this.boxes.length),this.names.push(e),this.boxes.push(t),this}get(e){const t=this.index.get(e);if(t===void 0)throw new Error(`Hitbox '${e}' not registered`);return this.boxes[t]}at(e){return this.boxes[e]}indexOf(e){const t=this.index.get(e);if(t===void 0)throw new Error(`Hitbox '${e}' not registered`);return t}keys(){return this.names}}export{n as HitboxLibrary};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class n{constructor(r,e=[]){this.mode=r;this.parts=e}add(r,e){return new n(this.mode,[...this.parts,{name:r,...e}])}}export{n as Hitbox};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./hitbox";export*from"./hitbox-library";export*from"./test";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const a={cx:0,cy:0,cz:0,hx:0,hy:0,hz:0};function R(n,l,m,r,e,u,c){const b=n.offset;if(a.cx=b?l+b[0]*e:l,a.cy=b?m+b[1]*u:m,a.cz=b?r+b[2]*c:r,n.shape==="sphere"){const o=n.radius*(e>u?e>c?e:c:u>c?u:c);a.hx=a.hy=a.hz=o}else if(n.shape==="box")a.hx=n.size[0]*.5*e,a.hy=n.size[1]*.5*u,a.hz=n.size[2]*.5*c;else{const o=n.radius*(e>c?e:c);a.hx=a.hz=o,a.hy=n.height*.5*u}return a}const s={part:"",distance:0,point:[0,0,0]};function B(n,l,m,r,e,u,c,b){let o=1/0,h=null;for(const i of l.parts){const t=R(i,m,r,e,u,c,b);let f;i.shape==="sphere"?f=n.entrySphere(t.cx,t.cy,t.cz,t.hx):i.shape==="box"?f=n.entryBox(t.cx,t.cy,t.cz,t.hx,t.hy,t.hz):f=n.entryCylinder(t.cx,t.cy,t.cz,t.hx,t.hy*2),f!==null&&f<o&&(o=f,h=i.name)}return h===null?null:(s.part=h,s.distance=o,s.point[0]=n.origin[0]+n.direction[0]*o,s.point[1]=n.origin[1]+n.direction[1]*o,s.point[2]=n.origin[2]+n.direction[2]*o,s)}function C(n,l,m,r,e,u,c,b){const o=u!==0?Math.cos(-u):1,h=u!==0?Math.sin(-u):0;for(const i of n.parts){const t=i.offset,f=t?l+t[0]*r:l,M=t?m+t[1]*e:m,g=c-f,D=b-M,d=g*o-D*h,p=g*h+D*o;let P;if(i.shape==="circle"){const x=i.radius*(r>e?r:e);P=d*d+p*p<=x*x}else if(i.shape==="rect")P=z(d,p,i.size[0]*.5*r,i.size[1]*.5*e);else{const x=i.radius*(r>e?r:e),H=i.length*.5*e,I=p>H?H:p<-H?-H:p,y=p-I;P=d*d+y*y<=x*x}if(P)return s.part=i.name,s.distance=0,s.point[0]=c,s.point[1]=b,s}return null}function E(n,l,m,r,e,u,c){const b=u-n,o=c-l;if(e===0)return z(b,o,m*.5,r*.5);const h=Math.cos(-e),i=Math.sin(-e);return z(b*h-o*i,b*i+o*h,m*.5,r*.5)}function z(n,l,m,r){return n>=-m&&n<=m&&l>=-r&&l<=r}export{R as placePart3D,E as pointInQuad2D,C as testHitbox2D,B as testHitbox3D};
|
package/dist/esm/core/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./binary-codec";export*from"./events";export*from"./fixed-ticker";export*from"./generate-id";export*from"./lerp";export*from"./driver";export*from"./navmesh";export*from"./pooled-codec";export*from"./prediction";export*from"./input";export*from"./free-list";export*from"./sparse-batcher";export*from"./simple-rng";export*from"./ray";export*from"../renderer";
|
|
1
|
+
export*from"./binary-codec";export*from"./events";export*from"./fixed-ticker";export*from"./generate-id";export*from"./lerp";export*from"./driver";export*from"./navmesh";export*from"./pooled-codec";export*from"./prediction";export*from"./clock";export*from"./timeline";export*from"./input";export*from"./free-list";export*from"./sparse-batcher";export*from"./slot-map";export*from"./state-machine";export*from"./simple-rng";export*from"./ray";export*from"./raycast";export*from"./hitbox";export*from"../renderer";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./manager";export*from"./sources";
|
|
1
|
+
export*from"./manager";export*from"./sources";export*from"./mouse-look";export*from"./scroll-zoom";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./mouse-look";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class c{constructor(t={}){this.lockedElement=null;this.pendingLockCleanup=null;this._forward=new Float32Array(3);this._right=new Float32Array(3);this._up=new Float32Array(3);this._orbit=new Float32Array(3);this.sensitivity=t.sensitivity??.002;const i=t.yaw??{};this.yaw=i.initial??0,this.yawMin=i.min??-1/0,this.yawMax=i.max??1/0;const n=t.pitch??{};this.pitch=n.initial??0,this.pitchMin=n.min??-Math.PI/2+.01,this.pitchMax=n.max??Math.PI/2-.01,this.invertX=t.invertX??!1,this.invertY=t.invertY??!1,this.drag=t.drag??!0,this.dragButton=t.dragButton??"left"}update(t){const i=t.mouse[this.dragButton];if(!(this.locked||this.drag&&i.down))return;const e=t.mouse.delta.position.x,o=t.mouse.delta.position.y;e===0&&o===0||(this.yaw-=e*this.sensitivity*(this.invertX?-1:1),this.yaw<this.yawMin?this.yaw=this.yawMin:this.yaw>this.yawMax&&(this.yaw=this.yawMax),this.pitch-=o*this.sensitivity*(this.invertY?-1:1),this.pitch<this.pitchMin?this.pitch=this.pitchMin:this.pitch>this.pitchMax&&(this.pitch=this.pitchMax))}lock(t){const i=t.requestPointerLock;if(typeof i!="function")return Promise.reject(new Error("Pointer Lock unsupported"));this.lockedElement=t;const n=i.call(t);return n&&typeof n.then=="function"?n:new Promise((e,o)=>{const r=()=>{document.removeEventListener("pointerlockchange",s),document.removeEventListener("pointerlockerror",a),this.pendingLockCleanup===r&&(this.pendingLockCleanup=null)},s=()=>{r(),document.pointerLockElement===t?e():o(new Error("Pointer Lock denied"))},a=()=>{r(),o(new Error("Pointer Lock denied"))};document.addEventListener("pointerlockchange",s),document.addEventListener("pointerlockerror",a),this.pendingLockCleanup=r})}unlock(){typeof document<"u"&&document.exitPointerLock&&document.exitPointerLock()}get locked(){return typeof document>"u"||this.lockedElement===null?!1:document.pointerLockElement===this.lockedElement}get forward(){const t=Math.cos(this.pitch),i=this._forward;return i[0]=Math.sin(this.yaw)*t,i[1]=Math.sin(this.pitch),i[2]=Math.cos(this.yaw)*t,i}get right(){const t=this._right;return t[0]=Math.cos(this.yaw),t[1]=0,t[2]=-Math.sin(this.yaw),t}get up(){const t=Math.sin(this.pitch),i=this._up;return i[0]=-Math.sin(this.yaw)*t,i[1]=Math.cos(this.pitch),i[2]=-Math.cos(this.yaw)*t,i}orbit(t,i){const n=Math.cos(this.pitch),e=this._orbit;return e[0]=t[0]+i*n*Math.sin(this.yaw),e[1]=t[1]+i*Math.sin(this.pitch),e[2]=t[2]+i*n*Math.cos(this.yaw),e}destroy(){this.pendingLockCleanup?.(),this.pendingLockCleanup=null,this.unlock(),this.lockedElement=null}}export{c as MouseLook};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./scroll-zoom";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class e{constructor(i){this.value=i.initial,this.min=i.min,this.max=i.max,this.sensitivity=i.sensitivity??.01}update(i){const t=i.mouse.delta.scroll.y;t!==0&&(this.value+=t*this.sensitivity,this.value<this.min?this.value=this.min:this.value>this.max&&(this.value=this.max))}}export{e as ScrollZoom};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class i{constructor(t=64){this.capacity=t;this.entries=[]}get size(){return this.entries.length}record(t,e){for(this.entries.push({sequence:t,cmd:e});this.entries.length>this.capacity;)this.entries.shift()}dropThrough(t){let e=0;for(;e<this.entries.length&&this.entries[e].sequence<=t;)e++;e>0&&this.entries.splice(0,e)}pending(){const t=new Array(this.entries.length);for(let e=0;e<this.entries.length;e++)t[e]=this.entries[e].cmd;return t}clear(){this.entries.length=0}}class s{constructor(t){this.log=new i(t.bufferSize??64),this.restore=t.restore,this.replay=t.replay}record(t,e){this.log.record(t,e)}get pending(){return this.log.size}clear(){this.log.clear()}reconcile(t,e){this.restore(e),this.log.dropThrough(t),this.replay(this.log.pending(),e)}}export{i as PredictionLog,s as Reconciler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class P{constructor(){this.origin=[0,0,0];this.direction=[0,0,1];this._point=[0,0,0]}set(i,c,b,t,s,r){this.origin[0]=i,this.origin[1]=c,this.origin[2]=b;const n=Math.sqrt(t*t+s*s+r*r);n>0&&(this.direction[0]=t/n,this.direction[1]=s/n,this.direction[2]=r/n)}at(i){return this._point[0]=this.origin[0]+this.direction[0]*i,this._point[1]=this.origin[1]+this.direction[1]*i,this._point[2]=this.origin[2]+this.direction[2]*i,this._point}intersectsPlane(i,c,b,t){const s=i*this.direction[0]+c*this.direction[1]+b*this.direction[2];if(Math.abs(s)<1e-10)return null;const r=(t-(i*this.origin[0]+c*this.origin[1]+b*this.origin[2]))/s;return r>=0?r:null}intersectsSphere(i,c,b,t){const s=this.origin[0]-i,r=this.origin[1]-c,n=this.origin[2]-b,o=2*(s*this.direction[0]+r*this.direction[1]+n*this.direction[2]),h=s*s+r*r+n*n-t*t,u=o*o-4*h;if(u<0)return null;const l=Math.sqrt(u),a=(-o-l)/2,f=(-o+l)/2;return a>=0?a:f>=0?f:null}intersectsAABB(i,c,b,t,s,r){let n=-1/0,o=1/0;const h=[[this.direction[0],this.origin[0],i,t,0],[this.direction[1],this.origin[1],c,s,1],[this.direction[2],this.origin[2],b,r,2]];for(const[u,l,a,f]of h){if(Math.abs(u)<1e-10){if(l<a||l>f)return null}else{const e=1/u;let d=(a-l)*e,m=(f-l)*e;if(d>m){const g=d;d=m,m=g}n=Math.max(n,d),o=Math.min(o,m)}if(n>o)return null}return o<0?null:n>=0?n:o}entrySphere(i,c,b,t){const s=this.origin[0]-i,r=this.origin[1]-c,n=this.origin[2]-b,o=s*s+r*r+n*n-t*t;if(o<=0)return null;const h=2*(s*this.direction[0]+r*this.direction[1]+n*this.direction[2]);if(h>=0)return null;const u=h*h-4*o;return u<0?null:(-h-Math.sqrt(u))/2}entryBox(i,c,b,t,s,r){let n=-1/0,o=1/0;const h=1e-10,u=this.origin,l=this.direction,a=[i-t,c-s,b-r],f=[i+t,c+s,b+r];for(let e=0;e<3;e++)if(Math.abs(l[e])<h){if(u[e]<a[e]||u[e]>f[e])return null}else{const d=1/l[e];let m=(a[e]-u[e])*d,g=(f[e]-u[e])*d;if(m>g){const y=m;m=g,g=y}if(m>n&&(n=m),g<o&&(o=g),n>o)return null}return o<0||n<0?null:n}entryCylinder(i,c,b,t,s){const r=this.origin[0],n=this.origin[1],o=this.origin[2],h=this.direction[0],u=this.direction[1],l=this.direction[2],a=s*.5,f=c-a,e=c+a,d=r-i,m=o-b,g=h*h+l*l;let y=1/0;if(g>=1e-10){const M=2*(d*h+m*l),_=d*d+m*m-t*t,p=M*M-4*g*_;if(p>=0){const v=Math.sqrt(p),x=(-M-v)/(2*g),I=(-M+v)/(2*g);if(x>=0){const q=n+u*x;q>=f&&q<=e&&x<y&&(y=x)}if(I>=0){const q=n+u*I;q>=f&&q<=e&&I<y&&(y=I)}}}if(Math.abs(u)>=1e-10)for(let M=0;M<2;M++){const p=((M===0?f:e)-n)/u;if(p<0)continue;const v=r+h*p-i,x=o+l*p-b;v*v+x*x<=t*t&&p<y&&(y=p)}return!isFinite(y)||n>=f&&n<=e&&d*d+m*m<=t*t?null:y}intersectsTriangle(i,c,b,t,s,r,n,o,h){const u=t-i,l=s-c,a=r-b,f=n-i,e=o-c,d=h-b,m=this.direction[0],g=this.direction[1],y=this.direction[2],M=g*d-y*e,_=y*f-m*d,p=m*e-g*f,v=u*M+l*_+a*p;if(Math.abs(v)<1e-10)return null;const x=1/v,I=this.origin[0]-i,q=this.origin[1]-c,z=this.origin[2]-b,B=x*(I*M+q*_+z*p);if(B<0||B>1)return null;const A=q*a-z*l,D=z*u-I*a,S=I*l-q*u,C=x*(m*A+g*D+y*S);if(C<0||B+C>1)return null;const F=x*(f*A+e*D+d*S);return F>=0?F:null}}export{P as Ray3D};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const d=16;class c{constructor(e){this.handles=[];this.parts=[];this.keys=new Float32Array(0);this.distances=new Float32Array(0);this.px=new Float32Array(0);this.py=new Float32Array(0);this.pz=new Float32Array(0);this.order=new Uint32Array(0);this.count=0;this.capacity=0;this.sorted=!1;this.dims=e,this.nearestHit=this.makeHit()}makeHit(){return{handle:null,distance:0,point:this.dims===2?[0,0]:[0,0,0],part:null}}reset(){this.count=0,this.sorted=!1}push(e,t,i,o,r=0,s=t,a=null){const n=this.count;n>=this.capacity&&this.grow(n+1),this.handles[n]=e,this.parts[n]=a,this.keys[n]=t,this.distances[n]=s,this.px[n]=i,this.py[n]=o,this.pz[n]=r,this.order[n]=n,this.count=n+1,this.sorted=!1}nearest(e,t){let i=-1,o=1/0;for(let r=0;r<this.count;r++){const s=this.keys[r];if(s>t||s>=o)continue;const a=this.handles[r];e&&!e(a)||(o=s,i=r)}return i===-1?null:this.fill(this.nearestHit,i)}collectInto(e,t,i){this.ensureSorted();let o=0;for(let r=0;r<this.count;r++){const s=this.order[r];if(this.keys[s]>i)break;const n=this.handles[s];if(t&&!t(n))continue;const h=e[o]??(e[o]=this.makeHit());this.fill(h,s),o++}e.length=o}containsId(e){for(let t=0;t<this.count;t++){const i=this.handles[t];if(i!==null&&(typeof i=="number"?i===e:i.id===e))return!0}return!1}fill(e,t){return e.handle=this.handles[t],e.part=this.parts[t],e.distance=this.distances[t],e.point[0]=this.px[t],e.point[1]=this.py[t],this.dims===3&&(e.point[2]=this.pz[t]),e}grow(e){const t=Math.max(e,this.capacity*2,16);this.handles.length=t,this.parts.length=t;const i=new Float32Array(t);i.set(this.keys),this.keys=i;const o=new Float32Array(t);o.set(this.distances),this.distances=o;const r=new Float32Array(t);r.set(this.px),this.px=r;const s=new Float32Array(t);s.set(this.py),this.py=s;const a=new Float32Array(t);a.set(this.pz),this.pz=a;const n=new Uint32Array(t);n.set(this.order),this.order=n,this.capacity=t}ensureSorted(){if(this.sorted)return;const e=this.order,t=this.keys;for(let i=1;i<this.count;i++){const o=e[i],r=t[o];let s=i-1;for(;s>=0&&t[e[s]]>r;)e[s+1]=e[s],s--;e[s+1]=o}this.sorted=!0}}export{c as HitBuffer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./hit-buffer";export*from"./raycaster";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{testHitbox3D as f}from"../hitbox/test";import{HitBuffer as l}from"./hit-buffer";class p{constructor(){this.buf=new l(3);this.resultBuffer=[];this._lookup=null;this._transform=null}lookup(r){return this._lookup=r,this}configure(r){return this._transform=r,this}cast(r){if(!this._lookup||!this._transform)throw new Error("Raycaster.cast: call lookup() and configure() first");this.buf.reset();const a=this._lookup.hitbox,u=this._lookup.query(),i=this._transform.position(),n=this._transform.scale();for(let o=0;o<u.length;o++){const t=u[o],s=a(t);if(s===null)continue;const e=f(r,s,i.x[t],i.y[t],i.z[t],n.x[t],n.y[t],n.z[t]);e&&this.buf.push(t,e.distance,e.point[0],e.point[1],e.point[2],e.distance,e.part)}return this}hit(r){return this.buf.nearest(r?.filter,r?.maxDistance??1/0)}hitAll(r){return this.buf.collectInto(this.resultBuffer,r?.filter,r?.maxDistance??1/0),this.resultBuffer}}export{p as Raycaster};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./slot-map";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{FreeList as n}from"../free-list";class l{constructor(t){this._size=0;this._capacity=t,this.freeList=new n(t),this.dense=new Uint32Array(t),this.sparse=new Int32Array(t).fill(-1)}add(){const t=this.freeList.allocate();return t===-1?-1:(this.dense[this._size]=t,this.sparse[t]=this._size,this._size++,t)}remove(t){const s=this.sparse[t];if(s===-1)return;const e=this._size-1;if(s!==e){const i=this.dense[e];this.dense[s]=i,this.sparse[i]=s}this.sparse[t]=-1,this._size--,this.freeList.free(t)}has(t){return t>=0&&t<this._capacity&&this.sparse[t]!==-1}get activeSlots(){return this.dense}get size(){return this._size}get capacity(){return this._capacity}hasAvailable(){return this.freeList.hasAvailable()}forEach(t){for(let s=0;s<this._size;s++)t(this.dense[s],s)}clear(){for(let t=0;t<this._size;t++){const s=this.dense[t];this.sparse[s]=-1,this.freeList.free(s)}this._size=0}}class h{constructor(t,s=t){this.slots=new l(t),this.items=new Array(t).fill(null),this.idToSlot=new Int32Array(s).fill(-1),this.slotToId=new Int32Array(t).fill(-1),this._maxId=s}add(t,s){if(t<0||t>=this._maxId)throw new Error(`SlotStore: id ${t} out of range [0, ${this._maxId})`);if(this.idToSlot[t]!==-1)throw new Error(`SlotStore: id ${t} is already present`);const e=this.slots.add();if(e===-1)throw new Error(`SlotStore: capacity (${this.slots.capacity}) reached`);return this.items[e]=s,this.idToSlot[t]=e,this.slotToId[e]=t,e}remove(t){if(t<0||t>=this._maxId)return;const s=this.idToSlot[t];s!==-1&&(this.items[s]=null,this.idToSlot[t]=-1,this.slotToId[s]=-1,this.slots.remove(s))}get(t){if(t<0||t>=this._maxId)return null;const s=this.idToSlot[t];return s===-1?null:this.items[s]}has(t){return t>=0&&t<this._maxId&&this.idToSlot[t]!==-1}slotOf(t){return t<0||t>=this._maxId?-1:this.idToSlot[t]}get size(){return this.slots.size}get capacity(){return this.slots.capacity}hasAvailable(){return this.slots.hasAvailable()}forEach(t){const s=this.slots.activeSlots,e=this.slots.size;for(let i=0;i<e;i++){const r=s[i];t(this.items[r],this.slotToId[r],r)}}clear(){const t=this.slots.activeSlots,s=this.slots.size;for(let e=0;e<s;e++){const i=t[e],r=this.slotToId[i];this.items[i]=null,r!==-1&&(this.idToSlot[r]=-1),this.slotToId[i]=-1}this.slots.clear()}}export{l as SlotMap,h as SlotStore};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./state-machine";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SlotStore as h}from"../slot-map";import{EventSystem as c}from"../events";import{SimpleRNG as m}from"../simple-rng";const u=7173490,d=256;class v{constructor(e){this.events=new c({events:["change"]});this.now=0;this.ticking=!1;this.dead=[];this.ev={id:0,from:0,to:0};this.step=(e,n,i)=>{const t=this.stateCol[i],s=this.updateFns[t];for(let a=0;a<s.length&&(s[a](e),this.stateCol[i]===t);a++);};this.rng=e.rng??new m(u);const n=e.capacity??1024;if(this.names=Object.keys(e.states),this.names.length>d)throw new Error(`StateMachine: at most ${d} states (got ${this.names.length})`);const i={};this.names.forEach((t,s)=>i[t]=s),this.id=i,this.initialId=i[e.initial],this.store=new h(n,e.maxId??n),this.stateCol=new Uint8Array(n),this.prevCol=new Uint8Array(n),this.enteredCol=new Uint32Array(n),this.cols={},this.fieldsByState=[];for(const t of this.names){const s=i[t],a=e.states[t],l=Object.keys(a);this.fieldsByState[s]=l;for(const r of l){if(this.cols[r])continue;const o=a[r];this.cols[r]={field:o,dv:new DataView(new ArrayBuffer(n*o.size)),size:o.size}}}this.enterFns=this.names.map(()=>[]),this.updateFns=this.names.map(()=>[]),this.exitFns=this.names.map(()=>[]),this.Handle=this.buildHandle()}get size(){return this.store.size}add(e,n){const i=this.id[e];return n.enter&&this.enterFns[i].push(n.enter),n.update&&this.updateFns[i].push(n.update),n.exit&&this.exitFns[i].push(n.exit),this}spawn(e){const n=new this.Handle(e),i=this.store.add(e,n);n._slot=i,this.stateCol[i]=this.prevCol[i]=this.initialId,this.enteredCol[i]=this.now;const t=this.enterFns[this.initialId];for(let s=0;s<t.length;s++)t[s](n,0);return n}of(e){return this.store.get(e)}has(e){return this.store.has(e)}remove(e){if(this.ticking){this.dead.push(e);return}this.store.remove(e)}tick(){if(this.now++,this.ticking=!0,this.store.forEach(this.step),this.ticking=!1,this.dead.length){for(let e=0;e<this.dead.length;e++)this.store.remove(this.dead[e]);this.dead.length=0}}serialize(e,n,i){const t=this.store.slotOf(e);let s=i;const a=this.stateCol[t];n.setUint8(s,a),s+=1;const l=this.fieldsByState[a];for(let r=0;r<l.length;r++){const o=this.cols[l[r]];o.field.write(n,s,o.field.read(o.dv,t*o.size)),s+=o.size}return s}restore(e,n,i){const t=this.store.slotOf(e);let s=i;const a=n.getUint8(s);s+=1,this.stateCol[t]=a,this.enteredCol[t]=this.now;const l=this.fieldsByState[a];for(let r=0;r<l.length;r++){const o=this.cols[l[r]];o.field.write(o.dv,t*o.size,o.field.read(n,s)),s+=o.size}return s}byteSize(e){const n=this.store.slotOf(e),i=this.fieldsByState[this.stateCol[n]];let t=1;for(let s=0;s<i.length;s++)t+=this.cols[i[s]].size;return t}transition(e,n,i){const t=e._slot,s=this.stateCol[t];if(n===s)return;const a=this.exitFns[s];for(let r=0;r<a.length;r++)a[r](e);this.prevCol[t]=s,this.stateCol[t]=n,this.enteredCol[t]=this.now;const l=this.enterFns[n];for(let r=0;r<l.length;r++)l[r](e,i);this.ev.id=e.id,this.ev.from=s,this.ev.to=n,this.events.emit("change",this.ev)}buildHandle(){const e=this;class n{constructor(t){this.id=t;this._slot=-1}get state(){return e.names[e.stateCol[this._slot]]}get stateId(){return e.stateCol[this._slot]}get ticksInState(){return e.now-e.enteredCol[this._slot]}is(t){return e.stateCol[this._slot]===e.id[t]}change(t,s=0){e.transition(this,typeof t=="number"?t:e.id[t],s)}}for(const i in this.cols){const t=this.cols[i];Object.defineProperty(n.prototype,i,{get(){return t.field.read(t.dv,this._slot*t.size)},set(s){t.field.write(t.dv,this._slot*t.size,s)},enumerable:!0})}return n}}export{v as StateMachine};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Timeline as m}from"./timeline";export{m as Timeline};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class h{constructor(t,e){this.entries=[];this._latestReceivedAt=-1/0;this.capacity=t,this.staleWindow=e}get length(){return this.entries.length}get latestReceivedAt(){return this._latestReceivedAt}at(t){return this.entries[t]}newest(){return this.entries[this.entries.length-1]}oldest(){return this.entries[0]}setStaleWindow(t){this.staleWindow=t}clear(){this.entries.length=0,this._latestReceivedAt=-1/0}record(t,e,s){let n=!1;const r=e-this._latestReceivedAt;this.entries.length>0&&r>this.staleWindow&&(this.entries.length=0,this._latestReceivedAt=-1/0,n=!0),e>this._latestReceivedAt&&(this._latestReceivedAt=e);let i=this.entries.length;for(;i>0&&this.entries[i-1].tick>=t;){if(this.entries[i-1].tick===t)return n;i--}for(this.entries.splice(i,0,{tick:t,receivedAt:e,sample:s});this.entries.length>this.capacity;)this.entries.shift();return n}straddle(t){for(let e=0;e<this.entries.length-1;e++)if(this.entries[e].tick<=t&&t<=this.entries[e+1].tick)return[e,e+1];return null}}export{h as Timeline};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PooledCodec as
|
|
1
|
+
import{PooledCodec as S}from"../core/pooled-codec";function p(n){let e=0;for(const o of Object.keys(n))e+=n[o].size;return e}function T(n,e){const o=typeof e=="object"&&e!==null&&"schema"in e&&"sync"in e,t=o?e.schema:e,c=o?e.sync:void 0,a=p(t),r=Object.keys(t),m=r.length,i=S.array(t),s={name:n,schema:t,size:a,fieldCount:m,fieldNames:r,arrayCodec:i};return c!==void 0&&(s.__sync=c),s}export{T as defineComponent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class u{constructor(t,n,o,r,e){this.world=t;this.components=n;this.fieldMappings=o;this.userCallback=r;this.conditionPredicate=e}query(...t){return new u(this.world,t,this.fieldMappings,this.userCallback,this.conditionPredicate)}fields(t){return new u(this.world,this.components,t,this.userCallback,this.conditionPredicate)}when(t){if(!this.fieldMappings)throw new Error("Must call .fields() before .when()");const n={};for(let e=0;e<this.components.length;e++){const a=this.components[e],l=this.fieldMappings[e];if(!l)continue;const d=Object.keys(l)[0],c=l[d];for(const i of c){const p=`${d}_${i}`,s=this.world.getFieldArray(a,i);n[p]=s}}const o={eid:0};for(const e in n){const a=n[e];Object.defineProperty(o,e,{get(){return a[this.eid]},set(l){a[this.eid]=l},enumerable:!0,configurable:!1}),o[`${e}_array`]=a}Object.seal(o);const r=t;return new u(this.world,this.components,this.fieldMappings,this.userCallback,r)}run(t){return new u(this.world,this.components,this.fieldMappings,t,this.conditionPredicate).buildAndRegister()}buildAndRegister(){if(!this.userCallback)throw new Error("System callback must be set");if(!this.fieldMappings)throw new Error("Field mappings must be set");const t=this.world,n=this.components,o=this.fieldMappings,r=this.userCallback,e={},a={},l=[];for(let s=0;s<n.length;s++){const f=n[s],y=o[s];if(!y)continue;const m=Object.keys(y)[0],g=y[m];l.push(m),a[m]=f,e[m]={};for(const x of g){const C=t.getFieldArray(f,x);e[m][x]=C}}const d=[];for(const s of l){const f=e[s];for(const y in f)d.push({prop:`${s}_${y}`,array:f[y]})}t.query(...n);const c=t._getQueryMaskKey(n),i=t.getQueryMask(n),p=new h(t,n,r,d,c,i,this.conditionPredicate);return t._registerSystem(p),p}}class h{constructor(t,n,o,r,e,a,l){this.world=t;this.components=n;this.userCallback=o;this.fieldDescs=r;this.queryMaskKey=e;this.queryMask=a;this.conditionPredicate=l;this.syncedComponentIndices=[];this.proxyEntity=this.createProxyEntity();for(const d of n)d.__sync!==void 0&&d.__worldIndex!==void 0&&this.syncedComponentIndices.push(d.__worldIndex)}execute(t){const n=this.world._queryByMaskKey(this.queryMaskKey,this.queryMask),o=this.userCallback,r=this.world,e=this.proxyEntity,a=n.length,l=this.syncedComponentIndices,d=l.length;if(!this.conditionPredicate&&d===0){for(let i=0;i<a;i++)e.eid=n[i],o(e,t,r);return}if(!this.conditionPredicate){for(let i=0;i<a;i++){const p=n[i];e.eid=p,o(e,t,r);for(let s=0;s<d;s++)r.markDirty(p,l[s])}return}const c=this.conditionPredicate;if(d===0){for(let i=0;i<a;i++)e.eid=n[i],c(e)&&o(e,t,r);return}for(let i=0;i<a;i++){const p=n[i];if(e.eid=p,c(e)){o(e,t,r);for(let s=0;s<d;s++)r.markDirty(p,l[s])}}}createProxyEntity(){const t=this.world,n={eid:0,despawn(){t.despawn(this.eid)}};for(let o=0;o<this.fieldDescs.length;o++){const{prop:r,array:e}=this.fieldDescs[o];n[`${r}_array`]=e,Object.defineProperty(n,r,{get(){return e[this.eid]},set(a){e[this.eid]=a},enumerable:!0,configurable:!1})}return Object.seal(n),Object.preventExtensions(n),n}getComponents(){return this.components}}export{h as ExecutableSystem,u as SystemBuilder};
|
package/dist/esm/ecs/world.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{generateId as E}from"../core/generate-id";import{ComponentStore as v}from"./component-store";import{EntityHandle as C}from"./entity-handle";import{WorldSystems as g}from"./world-systems";class B extends g{constructor(t){super();this.nextEntityId=0;this.freeEntityHead=0;this.freeEntityTail=0;this.freeEntityCount=0;this.freeEntityMask=0;this.aliveEntitiesArray=[];this.numMaskWords=0;this.components=[];this.queryResultBuffers={};this.archetypeVersion=0;this.queryCacheVersions={};this.queryMaskCache={};this.despawnedCount=0;this.worldId=E({prefix:"world_"});this.maxEntities=t.maxEntities??1e4,this.numMaskWords=Math.ceil(t.components.length/32),this.componentMasks=[];for(let n=0;n<this.numMaskWords;n++)this.componentMasks.push(new Uint32Array(this.maxEntities));this.numMaskWords>0&&(this.componentMasks0=this.componentMasks[0]);const e=Math.pow(2,Math.ceil(Math.log2(this.maxEntities)));this.freeEntityIds=new Uint32Array(e),this.freeEntityMask=e-1,this.aliveEntitiesIndices=new Uint32Array(this.maxEntities),this.aliveEntityFlags=new Uint8Array(this.maxEntities),this.despawnedBuffer=new Uint32Array(this.maxEntities),this.componentStoresArray=new Array(t.components.length),t.components.forEach((n,s)=>{this.components.push(n),n.__worldIndex=s;const c=new v(n,this.maxEntities);this.componentStoresArray[s]=c})}getComponentIndex(t){const e=t.__worldIndex;if(e===void 0){const n=this.components.map(s=>s.name).join(", ");throw new Error(`Component ${t.name} not registered in World[${this.worldId}]. Registered components: [${n}]. Did you forget to include it in the WorldConfig?`)}return e}setComponentBit(t,e){const n=e>>>5,s=e&31;this.componentMasks[n][t]|=1<<s}clearComponentBit(t,e){const n=e>>>5,s=e&31;this.componentMasks[n][t]&=~(1<<s)}hasComponentBit(t,e){const n=e>>>5,s=e&31;return(this.componentMasks[n][t]&1<<s)!==0}clearAllComponentBits(t){if(this.numMaskWords===1)this.componentMasks0[t]=0;else if(this.numMaskWords===2)this.componentMasks0[t]=0,this.componentMasks[1][t]=0;else if(this.numMaskWords===3)this.componentMasks0[t]=0,this.componentMasks[1][t]=0,this.componentMasks[2][t]=0;else for(let e=0;e<this.numMaskWords;e++)this.componentMasks[e][t]=0}matchesComponentMask(t,e){const n=e.length;if(n===1)return(this.componentMasks0[t]&e[0])===e[0];if(n===2)return(this.componentMasks0[t]&e[0])===e[0]&&(this.componentMasks[1][t]&e[1])===e[1];if(n===3)return(this.componentMasks0[t]&e[0])===e[0]&&(this.componentMasks[1][t]&e[1])===e[1]&&(this.componentMasks[2][t]&e[2])===e[2];if(n===4)return(this.componentMasks0[t]&e[0])===e[0]&&(this.componentMasks[1][t]&e[1])===e[1]&&(this.componentMasks[2][t]&e[2])===e[2]&&(this.componentMasks[3][t]&e[3])===e[3];for(let s=0;s<n;s++)if((this.componentMasks[s][t]&e[s])!==e[s])return!1;return!0}getQueryMask(t){const e=t.map(i=>i.name).sort().join(","),n=this.queryMaskCache[e];if(n)return n;let s=-1;const c=[];for(const i of t){const o=i.__worldIndex;if(o===void 0)return null;c.push(o),o>s&&(s=o)}const h=Math.floor(s/32)+1,p=new Array(h).fill(0);for(const i of c){const o=i>>>5,r=i&31;p[o]|=1<<r}return this.queryMaskCache[e]=p,p}maskToKey(t){let e="";for(let n=0;n<t.length;n++)t[n]!==0&&(e+=`${n}:${t[n].toString(36)},`);return e}_getQueryMaskKey(t){const e=this.getQueryMask(t);return e?this.maskToKey(e):""}_queryByMaskKey(t,e){let n=this.queryResultBuffers[t];if(n||(n=[],this.queryResultBuffers[t]=n),this.queryCacheVersions[t]===this.archetypeVersion)return n;const s=this.aliveEntitiesArray,c=s.length,h=e.length;let p=0;if(h===1){const i=e[0],o=this.componentMasks0;for(let r=0;r<c;r++){const a=s[r];(o[a]&i)===i&&(n[p++]=a)}}else if(h===2){const i=e[0],o=e[1],r=this.componentMasks0,a=this.componentMasks[1];for(let m=0;m<c;m++){const l=s[m];(r[l]&i)===i&&(a[l]&o)===o&&(n[p++]=l)}}else if(h===3){const i=e[0],o=e[1],r=e[2],a=this.componentMasks0,m=this.componentMasks[1],l=this.componentMasks[2];for(let y=0;y<c;y++){const d=s[y];(a[d]&i)===i&&(m[d]&o)===o&&(l[d]&r)===r&&(n[p++]=d)}}else if(h===4){const i=e[0],o=e[1],r=e[2],a=e[3],m=this.componentMasks0,l=this.componentMasks[1],y=this.componentMasks[2],d=this.componentMasks[3];for(let f=0;f<c;f++){const u=s[f];(m[u]&i)===i&&(l[u]&o)===o&&(y[u]&r)===r&&(d[u]&a)===a&&(n[p++]=u)}}else{const i=this.componentMasks;t:for(let o=0;o<c;o++){const r=s[o];for(let a=0;a<h;a++)if((i[a][r]&e[a])!==e[a])continue t;n[p++]=r}}return n.length=p,this.queryCacheVersions[t]=this.archetypeVersion,n}spawn(){let t=this.nextEntityId;if(this.freeEntityCount>0?(t=this.freeEntityIds[this.freeEntityTail],this.freeEntityTail=this.freeEntityTail+1&this.freeEntityMask,this.freeEntityCount--):this.nextEntityId++,t>=this.maxEntities)throw new Error(`Maximum entities (${this.maxEntities}) reached. Current alive: ${this.aliveEntitiesArray.length}, Free list: ${this.freeEntityCount}`);return this.aliveEntityFlags[t]=1,this.aliveEntitiesIndices[t]=this.aliveEntitiesArray.length,this.aliveEntitiesArray.push(t),this.clearAllComponentBits(t),this.invalidateQueryCache(),t}despawn(t){if(this.aliveEntityFlags[t]===0)return;this.despawnedBuffer[this.despawnedCount++]=t,this.aliveEntityFlags[t]=0;const e=this.aliveEntitiesIndices[t],n=this.aliveEntitiesArray.length-1;if(e!==n){const h=this.aliveEntitiesArray[n];this.aliveEntitiesArray[e]=h,this.aliveEntitiesIndices[h]=e}this.aliveEntitiesArray.pop();const s=this.componentStoresArray,c=this.components.length;for(let h=0;h<c;h++)this.hasComponentBit(t,h)&&s[h].clear(t);this.clearAllComponentBits(t),this.freeEntityIds[this.freeEntityHead]=t,this.freeEntityHead=this.freeEntityHead+1&this.freeEntityMask,this.freeEntityCount++,this.invalidateQueryCache()}isAlive(t){return this.aliveEntityFlags[t]===1}getDespawned(){return this.despawnedBuffer.subarray(0,this.despawnedCount)}flushDespawned(){this.despawnedCount=0}invalidateQueryCache(){this.archetypeVersion++}add(t,e,n){if(this.aliveEntityFlags[t]===0)throw new Error(`Cannot add component ${e.name} to entity ${t}: entity is not alive (was it despawned?). Current alive entities: ${this.aliveEntitiesArray.length}`);const s=this.getComponentIndex(e),c=this.componentStoresArray[s];this.setComponentBit(t,s),c.set(t,n),this.invalidateQueryCache()}remove(t,e){const n=e.__worldIndex;if(n===void 0)return;this.clearComponentBit(t,n);const s=this.componentStoresArray[n];s&&s.clear(t),this.invalidateQueryCache()}has(t,e){const n=e.__worldIndex;return n===void 0?!1:this.hasComponentBit(t,n)}get(t,e){const n=this.getComponentIndex(e);if(!this.hasComponentBit(t,n)){const s=this.getEntityComponentNames(t);throw new Error(`Cannot get component ${e.name} from entity ${t}: entity does not have this component. Entity has: [${s.join(", ")}]. Did you forget to call world.add()?`)}return this.componentStoresArray[n].get(t)}getMutable(t,e){const n=this.getComponentIndex(e);if(!this.hasComponentBit(t,n))throw new Error(`Entity ${t} does not have component ${e.name}`);return this.componentStoresArray[n].getMutable(t)}set(t,e,n){const s=this.getComponentIndex(e);if(!this.hasComponentBit(t,s))throw new Error(`Cannot set component ${e.name} on entity ${t}: entity does not have this component. Use add() first.`);this.componentStoresArray[s].set(t,n)}update(t,e,n){const s=this.getComponentIndex(e);if(!this.hasComponentBit(t,s))throw new Error(`Entity ${t} does not have component ${e.name}`);this.componentStoresArray[s].update(t,n)}query(...t){const e=this.getQueryMask(t);if(e===null)return[];const n=this.maskToKey(e);let s=this.queryResultBuffers[n];if(s||(s=[],this.queryResultBuffers[n]=s),this.queryCacheVersions[n]===this.archetypeVersion)return s;const c=this.aliveEntitiesArray,h=c.length,p=e.length;let i=0;if(p===1){const o=e[0],r=this.componentMasks0;for(let a=0;a<h;a++){const m=c[a];(r[m]&o)===o&&(s[i++]=m)}}else for(let o=0;o<h;o++){const r=c[o];this.matchesComponentMask(r,e)&&(s[i++]=r)}return s.length=i,this.queryCacheVersions[n]=this.archetypeVersion,s}getEntities(){return this.aliveEntitiesArray}getEntityCount(){return this.aliveEntitiesArray.length}getMaxEntities(){return this.maxEntities}getComponents(){return this.components}getEntityComponentNames(t){const e=[];for(let n=0;n<this.components.length;n++)this.hasComponentBit(t,n)&&e.push(this.components[n].name);return e}serialize(t,e){const n=e??Array.from(this.aliveEntitiesArray),s=[];for(const i of t){const o=i.__worldIndex;if(o===void 0)continue;const r=this.componentStoresArray[o];if(!r)continue;const a=[];for(const m of n)this.has(m,i)&&a.push({entity:m,...r.getMutable(m)});if(a.length>0){const m=i.arrayCodec.encode(a);s.push(m)}}const c=s.reduce((i,o)=>i+o.length,0),h=new Uint8Array(c);let p=0;for(const i of s)h.set(i,p),p+=i.length;return h}deserialize(t,e){throw new Error("Deserialization not yet implemented")}getFieldArray(t,e){const n=this.getComponentIndex(t);return this.componentStoresArray[n].getFieldArray(e)}entity(t){return new C(this,t)}}export{B as World};
|
|
1
|
+
import{generateId as E}from"../core/generate-id";import{ComponentStore as C}from"./component-store";import{EntityHandle as v}from"./entity-handle";import{WorldSystems as g}from"./world-systems";class T extends g{constructor(t){super();this.nextEntityId=0;this.freeEntityHead=0;this.freeEntityTail=0;this.freeEntityCount=0;this.freeEntityMask=0;this.aliveEntitiesArray=[];this.numMaskWords=0;this.components=[];this.queryResultBuffers={};this.archetypeVersion=0;this.queryCacheVersions={};this.queryMaskCache={};this.despawnedCount=0;this.dirtyBitsByComponent=[];this.fieldsByComponent=[];this.worldId=E({prefix:"world_"});this.maxEntities=t.maxEntities??1e4,this.numMaskWords=Math.ceil(t.components.length/32),this.componentMasks=[];for(let i=0;i<this.numMaskWords;i++)this.componentMasks.push(new Uint32Array(this.maxEntities));this.numMaskWords>0&&(this.componentMasks0=this.componentMasks[0]);const e=Math.pow(2,Math.ceil(Math.log2(this.maxEntities)));this.freeEntityIds=new Uint32Array(e),this.freeEntityMask=e-1,this.aliveEntitiesIndices=new Uint32Array(this.maxEntities),this.aliveEntityFlags=new Uint8Array(this.maxEntities),this.despawnedBuffer=new Uint32Array(this.maxEntities),this.componentStoresArray=new Array(t.components.length);const n=Math.ceil(this.maxEntities/32);this.fieldsByComponent=new Array(t.components.length),t.components.forEach((i,a)=>{this.components.push(i),i.__worldIndex=a;const r=new C(i,this.maxEntities);this.componentStoresArray[a]=r,this.dirtyBitsByComponent[a]=i.__sync!==void 0?new Uint32Array(n):null;const l={};for(let s=0;s<i.fieldNames.length;s++){const o=i.fieldNames[s];l[o]=r.getFieldArray(o)}Object.freeze(l),this.fieldsByComponent[a]=l})}getComponentIndex(t){const e=t.__worldIndex;if(e===void 0){const n=this.components.map(i=>i.name).join(", ");throw new Error(`Component ${t.name} not registered in World[${this.worldId}]. Registered components: [${n}]. Did you forget to include it in the WorldConfig?`)}return e}setComponentBit(t,e){const n=e>>>5,i=e&31;this.componentMasks[n][t]|=1<<i}clearComponentBit(t,e){const n=e>>>5,i=e&31;this.componentMasks[n][t]&=~(1<<i)}hasComponentBit(t,e){const n=e>>>5,i=e&31;return(this.componentMasks[n][t]&1<<i)!==0}clearAllComponentBits(t){if(this.numMaskWords===1)this.componentMasks0[t]=0;else if(this.numMaskWords===2)this.componentMasks0[t]=0,this.componentMasks[1][t]=0;else if(this.numMaskWords===3)this.componentMasks0[t]=0,this.componentMasks[1][t]=0,this.componentMasks[2][t]=0;else for(let e=0;e<this.numMaskWords;e++)this.componentMasks[e][t]=0}matchesComponentMask(t,e){const n=e.length;if(n===1)return(this.componentMasks0[t]&e[0])===e[0];if(n===2)return(this.componentMasks0[t]&e[0])===e[0]&&(this.componentMasks[1][t]&e[1])===e[1];if(n===3)return(this.componentMasks0[t]&e[0])===e[0]&&(this.componentMasks[1][t]&e[1])===e[1]&&(this.componentMasks[2][t]&e[2])===e[2];if(n===4)return(this.componentMasks0[t]&e[0])===e[0]&&(this.componentMasks[1][t]&e[1])===e[1]&&(this.componentMasks[2][t]&e[2])===e[2]&&(this.componentMasks[3][t]&e[3])===e[3];for(let i=0;i<n;i++)if((this.componentMasks[i][t]&e[i])!==e[i])return!1;return!0}getQueryMask(t){const e=t.map(s=>s.name).sort().join(","),n=this.queryMaskCache[e];if(n)return n;let i=-1;const a=[];for(const s of t){const o=s.__worldIndex;if(o===void 0)return null;a.push(o),o>i&&(i=o)}const r=Math.floor(i/32)+1,l=new Array(r).fill(0);for(const s of a){const o=s>>>5,h=s&31;l[o]|=1<<h}return this.queryMaskCache[e]=l,l}maskToKey(t){let e="";for(let n=0;n<t.length;n++)t[n]!==0&&(e+=`${n}:${t[n].toString(36)},`);return e}_getQueryMaskKey(t){const e=this.getQueryMask(t);return e?this.maskToKey(e):""}_queryByMaskKey(t,e){let n=this.queryResultBuffers[t];if(n||(n=[],this.queryResultBuffers[t]=n),this.queryCacheVersions[t]===this.archetypeVersion)return n;const i=this.aliveEntitiesArray,a=i.length,r=e.length;let l=0;if(r===1){const s=e[0],o=this.componentMasks0;for(let h=0;h<a;h++){const c=i[h];(o[c]&s)===s&&(n[l++]=c)}}else if(r===2){const s=e[0],o=e[1],h=this.componentMasks0,c=this.componentMasks[1];for(let d=0;d<a;d++){const m=i[d];(h[m]&s)===s&&(c[m]&o)===o&&(n[l++]=m)}}else if(r===3){const s=e[0],o=e[1],h=e[2],c=this.componentMasks0,d=this.componentMasks[1],m=this.componentMasks[2];for(let y=0;y<a;y++){const p=i[y];(c[p]&s)===s&&(d[p]&o)===o&&(m[p]&h)===h&&(n[l++]=p)}}else if(r===4){const s=e[0],o=e[1],h=e[2],c=e[3],d=this.componentMasks0,m=this.componentMasks[1],y=this.componentMasks[2],p=this.componentMasks[3];for(let u=0;u<a;u++){const f=i[u];(d[f]&s)===s&&(m[f]&o)===o&&(y[f]&h)===h&&(p[f]&c)===c&&(n[l++]=f)}}else{const s=this.componentMasks;t:for(let o=0;o<a;o++){const h=i[o];for(let c=0;c<r;c++)if((s[c][h]&e[c])!==e[c])continue t;n[l++]=h}}return n.length=l,this.queryCacheVersions[t]=this.archetypeVersion,n}spawn(){let t=this.nextEntityId;if(this.freeEntityCount>0?(t=this.freeEntityIds[this.freeEntityTail],this.freeEntityTail=this.freeEntityTail+1&this.freeEntityMask,this.freeEntityCount--):this.nextEntityId++,t>=this.maxEntities)throw new Error(`Maximum entities (${this.maxEntities}) reached. Current alive: ${this.aliveEntitiesArray.length}, Free list: ${this.freeEntityCount}`);return this.aliveEntityFlags[t]=1,this.aliveEntitiesIndices[t]=this.aliveEntitiesArray.length,this.aliveEntitiesArray.push(t),this.clearAllComponentBits(t),this.invalidateQueryCache(),t}despawn(t){if(this.aliveEntityFlags[t]===0)return;this.despawnedBuffer[this.despawnedCount++]=t,this.aliveEntityFlags[t]=0;const e=this.aliveEntitiesIndices[t],n=this.aliveEntitiesArray.length-1;if(e!==n){const r=this.aliveEntitiesArray[n];this.aliveEntitiesArray[e]=r,this.aliveEntitiesIndices[r]=e}this.aliveEntitiesArray.pop();const i=this.componentStoresArray,a=this.components.length;for(let r=0;r<a;r++)this.hasComponentBit(t,r)&&i[r].clear(t);this.clearAllComponentBits(t),this.freeEntityIds[this.freeEntityHead]=t,this.freeEntityHead=this.freeEntityHead+1&this.freeEntityMask,this.freeEntityCount++,this.invalidateQueryCache()}isAlive(t){return this.aliveEntityFlags[t]===1}getDespawned(){return this.despawnedBuffer.subarray(0,this.despawnedCount)}flushDespawned(){this.despawnedCount=0}invalidateQueryCache(){this.archetypeVersion++}markDirty(t,e){const n=this.dirtyBitsByComponent[e];n!=null&&(n[t>>>5]|=1<<(t&31))}isDirty(t,e){const n=e.__worldIndex;if(n===void 0)return!1;const i=this.dirtyBitsByComponent[n];return i==null?!1:(i[t>>>5]&1<<(t&31))!==0}clearDirty(t,e){const n=e.__worldIndex;if(n===void 0)return;const i=this.dirtyBitsByComponent[n];i!=null&&(i[t>>>5]&=~(1<<(t&31)))}forEachDirty(t,e){const n=t.__worldIndex;if(n===void 0)return;const i=this.dirtyBitsByComponent[n];if(i!=null)for(let a=0;a<i.length;a++){let r=i[a];if(r===0)continue;const l=a<<5;for(;r!==0;){const s=r&-r,o=31-Math.clz32(s);e(l+o),r^=s}}}clearAllDirty(){for(let t=0;t<this.dirtyBitsByComponent.length;t++){const e=this.dirtyBitsByComponent[t];e?.fill(0)}}add(t,e,n){if(this.aliveEntityFlags[t]===0)throw new Error(`Cannot add component ${e.name} to entity ${t}: entity is not alive (was it despawned?). Current alive entities: ${this.aliveEntitiesArray.length}`);const i=this.getComponentIndex(e),a=this.componentStoresArray[i];this.setComponentBit(t,i),a.set(t,n),this.markDirty(t,i),this.invalidateQueryCache()}remove(t,e){const n=e.__worldIndex;if(n===void 0)return;this.clearComponentBit(t,n);const i=this.componentStoresArray[n];i&&i.clear(t),this.invalidateQueryCache()}has(t,e){const n=e.__worldIndex;return n===void 0?!1:this.hasComponentBit(t,n)}get(t,e){const n=this.getComponentIndex(e);if(!this.hasComponentBit(t,n)){const i=this.getEntityComponentNames(t);throw new Error(`Cannot get component ${e.name} from entity ${t}: entity does not have this component. Entity has: [${i.join(", ")}]. Did you forget to call world.add()?`)}return this.componentStoresArray[n].get(t)}getMutable(t,e){const n=this.getComponentIndex(e);if(!this.hasComponentBit(t,n))throw new Error(`Entity ${t} does not have component ${e.name}`);return this.componentStoresArray[n].getMutable(t)}set(t,e,n){const i=this.getComponentIndex(e);if(!this.hasComponentBit(t,i))throw new Error(`Cannot set component ${e.name} on entity ${t}: entity does not have this component. Use add() first.`);this.componentStoresArray[i].set(t,n),this.markDirty(t,i)}update(t,e,n){const i=this.getComponentIndex(e);if(!this.hasComponentBit(t,i))throw new Error(`Entity ${t} does not have component ${e.name}`);this.componentStoresArray[i].update(t,n),this.markDirty(t,i)}query(...t){const e=this.getQueryMask(t);if(e===null)return[];const n=this.maskToKey(e);let i=this.queryResultBuffers[n];if(i||(i=[],this.queryResultBuffers[n]=i),this.queryCacheVersions[n]===this.archetypeVersion)return i;const a=this.aliveEntitiesArray,r=a.length,l=e.length;let s=0;if(l===1){const o=e[0],h=this.componentMasks0;for(let c=0;c<r;c++){const d=a[c];(h[d]&o)===o&&(i[s++]=d)}}else for(let o=0;o<r;o++){const h=a[o];this.matchesComponentMask(h,e)&&(i[s++]=h)}return i.length=s,this.queryCacheVersions[n]=this.archetypeVersion,i}getEntities(){return this.aliveEntitiesArray}getEntityCount(){return this.aliveEntitiesArray.length}getMaxEntities(){return this.maxEntities}getComponents(){return this.components}getEntityComponentNames(t){const e=[];for(let n=0;n<this.components.length;n++)this.hasComponentBit(t,n)&&e.push(this.components[n].name);return e}serialize(t,e){const n=e??Array.from(this.aliveEntitiesArray),i=[];for(const s of t){const o=s.__worldIndex;if(o===void 0)continue;const h=this.componentStoresArray[o];if(!h)continue;const c=[];for(const d of n)this.has(d,s)&&c.push({entity:d,...h.getMutable(d)});if(c.length>0){const d=s.arrayCodec.encode(c);i.push(d)}}const a=i.reduce((s,o)=>s+o.length,0),r=new Uint8Array(a);let l=0;for(const s of i)r.set(s,l),l+=s.length;return r}deserialize(t,e){throw new Error("Deserialization not yet implemented")}getFieldArray(t,e){const n=this.getComponentIndex(t);return this.componentStoresArray[n].getFieldArray(e)}fields(t){const e=this.getComponentIndex(t);return this.fieldsByComponent[e]}entity(t){return new v(this,t)}}export{T as World};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDriver as
|
|
1
|
+
import{createDriver as k,EventSystem as T,FixedTicker as _}from"../../core";import{InputManager as y,BrowserInputSource as b}from"../../core/input";import{TickerSchedule as E}from"./ticker-schedule";class w{constructor(e){this.options=e;this.fps=0;this.status="stopped";this._tickData={deltaTime:0,tick:0,input:null};this._skipData={ticks:0};this._renderData={deltaTime:0,alpha:0,input:null};const n=new Set(["client","manual-client"]),s=new Set(["manual-client","manual-server"]);this._isClient=n.has(this.options.type),this._isManual=s.has(this.options.type),this._scheduler=new E(this.options.maxSchedules??32);const i=["sync","pre-tick","tick","post-tick","skip","start","stop","toggle-pause"];this._isClient&&i.push("render"),this.events=new T({events:i}),this._input=new y;const a=this.events;if(this.ticker=new _({rate:this.options.tickRate,onTick:(t,r=0)=>{const p=this._input.snapshot();this._tickData.deltaTime=t,this._tickData.tick=r,this._tickData.input=p,a.emit("sync",this._tickData),a.emit("pre-tick",this._tickData),this.options.onTick?.(t,r,p),a.emit("tick",this._tickData),a.emit("post-tick",this._tickData),this._scheduler.run(r)},onTickSkipped:t=>{this._skipData.ticks=t,a.emit("skip",this._skipData)}}),this._isManual||(this._driver=k(this.options.type,t=>{this.step(t)})),this._isClient){const t=this.events,r=Math.round(this.options.tickRate/2),p=new Array(r).fill(0);let c=0,h=performance.now(),l=0,u=0;t.on("tick",()=>{l=(l+1)%r;const m=performance.now(),d=m-h;if(d>0){const o=c*1e3/d;p[l]=o,u<r&&u++}c=0,h=m;let v=0;for(let o=0;o<u;o++)v+=p[o];this.fps=Math.round(v/u)}),t.on("render",()=>{c++})}}step(e){if(this.ticker.tick(e),this._isClient){const n=this._input.peek(),s=this.ticker.alpha;this.options.onRender?.(e,s,n),this._renderData.deltaTime=e,this._renderData.alpha=s,this._renderData.input=n,this.events.emit("render",this._renderData)}}pause(){this._driver&&this._driver.stop(),this.status="paused",this.events.emit("toggle-pause",{paused:!0,lastToggledAt:Date.now(),lastToggleTick:this.ticker.tickCount})}resume(){this._driver&&this._driver.start(),this.status="running",this.events.emit("toggle-pause",{paused:!1,lastToggledAt:Date.now(),lastToggleTick:this.ticker.tickCount})}start(){if(this._driver&&this._driver.start(),this._scheduler.rebase(this.ticker.tickCount),this.status="running",this.events.emit("start",{startedAt:Date.now()}),this._isClient){const e=new b(document,document.body);this._input.listen(e)}}stop(){this._driver&&this._driver.stop(),this.ticker.resetTickCount(),this.status="stopped",this.events.emit("stop",{stoppedAt:Date.now()}),this._isClient&&this._input.unlisten()}every(e){const n=this.ticker.rate,s=this.ticker.tickCount;return{ticks:i=>this._scheduler.every(e,i,s),seconds:i=>this._scheduler.every(e*n,i,s),milliseconds:i=>this._scheduler.every(e/1e3*n,i,s)}}clearSchedule(e){return this._scheduler.clear(e)}clearSchedules(){this._scheduler.clearAll()}}export{w as GameLoop};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{SlotMap as a}from"../../core";const n=()=>{};class l{constructor(e){this._dirty=!1;this._running=!1;this._capacity=Math.max(1,Math.floor(e)),this._slots=new a(this._capacity),this._generations=new Uint32Array(this._capacity),this._pool=new Array(this._capacity);for(let t=0;t<this._capacity;t++)this._pool[t]={interval:0,next:0,cb:n,cancelled:!1}}get size(){return this._slots.size}get capacity(){return this._capacity}every(e,t,s){this._dirty&&!this._running&&this._compact();const i=this._slots.add();if(i===-1)return-1;const o=this._pool[i];return o.interval=Math.max(1,Math.round(e)),o.next=s+o.interval,o.cb=t,o.cancelled=!1,i+this._generations[i]*this._capacity}clear(e){const t=e%this._capacity;return t<0||!this._slots.has(t)||this._generations[t]!==(e-t)/this._capacity?!1:(this._pool[t].cancelled=!0,this._generations[t]++,this._dirty=!0,this._running||this._compact(),!0)}clearAll(){const e=this._slots.activeSlots,t=this._slots.size;for(let s=0;s<t;s++){const i=e[s];this._pool[i].cancelled=!0,this._generations[i]++}this._dirty=!0,this._running||this._compact()}run(e){this._dirty&&this._compact(),this._running=!0;const t=this._slots.activeSlots,s=this._slots.size;for(let i=0;i<s;i++){const o=this._pool[t[i]];o.cancelled||e>=o.next&&(o.next=e+o.interval,o.cb())}this._running=!1,this._dirty&&this._compact()}rebase(e){this._dirty&&this._compact();const t=this._slots.activeSlots,s=this._slots.size;for(let i=0;i<s;i++){const o=this._pool[t[i]];o.next=e+o.interval}}_compact(){const e=this._slots;let t=0;for(;t<e.size;){const s=e.activeSlots[t];this._pool[s].cancelled?(this._pool[s].cb=n,this._pool[s].cancelled=!1,e.remove(s)):t++}this._dirty=!1}}export{l as TickerSchedule};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{generateId as
|
|
1
|
+
import{generateId as h}from"../../core/generate-id/generate-id";class c{constructor(e){this.messageHandlers=[];this.closeHandlers=[];this.errorHandlers=[];this.socket=e,this.setupHandlers()}send(e){this.socket.readyState===WebSocket.OPEN&&this.socket.send(e)}onMessage(e){this.messageHandlers.push(e)}onClose(e){this.closeHandlers.push(e)}onError(e){this.errorHandlers.push(e)}close(){this.socket.close()}setupHandlers(){this.socket.binaryType="arraybuffer",this.socket.addEventListener("message",e=>{if(e.data instanceof ArrayBuffer){const r=new Uint8Array(e.data);for(const t of this.messageHandlers)t(r)}else{const r=new Error(`Unexpected message type: ${typeof e.data}`);for(const t of this.errorHandlers)t(r)}}),this.socket.addEventListener("close",()=>{for(const e of this.closeHandlers)e()}),this.socket.addEventListener("error",()=>{const e=new Error("WebSocket error");for(const r of this.errorHandlers)r(e)})}static connect(e){return new Promise((r,t)=>{const i=new WebSocket(e),a=new c(i);i.addEventListener("open",()=>{r(a)}),i.addEventListener("error",o=>{t(o)})})}}class v{constructor(e){this.messageHandlers=[];this.closeHandlers=[];this.errorHandlers=[];this.socket=e}send(e){this.socket.send(e)}onMessage(e){this.messageHandlers.push(e)}onClose(e){this.closeHandlers.push(e)}onError(e){this.errorHandlers.push(e)}close(){this.socket.close()}_handleOpen(){}_handleMessage(e){for(const r of this.messageHandlers)r(e)}_handleClose(){for(const e of this.closeHandlers)e()}_handleError(e){for(const r of this.errorHandlers)r(e)}}class p{constructor(e){this.peers=new Map;this.connectionHandlers=[];this.disconnectionHandlers=[];this.server=e}onConnection(e){this.connectionHandlers.push(e)}onDisconnection(e){this.disconnectionHandlers.push(e)}getPeer(e){return this.peers.get(e)}getPeerIds(){return Array.from(this.peers.keys())}close(){this.server.stop(),this.peers.clear()}_registerPeer(e){const r=h({prefix:"peer_"}),t=new v(e);return this.peers.set(r,t),r}_handlePeerMessage(e,r){const t=this.peers.get(e);t&&t._handleMessage(r)}_handlePeerDisconnection(e){const r=this.peers.get(e);if(r){r._handleClose(),this.peers.delete(e);for(const t of this.disconnectionHandlers)t(e)}}_handlePeerConnection(e){const r=this.peers.get(e);if(r)for(const t of this.connectionHandlers)t(r,e)}static create(e,r){const t=new WeakMap,i=r?.path,a=r?.fetch;let o;const l=Bun.serve({port:e,fetch(s,n){if(!((i===void 0||new URL(s.url).pathname===i)&&n.upgrade(s)))return a!==void 0?a(s,n):new Response("Expected WebSocket connection",{status:400})},websocket:{open(s){const n=o._registerPeer(s);t.set(s,n),o._handlePeerConnection(n)},message(s,n){const d=t.get(s);d&&n instanceof Uint8Array?o._handlePeerMessage(d,n):d&&n instanceof ArrayBuffer&&o._handlePeerMessage(d,new Uint8Array(n))},close(s){const n=t.get(s);n&&(o._handlePeerDisconnection(n),t.delete(s))}}});return o=new p(l),o}}export{c as BunWebSocketClientTransport,v as BunWebSocketPeerTransport,p as BunWebSocketServerTransport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./types";export*from"./base/renderer";export*from"./base/renderer-2d";export*from"./base/renderer-3d";export*from"./math";export*from"./gltf/skin-parser";export*from"./gltf/parser";import{SkeletalAnimation as l}from"./gltf/skeletal-animation";export*from"./spritesheet/helpers";export*from"./spritesheet/parser";export*from"./prefab-bucket";export*from"./prefab-bucket/specs";import{PrefabBucket as u}from"./prefab-bucket/concrete";export{u as PrefabBucket,l as SkeletalAnimation};
|
|
1
|
+
export*from"./types";export*from"./base/renderer";export*from"./base/renderer-2d";export*from"./base/renderer-3d";export*from"./math";export*from"./gltf/skin-parser";export*from"./gltf/parser";import{SkeletalAnimation as l}from"./gltf/skeletal-animation";export*from"./spritesheet/helpers";export*from"./spritesheet/parser";export*from"./prefab-bucket";export*from"./prefab-bucket/specs";import{PrefabBucket as u}from"./prefab-bucket/concrete";export*from"./raycast";export{u as PrefabBucket,l as SkeletalAnimation};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{BasePrefabBucket as
|
|
1
|
+
import{BasePrefabBucket as d}from"./index";import{parsers2d as c,parsers3d as f}from"./parsers";import{generateId as u}from"../../core/generate-id";class x extends d{constructor(e){super(e,e==="3d"?f:c);this._hitboxLibrary=null}hitboxes(e){return this._hitboxLibrary=e,this}get hitboxLibrary(){return this._hitboxLibrary}add(e){return super.add(e)}addAll(e){return super.addAll(e)}get(e){return super.get(e)}addGroup(e,p){if(e.includes("."))throw new Error(`PrefabBucket.addGroup: group name '${e}' is invalid - '.' is reserved for group paths`);if(this.groups.has(e))throw new Error(`PrefabBucket.addGroup: duplicate group '${e}'`);const t=[],s=[];for(const o of p){const r=o.id;if(r!==void 0&&r.includes("."))throw new Error(`PrefabBucket.addGroup: part id '${r}' is invalid - '.' is reserved for group paths`);const a=r!==void 0?`${e}.${r}`:u({prefix:`${e}.`,size:e.length+1+8}),{offset:n,...i}=o;this.addUnchecked({...i,id:a}),t.push(a),s.push(n?{partId:a,offset:n}:{partId:a})}return super.add({type:"composite",id:e,parts:s}),this.groups.set(e,t),this}getGroup(e){const t=this.groups.get(e);if(!t)throw new Error(`PrefabBucket.getGroup: unknown group '${e}'`);const s=t.map(r=>this.get(r)),o=this;return{prefabs:s,asComposite:()=>o.get(e)}}}export{x as PrefabBucket};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventSystem as n}from"../../core/events";class o{constructor(e,t={}){this.pending=[];this.pendingIds=new Set;this.prefabs=null;this.groups=new Map;this.mode=e,this.parsers=t,this.events=new n({events:["clips-changed"]})}add(e){if(e.id.includes("."))throw new Error(`PrefabBucket: id '${e.id}' is invalid - '.' is reserved for group paths`);return this.addUnchecked(e)}addUnchecked(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() - bucket is frozen");if(this.pendingIds.has(e.id))throw new Error(`PrefabBucket: duplicate id '${e.id}'`);return this.pending.push(e),this.pendingIds.add(e.id),this}addAll(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() \u2014 bucket is frozen");const t=new Set;for(const r of e){if(r.id.includes("."))throw new Error(`PrefabBucket: id '${r.id}' is invalid - '.' is reserved for group paths`);if(this.pendingIds.has(r.id)||t.has(r.id))throw new Error(`PrefabBucket: duplicate id '${r.id}'`);t.add(r.id)}for(const r of e)this.pending.push(r),this.pendingIds.add(r.id);return this}async load(){if(this.prefabs)return;const e={events:this.events},t=await Promise.all(this.pending.map(
|
|
1
|
+
import{EventSystem as n}from"../../core/events";class o{constructor(e,t={}){this.pending=[];this.pendingIds=new Set;this.prefabs=null;this.groups=new Map;this.mode=e,this.parsers=t,this.events=new n({events:["clips-changed"]})}add(e){if(e.id.includes("."))throw new Error(`PrefabBucket: id '${e.id}' is invalid - '.' is reserved for group paths`);return this.addUnchecked(e)}addUnchecked(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() - bucket is frozen");if(this.pendingIds.has(e.id))throw new Error(`PrefabBucket: duplicate id '${e.id}'`);return this.pending.push(e),this.pendingIds.add(e.id),this}addAll(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() \u2014 bucket is frozen");const t=new Set;for(const r of e){if(r.id.includes("."))throw new Error(`PrefabBucket: id '${r.id}' is invalid - '.' is reserved for group paths`);if(this.pendingIds.has(r.id)||t.has(r.id))throw new Error(`PrefabBucket: duplicate id '${r.id}'`);t.add(r.id)}for(const r of e)this.pending.push(r),this.pendingIds.add(r.id);return this}async load(){if(this.prefabs)return;const e={events:this.events},t=await Promise.all(this.pending.map(s=>{const a=this.parsers[s.type];if(!a)throw new Error(`PrefabBucket: no parser registered for type '${s.type}'`);return a(s,e)})),r=new Map;for(const s of t)r.set(s.id,s);this.prefabs=r,this.pending=[],this.pendingIds.clear()}get(e){if(!this.prefabs)throw new Error(`PrefabBucket: get('${e}') called before load()`);const t=this.prefabs.get(e);if(!t)throw new Error(`PrefabBucket: unknown prefab id '${e}'`);return t}get loaded(){return this.prefabs!==null}get size(){return this.prefabs?this.prefabs.size:this.pending.length}entries(){if(!this.prefabs)throw new Error("PrefabBucket: entries() called before load()");return Array.from(this.prefabs.values())}getAllByType(e){if(!this.prefabs)throw new Error(`PrefabBucket: getAllByType('${e}') called before load()`);const t=[];for(const r of this.prefabs.values())r.type===e&&t.push(r);return t}resetAnimations(){if(this.prefabs)for(const e of this.prefabs.values())e.resetAnimations?.()}}export{o as BasePrefabBucket};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseGltf as
|
|
1
|
+
import{parseGltf as b}from"../gltf/parser";import{parseSpritesheet as y}from"../spritesheet/parser";const v={gltf:async(t,p)=>{if(t.type!=="gltf")throw new Error("gltf parser given non-gltf spec");const n=await b(t.src,{animations:t.animations!==void 0?[...t.animations]:void 0,freezeAnimations:t.freezeAnimations===!0}),c=n.primitives.filter(s=>s.skinned).length,u=n.skin?.data.jointCount??0;let l=0;for(const s of n.primitives)l+=s.positions.length/3;const i={type:"gltf",id:t.id,parsed:n,skinnedPartCount:c,jointCount:u,totalVertexCount:l,metadata:t.metadata??{},hitbox:t.hitbox},h=t.animations!==void 0?[...t.animations]:n.skin?.animClips.map(s=>s.name)??[];if(h.length>0){const s={};for(const d of h)s[d]=d;i.animations=s,i.animationList=h}if(t.freezeAnimations!==!0){i.loadAnimations=async d=>{const a=n.skin,m=n.source;if(!a||!m)throw new Error(`loadAnimations: prefab '${t.id}' has no source \u2014 was the model skinned and not frozen?`);const f=new Set(a.animClips.map(r=>r.name)),e=[];for(const r of d){if(f.has(r))continue;const o=m.decodeAnimation(r);o&&(a.animClips.push(o),f.add(r),e.push(r))}if(e.length>0){i.animationList||(i.animationList=[]),i.animations||(i.animations={});const r=i.animationList,o=i.animations;for(const g of e)r.push(g),o[g]=g;p.events.emit("clips-changed",{prefabId:t.id,added:e,removed:[]})}},i.unloadAnimations=d=>{const a=n.skin;if(!a)return;const m=new Set(d),f=[];if(a.animClips=a.animClips.filter(e=>m.has(e.name)?(f.push(e.name),!1):!0),f.length>0){const e=i.animationList;if(e)for(let o=e.length-1;o>=0;o--)m.has(e[o])&&e.splice(o,1);const r=i.animations;if(r)for(const o of f)delete r[o];p.events.emit("clips-changed",{prefabId:t.id,added:[],removed:f})}};const s=new Set(h);i.resetAnimations=()=>{const d=n.skin;if(!d)return;const a=[];for(const m of d.animClips)s.has(m.name)||a.push(m.name);a.length>0&&i.unloadAnimations(a)}}return i},grid:t=>{if(t.type!=="grid")throw new Error("grid parser given non-grid spec");return{type:"grid",id:t.id,size:t.size,step:t.step,lineWidth:t.lineWidth,metadata:t.metadata??{},hitbox:t.hitbox}},cube:t=>{if(t.type!=="cube")throw new Error("cube parser given non-cube spec");return{type:"cube",id:t.id,size:t.size??1,metadata:t.metadata??{},hitbox:t.hitbox}},composite:t=>{if(t.type!=="composite")throw new Error("composite parser given non-composite spec");return{type:"composite",id:t.id,parts:t.parts,metadata:t.metadata??{},hitbox:t.hitbox}}},x={spritesheet:async(t,p)=>{if(t.type!=="spritesheet")throw new Error("spritesheet parser given non-spritesheet spec");const n=await y({image:t.src,frameWidth:t.frameWidth,frameHeight:t.frameHeight,data:t.data});return{type:"spritesheet",id:t.id,parsed:n,frameCount:n.uvs.length,width:n.width,height:n.height,metadata:t.metadata??{},hitbox:t.hitbox}}};export{x as parsers2d,v as parsers3d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./raycast";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class a{}class n{}export{a as Raycast,n as RaycastMemo};
|