IController - Remove the indexer property and refactor code accordingly, also simplify and cleanup many of the IController implementations

This commit is contained in:
adelikat 2016-12-14 14:12:16 -06:00
parent e94de78ebd
commit 2d9213c379
16 changed files with 214 additions and 287 deletions

View File

@ -341,7 +341,7 @@ namespace BizHawk.Client.ApiHawk
AutoFireStickyXorAdapter joypadAdaptor = Global.AutofireStickyXORAdapter;
IEnumerable<string> pressedButtons = from button in joypadAdaptor.Definition.BoolButtons
where joypadAdaptor[button]
where joypadAdaptor.IsPressed(button)
select button;
foreach (Joypad j in allJoypads)

View File

@ -9,14 +9,6 @@ namespace BizHawk.Client.Common
{
public class Controller : IController
{
private readonly WorkingDictionary<string, List<string>> _bindings = new WorkingDictionary<string, List<string>>();
private readonly WorkingDictionary<string, bool> _buttons = new WorkingDictionary<string, bool>();
private readonly WorkingDictionary<string, float> _floatButtons = new WorkingDictionary<string, float>();
private readonly Dictionary<string, ControllerDefinition.FloatRange> _floatRanges = new WorkingDictionary<string, ControllerDefinition.FloatRange>();
private readonly Dictionary<string, Config.AnalogBind> _floatBinds = new Dictionary<string, Config.AnalogBind>();
private ControllerDefinition _type;
public Controller(ControllerDefinition definition)
{
_type = definition;
@ -27,16 +19,37 @@ namespace BizHawk.Client.Common
}
}
public ControllerDefinition Definition { get { return _type; } }
public ControllerDefinition Definition
{
get { return _type; }
}
/// <summary>don't do this</summary>
public void ForceType(ControllerDefinition newtype) { _type = newtype; }
public bool this[string button] { get { return IsPressed(button); } }
public bool IsPressed(string button)
{
return _buttons[button];
}
public float GetFloat(string name)
{
return _floatButtons[name];
}
private readonly WorkingDictionary<string, List<string>> _bindings = new WorkingDictionary<string, List<string>>();
private readonly WorkingDictionary<string, bool> _buttons = new WorkingDictionary<string, bool>();
private readonly WorkingDictionary<string, float> _floatButtons = new WorkingDictionary<string, float>();
private readonly Dictionary<string, ControllerDefinition.FloatRange> _floatRanges = new WorkingDictionary<string, ControllerDefinition.FloatRange>();
private readonly Dictionary<string, Config.AnalogBind> _floatBinds = new Dictionary<string, Config.AnalogBind>();
private ControllerDefinition _type;
/// <summary>don't do this</summary>
public void ForceType(ControllerDefinition newtype) { _type = newtype; }
public bool this[string button]
{
get { return IsPressed(button); }
}
public bool AnyPressed
{
get
@ -50,8 +63,6 @@ namespace BizHawk.Client.Common
}
}
public float GetFloat(string name) { return _floatButtons[name]; }
// Looks for bindings which are activated by the supplied physical button.
public List<string> SearchBindings(string button)
{
@ -132,7 +143,7 @@ namespace BizHawk.Client.Common
_buttons[kvp.Key] = false;
foreach (var bound_button in kvp.Value)
{
if (controller[bound_button])
if (controller.IsPressed(bound_button))
{
_buttons[kvp.Key] = true;
}
@ -181,7 +192,7 @@ namespace BizHawk.Client.Common
{
foreach (var button in controller.Overrides)
{
_buttons[button] = controller[button];
_buttons[button] = controller.IsPressed(button);
}
foreach (var button in controller.FloatOverrides)
@ -260,7 +271,7 @@ namespace BizHawk.Client.Common
public int Off { get; set; }
public ControllerDefinition Definition { get { return _type; } }
public bool this[string button] { get { return IsPressed(button); } }
public bool IsPressed(string button)
{
if (_autofire)
@ -295,7 +306,7 @@ namespace BizHawk.Client.Common
{
foreach (var bound_button in kvp.Value)
{
if (_buttons[kvp.Key] == false && controller[bound_button])
if (_buttons[kvp.Key] == false && controller.IsPressed(bound_button))
{
_buttonStarts[kvp.Key] = _emulator.Frame;
}
@ -308,7 +319,7 @@ namespace BizHawk.Client.Common
_buttons[kvp.Key] = false;
foreach (var bound_button in kvp.Value)
{
if (controller[bound_button])
if (controller.IsPressed(bound_button))
{
_buttons[kvp.Key] = true;
}

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Client.Common
namespace BizHawk.Client.Common
{
public class AutoPatternBool
{

View File

@ -1,74 +1,56 @@
using System;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
{
public class AndAdapter : IController
{
public ControllerDefinition Definition
{
get { return Source.Definition; }
}
public bool IsPressed(string button)
{
return this[button];
if (Source != null && SourceAnd != null)
{
return Source.IsPressed(button) & SourceAnd.IsPressed(button);
}
return false;
}
// pass floats solely from the original source
// this works in the code because SourceOr is the autofire controller
public float GetFloat(string name) { return Source.GetFloat(name); }
public IController Source { get; set; }
public IController SourceAnd { get; set; }
public ControllerDefinition Definition { get { return Source.Definition; } set { throw new InvalidOperationException(); } }
public bool this[string button]
public float GetFloat(string name)
{
get
{
if (Source != null && SourceAnd != null)
{
return Source[button] & SourceAnd[button];
}
return false;
}
set
{
throw new InvalidOperationException();
}
return Source.GetFloat(name);
}
internal IController Source { get; set; }
internal IController SourceAnd { get; set; }
}
public class ORAdapter : IController
{
public ControllerDefinition Definition
{
get { return Source.Definition; }
}
public bool IsPressed(string button)
{
return this[button];
return (Source != null ? Source.IsPressed(button) : false)
| (SourceOr != null ? SourceOr.IsPressed(button) : false);
}
// pass floats solely from the original source
// this works in the code because SourceOr is the autofire controller
public float GetFloat(string name) { return Source.GetFloat(name); }
public IController Source { get; set; }
public IController SourceOr { get; set; }
public ControllerDefinition Definition
public float GetFloat(string name)
{
get { return Source.Definition; }
set { throw new InvalidOperationException(); }
return Source.GetFloat(name);
}
public bool this[string button]
{
get
{
return (Source != null ? Source[button] : false)
| (SourceOr != null ? SourceOr[button] : false);
}
set
{
throw new InvalidOperationException();
}
}
internal IController Source { get; set; }
internal IController SourceOr { get; set; }
}
}

View File

@ -12,11 +12,6 @@ namespace BizHawk.Client.Common
{
public ControllerDefinition Definition { get; set; }
public bool this[string button]
{
get { return IsPressed(button); }
}
public bool IsPressed(string button)
{
return _pressed.Contains(button);

View File

@ -7,28 +7,11 @@ namespace BizHawk.Client.Common
/// </summary>
public class CopyControllerAdapter : IController
{
public IController Source { get; set; }
private IController Curr
{
get
{
return Source == null
? NullController.Instance
: Source;
}
}
public ControllerDefinition Definition
{
get { return Curr.Definition; }
}
public bool this[string button]
{
get { return Curr[button]; }
}
public bool IsPressed(string button)
{
return Curr.IsPressed(button);
@ -38,5 +21,17 @@ namespace BizHawk.Client.Common
{
return Curr.GetFloat(name);
}
public IController Source { get; set; }
private IController Curr
{
get
{
return Source == null
? NullController.Instance
: Source;
}
}
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common.InputAdapterExtensions
{

View File

@ -11,40 +11,20 @@ namespace BizHawk.Client.Common
/// </summary>
public class OverrideAdaptor : IController
{
public ControllerDefinition Definition { get; private set; }
private readonly Dictionary<string, bool> _overrides = new Dictionary<string, bool>();
private readonly Dictionary<string, float> _floatOverrides = new Dictionary<string, float>();
private readonly List<string> _inverses = new List<string>();
public ControllerDefinition Definition { get; set; }
public bool this[string button]
{
get
{
if (_overrides.ContainsKey(button))
{
return _overrides[button];
}
throw new InvalidOperationException();
}
set
{
if (_overrides.ContainsKey(button))
{
_overrides[button] = value;
}
else
{
_overrides.Add(button, value);
}
}
}
public bool IsPressed(string button)
{
return this[button];
if (_overrides.ContainsKey(button))
{
return _overrides[button];
}
throw new InvalidOperationException();
}
public float GetFloat(string name)
@ -104,7 +84,15 @@ namespace BizHawk.Client.Common
public void SetButton(string button, bool value)
{
this[button] = value;
if (_overrides.ContainsKey(button))
{
_overrides[button] = value;
}
else
{
_overrides.Add(button, value);
}
_inverses.Remove(button);
}

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Common;
@ -18,9 +17,15 @@ namespace BizHawk.Client.Common
/// </summary>
public class StickyOrAdapter : IController
{
public ControllerDefinition Definition
{
get { return Source.Definition; }
}
public bool IsPressed(string button)
{
return this[button];
return Source.StickyIsInEffect(button)
|| SourceStickyOr.StickyIsInEffect(button);
}
// pass floats solely from the original source
@ -33,56 +38,34 @@ namespace BizHawk.Client.Common
public ISticky Source { get; set; }
public ISticky SourceStickyOr { get; set; }
public ControllerDefinition Definition { get { return Source.Definition; } set { throw new InvalidOperationException(); } }
public bool this[string button]
{
get
{
return Source.StickyIsInEffect(button) ||
SourceStickyOr.StickyIsInEffect(button);
}
set
{
throw new InvalidOperationException();
}
}
}
public class StickyXorAdapter : ISticky, IController
{
protected HashSet<string> stickySet = new HashSet<string>();
/// <summary>
/// Determines if a sticky is current mashing the button itself,
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
/// </summary>
public bool StickyIsInEffect(string button)
{
if (IsSticky(button))
{
return !Source.IsPressed(button);
}
public IController Source { get; set; }
return false;
}
public ControllerDefinition Definition
{
get { return Source.Definition; }
set { throw new InvalidOperationException(); }
}
public bool Locked { get; set; } // Pretty much a hack,
public bool IsPressed(string button)
{
return this[button];
}
// if SetFloat() is called (typically virtual pads), then that float will entirely override the Source input
// otherwise, the source is passed thru.
protected readonly WorkingDictionary<string, float?> _floatSet = new WorkingDictionary<string, float?>();
public void SetFloat(string name, float? value)
{
if (value.HasValue)
{
_floatSet[name] = value;
}
else
{
_floatSet.Remove(name);
}
var source = Source.IsPressed(button);
source ^= stickySet.Contains(button);
return source;
}
public float GetFloat(string name)
@ -102,40 +85,35 @@ namespace BizHawk.Client.Common
return Source.GetFloat(name);
}
public IController Source { get; set; }
public bool Locked { get; set; } // Pretty much a hack,
private List<string> _justPressed = new List<string>();
protected readonly HashSet<string> stickySet = new HashSet<string>();
// if SetFloat() is called (typically virtual pads), then that float will entirely override the Source input
// otherwise, the source is passed thru.
protected readonly WorkingDictionary<string, float?> _floatSet = new WorkingDictionary<string, float?>();
public void SetFloat(string name, float? value)
{
if (value.HasValue)
{
_floatSet[name] = value;
}
else
{
_floatSet.Remove(name);
}
}
public void ClearStickyFloats()
{
_floatSet.Clear();
}
public bool this[string button]
{
get
{
var source = Source[button];
source ^= stickySet.Contains(button);
return source;
}
set
{
throw new InvalidOperationException();
}
}
/// <summary>
/// Determines if a sticky is current mashing the button itself,
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
/// </summary>
public bool StickyIsInEffect(string button)
{
if (IsSticky(button))
{
return !Source.IsPressed(button);
}
return false;
}
public void SetSticky(string button, bool isSticky)
{
if (isSticky)
@ -189,16 +167,62 @@ namespace BizHawk.Client.Common
_justPressed = buttons;
}
private List<string> _justPressed = new List<string>();
}
public class AutoFireStickyXorAdapter : ISticky, IController
{
/// <summary>
/// Determines if a sticky is current mashing the button itself,
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
/// </summary>
public bool StickyIsInEffect(string button)
{
if (IsSticky(button))
{
return !Source.IsPressed(button);
}
return false;
}
public ControllerDefinition Definition
{
get { return Source.Definition; }
}
public bool IsPressed(string button)
{
var source = Source.IsPressed(button);
bool patternValue = false;
if (_boolPatterns.ContainsKey(button))
{ // I can't figure a way to determine right here if it should Peek or Get.
patternValue = _boolPatterns[button].PeekNextValue();
}
source ^= patternValue;
return source;
}
public float GetFloat(string name)
{
if (_floatPatterns.ContainsKey(name))
{
return _floatPatterns[name].PeekNextValue();
}
if (Source == null)
{
return 0;
}
return Source.GetFloat(name);
}
// TODO: Change the AutoHold adapter to be one of these, with an 'Off' value of 0?
// Probably would have slightly lower performance, but it seems weird to have such a similar class that is only used once.
private int On;
private int Off;
public void SetOnOffPatternFromConfig()
{
On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn;
@ -215,18 +239,8 @@ namespace BizHawk.Client.Common
public IController Source { get; set; }
public ControllerDefinition Definition
{
get { return Source.Definition; }
}
public bool Locked { get; set; } // Pretty much a hack,
public bool IsPressed(string button)
{
return this[button];
}
public void SetFloat(string name, float? value, AutoPatternFloat pattern = null)
{
if (value.HasValue)
@ -241,52 +255,11 @@ namespace BizHawk.Client.Common
}
}
public float GetFloat(string name)
{
if (_floatPatterns.ContainsKey(name))
return _floatPatterns[name].PeekNextValue();
if (Source == null)
return 0;
return Source.GetFloat(name);
}
public void ClearStickyFloats()
{
_floatPatterns.Clear();
}
public bool this[string button]
{
get
{
var source = Source[button];
bool patternValue = false;
if (_boolPatterns.ContainsKey(button))
{ // I can't figure a way to determine right here if it should Peek or Get.
patternValue = _boolPatterns[button].PeekNextValue();
}
source ^= patternValue;
return source;
}
}
/// <summary>
/// Determines if a sticky is current mashing the button itself,
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
/// </summary>
public bool StickyIsInEffect(string button)
{
if (IsSticky(button))
{
return !Source.IsPressed(button);
}
return false;
}
public void SetSticky(string button, bool isSticky, AutoPatternBool pattern = null)
{
if (isSticky)
@ -335,6 +308,7 @@ namespace BizHawk.Client.Common
}
private List<string> _justPressed = new List<string>();
public void MassToggleStickyState(List<string> buttons)
{
foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))

View File

@ -11,31 +11,15 @@ namespace BizHawk.Client.Common
/// </summary>
public class UD_LR_ControllerAdapter : IController
{
private HashSet<string> Unpresses = new HashSet<string>();
public ControllerDefinition Definition
{
get { return Source.Definition; }
}
public bool this[string button]
{
get { return IsPressed(button); }
}
public IController Source { get; set; }
// The float format implies no U+D and no L+R no matter what, so just passthru
public float GetFloat(string name)
{
return Source.GetFloat(name);
}
public bool IsPressed(string button)
{
bool PriorityUD_LR = !Global.Config.AllowUD_LR && !Global.Config.ForbidUD_LR; // implied by neither of the others being set (left as non-enum for back-compatibility)
if (Global.Config.AllowUD_LR)
{
return Source.IsPressed(button);
@ -165,5 +149,15 @@ namespace BizHawk.Client.Common
return Source.IsPressed(button);
}
// The float format implies no U+D and no L+R no matter what, so just passthru
public float GetFloat(string name)
{
return Source.GetFloat(name);
}
private readonly HashSet<string> Unpresses = new HashSet<string>();
public IController Source { get; set; }
}
}

View File

@ -25,11 +25,11 @@ namespace BizHawk.Client.Common
{
if (!controller.HasValue)
{
buttons[button] = adaptor[button];
buttons[button] = adaptor.IsPressed(button);
}
else if (button.Length >= 3 && button.Substring(0, 2) == "P" + controller)
{
buttons[button.Substring(3)] = adaptor["P" + controller + " " + button.Substring(3)];
buttons[button.Substring(3)] = adaptor.IsPressed("P" + controller + " " + button.Substring(3));
}
}
@ -52,6 +52,7 @@ namespace BizHawk.Client.Common
return buttons;
}
// TODO: what about float controls?
[LuaMethodAttributes(
"getimmediate",
"returns a lua table of any controller buttons currently pressed by the user"
@ -61,7 +62,7 @@ namespace BizHawk.Client.Common
var buttons = Lua.NewTable();
foreach (var button in Global.ActiveController.Definition.BoolButtons)
{
buttons[button] = Global.ActiveController[button];
buttons[button] = Global.ActiveController.IsPressed(button);
}
return buttons;

View File

@ -263,7 +263,7 @@ namespace BizHawk.Client.Common
// Movie may go into finished mode as a result from latching
if (!Movie.IsFinished)
{
if (Global.ClientControls["Scrub Input"])
if (Global.ClientControls.IsPressed("Scrub Input"))
{
LatchInputFromPlayer(Global.MovieInputSourceAdapter);
ClearFrame();

View File

@ -37,8 +37,7 @@ namespace BizHawk.Client.Common
}
}
#region IController Implementation
// TODO: get rid of this, add a SetBool() method or something for the set access, replace get wtih IsPressed
public bool this[string button]
{
get
@ -55,6 +54,8 @@ namespace BizHawk.Client.Common
}
}
#region IController Implementation
public bool IsPressed(string button)
{
return MyBoolButtons[button];

View File

@ -9,10 +9,7 @@ namespace BizHawk.Client.Common
{
#region IController Implementation
public bool this[string button]
{
get { return MyBoolButtons[button]; }
}
public ControllerDefinition Definition { get; set; }
public bool IsPressed(string button)
{
@ -28,8 +25,6 @@ namespace BizHawk.Client.Common
#region IMovieController Implementation
public ControllerDefinition Definition { get; set; }
/// <summary>
/// latches one player from the source
/// </summary>

View File

@ -371,7 +371,7 @@ namespace BizHawk.Client.Common
Changes = true;
InvalidateAfter(frame);
ChangeLog.AddBoolToggle(frame, buttonName, !adapter[buttonName], "Toggle " + buttonName + ": " + frame);
ChangeLog.AddBoolToggle(frame, buttonName, !adapter.IsPressed(buttonName), "Toggle " + buttonName + ": " + frame);
}
public void SetBoolState(int frame, string buttonName, bool val)
@ -380,7 +380,7 @@ namespace BizHawk.Client.Common
ExtendMovieForEdit(frame - _log.Count + 1);
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
var old = adapter[buttonName];
var old = adapter.IsPressed(buttonName);
adapter[buttonName] = val;
var lg = LogGeneratorInstance();
@ -406,7 +406,7 @@ namespace BizHawk.Client.Common
for (int i = 0; i < count; i++)
{
var adapter = GetInputState(frame + i) as Bk2ControllerAdapter;
bool old = adapter[buttonName];
bool old = adapter.IsPressed(buttonName);
adapter[buttonName] = val;
var lg = LogGeneratorInstance();

View File

@ -7,12 +7,14 @@
/// </summary>
ControllerDefinition Definition { get; }
// TODO - it is obnoxious for this to be here. must be removed.
bool this[string button] { get; }
// TODO - this can stay but it needs to be changed to go through the float
/// <summary>
/// Returns the current state of a boolean control
/// </summary>
bool IsPressed(string button);
/// <summary>
/// Returns the state of a float control
/// </summary>
float GetFloat(string name);
}
}