Removes essentials-framework as a submodule and brings the files back into the main repo

This commit is contained in:
Neil Dorin
2019-07-09 17:21:53 -06:00
parent 2cd68d40dc
commit 48c6bb78bc
362 changed files with 54624 additions and 5 deletions

View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// A Feedback whose output is derived from the return value of a provided Func.
/// </summary>
public class BoolFeedback : Feedback
{
/// <summary>
/// Returns the current value of the feedback, derived from the ValueFunc. The ValueFunc is
/// evaluated whenever FireUpdate() is called
/// </summary>
public override bool BoolValue { get { return _BoolValue; } }
bool _BoolValue;
public override eCueType Type { get { return eCueType.Bool; } }
/// <summary>
/// Fake value to be used in test mode
/// </summary>
public bool TestValue { get; private set; }
/// <summary>
/// Func that evaluates on FireUpdate
/// </summary>
public Func<bool> ValueFunc { get; private set; }
List<BoolInputSig> LinkedInputSigs = new List<BoolInputSig>();
List<BoolInputSig> LinkedComplementInputSigs = new List<BoolInputSig>();
public BoolFeedback(Func<bool> valueFunc)
: this(null, valueFunc)
{
}
public BoolFeedback(string key, Func<bool> valueFunc)
: base(key)
{
ValueFunc = valueFunc;
}
//public BoolFeedback(Cue cue, Func<bool> valueFunc)
// : base(cue)
//{
// if (cue == null) throw new ArgumentNullException("cue");
// ValueFunc = valueFunc;
//}
public override void FireUpdate()
{
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
if (newValue != _BoolValue)
{
_BoolValue = newValue;
LinkedInputSigs.ForEach(s => UpdateSig(s));
LinkedComplementInputSigs.ForEach(s => UpdateComplementSig(s));
OnOutputChange(newValue);
}
}
public void LinkInputSig(BoolInputSig sig)
{
LinkedInputSigs.Add(sig);
UpdateSig(sig);
}
public void UnlinkInputSig(BoolInputSig sig)
{
LinkedInputSigs.Remove(sig);
}
public void LinkComplementInputSig(BoolInputSig sig)
{
LinkedComplementInputSigs.Add(sig);
UpdateComplementSig(sig);
}
public void UnlinkComplementInputSig(BoolInputSig sig)
{
LinkedComplementInputSigs.Remove(sig);
}
public override string ToString()
{
return (InTestMode ? "TEST -- " : "") + BoolValue.ToString();
}
/// <summary>
/// Puts this in test mode, sets the test value and fires an update.
/// </summary>
/// <param name="value"></param>
public void SetTestValue(bool value)
{
TestValue = value;
InTestMode = true;
FireUpdate();
}
void UpdateSig(BoolInputSig sig)
{
sig.BoolValue = _BoolValue;
}
void UpdateComplementSig(BoolInputSig sig)
{
sig.BoolValue = !_BoolValue;
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
public class BoolFeedbackPulse
{
public uint TimeoutMs { get; set; }
/// <summary>
/// Defaults to false
/// </summary>
public bool CanRetrigger { get; set; }
public BoolFeedback Feedback { get; private set; }
CTimer Timer;
bool _BoolValue;
/// <summary>
/// Creates a non-retriggering one shot
/// </summary>
public BoolFeedbackPulse(uint timeoutMs)
: this(timeoutMs, false)
{
}
/// <summary>
/// Create a retriggerable one shot by setting canRetrigger true
/// </summary>
public BoolFeedbackPulse(uint timeoutMs, bool canRetrigger)
{
TimeoutMs = timeoutMs;
CanRetrigger = canRetrigger;
Feedback = new BoolFeedback(() => _BoolValue);
}
/// <summary>
/// Starts the
/// </summary>
/// <param name="timeout"></param>
public void Start()
{
if (Timer == null)
{
_BoolValue = true;
Feedback.FireUpdate();
Timer = new CTimer(o =>
{
_BoolValue = false;
Feedback.FireUpdate();
Timer = null;
}, TimeoutMs);
}
// Timer is running, if retrigger is set, reset it.
else if (CanRetrigger)
Timer.Reset(TimeoutMs);
}
public void Cancel()
{
if(Timer != null)
Timer.Reset(0);
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// A class that wraps a BoolFeedback with logic that extends it's true state for
/// a time period after the value goes false.
/// </summary>
public class BoolFeedbackPulseExtender
{
public uint TimeoutMs { get; set; }
public BoolFeedback Feedback { get; private set; }
CTimer Timer;
/// <summary>
/// When set to true, will cause Feedback to go high, and cancel the timer.
/// When false, will start the timer, and after timeout, will go low and
/// feedback will go low.
/// </summary>
public bool BoolValue
{
get { return _BoolValue; }
set
{
if (value)
{ // if Timer is running and the value goes high, cancel it.
if (Timer != null)
{
Timer.Stop();
Timer = null;
}
// if it's already true, don't fire again
if (_BoolValue == true)
return;
_BoolValue = true;
Feedback.FireUpdate();
}
else
{
if (Timer == null)
Timer = new CTimer(o => ClearFeedback(), TimeoutMs);
}
}
}
bool _BoolValue;
/// <summary>
/// Constructor
/// </summary>
/// <param name="timeoutMs">The time which the true state will be extended after set to false</param>
public BoolFeedbackPulseExtender(uint timeoutMs)
{
TimeoutMs = timeoutMs;
Feedback = new BoolFeedback(() => this.BoolValue);
}
/// <summary>
/// Forces the feedback to false regardless of timeout
/// </summary>
public void ClearNow()
{
if (Timer != null)
Timer.Stop();
ClearFeedback();
}
void ClearFeedback()
{
_BoolValue = false;
Feedback.FireUpdate();
Timer = null;
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
public abstract class BoolFeedbackLogic
{
/// <summary>
/// Output representing the "and" value of all connected inputs
/// </summary>
public BoolFeedback Output { get; private set; }
/// <summary>
/// List of all connected outputs
/// </summary>
protected List<BoolFeedback> OutputsIn = new List<BoolFeedback>();
protected bool ComputedValue;
public BoolFeedbackLogic()
{
Output = new BoolFeedback(() => ComputedValue);
}
public void AddOutputIn(BoolFeedback output)
{
// Don't double up outputs
if(OutputsIn.Contains(output)) return;
OutputsIn.Add(output);
output.OutputChange += AnyInput_OutputChange;
Evaluate();
}
public void AddOutputsIn(List<BoolFeedback> outputs)
{
foreach (var o in outputs)
{
// skip existing
if (OutputsIn.Contains(o)) continue;
OutputsIn.Add(o);
o.OutputChange += AnyInput_OutputChange;
}
Evaluate();
}
public void RemoveOutputIn(BoolFeedback output)
{
// Don't double up outputs
if (OutputsIn.Contains(output)) return;
OutputsIn.Remove(output);
output.OutputChange -= AnyInput_OutputChange;
Evaluate();
}
public void RemoveOutputsIn(List<BoolFeedback> outputs)
{
foreach (var o in outputs)
{
OutputsIn.Remove(o);
o.OutputChange -= AnyInput_OutputChange;
}
Evaluate();
}
void AnyInput_OutputChange(object sender, EventArgs e)
{
Evaluate();
}
protected abstract void Evaluate();
}
public class BoolFeedbackAnd : BoolFeedbackLogic
{
protected override void Evaluate()
{
var prevValue = ComputedValue;
var newValue = OutputsIn.All(o => o.BoolValue);
if (newValue != prevValue)
{
ComputedValue = newValue;
Output.FireUpdate();
}
}
}
public class BoolFeedbackOr : BoolFeedbackLogic
{
protected override void Evaluate()
{
var prevValue = ComputedValue;
var newValue = OutputsIn.Any(o => o.BoolValue);
if (newValue != prevValue)
{
ComputedValue = newValue;
Output.FireUpdate();
}
}
}
public class BoolFeedbackLinq : BoolFeedbackLogic
{
Func<IEnumerable<BoolFeedback>, bool> Predicate;
public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate)
: base()
{
Predicate = predicate;
}
protected override void Evaluate()
{
var prevValue = ComputedValue;
var newValue = Predicate(OutputsIn);
if (newValue != prevValue)
{
ComputedValue = newValue;
Output.FireUpdate();
}
}
}
}

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public abstract class Feedback : IKeyed
{
public event EventHandler<FeedbackEventArgs> OutputChange;
public string Key { get; private set; }
public virtual bool BoolValue { get { return false; } }
public virtual int IntValue { get { return 0; } }
public virtual string StringValue { get { return ""; } }
public virtual string SerialValue { get { return ""; } }
//public Cue Cue { get; private set; }
public abstract eCueType Type { get; }
/// <summary>
/// Feedbacks can be put into test mode for simulation of events without real data.
/// Using JSON debugging methods and the Set/ClearTestValue methods, we can simulate
/// Feedback behaviors
/// </summary>
public bool InTestMode { get; protected set; }
/// <summary>
/// Base Constructor - empty
/// </summary>
protected Feedback()
{
}
protected Feedback(string key)
{
if (key == null)
Key = "";
else
Key = key;
}
//protected Feedback(Cue cue)
//{
// Cue = cue;
//}
/// <summary>
/// Clears test mode and fires update.
/// </summary>
public void ClearTestValue()
{
InTestMode = false;
FireUpdate();
}
/// <summary>
/// Fires an update synchronously
/// </summary>
public abstract void FireUpdate();
/// <summary>
/// Fires the update asynchronously within a CrestronInvoke
/// </summary>
public void InvokeFireUpdate()
{
CrestronInvoke.BeginInvoke(o => FireUpdate());
}
///// <summary>
///// Helper method that fires event. Use this intstead of calling OutputChange
///// </summary>
//protected void OnOutputChange()
//{
// if (OutputChange != null) OutputChange(this, EventArgs.Empty);
//}
protected void OnOutputChange(bool value)
{
if (OutputChange != null) OutputChange(this, new FeedbackEventArgs(value));
}
protected void OnOutputChange(int value)
{
if (OutputChange != null) OutputChange(this, new FeedbackEventArgs(value));
}
protected void OnOutputChange(string value)
{
if (OutputChange != null) OutputChange(this, new FeedbackEventArgs(value));
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Basically a List , with an indexer to find feedbacks by key name
/// </summary>
public class FeedbackCollection<T> : List<T> where T : Feedback
{
/// <summary>
/// Case-insensitive port lookup linked to feedbacks' keys
/// </summary>
public T this[string key]
{
get
{
return this.FirstOrDefault(i => i.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
}
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
public class FeedbackEventArgs : EventArgs
{
public bool BoolValue { get; private set; }
public int IntValue { get; private set; }
public ushort UShortValue
{
get
{
return (ushort)IntValue;
}
}
public string StringValue { get; private set; }
public eFeedbackEventType Type { get; private set; }
public FeedbackEventArgs(bool value)
{
BoolValue = value;
Type = eFeedbackEventType.TypeBool;
}
public FeedbackEventArgs(int value)
{
IntValue = value;
Type = eFeedbackEventType.TypeInt;
}
public FeedbackEventArgs(string value)
{
StringValue = value;
Type = eFeedbackEventType.TypeString;
}
}
public enum eFeedbackEventType
{
TypeBool,
TypeInt,
TypeString
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
public class IntFeedback : Feedback
{
public override int IntValue { get { return _IntValue; } } // ValueFunc.Invoke(); } }
int _IntValue;
public ushort UShortValue { get { return (ushort)_IntValue; } }
public override eCueType Type { get { return eCueType.Int; } }
public int TestValue { get; private set; }
/// <summary>
/// Func evaluated on FireUpdate
/// </summary>
Func<int> ValueFunc;
List<UShortInputSig> LinkedInputSigs = new List<UShortInputSig>();
public IntFeedback(Func<int> valueFunc)
: this(null, valueFunc)
{
}
public IntFeedback(string key, Func<int> valueFunc)
: base(key)
{
ValueFunc = valueFunc;
}
//public IntFeedback(Cue cue, Func<int> valueFunc)
// : base(cue)
//{
// if (cue == null) throw new ArgumentNullException("cue");
// ValueFunc = valueFunc;
//}
public override void FireUpdate()
{
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
if (newValue != _IntValue)
{
_IntValue = newValue;
LinkedInputSigs.ForEach(s => UpdateSig(s));
OnOutputChange(newValue);
}
}
public void LinkInputSig(UShortInputSig sig)
{
LinkedInputSigs.Add(sig);
UpdateSig(sig);
}
public void UnlinkInputSig(UShortInputSig sig)
{
LinkedInputSigs.Remove(sig);
}
public override string ToString()
{
return (InTestMode ? "TEST -- " : "") + IntValue.ToString();
}
/// <summary>
/// Puts this in test mode, sets the test value and fires an update.
/// </summary>
/// <param name="value"></param>
public void SetTestValue(int value)
{
TestValue = value;
InTestMode = true;
FireUpdate();
}
void UpdateSig(UShortInputSig sig)
{
sig.UShortValue = UShortValue;
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// To be used for serial data feedback where the event chain / asynchronicity must be maintained
/// and calculating the value based on a Func when it is needed will not suffice.
/// </summary>
public class SerialFeedback : Feedback
{
public override string SerialValue { get { return _SerialValue; } }
string _SerialValue;
public override eCueType Type { get { return eCueType.Serial; } }
/// <summary>
/// Used in testing. Set/Clear functions
/// </summary>
public string TestValue { get; private set; }
List<StringInputSig> LinkedInputSigs = new List<StringInputSig>();
public SerialFeedback()
{
}
public SerialFeedback(string key)
: base(key)
{
}
public override void FireUpdate()
{
throw new NotImplementedException("This feedback type does not use Funcs");
}
public void FireUpdate(string newValue)
{
_SerialValue = newValue;
LinkedInputSigs.ForEach(s => UpdateSig(s, newValue));
OnOutputChange(newValue);
}
public void LinkInputSig(StringInputSig sig)
{
LinkedInputSigs.Add(sig);
UpdateSig(sig);
}
public void UnlinkInputSig(StringInputSig sig)
{
LinkedInputSigs.Remove(sig);
}
public override string ToString()
{
return (InTestMode ? "TEST -- " : "") + SerialValue;
}
/// <summary>
/// Puts this in test mode, sets the test value and fires an update.
/// </summary>
/// <param name="value"></param>
public void SetTestValue(string value)
{
TestValue = value;
InTestMode = true;
FireUpdate(TestValue);
}
void UpdateSig(StringInputSig sig)
{
sig.StringValue = _SerialValue;
}
void UpdateSig(StringInputSig sig, string value)
{
sig.StringValue = value;
}
}
}

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
public class StringFeedback : Feedback
{
public override string StringValue { get { return _StringValue; } } // ValueFunc.Invoke(); } }
string _StringValue;
public override eCueType Type { get { return eCueType.String; } }
/// <summary>
/// Used in testing. Set/Clear functions
/// </summary>
public string TestValue { get; private set; }
/// <summary>
/// Evalutated on FireUpdate
/// </summary>
public Func<string> ValueFunc { get; private set; }
List<StringInputSig> LinkedInputSigs = new List<StringInputSig>();
public StringFeedback(Func<string> valueFunc)
: this(null, valueFunc)
{
}
public StringFeedback(string key, Func<string> valueFunc)
: base(key)
{
ValueFunc = valueFunc;
}
//public StringFeedback(Cue cue, Func<string> valueFunc)
// : base(cue)
//{
// if (cue == null) throw new ArgumentNullException("cue");
// ValueFunc = valueFunc;
//}
public override void FireUpdate()
{
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
if (newValue != _StringValue)
{
_StringValue = newValue;
LinkedInputSigs.ForEach(s => UpdateSig(s));
OnOutputChange(newValue);
}
}
public void LinkInputSig(StringInputSig sig)
{
LinkedInputSigs.Add(sig);
UpdateSig(sig);
}
public void UnlinkInputSig(StringInputSig sig)
{
LinkedInputSigs.Remove(sig);
}
public override string ToString()
{
return (InTestMode ? "TEST -- " : "") + StringValue;
}
/// <summary>
/// Puts this in test mode, sets the test value and fires an update.
/// </summary>
/// <param name="value"></param>
public void SetTestValue(string value)
{
TestValue = value;
InTestMode = true;
FireUpdate();
}
void UpdateSig(StringInputSig sig)
{
sig.StringValue = _StringValue;
}
}
}