Skip to content

Instantly share code, notes, and snippets.

@mflux
Created Jun 26, 2018
Embed
What would you like to do?
Entity Components
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