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

com.artemis.injection.FieldHandler Maven / Gradle / Ivy

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

import com.artemis.InjectionException;
import com.artemis.World;
import com.artemis.utils.Bag;
import com.artemis.utils.reflect.ClassReflection;
import com.artemis.utils.reflect.Field;

import java.util.Map;

/**
 * FieldHandler provides dependency-values to an {@link com.artemis.injection.Injector}
 * by sequentially iterating over a list of registered {@link FieldResolver}.
 * 

* The method {@link #resolve(Class, Field)} will return the first non-null value provided by * {@link FieldResolver#resolve(Class, Field)}, or null if no resolver returned a valid value. *

*

* During {@link World} construction, after systems and managers have been created, {@link #initialize(World)} * will be called for each registered {@link FieldResolver} *

*

* If {@link FieldResolver} implements {@link UseInjectionCache}, {@link UseInjectionCache#setCache(InjectionCache)} * will be called prior to {@link FieldResolver#initialize(World)} being called, availing the {@link InjectionCache} * used by this handler. *

* * @author Snorre E. Brekke */ public class FieldHandler { private InjectionCache cache; protected Bag fieldResolvers; /** * Constructs a new FieldHandler with the provided fieldResolvers. This constructor should be used when full * control over the {@link FieldResolver} order is required. *

* For Artemis to function correctly, {@link ArtemisFieldResolver} should be added somewhere in the bag, or * added via {@link #addFieldResolver(FieldResolver)} prior to world construction. *

* * @param cache used for better reflection-speed. * @param fieldResolvers bag of fieldresolver this FieldHandler should use. * @see ArtemisFieldResolver */ public FieldHandler(InjectionCache cache, Bag fieldResolvers) { this.cache = cache; this.fieldResolvers = fieldResolvers; } /** * Constructs a ned FieldHandler with an {@link ArtemisFieldResolver} and {@link WiredFieldResolver} * already registered, which can resolve {@link com.artemis.ComponentMapper}, {@link com.artemis.BaseSystem} * and {@link com.artemis.Manager} types registered in the {@link World} * {@link com.artemis.annotations.Wire}. * * @param cache used for better reflection-speed. * @see ArtemisFieldResolver */ public FieldHandler(InjectionCache cache) { this.fieldResolvers = new Bag(FieldResolver.class); this.cache = cache; addFieldResolver(new ArtemisFieldResolver()); addFieldResolver(new AspectFieldResolver()); addFieldResolver(new WiredFieldResolver()); } /** * During {@link World} construction, after systems and managers have been created, {@link #initialize(World)} * will be called for each registered {@link FieldResolver} *

*

* If {@link FieldResolver} implements {@link UseInjectionCache}, {@link UseInjectionCache#setCache(InjectionCache)} * will be called prior to {@link FieldResolver#initialize(World)} being called, availing the {@link InjectionCache} * used by this handler. * * @param world the world this FieldHandler is being used for * @throws com.artemis.WorldConfigurationException when injector has no way to deal with injectables. */ public void initialize(World world, Map injectables) { boolean fieldResolverFound = false; for (int i = 0, s = fieldResolvers.size(); i < s; i++) { FieldResolver fieldResolver = fieldResolvers.get(i); if (ClassReflection.isInstance(UseInjectionCache.class, fieldResolver)) { ((UseInjectionCache) fieldResolver).setCache(cache); } if (ClassReflection.isInstance(PojoFieldResolver.class, fieldResolver)) { ((PojoFieldResolver) fieldResolver).setPojos(injectables); fieldResolverFound = true; } fieldResolver.initialize(world); } if ( injectables != null && !injectables.isEmpty() && !fieldResolverFound ) { throw new InjectionException("FieldHandler lacks resolver capable of dealing with your custom injectables. Register a WiredFieldResolver or PojoFieldResolver with your FieldHandler."); } } /** * Returns the first non-null value provided by * {@link FieldResolver#resolve(Class, Field)}, or null if no resolver returned a valid value. * * @param fieldType class of the field * @param field field for which a value should be resolved * @return a non-null value if any {@link FieldResolver} could provide an instance * for the {@code field}, null if the {@code field} could not be resolved */ public Object resolve(Class fieldType, Field field) { for (int i = 0, s = fieldResolvers.size(); i < s; i++) { Object resolved = fieldResolvers.get(i).resolve(fieldType, field); if (resolved != null) { return resolved; } } return null; } /** * Adds a {@link FieldResolver} to this handler. Resolvers added first, will be used first for resolving fields, * so the order of add operations is significant. * * @param fieldResolver is added to this FieldHandler fieldresolver-list */ public final void addFieldResolver(FieldResolver fieldResolver) { fieldResolvers.add(fieldResolver); } public Bag getFieldResolvers() { return fieldResolvers; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy