Skip to content

Commit

Permalink
remove entities via editor
Browse files Browse the repository at this point in the history
  • Loading branch information
patreeceeo committed Nov 11, 2023
1 parent 431674e commit 5045b09
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 15 deletions.
3 changes: 3 additions & 0 deletions src/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
} from "./systems/PhysicsSystem";
import { setPixiAppId } from "./components/PixiAppId";
import { loadComponents } from "./functions/loadComponents";
import { RemoveEntitySystem } from "./systems/RemoveEntitySystem";

if (module.hot) {
module.hot.accept((getParents) => {
Expand Down Expand Up @@ -96,6 +97,7 @@ function startEditor() {
addFrameRhythmCallback(() => {
EditorSystem();
RenderSystem();
RemoveEntitySystem();
}),
);
}
Expand All @@ -109,6 +111,7 @@ function startGame() {
GameSystem();
PhysicsSystem();
RenderSystem();
RemoveEntitySystem();
}),
);
}
Expand Down
3 changes: 1 addition & 2 deletions src/Component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { peekNextEntityId, setNextEntityId } from "./Entity";
import { registerEntity } from "./Query";
import { peekNextEntityId, setNextEntityId, registerEntity } from "./Entity";
import { localStorage } from "./globals";

export function savePartialComponent<T>(
Expand Down
14 changes: 13 additions & 1 deletion src/Entity.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { invariant } from "./Error";
import { registerEntity } from "./Query";

let _nextId = 0;
const ALL_ENTITIES: Array<number> = [];

export function registerEntity(entityId: number): void {
ALL_ENTITIES[entityId] = entityId;
}

export function addEntity(): number {
const id = _nextId;
Expand All @@ -10,6 +14,10 @@ export function addEntity(): number {
return id;
}

export function removeEntity(entityId: number): void {
delete ALL_ENTITIES[entityId];
}

export function peekNextEntityId(): number {
return _nextId;
}
Expand All @@ -18,6 +26,10 @@ export function setNextEntityId(id: number): void {
_nextId = id;
}

export function listEntities(): ReadonlyArray<number> {
return ALL_ENTITIES;
}

export enum EntityName {
DEFAULT_PIXI_APP = "DEFAULT_PIXI_APP",
FLOOR_IMAGE = "FLOOR_IMAGE",
Expand Down
14 changes: 4 additions & 10 deletions src/Query.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { listEntities } from "./Entity";

type Filter = (entityId: number) => boolean;
export type ComplexFilter<RestArgs extends Array<number>> = {
fn: (entityId: number, ...args: RestArgs) => boolean;
restArgs: RestArgs;
};

const ALL_ENTITIES: Array<number> = [];

export function registerEntity(entityId: number): void {
ALL_ENTITIES[entityId] = entityId;
}

export function executeFilterQuery(
fn: Filter,
results: Array<number>,
): ReadonlyArray<number> {
for (let i = 0; i < ALL_ENTITIES.length; i++) {
const entityId = ALL_ENTITIES[i];
for (const entityId of listEntities()) {
if (fn(entityId)) {
results.push(entityId);
}
Expand All @@ -27,8 +22,7 @@ export function executeComplexFilterQuery<RestArgs extends Array<number>>(
filter: ComplexFilter<RestArgs>,
results: Array<number>,
): Array<number> {
for (let i = 0; i < ALL_ENTITIES.length; i++) {
const entityId = ALL_ENTITIES[i];
for (const entityId of listEntities()) {
if (filter.fn(entityId, ...filter.restArgs)) {
results.push(entityId);
}
Expand Down
12 changes: 12 additions & 0 deletions src/components/ToBeRemoved.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { setRenderStateDirty } from "../systems/RenderSystem";

const DATA: Array<boolean> = [];

export function setToBeRemoved(entityId: number, value: boolean) {
DATA[entityId] = value;
setRenderStateDirty();
}

export function isToBeRemoved(entityId: number): boolean {
return !!DATA[entityId];
}
15 changes: 15 additions & 0 deletions src/systems/RemoveEntitySystem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { removeEntity } from "../Entity";
import { executeFilterQuery } from "../Query";
import { isToBeRemoved } from "../components/ToBeRemoved";

const entityIds: number[] = [];
export function listEntitiesToBeRemoved(): ReadonlyArray<number> {
entityIds.length = 0;
return executeFilterQuery(isToBeRemoved, entityIds);
}

export function RemoveEntitySystem() {
for (const entityId of listEntitiesToBeRemoved()) {
removeEntity(entityId);
}
}
23 changes: 21 additions & 2 deletions src/systems/RenderSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { hasLoadingCompleted } from "../components/LoadingState";
import { Layer, getLayer, hasLayer } from "../components/Layer";
import { getIsVisible, hasIsVisible } from "../components/IsVisible";
import { getPixiApp } from "../components/PixiApp";
import { isToBeRemoved } from "../components/ToBeRemoved";

const WIDTH = 768;
const HEIGHT = 768;
Expand Down Expand Up @@ -51,7 +52,7 @@ function createLayerParticleContainers(): Record<
};
}

function getParticleContainers(
function getParticleContainer(
app: Application,
spriteId: number,
): ParticleContainer | undefined {
Expand Down Expand Up @@ -82,6 +83,12 @@ function getSpriteEntities(): ReadonlyArray<number> {
);
}

function listSpritesEntitiesToBeRemoved(): ReadonlyArray<number> {
spriteIds.length = 0;
return executeFilterQuery(and(hasSprite, isToBeRemoved), spriteIds);
}

// TODO[simplify]: get rid of dirty flag and check whether the Pixi container already contains a sprite before adding.
export function RenderSystem() {
if (!_isDirty) return;

Expand Down Expand Up @@ -111,7 +118,7 @@ export function RenderSystem() {
for (const spriteId of getSpriteEntities()) {
const sprite = getSprite(spriteId);
const app = getPixiApp(getPixiAppId(spriteId));
const container = getParticleContainers(app, spriteId);
const container = getParticleContainer(app, spriteId);
sprite.x = getPositionX(spriteId);
sprite.y = getPositionY(spriteId);
sprite.texture = getImage(getLookLike(spriteId)).texture!;
Expand All @@ -127,6 +134,18 @@ export function RenderSystem() {
sprite.visible = isVisible;
}
}

// clean up sprites of deleted entities
for (const spriteId of listSpritesEntitiesToBeRemoved()) {
const sprite = getSprite(spriteId);
const app = getPixiApp(getPixiAppId(spriteId));
const container = getParticleContainer(app, spriteId);
if (container) {
container.removeChild(sprite);
} else {
app.stage.removeChild(sprite);
}
}
_isDirty = false;
}

Expand Down

0 comments on commit 5045b09

Please sign in to comment.