Created
June 26, 2018 22:07
-
-
Save mflux/6c76c2b9af6c4cc33928473ef3f3d532 to your computer and use it in GitHub Desktop.
Entity Components
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import R from 'ramda'; | |
import * as Perf from '../cpcs/performance'; | |
import fast from '../../node_modules/fast.js/index'; | |
/** | |
* @return {string} | |
*/ | |
function newId(){ | |
let d = new Date().getTime(); | |
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | |
const r = (d + Math.random()*16)%16 | 0; | |
d = Math.floor(d/16); | |
return (c=='x' ? r : (r&0x3|0x8)).toString(16); | |
}); | |
return uuid; | |
} | |
/** | |
* @return {object} | |
*/ | |
export const newWorld = () => ({}); | |
/** | |
* @return {Entity} | |
*/ | |
export const newEntity = () => ({}); | |
/** | |
* | |
* @param {object} entities | |
* @param {Entity} entity | |
*/ | |
export const addEntity = function( entities, entity ){ | |
const id = newId(); | |
entities[ id ] = entity; | |
entity._id = id; | |
return entity; | |
}; | |
/** | |
* | |
* @param {object} entities | |
* @param {Entity} entity | |
* @return {Entity} | |
*/ | |
export const removeEntity = function( entities, entity ){ | |
delete entities[ entity._id ]; | |
return entity; | |
}; | |
/** | |
* | |
* @param {object} entities | |
* @param {string} id | |
* @return {Entity} | |
*/ | |
export const getEntityById =function( entities, id ){ | |
return entities[ id ]; | |
}; | |
/** | |
* | |
* @param {object} entities | |
* @param {Entity} entity | |
* @return {string} | |
*/ | |
export const lookupEntityId = function( entities, entity ){ | |
for( let id in entities ){ | |
if( entities[ id ] === entity ){ | |
return id; | |
} | |
} | |
}; | |
export const createComponent = function( componentType, componentData = {} ){ | |
const component = new componentType( componentData ); | |
return component; | |
}; | |
/** | |
* | |
* @param {Entity} entity | |
* @param {Component.BaseComponent} component | |
*/ | |
export const addComponent = function( entity, component ){ | |
entity[ component.name ] = component; | |
return component; | |
}; | |
/** | |
* | |
* @param {Entity} entity | |
* @param {Component.BaseComponent} component | |
*/ | |
export const removeComponent = function( entity, component ){ | |
delete entity[ component.name ]; | |
return component; | |
}; | |
export const getEntities = function( entities, ...components ){ | |
//Perf.start('EC: Get Entities'); | |
const list = fast.filter( Object.values( entities ), function( entity ){ | |
return hasKeys( components, entity ) | |
}, this ); | |
//Perf.endByName('EC: Get Entities'); | |
return list; | |
}; | |
/** | |
* | |
* @param {object} entities | |
* @return {Entity[]} | |
*/ | |
export const getEntityList = function( entities ){ | |
return Object.values( entities ); | |
}; | |
/** | |
* | |
* @param {string[]} keys | |
* @param {object} object | |
*/ | |
export const hasKeys = function( keys, object ){ | |
const objectKeys = Object.keys( object ); | |
return keys.every( function( keyName ){ | |
if( keyName.charAt( 0 ) === '!' ){ | |
return ( object[ keyName.slice(1,keyName.length) ] === undefined ); | |
} | |
else{ | |
return ( object[ keyName ] !== undefined ); | |
} | |
}); | |
}; | |
/** | |
* | |
* @param {*} componentTemplate | |
*/ | |
export const defineComponent = function( componentTemplate ){ | |
const componentType = function( data ){ | |
const initializer = componentTemplate.init.bind( this ); | |
initializer( data ); | |
}; | |
componentType.prototype.name = componentTemplate.name; | |
return componentType; | |
}; | |
/** | |
* | |
* @param {object} entities | |
* @return {CPCS.World} | |
*/ | |
export const world = function( entities ){ | |
/** | |
* | |
* @param {Entity} entity | |
*/ | |
function addEntityIn( entity ){ | |
return addEntity( entities, entity ); | |
} | |
/** | |
* | |
* @param {Entity} entity | |
*/ | |
function removeEntityIn( entity ){ | |
return removeEntity( entities, entity ); | |
} | |
function getEntitiesIn(...args){ | |
return getEntities( entities, ...args ) | |
} | |
/** | |
* | |
* @param {string} id | |
* @return {Entity} | |
*/ | |
function getEntityByIdIn( id ){ | |
return getEntityById( entities, id ); | |
} | |
/** | |
* | |
* @param {Entity} entity | |
* @return {string} | |
*/ | |
function lookupEntityByIdIn( entity ){ | |
return lookupEntityId( entities, entity ); | |
} | |
/** | |
* @type {CPCS.World} | |
*/ | |
const w = { | |
addEntity: addEntityIn, | |
removeEntity: removeEntityIn, | |
getEntities: getEntitiesIn, | |
get: () => entities, | |
clone: () => R.clone( entities ), | |
getEntityById: getEntityByIdIn, | |
lookupEntityId: lookupEntityByIdIn | |
}; | |
return w; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment