Comparing version 0.3.2 to 0.3.3
@@ -5,3 +5,2 @@ import { component } from '../Component2.js'; | ||
import { Game } from '../Game.js'; | ||
import { logger } from '../logger.js'; | ||
import { system } from '../System.js'; | ||
@@ -19,3 +18,3 @@ import { describe, it, expect } from 'vitest'; | ||
const SetFlagEffect = effect([RemovableComponent, OutputComponent], function (ent) { | ||
logger.debug('Setting removablePresent: true'); | ||
console.debug('Setting removablePresent: true'); | ||
const output = ent.get(OutputComponent); | ||
@@ -25,3 +24,3 @@ output.removablePresent = true; | ||
return () => { | ||
logger.debug('Setting removablePresent: false'); | ||
console.debug('Setting removablePresent: false'); | ||
const output = ent.get(OutputComponent); | ||
@@ -33,18 +32,29 @@ output.removablePresent = false; | ||
const ReAddRemovableEffect = effect([not(RemovableComponent)], function (ent, game) { | ||
logger.debug('Adding RemovableComponent'); | ||
console.debug('Adding RemovableComponent'); | ||
game.add(ent.id, RemovableComponent); | ||
}); | ||
const IncrementRemoveTimerSystem = system([RemovableComponent], (ent) => { | ||
logger.debug('Incrementing stepsSinceAdded'); | ||
console.debug('Incrementing stepsSinceAdded'); | ||
const comp = ent.get(RemovableComponent); | ||
comp.stepsSinceAdded++; | ||
comp.$.changed = true; | ||
logger.debug(`stepsSinceAdded: ${comp.stepsSinceAdded}`); | ||
console.debug(`stepsSinceAdded: ${comp.stepsSinceAdded}`); | ||
}); | ||
const RemoveSystem = system([changed(RemovableComponent)], (ent, game) => { | ||
if (ent.get(RemovableComponent).stepsSinceAdded >= stepsTillToggle) { | ||
logger.debug('Removing RemovableComponent'); | ||
console.debug('Removing RemovableComponent'); | ||
game.remove(ent.id, RemovableComponent); | ||
} | ||
}); | ||
const DeleteMeComponent = component('DeleteMe', () => ({})); | ||
const DeleteSystem = system([DeleteMeComponent], (ent, game) => { | ||
console.debug('Deleting entity', ent.id); | ||
game.destroy(ent.id); | ||
}); | ||
const ReAddEffect = effect([DeleteMeComponent], (ent, game) => { | ||
return () => { | ||
const newId = game.create(); | ||
game.add(newId, OutputComponent); | ||
}; | ||
}); | ||
it('adds and removes components, and queries for those operations', () => { | ||
@@ -54,3 +64,3 @@ const game = new Game(); | ||
game.add(a, OutputComponent); | ||
logger.debug('Step 1'); | ||
console.debug('Step 1'); | ||
game.step(delta); | ||
@@ -60,3 +70,3 @@ let entity = game.get(a); | ||
expect(entity.get(OutputComponent).removablePresent).toBe(false); | ||
logger.debug('Step 2'); | ||
console.debug('Step 2'); | ||
game.step(delta); | ||
@@ -67,3 +77,3 @@ entity = game.get(a); | ||
expect(entity.maybeGet(RemovableComponent).stepsSinceAdded).toBe(0); | ||
logger.debug('Step 3'); | ||
console.debug('Step 3'); | ||
game.step(delta); | ||
@@ -74,3 +84,3 @@ entity = game.get(a); | ||
expect(entity.maybeGet(RemovableComponent).stepsSinceAdded).toBe(1); | ||
logger.debug('Step 4'); | ||
console.debug('Step 4'); | ||
game.step(delta); | ||
@@ -81,3 +91,3 @@ entity = game.get(a); | ||
expect(entity.maybeGet(RemovableComponent).stepsSinceAdded).toBe(2); | ||
logger.debug('Step 5'); | ||
console.debug('Step 5'); | ||
game.step(delta); | ||
@@ -87,3 +97,3 @@ entity = game.get(a); | ||
expect(entity.maybeGet(RemovableComponent)).toBe(null); | ||
logger.debug('Step 6'); | ||
console.debug('Step 6'); | ||
game.step(delta); | ||
@@ -95,3 +105,29 @@ entity = game.get(a); | ||
}); | ||
it('handles deleting and recycling entities', () => { | ||
const game = new Game({ | ||
logLevel: 'debug', | ||
}); | ||
const a = game.create(); | ||
game.add(a, DeleteMeComponent); | ||
console.debug('Step 1'); | ||
game.step(delta); | ||
const deleted = game.get(a); | ||
// why does it take 2 steps to remove? | ||
// the entity and component are only actually created | ||
// when operations are applied in step 1, at the end. | ||
// so step 2 is the first time the has(DeleteMe) query | ||
// matches. | ||
console.debug('Step 2'); | ||
game.step(delta); | ||
expect(deleted === null || deleted === void 0 ? void 0 : deleted.removed).toBe(true); | ||
console.debug('Step 3'); | ||
game.step(delta); | ||
// this assertion might be too strong, but currently | ||
// based on this game simulation, the original entity | ||
// should be pooled and reused to make the new one. | ||
const newEntity = game.findFirst([OutputComponent]); | ||
expect(newEntity).not.toBe(null); | ||
expect(newEntity).toBe(deleted); | ||
}); | ||
}); | ||
//# sourceMappingURL=integration.test.js.map |
import { EventSubscriber } from '@a-type/utils'; | ||
import { Archetype } from './Archetype.js'; | ||
import { logger } from './logger.js'; | ||
import { getIdSignifier } from './ids.js'; | ||
@@ -33,3 +32,3 @@ export class ArchetypeManager extends EventSubscriber { | ||
createEntity(entityId) { | ||
logger.debug(`Creating entity ${entityId}`); | ||
this.game.logger.debug(`Creating entity ${entityId}`); | ||
this.setEntityArchetype(entityId, this.emptyId); | ||
@@ -43,3 +42,3 @@ // allocate an Entity | ||
addComponent(entityId, instance) { | ||
logger.debug(`Adding ${Object.getPrototypeOf(instance).constructor.name} to entity ${entityId}`); | ||
this.game.logger.debug(`Adding ${instance.$.type.name} to entity ${entityId}`); | ||
const oldArchetypeId = this.lookupEntityArchetype(entityId); | ||
@@ -62,10 +61,10 @@ if (oldArchetypeId === undefined) { | ||
archetype.addEntity(entity); | ||
logger.debug(`Entity ${entityId} moved to archetype ${newArchetypeId}`); | ||
this.game.logger.debug(`Entity ${entityId} moved to archetype ${newArchetypeId}`); | ||
this.emit('entityComponentAdded', entityId, instance); | ||
} | ||
removeComponent(entityId, componentType) { | ||
logger.debug(`Removing ${this.game.componentManager.getTypeName(componentType)} from entity ${entityId}`); | ||
this.game.logger.debug(`Removing ${this.game.componentManager.getTypeName(componentType)} from entity ${entityId}`); | ||
const oldArchetypeId = this.lookupEntityArchetype(entityId); | ||
if (oldArchetypeId === undefined) { | ||
logger.warn(`Tried to remove component ${this.game.componentManager.getTypeName(componentType)} from ${entityId}, but it was not found in the archetype registry`); | ||
this.game.logger.warn(`Tried to remove component ${this.game.componentManager.getTypeName(componentType)} from ${entityId}, but it was not found in the archetype registry`); | ||
return; | ||
@@ -80,3 +79,3 @@ } | ||
archetype.addEntity(entity); | ||
logger.debug(`Entity ${entityId} moved to archetype ${newArchetypeId}`); | ||
this.game.logger.debug(`Entity ${entityId} moved to archetype ${newArchetypeId}`); | ||
this.emit('entityComponentRemoved', entityId, componentType); | ||
@@ -86,3 +85,3 @@ return removed; | ||
destroyEntity(entityId) { | ||
logger.debug(`Destroying entity ${entityId}`); | ||
this.game.logger.debug(`Destroying entity ${entityId}`); | ||
const archetypeId = this.lookupEntityArchetype(entityId); | ||
@@ -96,2 +95,3 @@ if (archetypeId === undefined) { | ||
this.emit('entityDestroyed', entityId); | ||
entity.__markRemoved(); | ||
return entity; | ||
@@ -102,3 +102,3 @@ } | ||
if (archetypeId === undefined) { | ||
logger.debug(`Could not find Archetype for Entity ${entityId}`); | ||
this.game.logger.debug(`Could not find Archetype for Entity ${entityId}`); | ||
return null; | ||
@@ -113,3 +113,3 @@ } | ||
archetype = this.archetypes[id] = new Archetype(id); | ||
logger.debug(`New Archetype ${id} created`); | ||
this.game.logger.debug(`New Archetype ${id} created`); | ||
this.emit('archetypeCreated', archetype); | ||
@@ -116,0 +116,0 @@ } |
@@ -7,7 +7,10 @@ import { ComponentHandle, ComponentInstance, ComponentInstanceInternal, InstanceFor } from './Component2.js'; | ||
private _destroyed; | ||
private _removed; | ||
get id(): number; | ||
get destroyed(): boolean; | ||
get removed(): boolean; | ||
__set: (entityId: number, components: ComponentInstanceInternal[] | Readonly<ComponentInstanceInternal[]>) => void; | ||
__addComponent: (instance: ComponentInstanceInternal) => void; | ||
__removeComponent: (typeId: number) => ComponentInstanceInternal; | ||
__markRemoved: () => void; | ||
get: <T extends ComponentHandle>(handle: T) => DefinedInstance<DefiniteComponents, OmittedComponents, T>; | ||
@@ -14,0 +17,0 @@ maybeGet: <T extends ComponentHandle>(handle: T) => InstanceFor<T> | null; |
@@ -7,2 +7,3 @@ export class Entity { | ||
this._destroyed = true; | ||
this._removed = false; | ||
// TODO: hide these behind Symbols? | ||
@@ -16,2 +17,3 @@ this.__set = (entityId, components) => { | ||
this._destroyed = false; | ||
this._removed = false; | ||
}; | ||
@@ -26,2 +28,5 @@ this.__addComponent = (instance) => { | ||
}; | ||
this.__markRemoved = () => { | ||
this._removed = true; | ||
}; | ||
this.get = (handle) => { | ||
@@ -47,2 +52,5 @@ var _a; | ||
} | ||
get removed() { | ||
return this._removed; | ||
} | ||
reset() { | ||
@@ -49,0 +57,0 @@ this.components.clear(); |
@@ -14,2 +14,3 @@ import { QueryManager } from './QueryManager.js'; | ||
import { ComponentHandle } from './Component2.js'; | ||
import { Logger } from './logger.js'; | ||
export type GameConstants = { | ||
@@ -42,6 +43,8 @@ maxComponentId: number; | ||
private _constants; | ||
constructor({ assetLoaders, ignoreSystemsWarning, phases, }?: { | ||
readonly logger: Logger; | ||
constructor({ assetLoaders, ignoreSystemsWarning, phases, logLevel, }?: { | ||
assetLoaders?: AssetLoaders; | ||
ignoreSystemsWarning?: boolean; | ||
phases?: string[]; | ||
logLevel?: 'debug' | 'info' | 'warn' | 'error'; | ||
}); | ||
@@ -48,0 +51,0 @@ get entityIds(): IdManager; |
@@ -12,4 +12,5 @@ import { QueryManager } from './QueryManager.js'; | ||
import { allSystems } from './System.js'; | ||
import { Logger } from './logger.js'; | ||
export class Game { | ||
constructor({ assetLoaders = {}, ignoreSystemsWarning, phases, } = {}) { | ||
constructor({ assetLoaders = {}, ignoreSystemsWarning, phases, logLevel, } = {}) { | ||
this.events = new EventSubscriber(); | ||
@@ -21,3 +22,2 @@ this._entityIds = new IdManager((...msgs) => console.debug('Entity IDs:', ...msgs)); | ||
this._phaseOperationQueue = []; | ||
this._globals = new Resources(); | ||
this._entityPool = new ObjectPool(() => new Entity(), (e) => e.reset()); | ||
@@ -191,2 +191,4 @@ this._removedList = new RemovedList(); | ||
this._archetypeManager = new ArchetypeManager(this); | ||
this._globals = new Resources(this); | ||
this.logger = new Logger(logLevel !== null && logLevel !== void 0 ? logLevel : 'info'); | ||
if (allSystems.length === 0 && !ignoreSystemsWarning) { | ||
@@ -193,0 +195,0 @@ throw new Error('No systems are defined at the type of game construction. You have to define systems before calling the Game constructor. Did you forget to import modules which define your systems?'); |
@@ -19,7 +19,7 @@ export class Pointer { | ||
if (ev.type === 'pointerdown') { | ||
if (ev.buttons === 1) { | ||
if (ev.button === 1) { | ||
this._primaryDown = true; | ||
this._primaryPressed = true; | ||
} | ||
else if (ev.buttons === 2) { | ||
else if (ev.button === 2) { | ||
this._secondaryDown = true; | ||
@@ -30,7 +30,7 @@ this._secondaryPressed = true; | ||
else if (ev.type === 'pointerup') { | ||
if (ev.buttons === 1) { | ||
if (ev.button === 1) { | ||
this._primaryUp = true; | ||
this._primaryPressed = false; | ||
} | ||
else if (ev.buttons === 2) { | ||
else if (ev.button === 2) { | ||
this._secondaryUp = true; | ||
@@ -37,0 +37,0 @@ this._secondaryPressed = false; |
@@ -1,2 +0,1 @@ | ||
import { logger } from '../logger.js'; | ||
export class ObjectPool { | ||
@@ -23,3 +22,3 @@ constructor(factory, reset = () => { }, initialSize = 1) { | ||
if (!item) { | ||
logger.warn(`Tried to release ${item}`); | ||
console.warn(`Tried to release ${item}. This might be a bug.`); | ||
return; | ||
@@ -26,0 +25,0 @@ } |
@@ -1,2 +0,6 @@ | ||
export declare const logger: { | ||
export declare class Logger { | ||
static readonly levels: readonly ["debug", "info", "warn", "error"]; | ||
private lvl; | ||
doLog: (level: 'info' | 'warn' | 'error' | 'debug', ...messages: unknown[]) => void; | ||
constructor(level: 'info' | 'warn' | 'error' | 'debug'); | ||
info: (...args: unknown[]) => void; | ||
@@ -7,2 +11,3 @@ warn: (...args: unknown[]) => void; | ||
log: (...args: unknown[]) => void; | ||
}; | ||
} | ||
export declare const defaultLogger: Logger; |
@@ -1,13 +0,19 @@ | ||
const doLog = (level, ...messages) => { | ||
if (localStorage.getItem('DEBUG') === 'true' || window.DEBUG) { | ||
console[level](...messages); | ||
export class Logger { | ||
constructor(level) { | ||
this.lvl = 2; | ||
this.doLog = (level, ...messages) => { | ||
if (Logger.levels.indexOf(level) >= this.lvl) { | ||
console[level](...messages); | ||
} | ||
}; | ||
this.info = this.doLog.bind(null, 'info'); | ||
this.warn = this.doLog.bind(null, 'warn'); | ||
this.error = this.doLog.bind(null, 'error'); | ||
this.debug = this.doLog.bind(null, 'debug'); | ||
this.log = this.doLog.bind(null, 'info'); | ||
this.lvl = Logger.levels.indexOf(level); | ||
} | ||
}; | ||
export const logger = { | ||
info: doLog.bind(null, 'info'), | ||
warn: doLog.bind(null, 'warn'), | ||
error: doLog.bind(null, 'error'), | ||
debug: doLog.bind(null, 'debug'), | ||
log: doLog.bind(null, 'log'), | ||
}; | ||
} | ||
Logger.levels = ['debug', 'info', 'warn', 'error']; | ||
export const defaultLogger = new Logger('info'); | ||
//# sourceMappingURL=logger.js.map |
import { isFilter, has } from './filters.js'; | ||
import { QueryIterator } from './QueryIterator.js'; | ||
import { logger } from './logger.js'; | ||
import { EventSubscriber } from '@a-type/utils'; | ||
@@ -40,3 +39,3 @@ export class Query extends EventSubscriber { | ||
this.archetypes.push(archetype); | ||
logger.debug(`Query ${this.toString()} added Archetype ${archetype.id}`); | ||
this.game.logger.debug(`Query ${this.toString()} added Archetype ${archetype.id}`); | ||
this.unsubscribes.push(archetype.subscribe('entityRemoved', this.handleEntityRemoved)); | ||
@@ -93,7 +92,7 @@ this.unsubscribes.push(archetype.subscribe('entityAdded', this.handleEntityAdded)); | ||
this.emitAdded = (entityId) => { | ||
logger.debug(`Entity ${entityId} added to query ${this.toString()}`); | ||
this.game.logger.debug(`Entity ${entityId} added to query ${this.toString()}`); | ||
this.emit('entityAdded', entityId); | ||
}; | ||
this.emitRemoved = (entityId) => { | ||
logger.debug(`Entity ${entityId} removed from query ${this.toString()}`); | ||
this.game.logger.debug(`Entity ${entityId} removed from query ${this.toString()}`); | ||
this.emit('entityRemoved', entityId); | ||
@@ -117,3 +116,3 @@ }; | ||
initialize(def) { | ||
logger.debug(`Initializing Query ${this.toString()}`); | ||
this.game.logger.debug(`Initializing Query ${this.toString()}`); | ||
this.filter = this.processDef(def); | ||
@@ -120,0 +119,0 @@ Object.values(this.game.archetypeManager.archetypes).forEach(this.matchArchetype); |
@@ -0,4 +1,7 @@ | ||
import { Game } from './index.js'; | ||
export declare class Resources<ResourceMap extends Record<string, any>> { | ||
private game; | ||
private handlePool; | ||
private handles; | ||
constructor(game: Game); | ||
private getOrCreateGlobalHandle; | ||
@@ -5,0 +8,0 @@ load: <Key extends keyof ResourceMap>(key: Key) => Promise<ResourceMap[Key]>; |
import { ObjectPool } from './internal/objectPool.js'; | ||
import { logger } from './logger.js'; | ||
import { ResourceHandle } from './ResourceHandle.js'; | ||
export class Resources { | ||
constructor() { | ||
this.handlePool = new ObjectPool(() => new ResourceHandle(), h => h.reset()); | ||
constructor(game) { | ||
this.game = game; | ||
this.handlePool = new ObjectPool(() => new ResourceHandle(), (h) => h.reset()); | ||
this.handles = new Map(); | ||
@@ -21,3 +21,3 @@ this.getOrCreateGlobalHandle = (key) => { | ||
this.getOrCreateGlobalHandle(key).resolve(value); | ||
logger.debug('Resolved resource', key); | ||
this.game.logger.debug('Resolved resource', key); | ||
}; | ||
@@ -24,0 +24,0 @@ this.immediate = (key) => { |
{ | ||
"name": "0g", | ||
"version": "0.3.2", | ||
"version": "0.3.3", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -6,3 +6,2 @@ import { component } from '../Component2.js'; | ||
import { Game } from '../Game.js'; | ||
import { logger } from '../logger.js'; | ||
import { system } from '../System.js'; | ||
@@ -27,3 +26,3 @@ import { describe, it, expect } from 'vitest'; | ||
function (ent) { | ||
logger.debug('Setting removablePresent: true'); | ||
console.debug('Setting removablePresent: true'); | ||
const output = ent.get(OutputComponent); | ||
@@ -34,3 +33,3 @@ output.removablePresent = true; | ||
return () => { | ||
logger.debug('Setting removablePresent: false'); | ||
console.debug('Setting removablePresent: false'); | ||
const output = ent.get(OutputComponent); | ||
@@ -46,3 +45,3 @@ output.removablePresent = false; | ||
function (ent, game) { | ||
logger.debug('Adding RemovableComponent'); | ||
console.debug('Adding RemovableComponent'); | ||
game.add(ent.id, RemovableComponent); | ||
@@ -53,7 +52,7 @@ }, | ||
const IncrementRemoveTimerSystem = system([RemovableComponent], (ent) => { | ||
logger.debug('Incrementing stepsSinceAdded'); | ||
console.debug('Incrementing stepsSinceAdded'); | ||
const comp = ent.get(RemovableComponent); | ||
comp.stepsSinceAdded++; | ||
comp.$.changed = true; | ||
logger.debug(`stepsSinceAdded: ${comp.stepsSinceAdded}`); | ||
console.debug(`stepsSinceAdded: ${comp.stepsSinceAdded}`); | ||
}); | ||
@@ -63,3 +62,3 @@ | ||
if (ent.get(RemovableComponent).stepsSinceAdded >= stepsTillToggle) { | ||
logger.debug('Removing RemovableComponent'); | ||
console.debug('Removing RemovableComponent'); | ||
game.remove(ent.id, RemovableComponent); | ||
@@ -69,2 +68,16 @@ } | ||
const DeleteMeComponent = component('DeleteMe', () => ({})); | ||
const DeleteSystem = system([DeleteMeComponent], (ent, game) => { | ||
console.debug('Deleting entity', ent.id); | ||
game.destroy(ent.id); | ||
}); | ||
const ReAddEffect = effect([DeleteMeComponent], (ent, game) => { | ||
return () => { | ||
const newId = game.create(); | ||
game.add(newId, OutputComponent); | ||
}; | ||
}); | ||
it('adds and removes components, and queries for those operations', () => { | ||
@@ -76,3 +89,3 @@ const game = new Game(); | ||
logger.debug('Step 1'); | ||
console.debug('Step 1'); | ||
game.step(delta); | ||
@@ -85,3 +98,3 @@ | ||
logger.debug('Step 2'); | ||
console.debug('Step 2'); | ||
game.step(delta); | ||
@@ -94,3 +107,3 @@ entity = game.get(a)!; | ||
logger.debug('Step 3'); | ||
console.debug('Step 3'); | ||
game.step(delta); | ||
@@ -103,3 +116,3 @@ entity = game.get(a)!; | ||
logger.debug('Step 4'); | ||
console.debug('Step 4'); | ||
game.step(delta); | ||
@@ -112,3 +125,3 @@ entity = game.get(a)!; | ||
logger.debug('Step 5'); | ||
console.debug('Step 5'); | ||
game.step(delta); | ||
@@ -120,3 +133,3 @@ entity = game.get(a)!; | ||
logger.debug('Step 6'); | ||
console.debug('Step 6'); | ||
game.step(delta); | ||
@@ -129,2 +142,35 @@ entity = game.get(a)!; | ||
}); | ||
it('handles deleting and recycling entities', () => { | ||
const game = new Game({ | ||
logLevel: 'debug', | ||
}); | ||
const a = game.create(); | ||
game.add(a, DeleteMeComponent); | ||
console.debug('Step 1'); | ||
game.step(delta); | ||
const deleted = game.get(a); | ||
// why does it take 2 steps to remove? | ||
// the entity and component are only actually created | ||
// when operations are applied in step 1, at the end. | ||
// so step 2 is the first time the has(DeleteMe) query | ||
// matches. | ||
console.debug('Step 2'); | ||
game.step(delta); | ||
expect(deleted?.removed).toBe(true); | ||
console.debug('Step 3'); | ||
game.step(delta); | ||
// this assertion might be too strong, but currently | ||
// based on this game simulation, the original entity | ||
// should be pooled and reused to make the new one. | ||
const newEntity = game.findFirst([OutputComponent]); | ||
expect(newEntity).not.toBe(null); | ||
expect(newEntity).toBe(deleted); | ||
}); | ||
}); |
@@ -5,3 +5,2 @@ import { EventSubscriber } from '@a-type/utils'; | ||
import { Game } from './Game.js'; | ||
import { logger } from './logger.js'; | ||
import { getIdSignifier } from './ids.js'; | ||
@@ -54,3 +53,3 @@ | ||
createEntity(entityId: number) { | ||
logger.debug(`Creating entity ${entityId}`); | ||
this.game.logger.debug(`Creating entity ${entityId}`); | ||
this.setEntityArchetype(entityId, this.emptyId); | ||
@@ -65,6 +64,4 @@ // allocate an Entity | ||
addComponent(entityId: number, instance: ComponentInstanceInternal) { | ||
logger.debug( | ||
`Adding ${ | ||
Object.getPrototypeOf(instance).constructor.name | ||
} to entity ${entityId}`, | ||
this.game.logger.debug( | ||
`Adding ${instance.$.type.name} to entity ${entityId}`, | ||
); | ||
@@ -95,3 +92,5 @@ const oldArchetypeId = this.lookupEntityArchetype(entityId); | ||
archetype.addEntity(entity); | ||
logger.debug(`Entity ${entityId} moved to archetype ${newArchetypeId}`); | ||
this.game.logger.debug( | ||
`Entity ${entityId} moved to archetype ${newArchetypeId}`, | ||
); | ||
this.emit('entityComponentAdded', entityId, instance); | ||
@@ -101,3 +100,3 @@ } | ||
removeComponent(entityId: number, componentType: number) { | ||
logger.debug( | ||
this.game.logger.debug( | ||
`Removing ${this.game.componentManager.getTypeName( | ||
@@ -109,3 +108,3 @@ componentType, | ||
if (oldArchetypeId === undefined) { | ||
logger.warn( | ||
this.game.logger.warn( | ||
`Tried to remove component ${this.game.componentManager.getTypeName( | ||
@@ -126,3 +125,5 @@ componentType, | ||
archetype.addEntity(entity); | ||
logger.debug(`Entity ${entityId} moved to archetype ${newArchetypeId}`); | ||
this.game.logger.debug( | ||
`Entity ${entityId} moved to archetype ${newArchetypeId}`, | ||
); | ||
this.emit('entityComponentRemoved', entityId, componentType); | ||
@@ -134,3 +135,3 @@ | ||
destroyEntity(entityId: number) { | ||
logger.debug(`Destroying entity ${entityId}`); | ||
this.game.logger.debug(`Destroying entity ${entityId}`); | ||
const archetypeId = this.lookupEntityArchetype(entityId); | ||
@@ -146,2 +147,3 @@ if (archetypeId === undefined) { | ||
this.emit('entityDestroyed', entityId); | ||
entity.__markRemoved(); | ||
return entity; | ||
@@ -153,3 +155,3 @@ } | ||
if (archetypeId === undefined) { | ||
logger.debug(`Could not find Archetype for Entity ${entityId}`); | ||
this.game.logger.debug(`Could not find Archetype for Entity ${entityId}`); | ||
return null; | ||
@@ -165,3 +167,3 @@ } | ||
archetype = this.archetypes[id] = new Archetype(id); | ||
logger.debug(`New Archetype ${id} created`); | ||
this.game.logger.debug(`New Archetype ${id} created`); | ||
this.emit('archetypeCreated', archetype); | ||
@@ -168,0 +170,0 @@ } |
@@ -30,2 +30,3 @@ import { | ||
private _destroyed = true; | ||
private _removed = false; | ||
@@ -40,2 +41,6 @@ get id() { | ||
get removed() { | ||
return this._removed; | ||
} | ||
// TODO: hide these behind Symbols? | ||
@@ -54,2 +59,3 @@ __set = ( | ||
this._destroyed = false; | ||
this._removed = false; | ||
}; | ||
@@ -67,2 +73,6 @@ | ||
__markRemoved = () => { | ||
this._removed = true; | ||
}; | ||
get = <T extends ComponentHandle>( | ||
@@ -69,0 +79,0 @@ handle: T, |
@@ -22,2 +22,3 @@ import { QueryManager } from './QueryManager.js'; | ||
import { allSystems } from './System.js'; | ||
import { Logger } from './logger.js'; | ||
@@ -48,3 +49,3 @@ export type GameConstants = { | ||
private _componentManager: ComponentManager; | ||
private _globals = new Resources<Globals>(); | ||
private _globals; | ||
private _runnableCleanups: (() => void)[]; | ||
@@ -68,2 +69,4 @@ private _entityPool = new ObjectPool( | ||
readonly logger; | ||
constructor({ | ||
@@ -73,2 +76,3 @@ assetLoaders = {}, | ||
phases, | ||
logLevel, | ||
}: { | ||
@@ -78,2 +82,3 @@ assetLoaders?: AssetLoaders; | ||
phases?: string[]; | ||
logLevel?: 'debug' | 'info' | 'warn' | 'error'; | ||
} = {}) { | ||
@@ -85,2 +90,4 @@ this._phases = phases ?? this._phases; | ||
this._archetypeManager = new ArchetypeManager(this); | ||
this._globals = new Resources<Globals>(this); | ||
this.logger = new Logger(logLevel ?? 'info'); | ||
@@ -87,0 +94,0 @@ if (allSystems.length === 0 && !ignoreSystemsWarning) { |
@@ -25,6 +25,6 @@ export class Pointer { | ||
if (ev.type === 'pointerdown') { | ||
if (ev.buttons === 1) { | ||
if (ev.button === 1) { | ||
this._primaryDown = true; | ||
this._primaryPressed = true; | ||
} else if (ev.buttons === 2) { | ||
} else if (ev.button === 2) { | ||
this._secondaryDown = true; | ||
@@ -34,6 +34,6 @@ this._secondaryPressed = true; | ||
} else if (ev.type === 'pointerup') { | ||
if (ev.buttons === 1) { | ||
if (ev.button === 1) { | ||
this._primaryUp = true; | ||
this._primaryPressed = false; | ||
} else if (ev.buttons === 2) { | ||
} else if (ev.button === 2) { | ||
this._secondaryUp = true; | ||
@@ -40,0 +40,0 @@ this._secondaryPressed = false; |
@@ -1,3 +0,1 @@ | ||
import { logger } from '../logger.js'; | ||
export class ObjectPool<T> { | ||
@@ -9,3 +7,3 @@ private free = new Array<T>(); | ||
private factory: () => T, | ||
private reset: (item: T) => void = () => { }, | ||
private reset: (item: T) => void = () => {}, | ||
initialSize: number = 1, | ||
@@ -29,3 +27,3 @@ ) { | ||
if (!item) { | ||
logger.warn(`Tried to release ${item}`); | ||
console.warn(`Tried to release ${item}. This might be a bug.`); | ||
return; | ||
@@ -32,0 +30,0 @@ } |
@@ -1,16 +0,26 @@ | ||
const doLog = ( | ||
level: 'info' | 'warn' | 'error' | 'debug' | 'log', | ||
...messages: unknown[] | ||
) => { | ||
if (localStorage.getItem('DEBUG') === 'true' || (window as any).DEBUG) { | ||
console[level](...messages); | ||
export class Logger { | ||
static readonly levels = ['debug', 'info', 'warn', 'error'] as const; | ||
private lvl = 2; | ||
doLog = ( | ||
level: 'info' | 'warn' | 'error' | 'debug', | ||
...messages: unknown[] | ||
) => { | ||
if (Logger.levels.indexOf(level) >= this.lvl) { | ||
console[level](...messages); | ||
} | ||
}; | ||
constructor(level: 'info' | 'warn' | 'error' | 'debug') { | ||
this.lvl = Logger.levels.indexOf(level); | ||
} | ||
}; | ||
export const logger = { | ||
info: doLog.bind(null, 'info'), | ||
warn: doLog.bind(null, 'warn'), | ||
error: doLog.bind(null, 'error'), | ||
debug: doLog.bind(null, 'debug'), | ||
log: doLog.bind(null, 'log'), | ||
}; | ||
info = this.doLog.bind(null, 'info'); | ||
warn = this.doLog.bind(null, 'warn'); | ||
error = this.doLog.bind(null, 'error'); | ||
debug = this.doLog.bind(null, 'debug'); | ||
log = this.doLog.bind(null, 'info'); | ||
} | ||
export const defaultLogger = new Logger('info'); |
@@ -5,3 +5,2 @@ import { Game } from './Game.js'; | ||
import { EntityImpostorFor, QueryIterator } from './QueryIterator.js'; | ||
import { logger } from './logger.js'; | ||
import { Entity } from './Entity.js'; | ||
@@ -64,3 +63,3 @@ import { EventSubscriber } from '@a-type/utils'; | ||
initialize(def: FilterDef) { | ||
logger.debug(`Initializing Query ${this.toString()}`); | ||
this.game.logger.debug(`Initializing Query ${this.toString()}`); | ||
this.filter = this.processDef(def); | ||
@@ -110,3 +109,5 @@ | ||
this.archetypes.push(archetype); | ||
logger.debug(`Query ${this.toString()} added Archetype ${archetype.id}`); | ||
this.game.logger.debug( | ||
`Query ${this.toString()} added Archetype ${archetype.id}`, | ||
); | ||
this.unsubscribes.push( | ||
@@ -209,3 +210,5 @@ archetype.subscribe('entityRemoved', this.handleEntityRemoved), | ||
private emitAdded = (entityId: number) => { | ||
logger.debug(`Entity ${entityId} added to query ${this.toString()}`); | ||
this.game.logger.debug( | ||
`Entity ${entityId} added to query ${this.toString()}`, | ||
); | ||
this.emit('entityAdded', entityId); | ||
@@ -215,3 +218,5 @@ }; | ||
private emitRemoved = (entityId: number) => { | ||
logger.debug(`Entity ${entityId} removed from query ${this.toString()}`); | ||
this.game.logger.debug( | ||
`Entity ${entityId} removed from query ${this.toString()}`, | ||
); | ||
this.emit('entityRemoved', entityId); | ||
@@ -218,0 +223,0 @@ }; |
@@ -0,9 +1,14 @@ | ||
import { Game } from './index.js'; | ||
import { ObjectPool } from './internal/objectPool.js'; | ||
import { logger } from './logger.js'; | ||
import { ResourceHandle } from './ResourceHandle.js'; | ||
export class Resources<ResourceMap extends Record<string, any>> { | ||
private handlePool = new ObjectPool(() => new ResourceHandle(), h => h.reset()); | ||
private handlePool = new ObjectPool( | ||
() => new ResourceHandle(), | ||
(h) => h.reset(), | ||
); | ||
private handles = new Map<string | number | symbol, ResourceHandle>(); | ||
constructor(private game: Game) {} | ||
private getOrCreateGlobalHandle = (key: string | number | symbol) => { | ||
@@ -29,3 +34,3 @@ let handle = this.handles.get(key); | ||
this.getOrCreateGlobalHandle(key).resolve(value); | ||
logger.debug('Resolved resource', key); | ||
this.game.logger.debug('Resolved resource', key); | ||
}; | ||
@@ -32,0 +37,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
262983
4934