package electrosphere.entity.scene; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityTags; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.attach.AttachUtils; import electrosphere.logger.LoggerInterface; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; /** * A game scene */ public class Scene { /** * The map of id -> entity */ Map entityIdMap; /** * The map of tag -> set of entities corresponding to that tag */ Map> tagEntityMap; /** * The list of behavior trees */ List behaviorTreeList; /** * Constructor */ public Scene(){ entityIdMap = new ConcurrentHashMap(); tagEntityMap = new ConcurrentHashMap>(); behaviorTreeList = new CopyOnWriteArrayList(); tagEntityMap.put(EntityTags.BONE_ATTACHED, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.COLLIDABLE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.SPRINTABLE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.MOVEABLE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.ATTACKER, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.TARGETABLE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.LIFE_STATE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.CREATURE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.UI, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.DRAWABLE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.DRAW_INSTANCED, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.DRAW_VOLUMETIC_SOLIDS_PASS, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.DRAW_VOLUMETIC_DEPTH_PASS, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.DRAW_CAST_SHADOW, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.LIGHT, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.ITEM, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.GRAVITY, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.PARTICLE, new CopyOnWriteArraySet()); tagEntityMap.put(EntityTags.TRANSFORM_ATTACHED, new CopyOnWriteArraySet()); } /** * Registers an entity to the scene * @param e The entity to register */ public void registerEntity(Entity e){ entityIdMap.put(e.getId(), e); } /** * Registers an entity to a given tag * @param e The entity * @param tag The tag */ public void registerEntityToTag(Entity e, String tag){ if(tagEntityMap.containsKey(tag)){ tagEntityMap.get(tag).add(e); } else { Set newEntityList = new CopyOnWriteArraySet(); newEntityList.add(e); tagEntityMap.put(tag,newEntityList); } } /** * Gets all entities registered to a tag * @param tag The tag * @return A list of all entities with the tag, or null if no entities have been added to the tag yet */ public Set getEntitiesWithTag(String tag){ return tagEntityMap.get(tag); } /** * Removes an entity from a tag * @param e The entity * @param tag The tag */ public void removeEntityFromTag(Entity e, String tag){ tagEntityMap.get(tag).remove(e); } /** * Deregisters an entity from an entity manager * @param e */ public void deregisterEntity(Entity e){ for(String key : tagEntityMap.keySet()){ tagEntityMap.get(key).remove(e); } entityIdMap.remove(e.getId()); } /** * Recursively deregisters an entity and all entities attached via AttachUtils * @param target The top level entity to deregister */ public void recursiveDeregister(Entity target){ if(AttachUtils.hasChildren(target)){ List childrenList = AttachUtils.getChildrenList(target); for(Entity currentChild : childrenList){ this.recursiveDeregister(currentChild); } } this.deregisterEntity(target); } /** * Gets an entity via its ID * @param id The id to search for * @return The entity with that ID */ public Entity getEntityFromId(int id){ return (Entity)entityIdMap.get(id); } /** * Checks if a scene contains a given entity * @param e The entity * @return true if the scene contains the entity, false otherwise */ public boolean containsEntity(Entity e){ return entityIdMap.containsKey(e.getId()); } /** * Registers a behavior tree to simulate each scene simulation frame * @param tree The behavior tree to register */ public void registerBehaviorTree(BehaviorTree tree){ behaviorTreeList.add(tree); } /** * Deregisters a behavior tree from the scene * @param tree The behavior tree to deregister */ public void deregisterBehaviorTree(BehaviorTree tree){ while(behaviorTreeList.contains(tree)){ behaviorTreeList.remove(tree); } } /** * Simulates all behavior trees stored in the entity manager */ public void simulateBehaviorTrees(float deltaTime){ Globals.profiler.beginAggregateCpuSample("Scene.simulateBehaviorTrees"); for(BehaviorTree tree : behaviorTreeList){ tree.simulate(deltaTime); } Globals.profiler.endCpuSample(); } /** * Gets the collection of all entities in the scene * @return The collection of all entities in the scene */ public Collection getEntityList(){ return this.entityIdMap.values(); } /** * Describes the scene in log messages */ public void describeScene(){ LoggerInterface.loggerEngine.WARNING("Entities present in scene:"); for(Entity entity : this.entityIdMap.values()){ LoggerInterface.loggerEngine.WARNING(entity.getId() + ""); } } }