package net.onedaybeard.dominatrix.inject;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import net.onedaybeard.dominatrix.util.Logger;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
public class PropertyInjector
{
public static final String TAG = PropertyInjector.class.getSimpleName();
private final List<WeakReference<InjectableProperties>> tweakables;
private Properties properties;
public static boolean debug = false;
private Injector injector;
public PropertyInjector()
{
tweakables = new LinkedList<WeakReference<InjectableProperties>>();
injector = new Injector();
}
public void setTypeInjector(Class<?> klazz, TypeInjector injector)
{
this.injector.setTypeInjector(klazz, injector);
}
public Array<InjectableProperties> getRegistered()
{
Array<InjectableProperties> collect = new Array<InjectableProperties>();
for (WeakReference<InjectableProperties> ref : tweakables)
{
InjectableProperties tp = ref.get();
if (tp != null)
collect.add(tp);
}
return collect;
}
public void clear()
{
tweakables.clear();
}
/**
* Registers an instance for injection via {@link #injectRegistered()} and
* {@link #inject(InjectableProperties)}
*/
public void register(InjectableProperties injectable)
{
tweakables.add(new WeakReference<InjectableProperties>(injectable));
if (debug)
Logger.log(TAG, "Tracking %d tweakable objects", tweakables.size());
}
/**
* Re-feeds previously feed properties, if any. Useful for game restarts etc.
*/
public void injectRegistered()
{
if (properties != null)
injectRegistered(properties);
}
public void injectRegistered(FileHandle file)
{
try
{
Properties properties = new Properties();
properties.load(file.read());
injectRegistered(properties);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public void injectRegistered(Properties properties)
{
System.gc();
this.properties = properties;
int nulledReferences = 0;
if (debug)
Logger.log(TAG, "Feeding new set of properties to registered objects.");
Iterator<WeakReference<InjectableProperties>> iterator = tweakables.iterator();
while (iterator.hasNext())
{
WeakReference<InjectableProperties> reference = iterator.next();
InjectableProperties tweakable = reference.get();
if (tweakable == null)
{
iterator.remove();
nulledReferences++;
}
else
{
safeInject(properties, tweakable);
}
}
if (debug && nulledReferences > 0)
Logger.log(TAG, "Cleared %d nulled references.", nulledReferences);
}
private void safeInject(Properties properties, InjectableProperties tweakable)
{
try
{
injector.inject(tweakable, properties);
tweakable.newValues(properties);
}
catch (Exception e)
{
Logger.error(TAG, e, "Failed feeding properties.");
}
}
public void inject(InjectableProperties tweakable)
{
if (properties != null)
safeInject(properties, tweakable);
}
}