r3-legacy/src/game-lib-entity-manager.js

476 lines
11 KiB
JavaScript
Raw Normal View History

2016-12-15 14:53:39 +01:00
/**
* GameLib.EntityManager
2017-01-06 16:53:53 +01:00
* @param graphics GameLib.D3.Graphics
* @param apiEntityManager GameLib.API.EntityManager
2016-12-15 14:53:39 +01:00
* @constructor
*/
GameLib.EntityManager = function(
2017-01-06 16:53:53 +01:00
graphics,
apiEntityManager
) {
2017-01-06 16:53:53 +01:00
this.graphics = graphics;
this.graphics.isNotThreeThrow();
2016-12-15 14:53:39 +01:00
if (GameLib.Utils.UndefinedOrNull(apiEntityManager)) {
apiEntityManager = {};
}
if (apiEntityManager instanceof GameLib.EntityManager) {
return apiEntityManager;
}
2016-12-15 14:53:39 +01:00
GameLib.API.EntityManager.call(
this,
2017-01-19 17:50:11 +01:00
apiEntityManager.id,
apiEntityManager.name,
apiEntityManager.entities,
2017-05-11 17:52:33 +02:00
// apiEntityManager.systems,
2017-01-19 17:50:11 +01:00
apiEntityManager.parentEntity
2016-12-15 14:53:39 +01:00
);
2017-01-05 19:34:28 +01:00
this.entities = this.entities.map(
function(apiEntity) {
2017-01-12 04:44:01 +01:00
if (apiEntity instanceof GameLib.API.Entity) {
return new GameLib.Entity(
this.graphics,
apiEntity
)
} else {
console.warn('Entity not of type API.Entity');
throw new Error('Entity not of type API.Entity');
}
2017-01-06 16:53:53 +01:00
}.bind(this)
2017-01-05 19:34:28 +01:00
);
2017-05-11 17:52:33 +02:00
// this.systems = this.systems.map(
// function(apiSystem) {
//
// if (apiSystem instanceof GameLib.API.System) {
// return new GameLib.System(
// this.graphics,
// apiSystem
// )
// } else {
// console.warn('System not of type API.System');
// throw new Error('System not of type API.System');
// }
//
// }.bind(this)
// );
this.buildIdToObject();
2017-01-19 17:50:11 +01:00
2016-12-15 14:53:39 +01:00
this.instance = this.createInstance();
this.registerCallbacks();
2016-12-15 14:53:39 +01:00
};
GameLib.EntityManager.prototype = Object.create(GameLib.API.EntityManager.prototype);
GameLib.EntityManager.prototype.constructor = GameLib.EntityManager;
/**
* Creates an Entity Manager instance
* @returns {*}
*/
GameLib.EntityManager.prototype.createInstance = function() {
/**
* Fuck the current ECS bullshit on the internet - both tiny-ecs and ecsjs SUCKS ASS
*/
return null;
2016-12-15 14:53:39 +01:00
};
/**
2017-05-11 17:52:33 +02:00
* Creates an GameLib.Entity and adds it to entities array
2016-12-15 14:53:39 +01:00
* @returns {*}
*/
GameLib.EntityManager.prototype.createEntity = function(name) {
2017-01-19 17:50:11 +01:00
var apiEntity = new GameLib.API.Entity(
null,
2017-05-22 15:42:05 +02:00
name,
null,
null,
this
2017-01-19 17:50:11 +01:00
);
2016-12-15 14:53:39 +01:00
2017-01-19 17:50:11 +01:00
var entity = new GameLib.Entity(
this.graphics,
apiEntity
);
2016-12-15 14:53:39 +01:00
this.entities.push(entity);
2017-06-13 10:45:24 +02:00
GameLib.Event.Emit(
GameLib.Event.NEW_ENTITY,
{
entity : entity
}
);
2016-12-15 14:53:39 +01:00
return entity;
};
/**
* Returns an entity by ID or null
* @param id
* @returns {*}
*/
GameLib.EntityManager.prototype.findEntityById = function(id) {
return this.entities.reduce(
function(result, entity){
if (entity.id === id) {
result = entity;
}
return result;
},
null
);
};
GameLib.EntityManager.prototype.findHelperByObject = function(object) {
return this.entities.reduce(
function(result, entity) {
var helpers = entity.getComponents(GameLib.D3.Helper);
var helper = helpers.reduce(
function(helperResult, tmpHelper) {
if (tmpHelper.object === object) {
helperResult = tmpHelper;
}
return helperResult;
},
null
);
if (helper) {
result = helper;
}
return result;
},
null
);
};
2016-12-15 14:53:39 +01:00
/**
* Adds an entity to this manager
2017-05-11 17:52:33 +02:00
* @param entity GameLib.Entity
*/
GameLib.EntityManager.prototype.addEntity = function(entity) {
2017-05-22 15:42:05 +02:00
entity.parentEntityManager = this;
this.entities.push(entity);
};
2017-05-11 17:52:33 +02:00
// /**
// * Adds a system to this manager
// * @param system GameLib.System
// */
// GameLib.EntityManager.prototype.addSystem = function(system) {
// this.systems.push(system);
// };
/**
* Returns entity by name
* @param name
* @returns {*}
*/
GameLib.EntityManager.prototype.queryByName = function(name) {
return this.entities.reduce(
function(result, entity){
if (entity.name === name) {
result = entity;
}
return result;
},
null
)
};
/**
* Removes an entity - do we remove all its components as well?
2016-12-15 14:53:39 +01:00
* @param entity GameLib.D3.Entity
* @returns boolean true if successful
2016-12-15 14:53:39 +01:00
*/
GameLib.EntityManager.prototype.removeEntity = function(entity) {
var index = this.entities.indexOf(entity);
if (index === -1) {
2016-12-15 14:53:39 +01:00
console.log('failed to remove entity : ', entity);
return false;
}
2017-05-22 15:42:05 +02:00
entity.parentEntityManager = null;
2016-12-15 14:53:39 +01:00
this.entities.splice(index, 1);
return true;
};
/**
* Returns all the entities with the following components
2016-12-15 14:53:39 +01:00
* @param components GameLib.Component[]
*/
GameLib.EntityManager.prototype.query = function(components) {
var entities = this.entities.reduce(
function(result, entity) {
2016-12-19 17:44:15 +01:00
var hasAllComponents = components.reduce(
function(componentResult, component) {
if (!entity.hasComponent(component)) {
componentResult = false;
2016-12-19 17:44:15 +01:00
}
return componentResult;
},
true
);
2016-12-19 17:44:15 +01:00
if (hasAllComponents) {
result.push(entity);
}
return result;
},
[]
);
return entities;
};
2016-12-19 17:44:15 +01:00
/**
* Returns all actual components of all entities that contain this component
* @param constructor
*/
GameLib.EntityManager.prototype.queryComponents = function(constructor) {
var entities = this.query([constructor]);
var components = entities.reduce(
function(result, entity){
2017-05-16 11:50:06 +02:00
var ecs = entity.getComponents(constructor);
ecs.map(function(ec){
result.push(ec);
});
return result;
},
[]
);
2016-12-19 17:44:15 +01:00
return components;
2016-12-15 14:53:39 +01:00
};
/**
* Converts a GameLib.Entity to GameLib.API.Entity
* @returns {GameLib.API.EntityManager}
2016-12-15 14:53:39 +01:00
*/
2017-05-16 14:51:57 +02:00
GameLib.EntityManager.prototype.toApiObject = function() {
2016-12-15 14:53:39 +01:00
var apiEntities = this.entities.map(
function (entity) {
2017-05-16 14:51:57 +02:00
return entity.toApiObject();
}
);
2017-05-11 17:52:33 +02:00
// var apiSystems = this.systems.map(
// function (system) {
2017-05-16 14:51:57 +02:00
// return system.toApiObject();
2017-05-11 17:52:33 +02:00
// }
// );
var apiEntityManager = new GameLib.API.EntityManager(
2017-01-19 17:50:11 +01:00
this.id,
this.name,
apiEntities,
2017-05-11 17:52:33 +02:00
// apiSystems,
2017-01-19 17:50:11 +01:00
this.parentEntity
);
return apiEntityManager;
2016-12-15 14:53:39 +01:00
};
/**
2017-01-06 16:53:53 +01:00
* Returns an EntityManager from an Object entity manager
* @param graphics
2017-01-06 16:53:53 +01:00
* @param objectEntityManager Object
2016-12-15 14:53:39 +01:00
* @constructor
*/
2017-06-14 14:21:57 +02:00
GameLib.EntityManager.FromObject = function(graphics, objectEntityManager) {
2017-06-14 14:21:57 +02:00
var apiEntityManager = GameLib.API.EntityManager.FromObject(objectEntityManager);
var entityManager = new GameLib.EntityManager(
2017-01-06 16:53:53 +01:00
graphics,
apiEntityManager
);
return entityManager;
2016-12-15 14:53:39 +01:00
};
2017-06-04 18:17:16 +02:00
/**
* Defines what should happen when a parent scene changes
* @param data
*/
GameLib.EntityManager.prototype.onParentSceneChange = function(data) {
2017-06-13 14:09:18 +02:00
if (
data.object instanceof GameLib.D3.Mesh ||
data.object instanceof GameLib.D3.Light
) {
/**
* We remove the helper (if any) from the old scene and add it to the new scene
*/
var helper = this.findHelperByObject(data.object);
if (helper) {
2017-06-14 14:21:57 +02:00
if (data.originalScene && data.originalScene.instance) {
data.originalScene.instance.remove(helper.instance);
}
data.newScene.instance.add(helper.instance);
}
/**
* We remove the mesh from the old scene and add it to the new scene
*/
2017-06-14 14:21:57 +02:00
if (data.originalScene && data.originalScene.removeObject) {
data.originalScene.removeObject(data.object);
}
data.newScene.addObject(data.object);
/**
* We inherit the parent entity of this new scene
*/
var originalEntity = null;
var newEntity = null;
if (data.object.hasOwnProperty('parentEntity')) {
originalEntity = data.object.parentEntity
}
if (data.newScene.hasOwnProperty('parentEntity')) {
newEntity = data.newScene.parentEntity;
}
2017-06-14 14:21:57 +02:00
var gui = null;
2017-06-14 14:21:57 +02:00
if (originalEntity) {
2017-06-14 14:21:57 +02:00
if (originalEntity.removeComponent) {
if (helper) {
originalEntity.removeComponent(helper);
}
originalEntity.removeComponent(data.object);
}
if (originalEntity.getFirstComponent) {
gui = originalEntity.getFirstComponent(GameLib.GUI);
if (gui) {
gui.removeObject(data.object);
gui.build(this);
}
}
}
if (newEntity) {
if (newEntity.addComponent) {
if (helper) {
newEntity.addComponent(helper);
}
newEntity.addComponent(data.object);
}
if (newEntity.getFirstComponent) {
gui = newEntity.getFirstComponent(GameLib.GUI);
if (gui) {
gui.addObject(data.object);
gui.build(this);
}
}
}
}
};
2017-06-08 18:17:03 +02:00
/**
* Change parent entity
* TODO: also change parent entity of children objects
* @param data
*/
GameLib.EntityManager.prototype.onParentEntityChange = function(data) {
2017-06-08 18:17:03 +02:00
if (data.originalEntity) {
data.originalEntity.removeComponent(data.object);
}
data.newEntity.addComponent(data.object);
2017-06-13 14:09:18 +02:00
// - ok not so cool - we may have parent entities of entities -
// - so not all children should inherit the parent entity
// data.object.buildIdToObject();
//
// for (var property in data.object.idToObject) {
// if (data.object.idToObject.hasOwnProperty(property)) {
// if (data.object.idToObject[property].hasOwnProperty('parentEntity')) {
// data.object.idToObject[property].parentEntity = data.newEntity;
// }
// }
// }
};
/**
*
*/
GameLib.EntityManager.prototype.registerCallbacks = function() {
this.subscribe(
GameLib.Event.PARENT_SCENE_CHANGE,
this.onParentSceneChange
);
this.subscribe(
GameLib.Event.PARENT_ENTITY_CHANGE,
this.onParentEntityChange
);
};
2016-12-15 14:53:39 +01:00
/**
* Links object Ids to actual objects
* @param idToObject
*/
2017-02-22 16:06:27 +01:00
// GameLib.EntityManager.prototype.linkObjects = function(idToObject) {
//
// this.entities.map(
// function(entity) {
// entity.components.map(
// function (componentId, index, array) {
// if (componentId instanceof GameLib.Component) {
// array[index] = componentId;
// } else {
// array[index] = idToObject[componentId];
// }
//
// Object.keys(array[index].linkedObjects).map(
// function (propertyName) {
// array[index][propertyName] = idToObject[array[index][propertyName]];
// }
// );
//
// array[index].loaded = true;
// }
// )
// }
// );
//
// };