Skip to content

Commit

Permalink
Fix some memory safety issues and update to latest shared-memory-obje…
Browse files Browse the repository at this point in the history
…cts version
  • Loading branch information
daneren2005 committed Apr 11, 2024
1 parent 0eeaa4b commit 3ee916d
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 27 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"update:commit": "ncu -u && npm install"
},
"dependencies": {
"@daneren2005/shared-memory-objects": "^0.0.3",
"@daneren2005/shared-memory-objects": "^0.0.4",
"bitecs": "^0.3.40",
"core-js": "^3.36.1",
"phaser": "^3.80.1",
Expand Down
14 changes: 14 additions & 0 deletions src/shared-memory-objects/entities/main-world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SpawnShipSystemWorker from '../systems/spawn-ship-system?worker';
import CollisionSystemWorker from '../systems/collision-system?worker';
import TargetEnemySystemWorker from '../systems/target-enemy-system?worker';
import MoveToTargetSystem from '../systems/move-to-target-system?worker';
import { GrowBufferData } from '@daneren2005/shared-memory-objects';

export default class MainWorld extends World {
systems: Array<System> = [];
Expand Down Expand Up @@ -53,6 +54,19 @@ export default class MainWorld extends World {
}));
}

growMemoryFromThread(memoryGrows: Array<GrowBufferData>, fromSystem: WorkerSystem) {
super.growMemoryFromThread(memoryGrows, fromSystem);

// Update other threads memory
this.systems.forEach(system => {
if(system === fromSystem || !(system instanceof WorkerSystem)) {
return;
}

system.pendingUpdates.memoryGrown.push(...memoryGrows);
});
}

destroy() {
this.systems.forEach(system => system.destroy());
this.systems = [];
Expand Down
12 changes: 3 additions & 9 deletions src/shared-memory-objects/entities/ship.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import computeAngle from '@/math/compute-angle';
import distance from '@/math/distance';
import euclideanDistance from '@/math/euclidean-distance';
import Entity from './entity';
import Station from './station';
// @ts-expect-error
import PhaserMath from 'phaser/src/math';
import degreesToRadians from '@/math/degrees-to-radians';
import { ENTITY_TYPES } from './types';
import World from './world';
import { SharedAllocatedMemory } from '@daneren2005/shared-memory-objects';

export default class Ship extends Entity {
station: Station;
station: Station | undefined;
uintMemory: Uint32Array;

velocityMemory: Float32Array;
Expand Down Expand Up @@ -71,15 +65,15 @@ export default class Ship extends Entity {
}

get color(): number {
return this.station.color;
return this.station?.color ?? 0;
}

die() {
if(this.dead) {
return;
}

this.station.removeShip(this);
this.station?.removeShip(this);

super.die();
}
Expand Down
16 changes: 13 additions & 3 deletions src/shared-memory-objects/entities/world.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Entity from './entity';
import Station from './station';
import { AllocatedMemory, MAX_BYTE_OFFSET_LENGTH, MemoryHeap, MemoryHeapMemory, SharedAllocatedMemory, SharedList, getPointer } from '@daneren2005/shared-memory-objects';
import { AllocatedMemory, GrowBufferData, MAX_BYTE_OFFSET_LENGTH, MemoryHeap, MemoryHeapMemory, SharedAllocatedMemory, SharedList, getPointer } from '@daneren2005/shared-memory-objects';
import EntityList from './entity-list';

import { ENTITY_TYPES } from './types';
import Ship from './ship';
import WorkerSystem from '../systems/worker-system';

const ID_INDEX = 0;
const BOUNDS_WIDTH_INDEX = 1;
Expand Down Expand Up @@ -35,7 +36,7 @@ export default class World {
});
} else {
this.heap = new MemoryHeap({
bufferSize: MAX_BYTE_OFFSET_LENGTH
bufferSize: 1024 * 100
});
this.memory = this.heap.allocUI32(World.ALLOCATE_COUNT);
this.entities = new EntityList(this, {
Expand Down Expand Up @@ -119,7 +120,11 @@ export default class World {
}

update(delta: number) {
this.garbageCollect();
try {
this.garbageCollect();
} catch(e) {
// TODO: Throws errors if ran when another buffer exists we haven't gotten yet
}
}

garbageCollect() {
Expand All @@ -131,6 +136,11 @@ export default class World {
});
}

growMemoryFromThread(memoryGrows: Array<GrowBufferData>, fromSystem: WorkerSystem) {
// Update our memory
memoryGrows.forEach(memoryGrown => this.heap.addSharedBuffer(memoryGrown));
}

getId() {
return Atomics.add(this.memory.data, ID_INDEX, 1);
}
Expand Down
25 changes: 22 additions & 3 deletions src/shared-memory-objects/systems/create-worker-system.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
import World from '../entities/world';
import { UpdateWorkerData } from './interfaces/update-worker-data';
import { UpdateMainData } from './interfaces/update-main-data';

export default function createWorkerSystem(initWorker: InitWorker) {
let world: World;
let workerRunner: WorkerRunner;
let pendingUpdates: UpdateMainData = {
memoryGrown: []
};
self.onmessage = function(e) {
if(e.data.init) {
world = new World(e.data.init);
workerRunner = initWorker(world);

world.heap.addOnGrowBufferHandlers(data => pendingUpdates.memoryGrown.push(data));
} else if(e.data.elapsedTime) {
workerRunner.run(e.data.elapsedTime);
world.garbageCollect();
let updates = e.data as UpdateWorkerData;
updates.memoryGrown.forEach(memoryGrown => world.heap.addSharedBuffer(memoryGrown));

try {
workerRunner.run(e.data.elapsedTime);
world.garbageCollect();
} catch(e) {
// TODO: Throws errors if ran when another buffer exists we haven't gotten yet
}

self.postMessage({
done: true
done: true,
...pendingUpdates
});

pendingUpdates = {
memoryGrown: []
};
}
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { GrowBufferData } from '@daneren2005/shared-memory-objects';

interface UpdateMainData {
memoryGrown: Array<GrowBufferData>
}

export type { UpdateMainData };
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { GrowBufferData } from '@daneren2005/shared-memory-objects';

interface UpdateWorkerData {
memoryGrown: Array<GrowBufferData>
}

export type { UpdateWorkerData };
20 changes: 16 additions & 4 deletions src/shared-memory-objects/systems/worker-system.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
import World, { WorldMemory } from '../entities/world';
import { UpdateMainData } from './interfaces/update-main-data';
import { UpdateWorkerData } from './interfaces/update-worker-data';
import System, { type SystemConfig } from './system';

export default class WorkerSystem extends System {
world: World;
worker: Worker;
runningResolve: (() => void) | null = null;

pendingUpdates: UpdateWorkerData = {
memoryGrown: []
};

constructor(world: World, options: WorkerSystemConfig) {
super(options);
this.world = world;
this.worker = options.worker;

this.worker.onmessage = (e) => {
if(e.data.done) {
let updates = e.data as UpdateMainData;
this.world.growMemoryFromThread(updates.memoryGrown, this);

this.runningResolve?.();
this.runningResolve = null;
}
};

const initConfig: WorldMemory = world.getSharedMemory();
world.heap.onGrowBufferHandlers.push(buffer => {
// TODO: Implement passing new buffer to thread
});
world.heap.addOnGrowBufferHandlers(data => this.pendingUpdates.memoryGrown.push(data));
this.worker.postMessage({
init: initConfig
});
Expand All @@ -32,8 +39,13 @@ export default class WorkerSystem extends System {
this.runningResolve = resolve;

this.worker.postMessage({
elapsedTime
elapsedTime,
...this.pendingUpdates
});

this.pendingUpdates = {
memoryGrown: []
};
});
}

Expand Down

0 comments on commit 3ee916d

Please sign in to comment.