Skip to content

Commit

Permalink
Merge pull request #59 from ayebear/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
ayebear authored May 11, 2022
2 parents 89c8e70 + 83cf4fb commit a1ec2eb
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 27 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "picoes",
"version": "1.1.0-rc1",
"version": "1.1.0",
"description": "Pico Entity System for JavaScript",
"main": "index.js",
"files": [
Expand Down
48 changes: 24 additions & 24 deletions src/entity_storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,25 @@ import { invoke } from './utilities.js'

/** @ignore */
export class EntityStorage {
/** EntityStorage constructor, needs reference back to world */
constructor(world) {
/** @ignore */
/** World instance */
this.world = world
/** @ignore */
/** Component keys to component classes */
this.componentClasses = {}
/** @ignore */
/** Used for generating entity IDs */
this.nextEntityId = 1

/**
* Maps entity IDs to entities
* @ignore
*/
/** Maps entity IDs to entities */
this.entities = new Map()

/**
* Maps component keys to entities
* @ignore
*/
/** Maps component keys to entities */
this.index = new Map()
}

/**
* Removes all entities along with their components.
* This is more efficient than calling entity.destroy() on each, since
* this will only call onRemove on each and then clear the index.
*/
clear() {
// Call onRemove on all components of all entities
for (const { data } of this.entities.values()) {
Expand All @@ -37,47 +35,47 @@ export class EntityStorage {
this.index.clear()
}

/** Registers a function/class with a name as a component */
registerComponent(name, componentClass) {
// Only allow functions and classes to be components
if (typeof componentClass !== 'function') {
throw new Error('Component is not a valid function or class.')
}
this.componentClasses[name] = componentClass
}

// Creates a new entity attached to the world
/** Creates a new entity attached to the world */
createEntity() {
const entityId = this.nextEntityId++
const entity = new Entity(this.world, entityId)
this.entities.set(entityId, entity)
return entity
}

// Forwards query args from world
/** Forwards query args from world */
each(...args) {
return this.queryIndex(this.queryArgs(...args))
}

// Returns an existing or new index
/** Returns an existing or new index */
accessIndex(component) {
return (
this.index.get(component) ||
this.index.set(component, new Map()).get(component)
)
}

// Add component with an entity to the index
/** Add component with an entity to the index */
addToIndex(entity, compName) {
this.accessIndex(compName).set(entity.id, entity)
}

// Remove component from the index for an entity
/** Remove component from the index for an entity */
removeFromIndex(entity, compName) {
this.accessIndex(compName).delete(entity.id)
}

/** Get component names and optional callback from query args */
queryArgs(...args) {
// Gather component names and a callback (if any) from args
const result = {
componentNames: [],
callback: null,
Expand All @@ -101,9 +99,11 @@ export class EntityStorage {
return result
}

// Uses an existing index or builds a new index, to get entities with the specified components
// If callback is defined, it will be called for each entity with component data, and returns undefined
// If callback is not defined, an array of entities will be returned
/**
* Uses an existing index or builds a new index, to get entities with the specified components
* If callback is defined, it will be called for each entity with component data, and returns undefined
* If callback is not defined, an array of entities will be returned
*/
queryIndex({ componentNames, callback }) {
// Return all entities (array if no callback)
if (componentNames.length === 0) {
Expand All @@ -125,7 +125,7 @@ export class EntityStorage {
componentNames.sort(
(a, b) => this.accessIndex(a).size - this.accessIndex(b).size
)
const iter = this.accessIndex(componentNames[0]).values()
const iter = this.accessIndex(componentNames.shift()).values()

// Return array of matched entities
if (!callback) {
Expand Down
10 changes: 8 additions & 2 deletions src/system_storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import { invoke } from './utilities.js'

/** @ignore */
export class SystemStorage {
/** SystemStorage constructor, needs reference back to world */
constructor(world) {
/** World instance */
this.world = world
/** List of systems, stored in run-order */
this.systems = []
/** Context passed to all systems */
this.context = { world }
}

/** Pushes a system to the list with optional init/constructor args */
register(systemClass, ...args) {
// Make sure the system is valid
if (typeof systemClass !== 'function') {
Expand All @@ -20,6 +25,7 @@ export class SystemStorage {
this.systems.push(newSystem)
}

/** Runs a system with optional args */
run(...args) {
let status = true
// Continue rerunning while any systems return true
Expand All @@ -35,15 +41,15 @@ export class SystemStorage {
}
}

// Update existing systems' context
/** Update existing systems' context */
setContext(data) {
this.context = { ...data, world: this.world }
for (const system of this.systems) {
this._injectContext(system)
}
}

// Injects context into a system based on current context state
/** Injects context into a system based on current context state */
_injectContext(system) {
for (const key in this.context) {
system[key] = this.context[key]
Expand Down

0 comments on commit a1ec2eb

Please sign in to comment.