All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.artemis.World Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
package com.artemis;

import com.artemis.injection.CachedInjector;
import com.artemis.injection.Injector;
import com.artemis.managers.UuidEntityManager;
import com.artemis.utils.Bag;
import com.artemis.utils.ImmutableBag;
import com.artemis.utils.reflect.ClassReflection;
import com.artemis.utils.reflect.Constructor;
import com.artemis.utils.reflect.ReflectionException;

import java.util.*;


/**
 * The primary instance for the framework.
 * 

* It contains all the managers. You must use this to create, delete and * retrieve entities. It is also important to set the delta each game loop * iteration, and initialize before game loop. *

* * @author Arni Arent */ public class World { /** * Manages all entities for the world. */ private final EntityManager em; /** * Manages all component-entity associations for the world. */ private final ComponentManager cm; private final AspectSubscriptionManager am; /** * The time passed since the last update. */ public float delta; final BitSet added; final BitSet changed; final BitSet disabled; final BitSet enabled; final BitSet deleted; /** * Contains all managers and managers classes mapped. */ final Map, Manager> managers; /** * Contains all managers unordered. */ final Bag managersBag; /** * Contains all systems and systems classes mapped. */ final Map, BaseSystem> systems; /** * Contains all systems unordered. */ private final Bag systemsBag; private boolean registerUuids; private Injector injector; final EntityEditPool editPool = new EntityEditPool(this); private SystemInvocationStrategy invocationStrategy; private WorldConfiguration configuration; /** * Creates a new world. *

* An EntityManager and ComponentManager are created and added upon * creation. *

*/ public World() { this(new WorldConfiguration()); } /** * @deprecated {@link World#World(WorldConfiguration)} provides more fine-grained control. */ @Deprecated public World(int expectedEntityCount) { this(new WorldConfiguration()); } /** * Creates a new world. *

* An EntityManager and ComponentManager are created and added upon * creation. *

*/ public World(WorldConfiguration configuration) { this.configuration = configuration; managers = new IdentityHashMap, Manager>(); managersBag = configuration.managers; systems = new IdentityHashMap, BaseSystem>(); systemsBag = configuration.systems; added = new BitSet(); changed = new BitSet(); deleted = new BitSet(); enabled = new BitSet(); disabled = new BitSet(); cm = new ComponentManager(configuration.expectedEntityCount()); em = new EntityManager(configuration.expectedEntityCount()); am = new AspectSubscriptionManager(); injector = configuration.injector; if (injector == null) { injector = new CachedInjector(); } configuration.initialize(this, injector, am); registerUuids = managers.get(UuidEntityManager.class) != null; if (invocationStrategy == null) setInvocationStrategy(new InvocationStrategy()); } /** * Makes sure all managers systems are initialized in the order they were * added. * * @deprecated automatically covered by {@link WorldConfiguration}. */ @Deprecated public void initialize() { } /** * Inject dependencies on object. * * Immediately perform dependency injection on the target. * {@link com.artemis.annotations.Wire} annotation is required on the target * or fields. * * If you want to specify nonstandard dependencies to inject, use * {@link com.artemis.WorldConfiguration#register(String, Object)} instead, or * configure an {@link com.artemis.injection.Injector} * * If you want a non-throwing alternative, use {@link #inject(Object, boolean)} * * @see com.artemis.annotations.Wire for more details about dependency injection. * @see #inject(Object, boolean) * @param target Object to inject into. * throws MundaneWireException if {@code target} is not annotated with com.artemis.annotations.Wire */ public void inject(Object target) { inject(target, true); } /** * Inject dependencies on object if it is annotated with {@link com.artemis.annotations.Wire}. * * If {@link com.artemis.annotations.Wire} is missing, no action will be taken. * * If you want to specify nonstandard dependencies to inject, use * {@link com.artemis.WorldConfiguration#register(String, Object)} instead, or * configure an {@link com.artemis.injection.Injector} * * @see com.artemis.annotations.Wire for more details about dependency injection. * @see #inject(Object) * @param target Object to inject into. * @param failIfWireAnnotationIsMissing if true, this method will * throws MundaneWireException if {@code target} is not annotated with com.artemis.annotations.Wire and * {@code failIfWireAnnotationIsMissing} is true */ public void inject(Object target, boolean failIfWireAnnotationIsMissing) { boolean injectable = injector.isInjectable(target); if (!injectable && failIfWireAnnotationIsMissing) throw new MundaneWireException(target.getClass().getName() + " must be annotated with @Wire"); if(injectable) injector.inject(target); } /** * Disposes all managers and systems. Only necessary if either need to free * managed resources upon bringing the world to an end. * * @throws ArtemisMultiException if any managers or systems throws an exception. */ public void dispose() { List exceptions = new ArrayList(); for (Manager manager : managersBag) { try { manager.dispose(); } catch (Exception e) { exceptions.add(e); } } for (BaseSystem system : systemsBag) { try { system.dispose(); } catch (Exception e) { exceptions.add(e); } } if (exceptions.size() > 0) throw new ArtemisMultiException(exceptions); } @SuppressWarnings("unchecked") public T createFactory(Class factory) { if (!factory.isInterface()) throw new MundaneWireException("Expected interface for type: " + factory); String impl = factory.getName() + "Impl"; try { Class implClass = ClassReflection.forName(impl); Constructor constructor = ClassReflection.getConstructor(implClass, World.class); return (T) constructor.newInstance(this); } catch (ReflectionException e) { throw new RuntimeException(e); } } /** * Returns a manager that takes care of all the entities in the world. * * @return entity manager */ public EntityManager getEntityManager() { return em; } /** * Returns a manager that takes care of all the components in the world. * * @return component manager */ public ComponentManager getComponentManager() { return cm; } /** * Add a manager into this world. *

* It can be retrieved later. World will notify this manager of changes to * entity. *

* * @param class type of the manager * @param manager manager to be added * @return the manager * * @deprecated {@link WorldConfiguration#setManager(Manager)} */ @Deprecated public final T setManager(T manager) { throw new MundaneWireException("use WorldConfiguration#setManager"); } /** * Returns a manager of the specified type. * * @param class type of the manager * @param managerType class type of the manager * @return the manager */ @SuppressWarnings("unchecked") public T getManager(Class managerType) { return (T) managers.get(managerType); } /** * @return all managers in this world */ public ImmutableBag getManagers() { return managersBag; } /** * Deletes the manager from this world. * * @param manager manager to delete * @deprecated A world should be static once initialized */ @Deprecated public void deleteManager(Manager manager) { managers.remove(manager.getClass()); managersBag.remove(manager); } /** * Time since last game loop. * * @return delta time since last game loop */ public float getDelta() { return delta; } /** * You must specify the delta for the game here. * * @param delta time since last game loop */ public void setDelta(float delta) { this.delta = delta; } /** * Adds a entity to this world. * * @param e the entity to add * @deprecated internally managed by artemis */ @Deprecated public void addEntity(Entity e) {} /** * @deprecated does nothing, internally tracked by artemis now. */ @Deprecated public void changedEntity(Entity e) {} /** * Delete the entity from the world. * * @param e the entity to delete */ public void deleteEntity(Entity e) { e.edit().deleteEntity(); } /** * Delete the entity from the world. * * @param entityId the entity to delete */ public void deleteEntity(int entityId) { deleteEntity(em.getEntity(entityId)); } /** * (Re)enable the entity in the world, after it having being disabled. *

* Won't do anything unless it was already disabled. *

* * @param e the entity to enable * @deprecated create your own components to track state. */ @Deprecated public void enable(Entity e) { if (disabled.get(e.id)) disabled.set(e.id, false); enabled.set(e.id, true); } /** * Disable the entity from being processed. *

* Won't delete it, it will continue to exist but won't get processed. *

* * @param e the entity to disable * @deprecated create your own components to track state. */ @Deprecated public void disable(Entity e) { if (enabled.get(e.id)) enabled.set(e.id, false); disabled.set(e.id); } /** * Create and return a new or reused entity instance. Entity is * automatically added to the world. * * @return entity */ public Entity createEntity() { Entity e = em.createEntityInstance(); e.edit(); return e; } /** * Create and return an {@link Entity} wrapping a new or reused entity instance. * Entity is automatically added to the world. * * @return entity */ public Entity createEntity(Archetype archetype) { Entity e = em.createEntityInstance(archetype); cm.addComponents(e, archetype); added.set(e.id); return e; } /** * Create and return a new or reused entity instance. *

* The uuid parameter is ignored if {@link UuidEntityManager} hasn't been added to the * world. *

* * @param uuid the UUID to give to the entity * @return entity */ public Entity createEntity(UUID uuid) { Entity entity = em.createEntityInstance(); entity.setUuid(uuid); entity.edit(); return entity; } /** * Get a entity having the specified id. * * @param entityId the entities id * @return the specific entity */ public Entity getEntity(int entityId) { return em.getEntity(entityId); } /** * Gives you all the systems in this world for possible iteration. * * @return all entity systems in world */ public ImmutableBag getSystems() { return systemsBag; } /** * Adds a system to this world that will be processed by * {@link #process()}. * * @param the system class type * @param system the system to add * @return the added system * * @deprecated {@link WorldConfiguration#setSystem(T)} */ @Deprecated public T setSystem(T system) { throw new MundaneWireException("use WorldConfiguration#setSystem"); } /** * Will add a system to this world. * * @param the system class type * @param system the system to add * @param passive whether or not this system will be processed by * {@link #process()} * @return the added system * @deprecated {@link WorldConfiguration#setSystem(T, boolean)} */ @Deprecated public T setSystem(T system, boolean passive) { throw new MundaneWireException("use WorldConfiguration#setSystem"); } /** * Remove the specified system from the world. * * @param system the system to be deleted from world * @deprecated A world should be static once initialized */ @Deprecated public void deleteSystem(BaseSystem system) {} /** * Retrieve a system for specified system type. * * @param the class type of system * @param type type of system * @return instance of the system in this world */ @SuppressWarnings("unchecked") public T getSystem(Class type) { return (T) systems.get(type); } // /** // * Performs an action on each entity. // * // * @param entityIds contains the entities upon which the action will be performed // * @param performer the performer that carries out the action // */ // private void check(BitSet entityIds, Performer performer) { // if (entityIds.isEmpty()) // return; // // notifyManagers(performer, entityIds); // } public void setInvocationStrategy(SystemInvocationStrategy invocationStrategy) { this.invocationStrategy = invocationStrategy; invocationStrategy.setWorld(this); } /** * Process all non-passive systems. */ public void process() { updateEntityStates(); em.clean(); cm.clean(); invocationStrategy.process(systemsBag); } void updateEntityStates() { // the first block is for entities with precalculated compositionIds, // such as those affected by EntityTransmuters, Archetypes // and EntityFactories. while (added.cardinality() > 0 || changed.cardinality() > 0) { am.process(added, changed, deleted); } while(editPool.processEntities()) { am.process(added, changed, deleted); // we're cheating here to support disabled and enabled entities with the // new subscription lists // @deprecate am.process(added, enabled, disabled); } } boolean hasUuidManager() { return registerUuids; } /** * Retrieves a ComponentMapper instance for fast retrieval of components * from entities. * * @param class type of the component * @param type type of component to get mapper for * @return mapper for specified component type */ public ComponentMapper getMapper(Class type) { return BasicComponentMapper.getFor(type, this); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy