Cleanup and documentation

This commit is contained in:
sigmabeta 2016-01-21 22:39:36 -05:00
parent d90dce6d12
commit cee84d8e90
21 changed files with 234 additions and 19 deletions

View File

@ -1,25 +1,48 @@
package org.dolphinemu.dolphinemu.model.settings;
/**
* Abstraction for a setting item as read from / written to Dolphin's configuration ini files.
* These files generally consist of a key/value pair, though the type of value is ambiguous and
* must be inferred at read-time. The type of value determines which child of this class is used
* to represent the Setting.
*/
public abstract class Setting
{
private String mKey;
private String mSection;
/**
* 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.
*/
public Setting(String key, String section)
{
mKey = key;
mSection = section;
}
/**
*
* @return The identifier used to write this setting to the ini file.
*/
public String getKey()
{
return mKey;
}
/**
*
* @return The name of the header under which this Setting should be written in the ini file.
*/
public String getSection()
{
return mSection;
}
/**
* @return A representation of this Setting's backing value converted to a String (e.g. for serialization).
*/
public abstract String getValueAsString();
}

View File

@ -2,12 +2,21 @@ package org.dolphinemu.dolphinemu.model.settings;
import java.util.HashMap;
public class SettingSection
/**
* A semantically-related group of Settings objects. These Settings are
* internally stored as a Hashmap.
*/
public final class SettingSection
{
private String mName;
private HashMap<String, Setting> mSettings = new HashMap<>();
/**
* Create a new SettingSection with no Settings in it.
*
* @param name The header of this section; e.g. [Core] or [Enhancements] without the brackets.
*/
public SettingSection(String name)
{
mName = name;
@ -18,11 +27,23 @@ public class SettingSection
return mName;
}
/**
* Convenience method; inserts a value directly into the backing Hashmap.
*
* @param key The key where the Setting will be inserted.
* @param setting The Setting to be inserted.
*/
public void putSetting(String key, Setting setting)
{
mSettings.put(key, setting);
}
/**
* Convenience method; gets a value directly from the backing Hashmap.
*
* @param key Used to retrieve the Setting.
* @return A Setting object (you should probably cast this before using)
*/
public Setting getSetting(String key)
{
return mSettings.get(key);

View File

@ -4,7 +4,7 @@ package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.BooleanSetting;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public class CheckBoxSetting extends SettingsItem
public final class CheckBoxSetting extends SettingsItem
{
private boolean mDefaultValue;

View File

@ -3,7 +3,7 @@ package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public class HeaderSetting extends SettingsItem
public final class HeaderSetting extends SettingsItem
{
public HeaderSetting(String key, Setting setting, int titleId, int descriptionId)
{

View File

@ -2,6 +2,13 @@ package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.Setting;
/**
* ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
* Each one corresponds to a {@link Setting} object, so this class's subclasses
* should vaguely correspond to those subclasses. There are a few with multiple analogues
* and a few with none (Headers, for example, do not correspond to anything in the ini
* file.)
*/
public abstract class SettingsItem
{
public static final int TYPE_HEADER = 0;
@ -15,41 +22,73 @@ public abstract class SettingsItem
private Setting mSetting;
private int mTitleId;
private int mNameId;
private int mDescriptionId;
public SettingsItem(String key, String section, Setting setting, int titleId, int descriptionId)
/**
* Base constructor. Takes a key / section name in case the third parameter, the Setting,
* is null; in which case, one can be constructed and saved using the key / section.
*
* @param key Identifier for the Setting represented by this Item.
* @param section Section to which the Setting belongs.
* @param setting A possibly-null backing Setting, to be modified on UI events.
* @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, Setting setting, int nameId, int descriptionId)
{
mKey = key;
mSection = section;
mSetting = setting;
mTitleId = titleId;
mNameId = nameId;
mDescriptionId = descriptionId;
}
/**
*
* @return The identifier for the backing Setting.
*/
public String getKey()
{
return mKey;
}
/**
*
* @return The header under which the backing Setting belongs.
*/
public String getSection()
{
return mSection;
}
/**
*
* @return The backing Setting, possibly null.
*/
public Setting getSetting()
{
return mSetting;
}
/**
* Replace the backing setting with a new one. Generally used in cases where
* the backing setting is null.
*
* @param setting A non-null Setting.
*/
public void setSetting(Setting setting)
{
mSetting = setting;
}
/**
*
* @return A resource ID for a text string representing this Setting's name.
*/
public int getNameId()
{
return mTitleId;
return mNameId;
}
public int getDescriptionId()
@ -57,5 +96,11 @@ public abstract class SettingsItem
return mDescriptionId;
}
/**
* Used by {@link org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter}'s onCreateViewHolder()
* method to determine which type of ViewHolder should be created.
*
* @return An integer (ideally, one of the constants defined in this file)
*/
public abstract int getType();
}

View File

@ -4,7 +4,7 @@ package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.IntSetting;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public class SingleChoiceSetting extends SettingsItem
public final class SingleChoiceSetting extends SettingsItem
{
private int mDefaultValue;

View File

@ -6,7 +6,7 @@ import org.dolphinemu.dolphinemu.model.settings.Setting;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
public class SliderSetting extends SettingsItem
public final class SliderSetting extends SettingsItem
{
private int mMax;
private int mDefaultValue;

View File

@ -2,7 +2,7 @@ package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public class SubmenuSetting extends SettingsItem
public final class SubmenuSetting extends SettingsItem
{
private String mMenuKey;

View File

@ -14,7 +14,7 @@ import android.view.View;
* Implementation from:
* https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36
*/
public class DividerItemDecoration extends RecyclerView.ItemDecoration
public final class DividerItemDecoration extends RecyclerView.ItemDecoration
{
private Drawable mDivider;

View File

@ -13,7 +13,7 @@ import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
public class SettingsActivityPresenter
public final class SettingsActivityPresenter
{
private SettingsActivityView mView;

View File

@ -4,15 +4,48 @@ import org.dolphinemu.dolphinemu.model.settings.SettingSection;
import java.util.HashMap;
/**
* Abstraction for the Activity that manages SettingsFragments.
*/
public interface SettingsActivityView
{
/**
* Show a new SettingsFragment.
*
* @param menuTag Identifier for the settings group that should be displayed.
* @param addToStack Whether or not this fragment should replace a previous one.
*/
void showSettingsFragment(String menuTag, boolean addToStack);
/**
* Called by a contained Fragment to get access to the Setting Hashmap
* loaded from disk, so that each Fragment doesn't need to perform its own
* read operation.
*
* @return A possibly null Hashmap of Settings.
*/
HashMap<String, SettingSection> getSettings();
/**
* Used to provide the Activity with a Settings Hashmap if a Fragment already
* has one; for example, if a rotation occurs, the Fragment will not be killed,
* but the Activity will, so the Activity needs to have its Hashmap resupplied.
*
* @param settings The Fragment's Settings hashmap.
*/
void setSettings(HashMap<String, SettingSection> settings);
/**
* Called when an asynchronous load operation completes.
*
* @param settings The (possibly null) result of the load operation.
*/
void onSettingsFileLoaded(HashMap<String, SettingSection> settings);
/**
* Display a popup text message on screen.
*
* @param message The contents of the onscreen message.
*/
void showToastMessage(String message);
}

View File

@ -30,7 +30,7 @@ import org.dolphinemu.dolphinemu.utils.SettingsFile;
import java.util.ArrayList;
public class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolder>
public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolder>
implements DialogInterface.OnClickListener, SeekBar.OnSeekBarChangeListener
{
private SettingsFragmentView mView;

View File

@ -17,7 +17,7 @@ import org.dolphinemu.dolphinemu.utils.SettingsFile;
import java.util.ArrayList;
import java.util.HashMap;
public class SettingsFragmentPresenter
public final class SettingsFragmentPresenter
{
private SettingsFragmentView mView;

View File

@ -9,19 +9,61 @@ import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Abstraction for a screen showing a list of settings. Instances of
* this type of view will each display a layer of the setting hierarchy.
*/
public interface SettingsFragmentView
{
/**
* Called by the containing Activity to notify the Fragment that an
* asynchronous load operation completed.
*
* @param settings The potentially-null result of the load operation.
*/
void onSettingsFileLoaded(HashMap<String, SettingSection> settings);
/**
* Pass a settings Hashmap to the containing activity, so that it can
* share the Hashmap with other SettingsFragments; useful so that rotations
* do not require an additional load operation.
*
* @param settings A Hashmap containing all the settings
*/
void passSettingsToActivity(HashMap<String, SettingSection> settings);
/**
* Pass an ArrayList to the View so that it can be displayed on screen.
*
* @param settingsList The result of converting the Hashmap to an ArrayList
*/
void showSettingsList(ArrayList<SettingsItem> settingsList);
/**
* @return The Fragment's containing activity.
*/
Activity getActivity();
/**
* Tell the Fragment to tell the containing Activity to show a new
* Fragment containing a submenu of settings.
*
* @param menuKey Identifier for the settings group that should be shown.
*/
void loadSubMenu(String menuKey);
/**
* Tell the Fragment to tell the containing activity to display a toast message.
*
* @param message Text to be shown in the Toast
*/
void showToastMessage(String message);
/**
* Have the fragment add a setting to the Hashmap. Useful if the setting
* was missing from the .ini file, but included in the UI.
*
* @param setting The (possibly missing) new setting.
*/
void addSetting(Setting setting);
}

View File

@ -10,7 +10,7 @@ import org.dolphinemu.dolphinemu.model.settings.view.CheckBoxSetting;
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
public class CheckBoxSettingViewHolder extends SettingViewHolder
public final class CheckBoxSettingViewHolder extends SettingViewHolder
{
private CheckBoxSetting mItem;

View File

@ -7,7 +7,7 @@ import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
public class HeaderViewHolder extends SettingViewHolder
public final class HeaderViewHolder extends SettingViewHolder
{
private TextView mHeaderName;

View File

@ -26,9 +26,26 @@ public abstract class SettingViewHolder extends RecyclerView.ViewHolder implemen
return mAdapter;
}
/**
* Gets handles to all this ViewHolder's child views using their XML-defined identifiers.
*
* @param root The newly inflated top-level view.
*/
protected abstract void findViews(View root);
/**
* Called by the adapter to set this ViewHolder's child views to display the list item
* it must now represent.
*
* @param item The list item that should be represented by this ViewHolder.
*/
public abstract void bind(SettingsItem item);
/**
* Called when this ViewHolder's view is clicked on. Implementations should usually pass
* this event up to the adapter.
*
* @param clicked The view that was clicked on.
*/
public abstract void onClick(View clicked);
}

View File

@ -8,7 +8,7 @@ import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting;
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
public class SingleChoiceViewHolder extends SettingViewHolder
public final class SingleChoiceViewHolder extends SettingViewHolder
{
private SingleChoiceSetting mItem;

View File

@ -9,7 +9,7 @@ import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting;
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
public class SliderViewHolder extends SettingViewHolder
public final class SliderViewHolder extends SettingViewHolder
{
private SliderSetting mItem;

View File

@ -8,7 +8,7 @@ import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting;
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
public class SubmenuViewHolder extends SettingViewHolder
public final class SubmenuViewHolder extends SettingViewHolder
{
private SubmenuSetting mItem;

View File

@ -23,6 +23,9 @@ import java.util.Set;
import rx.Observable;
import rx.Subscriber;
/**
* Contains static methods for interacting with .ini files in which settings are stored.
*/
public final class SettingsFile
{
public static final String FILE_NAME_DOLPHIN = "Dolphin";
@ -77,6 +80,14 @@ public final class SettingsFile
{
}
/**
* Reads a given .ini file from disk and returns it as an Rx Observable. If successful,
* this Observable emits a Hashmap of SettingSections, themselves effectively a Hashmap of
* key/value settings. If unsuccessful, the observer notifies the subscriber of why it failed.
*
* @param fileName The name of the settings file without a path or extension.
* @return An Observable that emits a Hashmap of the file's contents, then completes.
*/
public static Observable<HashMap<String, SettingSection>> readFile(final String fileName)
{
return Observable.create(new Observable.OnSubscribe<HashMap<String, SettingSection>>()
@ -141,6 +152,15 @@ public final class SettingsFile
});
}
/**
* Saves a Settings Hashmap to a given .ini file on disk, returning the operation
* as an Rx Observable. If successful, this Observable emits an event to notify subscribers;
* if unsuccessful, the observer notifies the subscriber of why it failed.
*
* @param fileName The target filename without a path or extension.
* @param sections The hashmap containing the Settings we want to serialize.
* @return An Observable representing the operation.
*/
public static Observable<Boolean> saveFile(final String fileName, final HashMap<String, SettingSection> sections)
{
return Observable.create(new Observable.OnSubscribe<Boolean>()
@ -199,6 +219,14 @@ public final class SettingsFile
return new SettingSection(sectionName);
}
/**
* For a line of text, determines what type of data is being represented, and returns
* a Setting object containing this data.
*
* @param current The section currently being parsed by the consuming method.
* @param line The line of text being parsed.
* @return A typed Setting containing the key/value contained in the line.
*/
private static Setting settingFromLine(SettingSection current, String line)
{
String[] splitLine = line.split("=");
@ -237,6 +265,12 @@ public final class SettingsFile
}
}
/**
* Writes the contents of a Section hashmap to disk.
*
* @param writer A PrintWriter pointed at a file on disk.
* @param section A section containing settings to be written to the file.
*/
private static void writeSection(PrintWriter writer, SettingSection section)
{
// Write the section header.