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

com.github.czyzby.autumn.mvc.component.preferences.PreferencesService Maven / Gradle / Ivy

Go to download

MVC framework based on LibGDX using Autumn for components management and LML as view templates.

There is a newer version: 1.9.1.9.6
Show newest version
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