Skip to content

Commit

Permalink
refactor: clean up some entity code
Browse files Browse the repository at this point in the history
  • Loading branch information
leia-uwu committed Sep 7, 2024
1 parent bf8dddf commit 56d5d86
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 45 deletions.
18 changes: 5 additions & 13 deletions client/src/game/entities/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,7 @@ export class EntityPool<T extends ClientEntity = ClientEntity> {
pool: Array<T> = [];
activeCount = 0;

entityCtr: new (
game: Game
) => T;

constructor(entityCtr: new (game: Game) => T) {
this.entityCtr = entityCtr;
}
constructor(public entityCtr: new (game: Game) => T) {}

allocEntity(game: Game, id: number) {
let entity: T | undefined = undefined;
Expand Down Expand Up @@ -108,9 +102,9 @@ export class EntityPool<T extends ClientEntity = ClientEntity> {

export class EntityManager {
entities: Array<ClientEntity> = [];
idToEntity: Array<ClientEntity | null> = new Array(
GameConstants.maxEntityId - 1
).fill(null);
idToEntity: Array<ClientEntity | null> = new Array(GameConstants.maxEntityId).fill(
null
);

constructor(
readonly game: Game,
Expand Down Expand Up @@ -182,9 +176,7 @@ export class EntityManager {
this.entities[i]?.destroy();
}
this.entities.length = 0;
for (let i = 0; i < GameConstants.maxEntityId; i++) {
this.idToEntity[i] = null;
}
this.idToEntity.fill(null);
}

update(dt: number) {
Expand Down
2 changes: 1 addition & 1 deletion common/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type ValidEntityType = Exclude<EntityType, EntityType.Invalid>;

export const GameConstants = {
maxPosition: 512,
maxEntityId: 1 << 16,
maxEntityId: (1 << 16) - 1,
leaderboardMaxEntries: 10,
player: {
nameMaxLength: 16,
Expand Down
45 changes: 18 additions & 27 deletions server/src/entities/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,32 +102,27 @@ export abstract class AbstractServerEntity<T extends ValidEntityType = ValidEnti

export type ServerEntity = Player | Projectile | Obstacle | Loot;

export abstract class EntityPool<
Ctr extends new (
game: Game
) => ServerEntity,
Inst extends InstanceType<Ctr> = InstanceType<Ctr>
> {
abstract type: Inst["__type"];

pool: Inst[] = [];
export abstract class EntityPool<T extends ServerEntity> {
abstract type: T["__type"];

pool: T[] = [];
activeCount = 0;

constructor(
public game: Game,
public ctr: Ctr
public entityCtr: new (game: Game) => T
) {}

allocEntity(...params: Parameters<Inst["init"]>) {
let entity: Inst | undefined = undefined;
allocEntity(...params: Parameters<T["init"]>) {
let entity: T | undefined = undefined;
for (let i = 0; i < this.pool.length; i++) {
if (!this.pool[i].active && !this.pool[i].registered) {
entity = this.pool[i];
break;
}
}
if (!entity) {
entity = new this.ctr(this.game) as Inst;
entity = new this.entityCtr(this.game) as T;
entity.initCache();
this.pool.push(entity);
}
Expand All @@ -145,14 +140,14 @@ export abstract class EntityPool<
return entity;
}

freeEntity(entity: Inst) {
freeEntity(entity: T) {
entity.active = false;

this.activeCount--;

// free some entities if pool is too big
if (this.pool.length > 128 && this.activeCount < this.pool.length / 2) {
const compact: Inst[] = [];
const compact: T[] = [];
for (let i = 0; i < this.pool.length; i++) {
const entity = this.pool[i];
if (entity.active) {
Expand All @@ -167,11 +162,10 @@ export abstract class EntityPool<

export class EntityManager {
entities: Array<ServerEntity> = [];
idToEntity: Array<ServerEntity | null> = new Array(
GameConstants.maxEntityId - 1
).fill(null);
idToEntity: Array<ServerEntity | null> = new Array(GameConstants.maxEntityId).fill(
null
);

idToType = new Uint8Array(GameConstants.maxEntityId);
dirtyPart = new Uint8Array(GameConstants.maxEntityId);
dirtyFull = new Uint8Array(GameConstants.maxEntityId);

Expand All @@ -181,10 +175,10 @@ export class EntityManager {
freeIds: number[] = [];

typeToPool: {
[EntityType.Player]: EntityPool<typeof Player>;
[EntityType.Projectile]: EntityPool<typeof Projectile>;
[EntityType.Obstacle]: EntityPool<typeof Obstacle>;
[EntityType.Loot]: EntityPool<typeof Loot>;
[EntityType.Player]: EntityPool<Player>;
[EntityType.Projectile]: EntityPool<Projectile>;
[EntityType.Obstacle]: EntityPool<Obstacle>;
[EntityType.Loot]: EntityPool<Loot>;
};

counts: DebugPacket["entityCounts"] = [];
Expand All @@ -202,7 +196,7 @@ export class EntityManager {

allocId() {
let id = 1;
if (this.idNext < GameConstants.maxEntityId) {
if (this.idNext <= GameConstants.maxEntityId) {
id = this.idNext++;
} else {
if (this.freeIds.length > 0) {
Expand All @@ -219,14 +213,12 @@ export class EntityManager {
}

register(entity: ServerEntity) {
const type = entity.__type;
const id = this.allocId();
entity.id = id;
entity.__arrayIdx = this.entities.length;
entity.registered = true;
this.entities[entity.__arrayIdx] = entity;
this.idToEntity[id] = entity;
this.idToType[id] = type;
this.dirtyPart[id] = 1;
this.dirtyFull[id] = 1;
this.updateCounts();
Expand All @@ -244,7 +236,6 @@ export class EntityManager {

this.freeId(entity.id);

this.idToType[entity.id] = 0;
this.dirtyPart[entity.id] = 0;
this.dirtyFull[entity.id] = 0;

Expand Down
2 changes: 1 addition & 1 deletion server/src/entities/loot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { Vector } from "../../../common/src/utils/vector";
import type { Game } from "../game";
import { AbstractServerEntity, EntityPool } from "./entity";

export class LootManager extends EntityPool<typeof Loot> {
export class LootManager extends EntityPool<Loot> {
override readonly type = EntityType.Loot;
constructor(readonly game: Game) {
super(game, Loot);
Expand Down
2 changes: 1 addition & 1 deletion server/src/entities/obstacle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { Vector } from "../../../common/src/utils/vector";
import type { Game } from "../game";
import { AbstractServerEntity, EntityPool } from "./entity";

export class ObstacleManager extends EntityPool<typeof Obstacle> {
export class ObstacleManager extends EntityPool<Obstacle> {
override readonly type = EntityType.Obstacle;
constructor(game: Game) {
super(game, Obstacle);
Expand Down
2 changes: 1 addition & 1 deletion server/src/entities/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { AbstractServerEntity, EntityPool } from "./entity";
import type { Loot } from "./loot";
import { Obstacle } from "./obstacle";

export class PlayerManager extends EntityPool<typeof Player> {
export class PlayerManager extends EntityPool<Player> {
override readonly type = EntityType.Player;

players: Player[] = [];
Expand Down
2 changes: 1 addition & 1 deletion server/src/entities/projectile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { Game } from "../game";
import { AbstractServerEntity, EntityPool, type ServerEntity } from "./entity";
import type { Player } from "./player";

export class ProjectileManager extends EntityPool<typeof Projectile> {
export class ProjectileManager extends EntityPool<Projectile> {
override readonly type = EntityType.Projectile;

constructor(readonly game: Game) {
Expand Down

0 comments on commit 56d5d86

Please sign in to comment.