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

com.artemis.WorldConfigurationBuilder Maven / Gradle / Ivy

package com.artemis;

import com.artemis.annotations.UnstableApi;
import com.artemis.injection.CachedInjector;
import com.artemis.injection.FieldHandler;
import com.artemis.injection.FieldResolver;
import com.artemis.injection.InjectionCache;
import com.artemis.utils.Bag;
import com.artemis.utils.Sort;
import com.artemis.utils.reflect.ClassReflection;
import com.artemis.utils.reflect.ReflectionException;

/**
 * World builder.
 *
 * Allows convenient var-arg addition of systems, managers. Supports plugins.
 *
 * @author Daan van Yperen
 * @see WorldConfiguration
 */
public class WorldConfigurationBuilder {
	private Bag> systems;
	private Bag> fieldResolvers;
	private Bag> plugins;

	private ArtemisPlugin activePlugin;
	private final InjectionCache cache;
	private SystemInvocationStrategy invocationStrategy;

	public WorldConfigurationBuilder() {
		reset();
		cache = InjectionCache.sharedCache.get();
	}

	/**
	 * Assemble world with systems.
	 * 

* Deprecated: World Configuration */ public WorldConfiguration build() { appendPlugins(); final WorldConfiguration config = new WorldConfiguration(); registerSystems(config); registerFieldResolvers(config); registerInvocationStrategies(config); reset(); return config; } private void registerInvocationStrategies(WorldConfiguration config) { if (invocationStrategy != null) { config.setInvocationStrategy(invocationStrategy); } } /** * Append plugin configurations. * Supports plugins registering plugins. */ private void appendPlugins() { int i = 0; while (i < plugins.size()) { activePlugin = plugins.get(i).item; activePlugin.setup(this); i++; } activePlugin = null; } /** * add custom field handler with resolvers. */ protected void registerFieldResolvers(WorldConfiguration config) { if (fieldResolvers.size() > 0) { Sort.instance().sort(fieldResolvers); // instance default field handler final FieldHandler fieldHandler = new FieldHandler(InjectionCache.sharedCache.get()); for (ConfigurationElement configurationElement : fieldResolvers) { fieldHandler.addFieldResolver(configurationElement.item); } config.setInjector(new CachedInjector().setFieldHandler(fieldHandler)); } } /** * add systems to config. */ private void registerSystems(WorldConfiguration config) { Sort.instance().sort(systems); for (ConfigurationElement configurationElement : systems) { config.setSystem(configurationElement.item); } } /** * Reset builder */ private void reset() { invocationStrategy = null; systems = new Bag>(); fieldResolvers = new Bag>(); plugins = new Bag>(); } /** * Add field resolver. * * @param fieldResolvers * @return this */ public WorldConfigurationBuilder register(FieldResolver... fieldResolvers) { for (FieldResolver fieldResolver : fieldResolvers) { this.fieldResolvers.add(ConfigurationElement.of(fieldResolver)); } return this; } /** * Add system invocation strategy. * * @param strategy strategy to invoke. * @return this */ public WorldConfigurationBuilder register(SystemInvocationStrategy strategy) { this.invocationStrategy = strategy; return this; } /** * Specify dependency on systems/plugins. *

* Managers track priority separate from system priority, and are always added before systems. * * @param types required systems. * @return this */ public final WorldConfigurationBuilder dependsOn(Class... types) { return dependsOn(Priority.NORMAL, types); } /** * Specify dependency on systems/plugins. *

* * @param types required systems. * @param priority Higher priority are registered first. Not supported for plugins. * @return this * @throws WorldConfigurationException if unsupported classes are passed or plugins are given a priority. */ @SuppressWarnings("unchecked") public final WorldConfigurationBuilder dependsOn(int priority, Class... types) { for (Class type : types) { try { switch (cache.getFieldClassType(type)) { case SYSTEM: dependsOnSystem(priority, type); break; default: if (ClassReflection.isAssignableFrom(ArtemisPlugin.class, type)) { if (priority != Priority.NORMAL) { throw new WorldConfigurationException("Priority not supported on plugins."); } dependsOnPlugin(type); } else { throw new WorldConfigurationException("Unsupported type. Only supports systems."); } } } catch (ReflectionException e) { throw new WorldConfigurationException("Unable to instance " + type + " via reflection.", e); } } return this; } protected void dependsOnSystem(int priority, Class type) throws ReflectionException { if (!containsType(systems, type)) { this.systems.add(ConfigurationElement.of(ClassReflection.newInstance(type), priority)); } } private void dependsOnPlugin(Class type) throws ReflectionException { if (!containsType(plugins, type)) { this.plugins.add(ConfigurationElement.of(ClassReflection.newInstance(type))); } } /** * Register active system(s). * Only one instance of each class is allowed. * Use {@link #dependsOn} from within plugins whenever possible. * * @param systems systems to add, order is preserved. * @param priority priority of added systems, higher priority are added before lower priority. * @return this * @throws WorldConfigurationException if registering the same class twice. */ public WorldConfigurationBuilder with(int priority, BaseSystem... systems) { addSystems(priority, systems); return this; } /** * Register active system(s). * Only one instance of each class is allowed. * Use {@link #dependsOn} from within plugins whenever possible. * * @param systems systems to add, order is preserved. * @return this * @throws WorldConfigurationException if registering the same class twice. */ public WorldConfigurationBuilder with(BaseSystem... systems) { addSystems(Priority.NORMAL, systems); return this; } /** * Add plugins to world. *

* Upon build plugins will be called to register dependencies. *

* Only one instance of each class is allowed. * Use {@link #dependsOn} from within plugins whenever possible. * * @param plugins Plugins to add. * @return this * @throws WorldConfigurationException if type is added more than once. */ public WorldConfigurationBuilder with(ArtemisPlugin... plugins) { addPlugins(plugins); return this; } /** * Register passive systems. * Only one instance of each class is allowed. * Use {@link #dependsOn} from within plugins. * * @param systems systems to add, order is preserved. * @param priority priority of added systems, higher priority are added before lower priority. * @return this * @throws WorldConfigurationException if type is added more than once. */ public WorldConfigurationBuilder withPassive(int priority, BaseSystem... systems) { addSystems(priority, systems); return this; } /** * helper to queue systems for registration. */ private void addSystems(int priority, BaseSystem[] systems) { for (BaseSystem system : systems) { if (containsType(this.systems, system.getClass())) { throw new WorldConfigurationException("System of type " + system.getClass() + " registered twice. Only once allowed."); } this.systems.add(new ConfigurationElement(system, priority)); } } /** * Check if bag of registerables contains any of passed type. * * @param items bag of registerables. * @param type type to check for. * @return {@code true} if found {@code false} if none. */ @SuppressWarnings("unchecked") private boolean containsType(Bag items, Class type) { for (ConfigurationElement registration : (Bag>) items) { if (registration.itemType == type) { return true; } } return false; } /** * Add new plugins. */ private void addPlugins(ArtemisPlugin[] plugins) { for (ArtemisPlugin plugin : plugins) { if (containsType(this.plugins, plugin.getClass())) { throw new WorldConfigurationException("Plugin of type " + plugin.getClass() + " registered twice. Only once allowed."); } this.plugins.add(ConfigurationElement.of(plugin)); } } /** Guideline constants for priority, higher values has more priority. Will probably change. */ @UnstableApi public static abstract class Priority { public static final int LOWEST = Integer.MIN_VALUE; public static final int LOW = -10000; public static final int OPERATIONS = -1000; public static final int NORMAL = 0; public static final int HIGH = 10000; public static final int HIGHEST = Integer.MAX_VALUE; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy