com.github.czyzby.autumn.mvc.component.preferences.PreferencesService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gdx-autumn-mvc Show documentation
Show all versions of gdx-autumn-mvc Show documentation
MVC framework based on LibGDX using Autumn for components management and LML as view templates.
package com.github.czyzby.autumn.mvc.component.preferences;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectMap.Entry;
import com.badlogic.gdx.utils.ObjectSet;
import com.badlogic.gdx.utils.reflect.Field;
import com.github.czyzby.autumn.annotation.Destroy;
import com.github.czyzby.autumn.annotation.Initiate;
import com.github.czyzby.autumn.annotation.Inject;
import com.github.czyzby.autumn.context.Context;
import com.github.czyzby.autumn.context.ContextDestroyer;
import com.github.czyzby.autumn.context.ContextInitializer;
import com.github.czyzby.autumn.mvc.component.preferences.dto.Preference;
import com.github.czyzby.autumn.mvc.component.preferences.dto.ReflectionPreference;
import com.github.czyzby.autumn.mvc.component.ui.InterfaceService;
import com.github.czyzby.autumn.mvc.config.AutumnActionPriority;
import com.github.czyzby.autumn.mvc.stereotype.preference.Property;
import com.github.czyzby.autumn.processor.AbstractAnnotationProcessor;
import com.github.czyzby.kiwi.util.common.Exceptions;
import com.github.czyzby.kiwi.util.common.Strings;
import com.github.czyzby.kiwi.util.gdx.collection.GdxMaps;
import com.github.czyzby.kiwi.util.gdx.collection.GdxSets;
/** Manages application's preferences.
*
* @author MJ
* @see Property */
public class PreferencesService extends AbstractAnnotationProcessor {
/** Prefix used to add action of accessing the preference in LML templates. This value will be added before
* preference name to construct the action. */
public static String GETTER_PREFIX = "get", SETTER_PREFIX = "set";
/** Preference names (keys) with their {@link Preference} objects (values). */
private final ObjectMap> preferences = GdxMaps.newObjectMap();
/** Preference names (keys) with their {@link Preferences} files (values). */
private final ObjectMap namesToFiles = GdxMaps.newObjectMap();
/** Preference names (keys) with their {@link Preferences} files names, as stored in LML parser (values). */
private final ObjectMap preferencesToInitiate = GdxMaps.newObjectMap();
@Inject private InterfaceService interfaceService;
@Override
public Class getSupportedAnnotationType() {
return Property.class;
}
@Override
public boolean isSupportingFields() {
return true;
}
@Override
public void processField(final Field field, final Property annotation, final Object component,
final Context context, final ContextInitializer initializer, final ContextDestroyer contextDestroyer) {
final String name = Strings.isBlank(annotation.value()) ? field.getName() : annotation.value();
addPreference(name, annotation.preferences(),
new ReflectionPreference(field.isStatic() ? null : component, field));
}
/** @param name name of the preference. Will determine how the preference is saved in the file. set(name) and
* get(name) methods will be added to LML templates.
* @param preferencesName name of the registered preferences.
* @param preference container of the preference. Note that the preference won't be initiated (read from preferences
* file) unless {@link #initiatePreferences()} is called. */
public void addPreference(final String name, final String preferencesName, final Preference> preference) {
preferences.put(name, preference);
preferencesToInitiate.put(name, preferencesName);
}
/** Initiates all {@link Property}-annotated preferences. Called automatically during application initiation. */
@Initiate(priority = AutumnActionPriority.HIGH_PRIORITY)
public void initiatePreferences() {
for (final Entry preference : preferencesToInitiate) {
final String name = preference.key;
final Preferences preferences = getPreferences(preference.value);
namesToFiles.put(name, preferences);
final Preference> preferenceWrapper = this.preferences.get(name);
initiatePreference(name, preferenceWrapper, preferences);
addLmlActions(name, preferenceWrapper);
}
preferencesToInitiate.clear();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void initiatePreference(final String name, final Preference preference,
final Preferences preferences) {
if (preferences.contains(name)) {
try {
preference.read(name, preferences);
} catch (final Exception exception) {
Exceptions.ignore(exception);
preference.set(preference.getDefault());
}
} else {
preference.set(preference.getDefault());
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void addLmlActions(final String name, final Preference> preference) {
interfaceService.getParser().getData().addActorConsumer(GETTER_PREFIX + name,
new Preference.PreferenceGetter(preference));
interfaceService.getParser().getData().addActorConsumer(SETTER_PREFIX + name,
new Preference.PreferenceSetter(preference));
}
/** @param preferencesName name of the registered preferences.
* @return preferences object mapped to the selected name. */
public Preferences getPreferences(final String preferencesName) {
return interfaceService.getParser().getData().getPreferences(preferencesName);
}
/** @param preference name of the preference.
* @return preference wrapper, allowing to access chosen preference. */
public Preference> getPreference(final String preference) {
return preferences.get(preference);
}
/** @param preference name of the preference.
* @param preferenceType class of the preference value managed by the wrapper.
* @return preference wrapper, allowing to access chosen preference.
* @param type supported by the preference. Performs unchecked cast. */
@SuppressWarnings("unchecked")
public Preference getPreference(final String preference, final Class preferenceType) {
return (Preference) preferences.get(preference);
}
@Override
public boolean isSupportingTypes() {
return true;
}
@Override
public void processType(final Class> type, final Property annotation, final Object component,
final Context context, final ContextInitializer initializer, final ContextDestroyer contextDestroyer) {
if (component instanceof Preference>) {
addPreference(annotation.value(), annotation.preferences(), (Preference>) component);
} else {
throw new GdxRuntimeException(
"Invalid type annotated with @Property: expecting Preference, got: " + component);
}
}
/** Saves all current preferences. This is a reasonably heavy operation, as it flushes all preferences files - by
* default, this is done once, before the application is closed. */
@Destroy(priority = AutumnActionPriority.MIN_PRIORITY)
public void savePreferences() {
final ObjectSet preferencesToFlush = GdxSets.newSet();
for (final Entry> preference : preferences) {
final Preferences preferencesFile = namesToFiles.get(preference.key);
preferencesToFlush.add(preferencesFile);
preference.value.save(preference.key, preferencesFile);
}
for (final Preferences preferencesFile : preferencesToFlush) {
preferencesFile.flush();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy