Android: Refactor the settings managemnt

1. Create Settings class the encaupslate the loading/saving of all settings
2. Decouple the logic of saving the settings into 3 different config files
from the UI code.
This commit is contained in:
mahdihijazi 2018-07-23 22:23:12 +02:00
parent 61835a7e08
commit c664bb7458
22 changed files with 817 additions and 816 deletions

View File

@ -4,9 +4,9 @@ public final class BooleanSetting extends Setting
{
private boolean mValue;
public BooleanSetting(String key, String section, int file, boolean value)
public BooleanSetting(String key, String section, boolean value)
{
super(key, section, file);
super(key, section);
mValue = value;
}

View File

@ -4,9 +4,9 @@ public final class FloatSetting extends Setting
{
private float mValue;
public FloatSetting(String key, String section, int file, float value)
public FloatSetting(String key, String section, float value)
{
super(key, section, file);
super(key, section);
mValue = value;
}

View File

@ -7,15 +7,15 @@ public final class IntSetting extends Setting
private int mValue;
private MenuTag menuTag;
public IntSetting(String key, String section, int file, int value)
public IntSetting(String key, String section, int value)
{
super(key, section, file);
super(key, section);
mValue = value;
}
public IntSetting(String key, String section, int file, int value, MenuTag menuTag)
public IntSetting(String key, String section, int value, MenuTag menuTag)
{
super(key, section, file);
super(key, section);
mValue = value;
this.menuTag = menuTag;
}

View File

@ -10,20 +10,17 @@ public abstract class Setting
{
private String mKey;
private String mSection;
private int mFile;
/**
* Base constructor.
*
* @param key Everything to the left of the = in a line from the ini file.
* @param section The corresponding recent section header; e.g. [Core] or [Enhancements] without the brackets.
* @param file The ini file the Setting is stored in.
*/
public Setting(String key, String section, int file)
public Setting(String key, String section)
{
mKey = key;
mSection = section;
mFile = file;
}
/**
@ -44,14 +41,6 @@ public abstract class Setting
return mSection;
}
/**
*
* @return The ini file the Setting is stored in.
*/
public int getFile()
{
return mFile;
}
/**
* @return A representation of this Setting's backing value converted to a String (e.g. for serialization).

View File

@ -0,0 +1,136 @@
package org.dolphinemu.dolphinemu.features.settings.model;
import android.text.TextUtils;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class Settings
{
public static final String SECTION_INI_CORE = "Core";
public static final String SECTION_INI_INTERFACE = "Interface";
public static final String SECTION_GFX_SETTINGS = "Settings";
public static final String SECTION_GFX_ENHANCEMENTS = "Enhancements";
public static final String SECTION_GFX_HACKS = "Hacks";
public static final String SECTION_STEREOSCOPY = "Stereoscopy";
public static final String SECTION_WIIMOTE = "Wiimote";
public static final String SECTION_BINDINGS = "Android";
private String gameId;
private static final Map<String, List<String>> configFileSectionsMap = new HashMap<>();
static
{
configFileSectionsMap.put(SettingsFile.FILE_NAME_DOLPHIN, Arrays.asList(SECTION_INI_CORE, SECTION_INI_INTERFACE, SECTION_BINDINGS));
configFileSectionsMap.put(SettingsFile.FILE_NAME_GFX, Arrays.asList(SECTION_GFX_SETTINGS, SECTION_GFX_ENHANCEMENTS, SECTION_GFX_HACKS, SECTION_STEREOSCOPY));
configFileSectionsMap.put(SettingsFile.FILE_NAME_WIIMOTE, Arrays.asList(SECTION_WIIMOTE + 1, SECTION_WIIMOTE + 2, SECTION_WIIMOTE + 3, SECTION_WIIMOTE + 4));
}
/**
* A HashMap<String, SettingSection> that constructs a new SettingSection instead of returning null
* when getting a key not already in the map
*/
public static final class SettingsSectionMap extends HashMap<String, SettingSection>
{
@Override
public SettingSection get(Object key)
{
if (!(key instanceof String))
{
return null;
}
String stringKey = (String) key;
if (!super.containsKey(stringKey))
{
SettingSection section = new SettingSection(stringKey);
super.put(stringKey, section);
return section;
}
return super.get(key);
}
}
private HashMap<String, SettingSection> sections = new Settings.SettingsSectionMap();
public SettingSection getSection(String sectionName)
{
return sections.get(sectionName);
}
public boolean isEmpty()
{
return sections.isEmpty();
}
public HashMap<String, SettingSection> getSections()
{
return sections;
}
public void loadSettings(SettingsActivityView view)
{
sections = new Settings.SettingsSectionMap();
if (TextUtils.isEmpty(gameId))
{
for (Map.Entry<String, List<String>> entry : configFileSectionsMap.entrySet())
{
String fileName = entry.getKey();
sections.putAll(SettingsFile.readFile(fileName, view));
}
}
else
{
// custom game settings
sections.putAll(SettingsFile.readFile("../GameSettings/" + gameId, view));
}
}
public void loadSettings(String gameId, SettingsActivityView view)
{
this.gameId = gameId;
loadSettings(view);
}
public void saveSettings(SettingsActivityView view)
{
if (TextUtils.isEmpty(gameId))
{
view.showToastMessage("Saved settings to INI files");
for (Map.Entry<String, List<String>> entry : configFileSectionsMap.entrySet())
{
String fileName = entry.getKey();
List<String> sectionNames = entry.getValue();
TreeMap<String, SettingSection> iniSections = new TreeMap<>();
for (String section : sectionNames)
{
iniSections.put(section, sections.get(section));
}
SettingsFile.saveFile(fileName, iniSections, view);
}
}
else
{
// custom game settings
view.showToastMessage("Saved settings for " + gameId);
TreeMap<String, SettingSection> iniSections = new TreeMap<>(sections);
SettingsFile.saveFile("../GameSettings/" + gameId, iniSections, view);
}
}
}

View File

@ -4,9 +4,9 @@ public final class StringSetting extends Setting
{
private String mValue;
public StringSetting(String key, String section, int file, String value)
public StringSetting(String key, String section, String value)
{
super(key, section, file);
super(key, section);
mValue = value;
}

View File

@ -7,9 +7,9 @@ public final class CheckBoxSetting extends SettingsItem
{
private boolean mDefaultValue;
public CheckBoxSetting(String key, String section, int file, int titleId, int descriptionId, boolean defaultValue, Setting setting)
public CheckBoxSetting(String key, String section, int titleId, int descriptionId, boolean defaultValue, Setting setting)
{
super(key, section, file, setting, titleId, descriptionId);
super(key, section, setting, titleId, descriptionId);
mDefaultValue = defaultValue;
}
@ -35,7 +35,7 @@ public final class CheckBoxSetting extends SettingsItem
{
if (getSetting() == null)
{
BooleanSetting setting = new BooleanSetting(getKey(), getSection(), getFile(), checked);
BooleanSetting setting = new BooleanSetting(getKey(), getSection(), checked);
setSetting(setting);
return setting;
}

View File

@ -6,7 +6,7 @@ public final class HeaderSetting extends SettingsItem
{
public HeaderSetting(String key, Setting setting, int titleId, int descriptionId)
{
super(key, null, 0, setting, titleId, descriptionId);
super(key, null, setting, titleId, descriptionId);
}
@Override

View File

@ -5,9 +5,9 @@ import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
public final class InputBindingSetting extends SettingsItem
{
public InputBindingSetting(String key, String section, int file, int titleId, Setting setting)
public InputBindingSetting(String key, String section, int titleId, Setting setting)
{
super(key, section, file, setting, titleId, 0);
super(key, section, setting, titleId, 0);
}
public String getValue()
@ -32,7 +32,7 @@ public final class InputBindingSetting extends SettingsItem
{
if (getSetting() == null)
{
StringSetting setting = new StringSetting(getKey(), getSection(), getFile(), bind);
StringSetting setting = new StringSetting(getKey(), getSection(), bind);
setSetting(setting);
return setting;
}

View File

@ -22,7 +22,6 @@ public abstract class SettingsItem
private String mKey;
private String mSection;
private int mFile;
private Setting mSetting;
@ -39,11 +38,10 @@ public abstract class SettingsItem
* @param nameId Resource ID for a text string to be displayed as this setting's name.
* @param descriptionId Resource ID for a text string to be displayed as this setting's description.
*/
public SettingsItem(String key, String section, int file, Setting setting, int nameId, int descriptionId)
public SettingsItem(String key, String section, Setting setting, int nameId, int descriptionId)
{
mKey = key;
mSection = section;
mFile = file;
mSetting = setting;
mNameId = nameId;
mDescriptionId = descriptionId;
@ -67,14 +65,6 @@ public abstract class SettingsItem
return mSection;
}
/**
*
* @return The file the backing Setting is saved to.
*/
public int getFile()
{
return mFile;
}
/**
*

View File

@ -12,18 +12,18 @@ public final class SingleChoiceSetting extends SettingsItem
private int mValuesId;
private MenuTag menuTag;
public SingleChoiceSetting(String key, String section, int file, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting, MenuTag menuTag)
public SingleChoiceSetting(String key, String section, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting, MenuTag menuTag)
{
super(key, section, file, setting, titleId, descriptionId);
super(key, section, setting, titleId, descriptionId);
mValuesId = valuesId;
mChoicesId = choicesId;
mDefaultValue = defaultValue;
this.menuTag = menuTag;
}
public SingleChoiceSetting(String key, String section, int file, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting)
public SingleChoiceSetting(String key, String section, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting)
{
this(key, section, file, titleId, descriptionId, choicesId, valuesId, defaultValue, setting, null);
this(key, section, titleId, descriptionId, choicesId, valuesId, defaultValue, setting, null);
}
public int getChoicesId()
@ -65,7 +65,7 @@ public final class SingleChoiceSetting extends SettingsItem
{
if (getSetting() == null)
{
IntSetting setting = new IntSetting(getKey(), getSection(), getFile(), selection);
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
setSetting(setting);
return setting;
}

View File

@ -4,7 +4,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.FloatSetting;
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
import org.dolphinemu.dolphinemu.features.settings.model.Setting;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
public final class SliderSetting extends SettingsItem
{
@ -13,9 +13,9 @@ public final class SliderSetting extends SettingsItem
private String mUnits;
public SliderSetting(String key, String section, int file, int titleId, int descriptionId, int max, String units, int defaultValue, Setting setting)
public SliderSetting(String key, String section, int titleId, int descriptionId, int max, String units, int defaultValue, Setting setting)
{
super(key, section, file, setting, titleId, descriptionId);
super(key, section, setting, titleId, descriptionId);
mMax = max;
mUnits = units;
mDefaultValue = defaultValue;
@ -71,7 +71,7 @@ public final class SliderSetting extends SettingsItem
{
if (getSetting() == null)
{
IntSetting setting = new IntSetting(getKey(), getSection(), getFile(), selection);
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
setSetting(setting);
return setting;
}
@ -94,7 +94,7 @@ public final class SliderSetting extends SettingsItem
{
if (getSetting() == null)
{
FloatSetting setting = new FloatSetting(getKey(), getSection(), getFile(), selection);
FloatSetting setting = new FloatSetting(getKey(), getSection(), selection);
setSetting(setting);
return setting;
}

View File

@ -10,9 +10,9 @@ public class StringSingleChoiceSetting extends SettingsItem
private String[] mChoicesId;
private String[] mValuesId;
public StringSingleChoiceSetting(String key, String section, int file, int titleId, int descriptionId, String[] choicesId, String[] valuesId, String defaultValue, Setting setting)
public StringSingleChoiceSetting(String key, String section, int titleId, int descriptionId, String[] choicesId, String[] valuesId, String defaultValue, Setting setting)
{
super(key, section, file, setting, titleId, descriptionId);
super(key, section, setting, titleId, descriptionId);
mValuesId = valuesId;
mChoicesId = choicesId;
mDefaultValue = defaultValue;
@ -75,7 +75,7 @@ public class StringSingleChoiceSetting extends SettingsItem
{
if (getSetting() == null)
{
StringSetting setting = new StringSetting(getKey(), getSection(), getFile(), selection);
StringSetting setting = new StringSetting(getKey(), getSection(), selection);
setSetting(setting);
return setting;
}

View File

@ -9,7 +9,7 @@ public final class SubmenuSetting extends SettingsItem
public SubmenuSetting(String key, Setting setting, int titleId, int descriptionId, MenuTag menuKey)
{
super(key, null, 0, setting, titleId, descriptionId);
super(key, null, setting, titleId, descriptionId);
mMenuKey = menuKey;
}

View File

@ -19,7 +19,6 @@ import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import java.util.ArrayList;
import java.util.HashMap;
public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView
@ -186,19 +185,19 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
}
@Override
public HashMap<String, SettingSection> getSettings(int file)
public org.dolphinemu.dolphinemu.features.settings.model.Settings getSettings()
{
return mPresenter.getSettings(file);
return mPresenter.getSettings();
}
@Override
public void setSettings(ArrayList<HashMap<String, SettingSection>> settings)
public void setSettings(org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
{
mPresenter.setSettings(settings);
}
@Override
public void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings)
public void onSettingsFileLoaded(org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
{
SettingsFragmentView fragment = getFragment();

View File

@ -5,224 +5,202 @@ import android.os.Bundle;
import android.text.TextUtils;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService.DirectoryInitializationState;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
import java.util.ArrayList;
import java.util.HashMap;
public final class SettingsActivityPresenter
{
private static final String KEY_SHOULD_SAVE = "should_save";
private static final String KEY_SHOULD_SAVE = "should_save";
private SettingsActivityView mView;
private SettingsActivityView mView;
private ArrayList<HashMap<String, SettingSection>> mSettings = new ArrayList<>();
private Settings mSettings = new Settings();
private int mStackCount;
private int mStackCount;
private boolean mShouldSave;
private boolean mShouldSave;
private DirectoryStateReceiver directoryStateReceiver;
private DirectoryStateReceiver directoryStateReceiver;
private MenuTag menuTag;
private String gameId;
private MenuTag menuTag;
private String gameId;
public SettingsActivityPresenter(SettingsActivityView view)
{
mView = view;
}
SettingsActivityPresenter(SettingsActivityView view)
{
mView = view;
}
public void onCreate(Bundle savedInstanceState, MenuTag menuTag, String gameId)
{
if (savedInstanceState == null)
{
this.menuTag = menuTag;
this.gameId = gameId;
}
else
{
mShouldSave = savedInstanceState.getBoolean(KEY_SHOULD_SAVE);
}
}
public void onCreate(Bundle savedInstanceState, MenuTag menuTag, String gameId)
{
if (savedInstanceState == null)
{
this.menuTag = menuTag;
this.gameId = gameId;
}
else
{
mShouldSave = savedInstanceState.getBoolean(KEY_SHOULD_SAVE);
}
}
public void onStart()
{
prepareDolphinDirectoriesIfNeeded();
}
public void onStart()
{
prepareDolphinDirectoriesIfNeeded();
}
void loadSettingsUI()
{
if (mSettings.isEmpty())
{
if (!TextUtils.isEmpty(gameId))
{
mSettings.add(SettingsFile.SETTINGS_DOLPHIN, SettingsFile.readFile("../GameSettings/" + gameId, mView));
mSettings.add(SettingsFile.SETTINGS_GFX, SettingsFile.readFile("../GameSettings/" + gameId, mView));
mSettings.add(SettingsFile.SETTINGS_WIIMOTE, SettingsFile.readFile("../GameSettings/" + gameId, mView));
}
else
{
mSettings.add(SettingsFile.SETTINGS_DOLPHIN, SettingsFile.readFile(SettingsFile.FILE_NAME_DOLPHIN, mView));
mSettings.add(SettingsFile.SETTINGS_GFX, SettingsFile.readFile(SettingsFile.FILE_NAME_GFX, mView));
mSettings.add(SettingsFile.SETTINGS_WIIMOTE, SettingsFile.readFile(SettingsFile.FILE_NAME_WIIMOTE, mView));
}
}
private void loadSettingsUI()
{
if (mSettings.isEmpty())
{
if (!TextUtils.isEmpty(gameId))
{
mSettings.loadSettings(gameId, mView);
}
else
{
mSettings.loadSettings(mView);
}
}
mView.showSettingsFragment(menuTag, null, false, gameId);
mView.onSettingsFileLoaded(mSettings);
}
mView.showSettingsFragment(menuTag, null, false, gameId);
mView.onSettingsFileLoaded(mSettings);
}
private void prepareDolphinDirectoriesIfNeeded()
{
if (DirectoryInitializationService.areDolphinDirectoriesReady()) {
loadSettingsUI();
} else {
mView.showLoading();
IntentFilter statusIntentFilter = new IntentFilter(
DirectoryInitializationService.BROADCAST_ACTION);
private void prepareDolphinDirectoriesIfNeeded()
{
if (DirectoryInitializationService.areDolphinDirectoriesReady())
{
loadSettingsUI();
}
else
{
mView.showLoading();
IntentFilter statusIntentFilter = new IntentFilter(
DirectoryInitializationService.BROADCAST_ACTION);
directoryStateReceiver =
new DirectoryStateReceiver(directoryInitializationState ->
{
if (directoryInitializationState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
{
mView.hideLoading();
loadSettingsUI();
}
else if (directoryInitializationState == DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
{
mView.showPermissionNeededHint();
mView.hideLoading();
}
else if (directoryInitializationState == DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
{
mView.showExternalStorageNotMountedHint();
mView.hideLoading();
}
});
directoryStateReceiver =
new DirectoryStateReceiver(directoryInitializationState ->
{
if (directoryInitializationState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
{
mView.hideLoading();
loadSettingsUI();
}
else if (directoryInitializationState == DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
{
mView.showPermissionNeededHint();
mView.hideLoading();
}
else if (directoryInitializationState == DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
{
mView.showExternalStorageNotMountedHint();
mView.hideLoading();
}
});
mView.startDirectoryInitializationService(directoryStateReceiver, statusIntentFilter);
}
}
mView.startDirectoryInitializationService(directoryStateReceiver, statusIntentFilter);
}
}
public void setSettings(ArrayList<HashMap<String, SettingSection>> settings)
{
mSettings = settings;
}
public void setSettings(Settings settings)
{
mSettings = settings;
}
public HashMap<String, SettingSection> getSettings(int file)
{
return mSettings.get(file);
}
public Settings getSettings()
{
return mSettings;
}
public void onStop(boolean finishing)
{
if (directoryStateReceiver != null)
{
mView.stopListeningToDirectoryInitializationService(directoryStateReceiver);
directoryStateReceiver = null;
}
public void onStop(boolean finishing)
{
if (directoryStateReceiver != null)
{
mView.stopListeningToDirectoryInitializationService(directoryStateReceiver);
directoryStateReceiver = null;
}
if (mSettings != null && finishing && mShouldSave)
{
if (!TextUtils.isEmpty(gameId)) {
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
// Needed workaround for now due to an odd bug in how it handles saving two different settings sections to the same file. It won't save GFX settings if it follows the normal saving pattern
if (menuTag.equals(MenuTag.CONFIG))
{
SettingsFile.saveFile("../GameSettings/" + gameId, mSettings.get(SettingsFile.SETTINGS_DOLPHIN), mView);
}
else if (menuTag.equals(MenuTag.GRAPHICS))
{
SettingsFile.saveFile("../GameSettings/" + gameId, mSettings.get(SettingsFile.SETTINGS_GFX), mView);
}
mView.showToastMessage("Saved settings for " + gameId);
} else {
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
SettingsFile.saveFile(SettingsFile.FILE_NAME_DOLPHIN, mSettings.get(SettingsFile.SETTINGS_DOLPHIN), mView);
SettingsFile.saveFile(SettingsFile.FILE_NAME_GFX, mSettings.get(SettingsFile.SETTINGS_GFX), mView);
SettingsFile.saveFile(SettingsFile.FILE_NAME_WIIMOTE, mSettings.get(SettingsFile.SETTINGS_WIIMOTE), mView);
mView.showToastMessage("Saved settings to INI files");
}
}
}
if (mSettings != null && finishing && mShouldSave)
{
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
mSettings.saveSettings(mView);
}
}
public void addToStack()
{
mStackCount++;
}
public void addToStack()
{
mStackCount++;
}
public void onBackPressed()
{
if (mStackCount > 0)
{
mView.popBackStack();
mStackCount--;
}
else
{
mView.finish();
}
}
public void onBackPressed()
{
if (mStackCount > 0)
{
mView.popBackStack();
mStackCount--;
}
else
{
mView.finish();
}
}
public boolean handleOptionsItem(int itemId)
{
switch (itemId)
{
case R.id.menu_save_exit:
mView.finish();
return true;
}
public boolean handleOptionsItem(int itemId)
{
switch (itemId)
{
case R.id.menu_save_exit:
mView.finish();
return true;
}
return false;
}
return false;
}
public void onSettingChanged()
{
mShouldSave = true;
}
public void onSettingChanged()
{
mShouldSave = true;
}
public void saveState(Bundle outState)
{
outState.putBoolean(KEY_SHOULD_SAVE, mShouldSave);
}
public void saveState(Bundle outState)
{
outState.putBoolean(KEY_SHOULD_SAVE, mShouldSave);
}
public void onGcPadSettingChanged(MenuTag key, int value)
{
if (value != 0) // Not disabled
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value/6);
mView.showSettingsFragment(key, bundle, true, gameId);
}
}
public void onGcPadSettingChanged(MenuTag key, int value)
{
if (value != 0) // Not disabled
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value / 6);
mView.showSettingsFragment(key, bundle, true, gameId);
}
}
public void onWiimoteSettingChanged(MenuTag menuTag, int value)
{
switch (value)
{
case 1:
mView.showSettingsFragment(menuTag, null, true, gameId);
break;
public void onWiimoteSettingChanged(MenuTag menuTag, int value)
{
switch (value)
{
case 1:
mView.showSettingsFragment(menuTag, null, true, gameId);
break;
case 2:
mView.showToastMessage("Please make sure Continuous Scanning is enabled in Core Settings.");
break;
}
}
case 2:
mView.showToastMessage("Please make sure Continuous Scanning is enabled in Core Settings.");
break;
}
}
public void onExtensionSettingChanged(MenuTag menuTag, int value)
{
if (value != 0) // None
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value);
mView.showSettingsFragment(menuTag, bundle, true, gameId);
}
}
public void onExtensionSettingChanged(MenuTag menuTag, int value)
{
if (value != 0) // None
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value);
mView.showSettingsFragment(menuTag, bundle, true, gameId);
}
}
}

View File

@ -3,12 +3,9 @@ package org.dolphinemu.dolphinemu.features.settings.ui;
import android.content.IntentFilter;
import android.os.Bundle;
import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Abstraction for the Activity that manages SettingsFragments.
*/
@ -27,10 +24,9 @@ public interface SettingsActivityView
* loaded from disk, so that each Fragment doesn't need to perform its own
* read operation.
*
* @param file The settings file to load.
* @return A possibly null HashMap of Settings.
*/
HashMap<String, SettingSection> getSettings(int file);
Settings getSettings();
/**
* Used to provide the Activity with Settings HashMaps if a Fragment already
@ -39,14 +35,14 @@ public interface SettingsActivityView
*
* @param settings The ArrayList of all the Settings HashMaps.
*/
void setSettings(ArrayList<HashMap<String, SettingSection>> settings);
void setSettings(Settings settings);
/**
* Called when an asynchronous load operation completes.
*
* @param settings The (possibly null) result of the ini load operation.
*/
void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings);
void onSettingsFileLoaded(Settings settings);
/**
* Called when an asynchronous load operation fails.

View File

@ -17,6 +17,7 @@ import org.dolphinemu.dolphinemu.dialogs.MotionAlertDialog;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
import org.dolphinemu.dolphinemu.features.settings.model.FloatSetting;
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.CheckBoxSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
@ -33,7 +34,7 @@ import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SingleChoiceVie
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SliderViewHolder;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SubmenuViewHolder;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import java.util.ArrayList;
@ -143,7 +144,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
if (item.getKey().equals(SettingsFile.KEY_SKIP_EFB) || item.getKey().equals(SettingsFile.KEY_IGNORE_FORMAT))
{
mView.putSetting(new BooleanSetting(item.getKey(), item.getSection(), item.getFile(), !checked));
mView.putSetting(new BooleanSetting(item.getKey(), item.getSection(), !checked));
}
mView.onSettingChanged();
@ -227,7 +228,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
});
dialog.setOnDismissListener(dialog1 ->
{
StringSetting setting = new StringSetting(item.getKey(), item.getSection(), item.getFile(), item.getValue());
StringSetting setting = new StringSetting(item.getKey(), item.getSection(), item.getValue());
notifyItemChanged(position);
if (setting != null)
@ -404,35 +405,34 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
return -1;
}
public void putVideoBackendSetting(int which)
private void putVideoBackendSetting(int which)
{
StringSetting gfxBackend = null;
switch (which)
{
case 0:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, Settings.SECTION_INI_CORE, "OGL");
break;
case 1:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, Settings.SECTION_INI_CORE, "Vulkan");
break;
case 2:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, Settings.SECTION_INI_CORE, "Software Renderer");
break;
case 3:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, Settings.SECTION_INI_CORE, "Null");
break;
}
mView.putSetting(gfxBackend);
}
private void putExtensionSetting(int which, int wiimoteNumber)
{
StringSetting gfxBackend = null;
switch (which)
{
case 0:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_INI_CORE, SettingsFile.SETTINGS_DOLPHIN, "OGL");
break;
case 1:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_INI_CORE, SettingsFile.SETTINGS_DOLPHIN, "Vulkan");
break;
case 2:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_INI_CORE, SettingsFile.SETTINGS_DOLPHIN, "Software Renderer");
break;
case 3:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_INI_CORE, SettingsFile.SETTINGS_DOLPHIN, "Null");
break;
}
mView.putSetting(gfxBackend);
}
public void putExtensionSetting(int which, int wiimoteNumber)
{
StringSetting extension = new StringSetting(SettingsFile.KEY_WIIMOTE_EXTENSION, SettingsFile.SECTION_WIIMOTE + wiimoteNumber,
SettingsFile.SETTINGS_WIIMOTE, mContext.getResources().getStringArray(R.array.wiimoteExtensionsEntries)[which]);
StringSetting extension = new StringSetting(SettingsFile.KEY_WIIMOTE_EXTENSION, Settings.SECTION_WIIMOTE + wiimoteNumber, mContext.getResources().getStringArray(R.array.wiimoteExtensionsEntries)[which]);
mView.putSetting(extension);
}
}

View File

@ -13,13 +13,10 @@ import android.view.ViewGroup;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.Setting;
import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
import org.dolphinemu.dolphinemu.ui.DividerItemDecoration;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
import java.util.ArrayList;
import java.util.HashMap;
public final class SettingsFragment extends Fragment implements SettingsFragmentView
{
@ -105,13 +102,7 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), null));
SettingsActivityView activity = (SettingsActivityView) getActivity();
ArrayList<HashMap<String, SettingSection>> settings = new ArrayList<>();
settings.add(SettingsFile.SETTINGS_DOLPHIN, activity.getSettings(SettingsFile.SETTINGS_DOLPHIN));
settings.add(SettingsFile.SETTINGS_GFX, activity.getSettings(SettingsFile.SETTINGS_GFX));
settings.add(SettingsFile.SETTINGS_WIIMOTE, activity.getSettings(SettingsFile.SETTINGS_WIIMOTE));
mPresenter.onViewCreated(settings);
mPresenter.onViewCreated(activity.getSettings());
}
@Override
@ -127,13 +118,13 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
}
@Override
public void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings)
public void onSettingsFileLoaded(org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
{
mPresenter.setSettings(settings);
}
@Override
public void passSettingsToActivity(ArrayList<HashMap<String, SettingSection>> settings)
public void passSettingsToActivity(org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
{
if (mActivity != null)
{

View File

@ -3,11 +3,10 @@ package org.dolphinemu.dolphinemu.features.settings.ui;
import android.support.v4.app.FragmentActivity;
import org.dolphinemu.dolphinemu.features.settings.model.Setting;
import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Abstraction for a screen showing a list of settings. Instances of
@ -21,7 +20,7 @@ public interface SettingsFragmentView
*
* @param settings The (possibly null) result of the ini load operation.
*/
void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings);
void onSettingsFileLoaded(Settings settings);
/**
* Pass a settings HashMap to the containing activity, so that it can
@ -30,7 +29,7 @@ public interface SettingsFragmentView
*
* @param settings An ArrayList containing all the settings HashMaps.
*/
void passSettingsToActivity(ArrayList<HashMap<String, SettingSection>> settings);
void passSettingsToActivity(Settings settings);
/**
* Pass an ArrayList to the View so that it can be displayed on screen.

View File

@ -1,4 +1,4 @@
package org.dolphinemu.dolphinemu.utils;
package org.dolphinemu.dolphinemu.features.settings.utils;
import android.support.annotation.NonNull;
@ -7,9 +7,11 @@ import org.dolphinemu.dolphinemu.features.settings.model.FloatSetting;
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
import org.dolphinemu.dolphinemu.features.settings.model.Setting;
import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView;
import org.dolphinemu.dolphinemu.utils.Log;
import java.io.BufferedReader;
import java.io.File;
@ -20,63 +22,19 @@ import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* A HashMap<String, SettingSection> that constructs a new SettingSection instead of returning null
* when getting a key not already in the map
*/
final class SettingsSectionMap extends HashMap<String, SettingSection>
{
@Override
public SettingSection get(Object key)
{
if (!(key instanceof String))
{
return null;
}
String stringKey = (String)key;
if (!super.containsKey(stringKey))
{
SettingSection section = new SettingSection(stringKey);
super.put(stringKey, section);
return section;
}
return super.get(key);
}
}
/**
* Contains static methods for interacting with .ini files in which settings are stored.
*/
public final class SettingsFile
{
public static final int SETTINGS_DOLPHIN = 0;
public static final int SETTINGS_GFX = 1;
public static final int SETTINGS_WIIMOTE = 2;
public static final String FILE_NAME_DOLPHIN = "Dolphin";
public static final String FILE_NAME_GFX = "GFX";
public static final String FILE_NAME_GCPAD = "GCPadNew";
public static final String FILE_NAME_WIIMOTE = "WiimoteNew";
public static final String SECTION_INI_CORE = "Core";
public static final String SECTION_INI_INTERFACE = "Interface";
public static final String SECTION_CONFIG_GENERAL = "General";
public static final String SECTION_CONFIG_INTERFACE = "Interface";
public static final String SECTION_GFX_SETTINGS = "Settings";
public static final String SECTION_GFX_ENHANCEMENTS = "Enhancements";
public static final String SECTION_GFX_HACKS = "Hacks";
public static final String SECTION_STEREOSCOPY = "Stereoscopy";
public static final String SECTION_WIIMOTE = "Wiimote";
public static final String SECTION_BINDINGS = "Android";
public static final String KEY_CPU_CORE = "CPUCore";
public static final String KEY_DUAL_CORE = "CPUThread";
@ -286,7 +244,7 @@ public final class SettingsFile
}
/**
* Reads a given .ini file from disk and returns it as a HashMap of SettingSections, themselves
* Reads a given .ini file from disk and returns it as a HashMap of Settings, themselves
* effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
* failed.
*
@ -296,7 +254,7 @@ public final class SettingsFile
*/
public static HashMap<String, SettingSection> readFile(final String fileName, SettingsActivityView view)
{
HashMap<String, SettingSection> sections = new SettingsSectionMap();
HashMap<String, SettingSection> sections = new Settings.SettingsSectionMap();
File ini = getSettingsFile(fileName);
@ -316,7 +274,7 @@ public final class SettingsFile
}
else if ((current != null))
{
Setting setting = settingFromLine(current, line, fileName);
Setting setting = settingFromLine(current, line);
if (setting != null)
{
current.putSetting(setting);
@ -366,7 +324,7 @@ public final class SettingsFile
* @param view The current view.
* @return An Observable representing the operation.
*/
public static void saveFile(final String fileName, final HashMap<String, SettingSection> sections, SettingsActivityView view)
public static void saveFile(final String fileName, TreeMap<String, SettingSection> sections, SettingsActivityView view)
{
File ini = getSettingsFile(fileName);
@ -417,19 +375,19 @@ public final class SettingsFile
private static void addGcPadSettingsIfTheyDontExist(HashMap<String, SettingSection> sections)
{
SettingSection coreSection = sections.get(SettingsFile.SECTION_INI_CORE);
SettingSection coreSection = sections.get(Settings.SECTION_INI_CORE);
for (int i = 0; i < 4; i++)
{
String key = SettingsFile.KEY_GCPAD_TYPE + i;
if (coreSection.getSetting(key) == null)
{
Setting gcPadSetting = new IntSetting(key, SettingsFile.SECTION_INI_CORE, SettingsFile.SETTINGS_DOLPHIN, 0);
Setting gcPadSetting = new IntSetting(key, Settings.SECTION_INI_CORE,0);
coreSection.putSetting(gcPadSetting);
}
}
sections.put(SettingsFile.SECTION_INI_CORE, coreSection);
sections.put(Settings.SECTION_INI_CORE, coreSection);
}
/**
@ -438,10 +396,9 @@ public final class SettingsFile
*
* @param current The section currently being parsed by the consuming method.
* @param line The line of text being parsed.
* @param fileName The name of the ini file the setting is in.
* @return A typed Setting containing the key/value contained in the line.
*/
private static Setting settingFromLine(SettingSection current, String line, String fileName)
private static Setting settingFromLine(SettingSection current, String line)
{
String[] splitLine = line.split("=");
@ -454,25 +411,11 @@ public final class SettingsFile
String key = splitLine[0].trim();
String value = splitLine[1].trim();
int file;
switch (fileName)
{
case FILE_NAME_GFX:
file = SETTINGS_GFX;
break;
case FILE_NAME_WIIMOTE:
file = SETTINGS_WIIMOTE;
break;
default:
file = SETTINGS_DOLPHIN;
break;
}
try
{
int valueAsInt = Integer.valueOf(value);
return new IntSetting(key, current.getName(), file, valueAsInt);
return new IntSetting(key, current.getName(), valueAsInt);
}
catch (NumberFormatException ex)
{
@ -482,7 +425,7 @@ public final class SettingsFile
{
float valueAsFloat = Float.valueOf(value);
return new FloatSetting(key, current.getName(), file, valueAsFloat);
return new FloatSetting(key, current.getName(), valueAsFloat);
}
catch (NumberFormatException ex)
{
@ -491,11 +434,11 @@ public final class SettingsFile
switch (value)
{
case "True":
return new BooleanSetting(key, current.getName(), file, true);
return new BooleanSetting(key, current.getName(), true);
case "False":
return new BooleanSetting(key, current.getName(), file, false);
return new BooleanSetting(key, current.getName(), false);
default:
return new StringSetting(key, current.getName(), file, value);
return new StringSetting(key, current.getName(), value);
}
}