- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #28 from astingen/refactor/IntermediateControls
Refactor/intermediate controls
Showing
65 changed files
with
6,300 additions
and
2,594 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> | ||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CSharpWarnings_003A_003ACS1591/@EntryIndexedValue">HINT</s:String> | ||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></s:String></wpf:ResourceDictionary> |
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
75 changes: 75 additions & 0 deletions
75
QscQsys/QscQsys/Intermediaries/AbstractIntermediaryControl.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using System; | ||
namespace QscQsys.Intermediaries | ||
{ | ||
public abstract class AbstractIntermediaryControl : IQsysIntermediaryControl | ||
{ | ||
public event EventHandler<QsysInternalEventsArgs> OnStateChanged; | ||
public event EventHandler<BoolEventArgs> OnSubscribeChanged; | ||
|
||
private readonly string _name; | ||
private QsysStateData _state; | ||
private bool _subscribe; | ||
|
||
public abstract QsysCore Core { get; } | ||
|
||
public string Name { get { return _name; } } | ||
|
||
public QsysStateData State | ||
{ | ||
get { return _state; } | ||
protected set | ||
{ | ||
if (_state == value) | ||
return; | ||
|
||
_state = value; | ||
|
||
var handler = OnStateChanged; | ||
if (handler != null) | ||
handler(this, new QsysInternalEventsArgs(_state)); | ||
} | ||
} | ||
|
||
public bool Subscribe | ||
{ | ||
get { return _subscribe; } | ||
protected set | ||
{ | ||
if (_subscribe == value) | ||
return; | ||
|
||
_subscribe = value; | ||
|
||
var handler = OnSubscribeChanged; | ||
if (handler != null) | ||
handler(this, new BoolEventArgs(_subscribe)); | ||
} | ||
} | ||
|
||
public abstract void SendChangePosition(double position); | ||
public abstract void SendChangeDoubleValue(double value); | ||
public abstract void SendChangeStringValue(string value); | ||
|
||
public void SendChangeBoolValue(bool value) | ||
{ | ||
SendChangeDoubleValue(value ? 1 : 0); | ||
} | ||
|
||
protected AbstractIntermediaryControl(string name) | ||
{ | ||
_name = name; | ||
} | ||
|
||
protected void StateChanged(QsysStateData state) | ||
{ | ||
State = state; | ||
} | ||
|
||
|
||
public void SetSubscribe() | ||
{ | ||
Subscribe = true; | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System; | ||
|
||
namespace QscQsys.Intermediaries | ||
{ | ||
public interface IQsysIntermediary | ||
{ | ||
string Name { get; } | ||
QsysCore Core { get; } | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
QscQsys/QscQsys/Intermediaries/IQsysIntermediaryControl.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System; | ||
using JetBrains.Annotations; | ||
|
||
namespace QscQsys.Intermediaries | ||
{ | ||
public interface IQsysIntermediaryControl : IQsysIntermediary | ||
{ | ||
event EventHandler<QsysInternalEventsArgs> OnStateChanged; | ||
event EventHandler<BoolEventArgs> OnSubscribeChanged; | ||
|
||
[CanBeNull] | ||
QsysStateData State { get; } | ||
bool Subscribe { get; } | ||
|
||
void SendChangePosition(double position); | ||
void SendChangeDoubleValue(double value); | ||
void SendChangeStringValue(string value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,287 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Newtonsoft.Json; | ||
|
||
namespace QscQsys.Intermediaries | ||
{ | ||
/// <summary> | ||
/// Acts as an intermediary between the QSys Core and the QsysNamedControls | ||
/// </summary> | ||
public sealed class NamedComponent : IQsysIntermediary | ||
{ | ||
#region Fields | ||
|
||
private readonly string _name; | ||
private readonly QsysCore _core; | ||
private readonly Dictionary<string, NamedComponentControl> _controls; | ||
private readonly Dictionary<string, Action<QsysStateData>> _controlUpdateCallbacks; | ||
private bool _subscribe; | ||
|
||
#endregion | ||
|
||
#region Events | ||
|
||
public event EventHandler<QsysInternalEventsArgs> OnFeedbackReceived; | ||
|
||
public event EventHandler<ComponentControlEventArgs> OnComponentControlAdded; | ||
|
||
public event EventHandler<ComponentControlSubscribeEventArgs> OnComponentSubscribeChanged; | ||
|
||
#endregion | ||
|
||
#region Properties | ||
|
||
public string Name { get { return _name; } } | ||
|
||
public QsysCore Core { get { return _core; } } | ||
|
||
public bool Subscribe { get { return _subscribe; } } | ||
|
||
#endregion | ||
|
||
#region Constructor | ||
|
||
private NamedComponent(string name, QsysCore core) | ||
{ | ||
_subscribe = true; | ||
_controls = new Dictionary<string, NamedComponentControl>(); | ||
_controlUpdateCallbacks = new Dictionary<string, Action<QsysStateData>>(); | ||
_name = name; | ||
_core = core; | ||
} | ||
|
||
#endregion | ||
|
||
#region Methods | ||
|
||
private void UpdateState(QsysStateData state) | ||
{ | ||
var handler = OnFeedbackReceived; | ||
if (handler != null) | ||
handler(this, new QsysInternalEventsArgs(state)); | ||
|
||
Action<QsysStateData> updateCallback; | ||
if (TryGetComponentUpdateCallback(state.Name, out updateCallback)) | ||
updateCallback(state); | ||
} | ||
|
||
public Component ToComponentSubscribeControls() | ||
{ | ||
return Component.Instantiate( | ||
Name, | ||
GetComponentControlsSubscribe().Select(control => control.ToControlName()) | ||
); | ||
} | ||
|
||
#endregion | ||
|
||
#region SendData | ||
|
||
internal void SendChangePosition(string method, double position) | ||
{ | ||
var change = new ComponentChange() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "position", | ||
Caller = Name, | ||
Method = method, | ||
Position = position | ||
}), | ||
Params = | ||
new ComponentChangeParams() | ||
{ | ||
Name = Name, | ||
Controls = | ||
new List<ComponentSetValue>() { new ComponentSetValue() { Name = method, Position = position } } | ||
} | ||
}; | ||
|
||
Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = | ||
NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
internal void SendChangeDoubleValue(string method, double value) | ||
{ | ||
var change = new ComponentChange() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "value", | ||
Caller = Name, | ||
Method = method, | ||
Value = value, | ||
StringValue = value.ToString() | ||
}), | ||
Params = | ||
new ComponentChangeParams() | ||
{ | ||
Name = Name, | ||
Controls = | ||
new List<ComponentSetValue>() { new ComponentSetValue() { Name = method, Value = value } } | ||
} | ||
}; | ||
|
||
Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = | ||
NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
internal void SendChangeStringValue(string method, string value) | ||
{ | ||
var change = new ComponentChangeString() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "string_value", | ||
Caller = Name, | ||
Method = method, | ||
StringValue = value | ||
}), | ||
Params = | ||
new ComponentChangeParamsString() | ||
{ | ||
Name = Name, | ||
Controls = | ||
new List<ComponentSetValueString>() | ||
{ | ||
new ComponentSetValueString() {Name = method, Value = value} | ||
} | ||
} | ||
}; | ||
|
||
Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = | ||
NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
#endregion | ||
|
||
#region ComponentControls | ||
|
||
public NamedComponentControl LazyLoadComponentControl(string name) | ||
{ | ||
return LazyLoadComponentControl(name, true); | ||
} | ||
|
||
public NamedComponentControl LazyLoadComponentControl(string name, bool subscribe) | ||
{ | ||
NamedComponentControl control; | ||
|
||
lock (_controls) | ||
{ | ||
if (_controls.TryGetValue(name, out control)) | ||
{ | ||
if (subscribe) | ||
control.SetSubscribe(); | ||
return control; | ||
} | ||
|
||
Action<QsysStateData> updateCallback; | ||
control = NamedComponentControl.Create(name, this, subscribe, out updateCallback); | ||
_controls.Add(name, control); | ||
_controlUpdateCallbacks.Add(name, updateCallback); | ||
} | ||
|
||
SubscribeControl(control); | ||
|
||
var handler = OnComponentControlAdded; | ||
if (handler != null) | ||
handler(this, new ComponentControlEventArgs(control)); | ||
|
||
return control; | ||
} | ||
|
||
public bool TryGetComponentControl(string name, out NamedComponentControl control) | ||
{ | ||
lock (_controls) | ||
{ | ||
return _controls.TryGetValue(name, out control); | ||
} | ||
} | ||
|
||
private bool TryGetComponentUpdateCallback(string name, out Action<QsysStateData> updateCallback) | ||
{ | ||
lock (_controls) | ||
{ | ||
return _controlUpdateCallbacks.TryGetValue(name, out updateCallback); | ||
} | ||
} | ||
|
||
public IEnumerable<NamedComponentControl> GetComponentControls() | ||
{ | ||
lock (_controls) | ||
{ | ||
return _controls.Values.ToArray(); | ||
} | ||
} | ||
|
||
public IEnumerable<NamedComponentControl> GetComponentControlsSubscribe() | ||
{ | ||
lock (_controls) | ||
{ | ||
return _controls.Values.Where(c => c.Subscribe).ToArray(); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region Control Callbacks | ||
|
||
private void SubscribeControl(NamedComponentControl control) | ||
{ | ||
if (control == null) | ||
return; | ||
|
||
control.OnSubscribeChanged += ControlOnSubscribeChanged; | ||
} | ||
|
||
private void UnsubscribeControl(NamedComponentControl control) | ||
{ | ||
if (control == null) | ||
return; | ||
|
||
control.OnSubscribeChanged -= ControlOnSubscribeChanged; | ||
} | ||
|
||
private void ControlOnSubscribeChanged(object sender, BoolEventArgs args) | ||
{ | ||
var control = sender as NamedComponentControl; | ||
|
||
if (control == null) | ||
return; | ||
|
||
var handler = OnComponentSubscribeChanged; | ||
if (handler != null) | ||
handler(this, new ComponentControlSubscribeEventArgs(control, args.Data)); | ||
} | ||
|
||
#endregion | ||
|
||
#region Static Methods | ||
|
||
public static NamedComponent Create(string name, QsysCore core, out Action<QsysStateData> updateCallback) | ||
{ | ||
var component = new NamedComponent(name, core); | ||
updateCallback = component.UpdateState; | ||
return component; | ||
} | ||
|
||
#endregion | ||
} | ||
|
||
} |
135 changes: 135 additions & 0 deletions
135
QscQsys/QscQsys/Intermediaries/NamedComponentControl.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Newtonsoft.Json; | ||
|
||
namespace QscQsys.Intermediaries | ||
{ | ||
public sealed class NamedComponentControl : AbstractIntermediaryControl | ||
{ | ||
private readonly NamedComponent _component; | ||
|
||
public NamedComponent Component { get { return _component; } } | ||
|
||
public override QsysCore Core { get { return _component.Core; } } | ||
|
||
private NamedComponentControl(string name, NamedComponent component):base(name) | ||
{ | ||
_component = component; | ||
} | ||
|
||
#region Send Data | ||
|
||
public override void SendChangePosition(double position) | ||
{ | ||
var change = new ComponentChange() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "position", | ||
Caller = Component.Name, | ||
Method = Name, | ||
Position = position | ||
}), | ||
Params = | ||
new ComponentChangeParams() | ||
{ | ||
Name = Component.Name, | ||
Controls = | ||
new List<ComponentSetValue>() { new ComponentSetValue() { Name = Name, Position = position } } | ||
} | ||
}; | ||
|
||
Component.Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = | ||
NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
public override void SendChangeDoubleValue(double value) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
var change = new ComponentChange() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "value", | ||
Caller = Component.Name, | ||
Method = Name, | ||
Value = value, | ||
StringValue = value.ToString() | ||
}), | ||
Params = | ||
new ComponentChangeParams() | ||
{ | ||
Name = Component.Name, | ||
Controls = | ||
new List<ComponentSetValue>() { new ComponentSetValue() { Name = Name, Value = value } } | ||
} | ||
}; | ||
|
||
Component.Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = | ||
NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
public override void SendChangeStringValue(string value) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
var change = new ComponentChangeString() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "string_value", | ||
Caller = Component.Name, | ||
Method = Name, | ||
StringValue = value | ||
}), | ||
Params = | ||
new ComponentChangeParamsString() | ||
{ | ||
Name = Component.Name, | ||
Controls = | ||
new List<ComponentSetValueString>() | ||
{ | ||
new ComponentSetValueString() {Name = Name, Value = value} | ||
} | ||
} | ||
}; | ||
|
||
Component.Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = | ||
NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
#endregion | ||
|
||
public ControlName ToControlName() | ||
{ | ||
return ControlName.Instantiate(Name); | ||
} | ||
|
||
public static NamedComponentControl Create(string name, NamedComponent component, bool subscribe, | ||
out Action<QsysStateData> updateCallback) | ||
{ | ||
var control = new NamedComponentControl(name, component); | ||
control.Subscribe = subscribe; | ||
updateCallback = control.StateChanged; | ||
return control; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using System; | ||
using Newtonsoft.Json; | ||
|
||
namespace QscQsys.Intermediaries | ||
{ | ||
/// <summary> | ||
/// Acts as an intermediary between the QSys Core and the QsysNamedControls | ||
/// </summary> | ||
public sealed class NamedControl : AbstractIntermediaryControl | ||
{ | ||
private readonly QsysCore _core; | ||
|
||
public override QsysCore Core {get { return _core; }} | ||
|
||
private NamedControl(string name, QsysCore core) : base(name) | ||
{ | ||
_core = core; | ||
} | ||
|
||
public static NamedControl Create(string name, QsysCore core, bool subscribe, out Action<QsysStateData> updateCallback) | ||
{ | ||
var control = new NamedControl(name, core); | ||
control.Subscribe = subscribe; | ||
updateCallback = control.StateChanged; | ||
return control; | ||
} | ||
|
||
public override void SendChangePosition(double value) | ||
{ | ||
var change = new ControlIntegerChange() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "position", | ||
Caller = Name, | ||
Method = "Control.Set", | ||
Position = value | ||
}), | ||
Params = new ControlIntegerParams() {Name = Name, Position = value} | ||
}; | ||
|
||
Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
public override void SendChangeDoubleValue(double value) | ||
{ | ||
var change = new ControlIntegerChange() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "value", | ||
Caller = Name, | ||
Method = "Control.Set", | ||
Value = value, | ||
StringValue = value.ToString() | ||
}), | ||
Params = new ControlIntegerParams() {Name = Name, Value = value} | ||
}; | ||
|
||
Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = NullValueHandling.Ignore | ||
})); | ||
} | ||
|
||
public override void SendChangeStringValue(string value) | ||
{ | ||
var change = new ControlStringChange() | ||
{ | ||
ID = | ||
JsonConvert.SerializeObject(new CustomResponseId() | ||
{ | ||
ValueType = "string_value", | ||
Caller = Name, | ||
Method = "Control.Set", | ||
StringValue = value | ||
}), | ||
Params = new ControlStringParams() {Name = Name, Value = value} | ||
}; | ||
|
||
Core.Enqueue(JsonConvert.SerializeObject(change, Formatting.None, | ||
new JsonSerializerSettings | ||
{ | ||
NullValueHandling = NullValueHandling.Ignore | ||
})); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
QscQsys/QscQsys/NamedComponents/AbstractQsysComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
using System; | ||
using QscQsys.Intermediaries; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public abstract class AbstractQsysComponent : IDisposable | ||
{ | ||
//protected bool _registered; | ||
//private Component _component; | ||
private bool _isInitialized; | ||
private NamedComponent _component; | ||
private bool _disposed; | ||
|
||
public string ComponentName { get; private set; } | ||
public bool IsRegistered { get { return Component != null; } } | ||
public string CoreId { get; private set; } | ||
|
||
public NamedComponent Component | ||
{ | ||
get { return _component; } | ||
private set | ||
{ | ||
if (_component == value) | ||
return; | ||
|
||
Unsubscribe(_component); | ||
_component = value; | ||
Subscribe(_component); | ||
|
||
HandleComponentUpdated(_component); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Initialize to be called from concrete's initialize method | ||
/// </summary> | ||
/// <param name="coreId"></param> | ||
/// <param name="componentName"></param> | ||
protected void InternalInitialize(string coreId, string componentName) | ||
{ | ||
if (_isInitialized) | ||
return; | ||
|
||
_isInitialized = true; | ||
|
||
CoreId = coreId; | ||
ComponentName = componentName; | ||
|
||
QsysCoreManager.CoreAdded += QsysCoreManager_CoreAdded; | ||
|
||
RegisterWithCore(); | ||
} | ||
|
||
#region NamedComponent Callbacks | ||
|
||
protected virtual void HandleComponentUpdated(NamedComponent component) | ||
{ } | ||
|
||
private void Subscribe(NamedComponent component) | ||
{ | ||
if (component == null) | ||
return; | ||
|
||
component.OnFeedbackReceived += ComponentOnFeedbackReceived; | ||
} | ||
|
||
private void Unsubscribe(NamedComponent component) | ||
{ | ||
if (component == null) | ||
return; | ||
|
||
component.OnFeedbackReceived -= ComponentOnFeedbackReceived; | ||
} | ||
|
||
protected virtual void ComponentOnFeedbackReceived(object sender, QsysInternalEventsArgs qsysInternalEventsArgs) | ||
{ | ||
} | ||
|
||
#endregion | ||
|
||
#region Core Manger Callbacks | ||
|
||
private void QsysCoreManager_CoreAdded(object sender, CoreEventArgs e) | ||
{ | ||
if (e.CoreId == CoreId) | ||
RegisterWithCore(); | ||
} | ||
|
||
private void RegisterWithCore() | ||
{ | ||
|
||
QsysCore core; | ||
if (!QsysCoreManager.TryGetCore(CoreId, out core)) | ||
return; | ||
|
||
Component = core.LazyLoadNamedComponent(ComponentName); | ||
} | ||
|
||
#endregion | ||
|
||
/// <summary> | ||
/// Clean up of unmanaged resources | ||
/// </summary> | ||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (_disposed) return; | ||
|
||
_disposed = true; | ||
if (disposing) | ||
{ | ||
QsysCoreManager.CoreAdded -= QsysCoreManager_CoreAdded; | ||
Component = null; | ||
} | ||
} | ||
} | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public class QsysFader : AbstractQsysComponent | ||
{ | ||
public delegate void VolumeChange(SimplSharpString cName, ushort value); | ||
public delegate void MuteChange(SimplSharpString cName, ushort value); | ||
public delegate void GainStringChange(SimplSharpString cName, SimplSharpString value); | ||
public VolumeChange newVolumeChange { get; set; } | ||
public MuteChange newMuteChange { get; set; } | ||
public GainStringChange newGainStringChange { get; set; } | ||
|
||
private bool _currentMute; | ||
private string _currentGainString; | ||
private int _currentLvl; | ||
|
||
private NamedComponentControl _gainControl; | ||
private NamedComponentControl _muteControl; | ||
|
||
public NamedComponentControl GainControl | ||
{ | ||
get { return _gainControl; } | ||
private set | ||
{ | ||
if (_gainControl == value) | ||
return; | ||
|
||
UnsubscribeGainControl(_gainControl); | ||
_gainControl = value; | ||
SubscribeGainControl(_gainControl); | ||
|
||
} | ||
} | ||
|
||
public NamedComponentControl MuteControl | ||
{ | ||
get { return _muteControl; } | ||
private set | ||
{ | ||
if (_muteControl == value) | ||
return; | ||
|
||
UnsubscribeMuteControl(_muteControl); | ||
_muteControl = value; | ||
SubscribeMuteControl(_muteControl); | ||
|
||
} | ||
} | ||
|
||
public bool MuteValue { get { return _currentMute; } } | ||
public int VolumeValue { get { return _currentLvl; } } | ||
public string GainValue { get { return _currentGainString; } } | ||
|
||
public void Initialize(string coreId, string componentName) | ||
{ | ||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
if (component == null) | ||
{ | ||
GainControl = null; | ||
MuteControl = null; | ||
return; | ||
} | ||
|
||
GainControl = component.LazyLoadComponentControl(ControlNameUtils.GetGainControlName()); | ||
MuteControl = component.LazyLoadComponentControl(ControlNameUtils.GetMuteControlName()); | ||
} | ||
|
||
#region Gain Control Callbacks | ||
|
||
private void SubscribeGainControl(NamedComponentControl gainControl) | ||
{ | ||
if (gainControl == null) | ||
return; | ||
|
||
gainControl.OnStateChanged += GainControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeGainControl(NamedComponentControl gainControl) | ||
{ | ||
if (gainControl == null) | ||
return; | ||
|
||
gainControl.OnStateChanged += GainControlOnStateChanged; | ||
} | ||
|
||
private void GainControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
if (args.Type == "position" || args.Type == "change") | ||
{ | ||
_currentLvl = SimplUtils.ScaleToUshort(args.Position); | ||
|
||
var callback = newVolumeChange; | ||
if (callback != null) | ||
callback(ComponentName, (ushort)_currentLvl); | ||
} | ||
|
||
if (args.Type == "value" || args.Type == "change") | ||
{ | ||
_currentGainString = args.StringValue; | ||
|
||
var callback = newGainStringChange; | ||
if (callback != null && !string.IsNullOrEmpty(_currentGainString)) | ||
callback(ComponentName, _currentGainString); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region Mute Control Callbacks | ||
|
||
private void SubscribeMuteControl(NamedComponentControl muteControl) | ||
{ | ||
if (muteControl == null) | ||
return; | ||
|
||
muteControl.OnStateChanged += MuteControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeMuteControl(NamedComponentControl muteControl) | ||
{ | ||
if (muteControl == null) | ||
return; | ||
|
||
muteControl.OnStateChanged += MuteControlOnStateChanged; | ||
} | ||
|
||
private void MuteControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
_currentMute = args.BoolValue; | ||
|
||
var callback = newMuteChange; | ||
if (callback != null) | ||
callback(ComponentName, _currentMute.BoolToSplus()); | ||
} | ||
|
||
#endregion | ||
|
||
/// <summary> | ||
/// Sets the current volume value. | ||
/// </summary> | ||
/// <param name="value">Volume value to set the fader to.</param> | ||
public void Volume(ushort value) | ||
{ | ||
if (GainControl != null) | ||
GainControl.SendChangePosition(SimplUtils.ScaleToDouble(value)); | ||
} | ||
|
||
public void Decibels(double value) | ||
{ | ||
if (GainControl != null) | ||
GainControl.SendChangeDoubleValue(value); | ||
} | ||
|
||
public void Decibels(short value) | ||
{ | ||
Decibels((double)value); | ||
} | ||
|
||
/// <summary> | ||
/// Sets the current mute state. | ||
/// </summary> | ||
/// <param name="value">The state to set the mute.</param> | ||
public void Mute(bool value) | ||
{ | ||
if (MuteControl != null) | ||
MuteControl.SendChangeBoolValue(value); | ||
} | ||
|
||
/// <summary> | ||
/// Sets the current mute state. | ||
/// </summary> | ||
/// <param name="value">The state to set the mute.</param> | ||
public void Mute(ushort value) | ||
{ | ||
Mute(value.BoolFromSplus()); | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
base.Dispose(disposing); | ||
|
||
if (disposing) | ||
{ | ||
GainControl = null; | ||
MuteControl = null; | ||
} | ||
} | ||
} | ||
} |
154 changes: 154 additions & 0 deletions
154
QscQsys/QscQsys/NamedComponents/QsysMatrixMixerCrosspoint.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public sealed class QsysMatrixMixerCrosspoint : AbstractQsysComponent | ||
{ | ||
public delegate void CrossPointMuteChange(SimplSharpString cName, ushort value); | ||
public delegate void CrossPointGainChange(SimplSharpString cName, ushort value); | ||
public CrossPointMuteChange newCrossPointMuteChange { get; set; } | ||
public CrossPointGainChange newCrossPointGainChange { get; set; } | ||
|
||
|
||
|
||
private ushort _input; | ||
private ushort _output; | ||
private bool _initialized; | ||
|
||
private NamedComponentControl _muteControl; | ||
private NamedComponentControl _gainControl; | ||
|
||
private string MuteControlName | ||
{ | ||
get { return ControlNameUtils.GetMatrixCrosspointMuteName(_input, _output); } | ||
} | ||
|
||
private string GainControlName | ||
{ | ||
get { return ControlNameUtils.GetMatrixCrosspointGainName(_input, _output); } | ||
} | ||
|
||
public NamedComponentControl MuteControl | ||
{ | ||
get { return _muteControl; } | ||
private set | ||
{ | ||
if (_muteControl == value) | ||
return; | ||
|
||
UnsubscribeMuteControl(_muteControl); | ||
_muteControl = value; | ||
SubscribeMuteControl(_muteControl); | ||
} | ||
} | ||
|
||
public NamedComponentControl GainControl | ||
{ | ||
get { return _gainControl; } | ||
private set | ||
{ | ||
if (_gainControl == value) | ||
return; | ||
|
||
UnsubscribeGainControl(_gainControl); | ||
_gainControl = value; | ||
SubscribeGainControl(_gainControl); | ||
} | ||
} | ||
|
||
public void Initialize(string coreId, string componentName, ushort input, ushort output) | ||
{ | ||
if (_initialized) | ||
return; | ||
|
||
_initialized = true; | ||
|
||
_input = input; | ||
_output = output; | ||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
if (component == null) | ||
{ | ||
MuteControl = null; | ||
GainControl = null; | ||
return; | ||
} | ||
|
||
MuteControl = component.LazyLoadComponentControl(MuteControlName); | ||
GainControl = component.LazyLoadComponentControl(GainControlName); | ||
} | ||
|
||
public void SetCrossPointMute(ushort value) | ||
{ | ||
if (MuteControl != null) | ||
MuteControl.SendChangeBoolValue(value.BoolFromSplus()); | ||
} | ||
|
||
public void SetCrossPointGain(ushort value) | ||
{ | ||
if (GainControl != null) | ||
GainControl.SendChangePosition(SimplUtils.ScaleToDouble(value)); | ||
} | ||
|
||
#region Mute Control Callbacks | ||
|
||
private void SubscribeMuteControl(NamedComponentControl muteControl) | ||
{ | ||
if (muteControl == null) | ||
return; | ||
|
||
muteControl.OnStateChanged += MuteControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeMuteControl(NamedComponentControl muteControl) | ||
{ | ||
if (muteControl == null) | ||
return; | ||
|
||
muteControl.OnStateChanged -= MuteControlOnStateChanged; | ||
} | ||
|
||
private void MuteControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
var callback = newCrossPointMuteChange; | ||
if (callback != null) | ||
callback(MuteControlName, args.BoolValue.BoolToSplus()); | ||
} | ||
|
||
#endregion | ||
|
||
#region Gain Control Callbacks | ||
|
||
private void SubscribeGainControl(NamedComponentControl gainControl) | ||
{ | ||
if (gainControl == null) | ||
return; | ||
|
||
gainControl.OnStateChanged += GainControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeGainControl(NamedComponentControl gainControl) | ||
{ | ||
if (gainControl == null) | ||
return; | ||
|
||
gainControl.OnStateChanged -= GainControlOnStateChanged; | ||
} | ||
|
||
private void GainControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
var callback = newCrossPointGainChange; | ||
if (callback != null) | ||
callback(GainControlName, SimplUtils.ScaleToUshort(args.Position)); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
120 changes: 120 additions & 0 deletions
120
QscQsys/QscQsys/NamedComponents/QsysMatrixMixerOutputAllCrosspoints.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public class QsysMatrixMixerOutputAllCrosspoints : AbstractQsysComponent | ||
{ | ||
public delegate void CrossPointMuteChange(SimplSharpString cName, ushort input, ushort value); | ||
|
||
public CrossPointMuteChange newCrossPointMuteChange { get; set; } | ||
|
||
private ushort _inputCount; | ||
private ushort _output; | ||
private bool _initialized; | ||
private readonly Dictionary<NamedComponentControl, int> _muteControls; | ||
private readonly Dictionary<int, NamedComponentControl> _muteControlsByInput; | ||
|
||
public QsysMatrixMixerOutputAllCrosspoints() | ||
{ | ||
_muteControls = new Dictionary<NamedComponentControl, int>(); | ||
_muteControlsByInput = new Dictionary<int, NamedComponentControl>(); | ||
} | ||
|
||
public void Initialize(string coreId, string componentName, ushort inputCount, ushort output) | ||
{ | ||
if (_initialized) | ||
return; | ||
|
||
_initialized = true; | ||
|
||
_inputCount = inputCount; | ||
_output = output; | ||
|
||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
lock (_muteControls) | ||
{ | ||
foreach (var control in _muteControls.Keys) | ||
UnsubscribeMuteControl(control); | ||
_muteControls.Clear(); | ||
_muteControlsByInput.Clear(); | ||
|
||
if (component == null) | ||
return; | ||
|
||
for (int input = 1; input <= _inputCount; input++) | ||
{ | ||
string controlName = ControlNameUtils.GetMatrixCrosspointMuteName(input, _output); | ||
var control = component.LazyLoadComponentControl(controlName); | ||
_muteControls.Add(control, input); | ||
_muteControlsByInput.Add(input, control); | ||
SubscribeMuteControl(control); | ||
UpdateState(input, control.State); | ||
} | ||
} | ||
} | ||
|
||
private void SubscribeMuteControl(NamedComponentControl control) | ||
{ | ||
if (control == null) | ||
return; | ||
|
||
control.OnStateChanged += ControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeMuteControl(NamedComponentControl control) | ||
{ | ||
if (control == null) | ||
return; | ||
|
||
control.OnStateChanged -= ControlOnStateChanged; | ||
} | ||
|
||
private void ControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
NamedComponentControl control = sender as NamedComponentControl; | ||
if (control == null) | ||
return; | ||
|
||
int inputNumber; | ||
lock (_muteControls) | ||
{ | ||
if (!_muteControls.TryGetValue(control, out inputNumber)) | ||
return; | ||
} | ||
|
||
UpdateState(inputNumber, args.Data); | ||
} | ||
|
||
private void UpdateState(int input, QsysStateData state) | ||
{ | ||
if (state == null) | ||
return; | ||
|
||
var callback = newCrossPointMuteChange; | ||
if (callback != null) | ||
callback(state.Name, (ushort)input, state.BoolValue.BoolToSplus()); | ||
} | ||
|
||
public void SetCrossPointMute(ushort input, ushort value) | ||
{ | ||
NamedComponentControl control; | ||
lock (_muteControls) | ||
{ | ||
if (!_muteControlsByInput.TryGetValue(input, out control)) | ||
return; | ||
} | ||
|
||
control.SendChangeBoolValue(value.BoolFromSplus()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
using System; | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public sealed class QsysMeter : AbstractQsysComponent | ||
{ | ||
public delegate void MeterChange(SimplSharpString cName, ushort meterValue); | ||
public MeterChange onMeterChange { get; set; } | ||
|
||
private int _meterIndex; | ||
private NamedComponentControl _meter; | ||
|
||
public NamedComponentControl Meter | ||
{ | ||
get { return _meter; } | ||
private set | ||
{ | ||
if (_meter == value) | ||
return; | ||
|
||
UnsubscribeMeter(_meter); | ||
_meter = value; | ||
SubscribeMeter(_meter); | ||
} | ||
} | ||
|
||
public void Initialize(string coreId, string componentName, int meterIndex) | ||
{ | ||
_meterIndex = meterIndex; | ||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
if (component == null) | ||
{ | ||
Meter = null; | ||
return; | ||
} | ||
|
||
Meter = component.LazyLoadComponentControl(ControlNameUtils.GetMeterName(_meterIndex)); | ||
} | ||
|
||
#region Meter Control Callbacks | ||
|
||
private void SubscribeMeter(NamedComponentControl meter) | ||
{ | ||
if (meter == null) | ||
return; | ||
|
||
meter.OnStateChanged += MeterOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeMeter(NamedComponentControl meter) | ||
{ | ||
if (meter == null) | ||
return; | ||
|
||
meter.OnStateChanged += MeterOnStateChanged; | ||
} | ||
|
||
private void MeterOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
var callback = onMeterChange; | ||
if (callback == null) | ||
return; | ||
|
||
double value = SimplUtils.ScaleToUshort(args.Position); | ||
callback(ControlNameUtils.GetMeterName(_meterIndex), Convert.ToUInt16(value)); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using System; | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public sealed class QsysNv32hDecoder : AbstractQsysComponent | ||
{ | ||
private const string CONTROL_NAME = "hdmi_out_0_select_index"; | ||
|
||
public delegate void Nv32hDecoderInputChange(SimplSharpString cName, ushort input); | ||
public Nv32hDecoderInputChange newNv32hDecoderInputChange { get; set; } | ||
|
||
private NamedComponentControl _inputControl; | ||
|
||
public NamedComponentControl InputControl | ||
{ | ||
get { return _inputControl; } | ||
private set | ||
{ | ||
if (_inputControl == value) | ||
return; | ||
|
||
UnsubscribeInputControl(_inputControl); | ||
_inputControl = value; | ||
SubscribeInputControl(_inputControl); | ||
} | ||
} | ||
|
||
private int _currentSource; | ||
|
||
public int CurrentSource { get { return _currentSource; } } | ||
|
||
public void Initialize(string coreId, string componentName) | ||
{ | ||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
if (component == null) | ||
{ | ||
InputControl = null; | ||
return; | ||
} | ||
|
||
InputControl = component.LazyLoadComponentControl(CONTROL_NAME); | ||
} | ||
|
||
public void ChangeInput(int source) | ||
{ | ||
if (InputControl != null) | ||
InputControl.SendChangeDoubleValue(source); | ||
} | ||
|
||
#region Input Control Callbacks | ||
|
||
private void SubscribeInputControl(NamedComponentControl inputControl) | ||
{ | ||
if (inputControl == null) | ||
return; | ||
|
||
inputControl.OnStateChanged += InputControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeInputControl(NamedComponentControl inputControl) | ||
{ | ||
if (inputControl == null) | ||
return; | ||
|
||
inputControl.OnStateChanged -= InputControlOnStateChanged; | ||
} | ||
|
||
private void InputControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
_currentSource = Convert.ToInt16(args.Value); | ||
|
||
var callback = newNv32hDecoderInputChange; | ||
if (callback != null) | ||
callback(ComponentName, Convert.ToUInt16(_currentSource)); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,398 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using Crestron.SimplSharp; | ||
using ExtensionMethods; | ||
using Newtonsoft.Json; | ||
using QscQsys.Intermediaries; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public class QsysPotsController : AbstractQsysComponent | ||
{ | ||
private const string CONTROL_CALL_OFFHOOK = "call_offhook"; | ||
private const string CONTROL_CALL_RINGING = "call_ringing"; | ||
private const string CONTROL_CALL_AUTOANSWER = "call_autoanswer"; | ||
private const string CONTROL_CALL_DND = "call_dnd"; | ||
private const string CONTROL_CALL_STATUS = "call_status"; | ||
private const string CONTROL_RECENT_CALLS = "recent_calls"; | ||
private const string CONTROL_CALL_NUMBER = "call_number"; | ||
private const string CONTROL_CALL_CONNECT = "call_connect"; | ||
private const string CONTROL_CALL_DISCONNECT = "call_disconnect"; | ||
|
||
public delegate void OffHookEvent(SimplSharpString cName, ushort value); | ||
public delegate void RingingEvent(SimplSharpString cName, ushort value); | ||
public delegate void DialingEvent(SimplSharpString cName, ushort value); | ||
public delegate void IncomingCallEvent(SimplSharpString cName, ushort value); | ||
public delegate void AutoAnswerEvent(SimplSharpString cName, ushort value); | ||
public delegate void DndEvent(SimplSharpString cName, ushort value); | ||
public delegate void DialStringEvent(SimplSharpString cName, SimplSharpString dialString); | ||
public delegate void CurrentlyCallingEvent(SimplSharpString cName, SimplSharpString currentlyCalling); | ||
public delegate void CurrentCallStatus(SimplSharpString cName, SimplSharpString callStatus); | ||
public delegate void RecentCallsEvent(SimplSharpString cName, SimplSharpString item1, SimplSharpString item2, SimplSharpString item3, SimplSharpString item4, SimplSharpString item5); | ||
public delegate void RecentCallListEvent(SimplSharpString cName, SimplSharpString xsig); | ||
public OffHookEvent onOffHookEvent { get; set; } | ||
public RingingEvent onRingingEvent { get; set; } | ||
public DialingEvent onDialingEvent { get; set; } | ||
public IncomingCallEvent onIncomingCallEvent { get; set; } | ||
public AutoAnswerEvent onAutoAnswerEvent { get; set; } | ||
public DndEvent onDndEvent { get; set; } | ||
public DialStringEvent onDialStringEvent { get; set; } | ||
public CurrentlyCallingEvent onCurrentlyCallingEvent { get; set; } | ||
public CurrentCallStatus onCurrentCallStatusChange { get; set; } | ||
public RecentCallsEvent onRecentCallsEvent { get; set; } | ||
public RecentCallListEvent onRecentCallListEvent { get; set; } | ||
|
||
private bool _hookState; | ||
private bool _ringingState; | ||
private bool _dialingState; | ||
private bool _incomingCall; | ||
private bool _autoAnswer; | ||
private bool _dnd; | ||
private readonly StringBuilder _dialString; | ||
private string _currentlyCalling; | ||
private string _lastCalled; | ||
private string _callStatus; | ||
private readonly List<ListBoxChoice> _recentCalls; | ||
|
||
public bool IsOffhook { get { return _hookState; } } | ||
public bool IsRinging { get { return _ringingState; } } | ||
public bool IsDialing { get { return _dialingState; } } | ||
public bool IsIncomingCall { get { return _incomingCall; } } | ||
public bool AutoAnswer { get { return _autoAnswer; } } | ||
public bool DND { get { return _dnd; } } | ||
public string DialString { get { return _dialString.ToString(); } } | ||
public string CurrentlyCalling { get { return _currentlyCalling; } } | ||
public string LastNumberCalled { get { return _lastCalled; } } | ||
public string CallStatus { get { return _callStatus; } } | ||
public List<ListBoxChoice> RecentCalls { get { return _recentCalls; } } | ||
|
||
public QsysPotsController() | ||
{ | ||
_dialString = new StringBuilder(); | ||
_recentCalls = new List<ListBoxChoice>(); | ||
} | ||
|
||
public void Initialize(string coreId, string componentName) | ||
{ | ||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
if (component == null) | ||
return; | ||
|
||
component.LazyLoadComponentControl(CONTROL_CALL_OFFHOOK); | ||
component.LazyLoadComponentControl(CONTROL_CALL_RINGING); | ||
component.LazyLoadComponentControl(CONTROL_CALL_AUTOANSWER); | ||
component.LazyLoadComponentControl(CONTROL_CALL_DND); | ||
component.LazyLoadComponentControl(CONTROL_CALL_STATUS); | ||
component.LazyLoadComponentControl(CONTROL_RECENT_CALLS); | ||
} | ||
|
||
protected override void ComponentOnFeedbackReceived(object sender, QsysInternalEventsArgs args) | ||
{ | ||
base.ComponentOnFeedbackReceived(sender, args); | ||
|
||
switch (args.Name) | ||
{ | ||
case CONTROL_CALL_OFFHOOK: | ||
if (Math.Abs(args.Value - 1) < QsysCore.TOLERANCE) | ||
{ | ||
_hookState = true; | ||
|
||
if (onOffHookEvent != null) | ||
onOffHookEvent(ComponentName, 1); | ||
|
||
if (onCurrentlyCallingEvent != null) | ||
onCurrentlyCallingEvent(ComponentName, _currentlyCalling); | ||
} | ||
else if (Math.Abs(args.Value) < QsysCore.TOLERANCE) | ||
{ | ||
_hookState = false; | ||
_dialString.Remove(0, _dialString.Length); | ||
|
||
if (onOffHookEvent != null) | ||
onOffHookEvent(ComponentName, 0); | ||
|
||
|
||
_lastCalled = _currentlyCalling; | ||
_currentlyCalling = string.Empty; | ||
|
||
if (onCurrentlyCallingEvent != null) | ||
onCurrentlyCallingEvent(ComponentName, _currentlyCalling); | ||
|
||
if (onDialStringEvent != null) | ||
onDialStringEvent(ComponentName, _dialString.ToString()); | ||
} | ||
break; | ||
case CONTROL_CALL_RINGING: | ||
if (Math.Abs(args.Value - 1) < QsysCore.TOLERANCE) | ||
{ | ||
_ringingState = true; | ||
|
||
if (onRingingEvent != null) | ||
onRingingEvent(ComponentName, 1); | ||
} | ||
else if (Math.Abs(args.Value) < QsysCore.TOLERANCE) | ||
{ | ||
_ringingState = false; | ||
|
||
if (onRingingEvent != null) | ||
onRingingEvent(ComponentName, 0); | ||
} | ||
break; | ||
case CONTROL_CALL_AUTOANSWER: | ||
_autoAnswer = Convert.ToBoolean(args.Value); | ||
|
||
if (onAutoAnswerEvent != null) | ||
onAutoAnswerEvent(ComponentName, Convert.ToUInt16(args.Value)); | ||
|
||
break; | ||
case CONTROL_CALL_DND: | ||
_dnd = Convert.ToBoolean(args.Value); | ||
|
||
if (onDndEvent != null) | ||
onDndEvent(ComponentName, Convert.ToUInt16(args.Value)); | ||
|
||
break; | ||
case CONTROL_CALL_STATUS: | ||
if (args.StringValue.Length > 0) | ||
{ | ||
_callStatus = args.StringValue; | ||
|
||
if (onCurrentCallStatusChange != null) | ||
onCurrentCallStatusChange(ComponentName, args.StringValue); | ||
|
||
if (_callStatus.Contains("Dialing") && _dialingState == false) | ||
{ | ||
_dialingState = true; | ||
|
||
if (onDialingEvent != null) | ||
onDialingEvent(ComponentName, 1); | ||
} | ||
else if (_dialingState) | ||
{ | ||
_dialingState = false; | ||
|
||
if (onDialingEvent != null) | ||
onDialingEvent(ComponentName, 0); | ||
} | ||
|
||
if (_callStatus.Contains("Incoming Call")) | ||
{ | ||
_incomingCall = true; | ||
|
||
if (onIncomingCallEvent != null) | ||
onIncomingCallEvent(ComponentName, 1); | ||
} | ||
else if (_incomingCall) | ||
{ | ||
_incomingCall = false; | ||
|
||
if (onIncomingCallEvent != null) | ||
onIncomingCallEvent(ComponentName, 0); | ||
} | ||
} | ||
break; | ||
case CONTROL_RECENT_CALLS: | ||
_recentCalls.Clear(); | ||
foreach (var choice in args.Choices) | ||
{ | ||
var newChoice = JsonConvert.DeserializeObject<ListBoxChoice>(choice); | ||
_recentCalls.Add(newChoice); | ||
} | ||
|
||
if (onRecentCallsEvent != null) | ||
{ | ||
List<string> calls = new List<string> { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty }; | ||
|
||
for (int i = 0; i <= 4; i++) | ||
{ | ||
if (_recentCalls.Count > i) | ||
{ | ||
calls[i] = _recentCalls[i].Text; | ||
} | ||
else | ||
{ | ||
break; | ||
} | ||
} | ||
onRecentCallsEvent(ComponentName, calls[0], calls[1], calls[2], calls[3], calls[4]); | ||
} | ||
if (onRecentCallListEvent != null) | ||
{ | ||
List<string> calls = new List<string>(); | ||
|
||
foreach (var call in calls) | ||
{ | ||
|
||
var encodedBytes = XSig.GetBytes(calls.IndexOf(call), call); | ||
onRecentCallListEvent(ComponentName, Encoding.GetEncoding(28591).GetString(encodedBytes, 0, encodedBytes.Length)); | ||
} | ||
} | ||
|
||
break; | ||
} | ||
} | ||
|
||
public void NumPad(string number) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
_dialString.Append(number); | ||
|
||
if (_hookState) | ||
Component.SendChangeDoubleValue(string.Format("call_pinpad_{0}", number), 1); | ||
|
||
if (onDialingEvent != null) | ||
onDialStringEvent(ComponentName, _dialString.ToString()); | ||
} | ||
|
||
public void NumString(string number) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
if (_hookState) | ||
return; | ||
|
||
_dialString.Append(number); | ||
|
||
if (onDialingEvent != null) | ||
onDialStringEvent(ComponentName, _dialString.ToString()); | ||
} | ||
|
||
public void NumPadDelete() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
if (_dialString.Length == 0) | ||
return; | ||
|
||
_dialString.Remove(_dialString.Length - 1, 1); | ||
|
||
if (onDialingEvent != null) | ||
onDialStringEvent(ComponentName, _dialString.ToString()); | ||
} | ||
|
||
public void NumPadClear() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
if (_dialString.Length == 0) | ||
return; | ||
|
||
_dialString.Remove(0, _dialString.Length); | ||
|
||
if (onDialingEvent != null) | ||
onDialStringEvent(ComponentName, _dialString.ToString()); | ||
} | ||
|
||
public void Dial() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
_currentlyCalling = _dialString.ToString(); | ||
_dialString.Remove(0, _dialString.Length); | ||
|
||
DialNow(); | ||
} | ||
|
||
public void Dial(string number) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
_currentlyCalling = _dialString.ToString() + number; | ||
_dialString.Remove(0, _dialString.Length); | ||
|
||
DialNow(); | ||
} | ||
|
||
private void DialNow() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
var callback = onDialStringEvent; | ||
if (callback != null) | ||
callback(ComponentName, string.Empty); | ||
|
||
Component.SendChangeStringValue(CONTROL_CALL_NUMBER, _currentlyCalling); | ||
|
||
Connect(); | ||
} | ||
|
||
public void Connect() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
Component.SendChangeDoubleValue(CONTROL_CALL_CONNECT, 1); | ||
} | ||
|
||
public void Disconnect() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
Component.SendChangeDoubleValue(CONTROL_CALL_DISCONNECT, 1); | ||
} | ||
|
||
public void Redial() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
_dialString.Remove(0, _dialString.Length); | ||
_dialString.Append(_lastCalled); | ||
Dial(); | ||
} | ||
|
||
public void AutoAnswerToggle() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
Component.SendChangeDoubleValue(CONTROL_CALL_AUTOANSWER, Convert.ToDouble(!_autoAnswer)); | ||
} | ||
|
||
public void DndToggle() | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
Component.SendChangeDoubleValue(CONTROL_CALL_DND, Convert.ToDouble(!_dnd)); | ||
} | ||
|
||
public void SelectRecentCall(int index) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
if (_recentCalls.Count < index) | ||
return; | ||
|
||
_dialString.Remove(0, _dialString.Length); | ||
|
||
var call = _recentCalls[index - 1].Text; | ||
|
||
if (call.Contains(' ')) | ||
call = call.Remove(call.IndexOf(' '), call.Length - call.IndexOf(' ')); | ||
|
||
_dialString.Append(call); | ||
|
||
if (onDialStringEvent != null) | ||
onDialStringEvent(ComponentName, call); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
using System.Collections.Generic; | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public class QsysRoomCombiner : AbstractQsysComponent | ||
{ | ||
public delegate void WallStateChange(SimplSharpString cName, ushort wall, ushort value); | ||
public delegate void RoomCombinedChange(SimplSharpString cName, ushort room, ushort value); | ||
public WallStateChange onWallStateChange { get; set; } | ||
public RoomCombinedChange onRoomCombinedChange { get; set; } | ||
|
||
// Wall Controls Dictionary | ||
private readonly Dictionary<int, NamedComponentControl> _wallControls; | ||
private readonly Dictionary<NamedComponentControl, int> _wallControlsReverse; | ||
|
||
// Room Combined Control Dictionary | ||
private readonly Dictionary<int, NamedComponentControl> _combineControls; | ||
private readonly Dictionary<NamedComponentControl, int> _combineControlsReverse; | ||
|
||
public int WallCount { get; private set; } | ||
|
||
public int RoomCount { get; private set; } | ||
|
||
public QsysRoomCombiner() | ||
{ | ||
_wallControls = new Dictionary<int, NamedComponentControl>(); | ||
_wallControlsReverse = new Dictionary<NamedComponentControl, int>(); | ||
_combineControls = new Dictionary<int, NamedComponentControl>(); | ||
_combineControlsReverse = new Dictionary<NamedComponentControl, int>(); | ||
} | ||
|
||
public void Initialize(string coreId, string componentName, int rooms, int walls) | ||
{ | ||
WallCount = walls; | ||
RoomCount = rooms; | ||
|
||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
lock (_wallControls) | ||
{ | ||
foreach(var control in _wallControls.Values) | ||
UnsubscribeWallControl(control); | ||
_wallControls.Clear(); | ||
_wallControlsReverse.Clear(); | ||
} | ||
|
||
lock (_combineControls) | ||
{ | ||
foreach (var control in _combineControls.Values) | ||
UnsubscribeRoomCombineControl(control); | ||
_combineControls.Clear(); | ||
_combineControlsReverse.Clear(); | ||
} | ||
|
||
if (component == null) | ||
return; | ||
|
||
for (int wallIndex = 1; wallIndex <= WallCount; wallIndex++) | ||
{ | ||
var control = component.LazyLoadComponentControl(ControlNameUtils.GetRoomCombinerWallOpenName(wallIndex)); | ||
_wallControls.Add(wallIndex, control); | ||
_wallControlsReverse.Add(control, wallIndex); | ||
SubscribeWallControl(control); | ||
UpdateWallState(wallIndex, control.State); | ||
} | ||
|
||
for (int roomIndex = 1; roomIndex <= RoomCount; roomIndex++) | ||
{ | ||
var control = component.LazyLoadComponentControl(ControlNameUtils.GetRoomCombinerOutputCombinedName(roomIndex)); | ||
_combineControls.Add(roomIndex, control); | ||
_combineControlsReverse.Add(control, roomIndex); | ||
SubscribeRoomCombineControl(control); | ||
UpdateRoomCombineState(roomIndex, control.State); | ||
} | ||
} | ||
|
||
#region Wall Control Callbacks | ||
|
||
private void SubscribeWallControl(NamedComponentControl wallControl) | ||
{ | ||
if (wallControl == null) | ||
return; | ||
|
||
wallControl.OnStateChanged += WallControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeWallControl(NamedComponentControl wallControl) | ||
{ | ||
if (wallControl == null) | ||
return; | ||
|
||
wallControl.OnStateChanged -= WallControlOnStateChanged; | ||
} | ||
|
||
private void WallControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
var control = sender as NamedComponentControl; | ||
|
||
if (control == null) | ||
return; | ||
|
||
int index; | ||
lock (_wallControls) | ||
{ | ||
if (!_wallControlsReverse.TryGetValue(control, out index)) | ||
return; | ||
} | ||
|
||
UpdateWallState(index, args.Data); | ||
|
||
} | ||
|
||
private void UpdateWallState(int wallIndex, QsysStateData state) | ||
{ | ||
if (state == null) | ||
return; | ||
|
||
var callback = onWallStateChange; | ||
if (callback != null) | ||
callback(ControlNameUtils.GetRoomCombinerWallOpenName(wallIndex), (ushort)wallIndex, | ||
state.BoolValue.BoolToSplus()); | ||
} | ||
|
||
#endregion | ||
|
||
#region Room Control Callbacks | ||
|
||
private void SubscribeRoomCombineControl(NamedComponentControl roomCombineControl) | ||
{ | ||
if (roomCombineControl == null) | ||
return; | ||
|
||
roomCombineControl.OnStateChanged += RoomCombineControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeRoomCombineControl(NamedComponentControl roomCombineControl) | ||
{ | ||
if (roomCombineControl == null) | ||
return; | ||
|
||
roomCombineControl.OnStateChanged -= RoomCombineControlOnStateChanged; | ||
} | ||
|
||
private void RoomCombineControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
var control = sender as NamedComponentControl; | ||
if (control == null) | ||
return; | ||
|
||
int index; | ||
lock (_combineControls) | ||
{ | ||
if (!_combineControlsReverse.TryGetValue(control, out index)) | ||
return; | ||
} | ||
|
||
UpdateRoomCombineState(index, args.Data); | ||
} | ||
|
||
private void UpdateRoomCombineState(int roomIndex, QsysStateData state) | ||
{ | ||
if (state == null) | ||
return; | ||
|
||
var callback = onRoomCombinedChange; | ||
if (callback != null) | ||
callback(ControlNameUtils.GetRoomCombinerOutputCombinedName(roomIndex), (ushort)roomIndex, | ||
state.BoolValue.BoolToSplus()); | ||
} | ||
|
||
#endregion | ||
|
||
public void SetWall(int wall, bool state) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
NamedComponentControl control; | ||
|
||
lock (_wallControls) | ||
{ | ||
if (!_wallControls.TryGetValue(wall, out control)) | ||
return; | ||
} | ||
|
||
control.SendChangeBoolValue(state); | ||
} | ||
|
||
public void SetWall(ushort wall, ushort value) | ||
{ | ||
SetWall(wall, value.BoolFromSplus()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
using System; | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public sealed class QsysRouter : AbstractQsysComponent | ||
{ | ||
public delegate void RouterInputChange(SimplSharpString cName, ushort input); | ||
public delegate void MuteChange(SimplSharpString cName, ushort value); | ||
public RouterInputChange newRouterInputChange { get; set; } | ||
public MuteChange newOutputMuteChange { get; set; } | ||
|
||
private int _output; | ||
private int _currentSelectedInput; | ||
private bool _currentMute; | ||
|
||
private NamedComponentControl _inputControl; | ||
private NamedComponentControl _muteControl; | ||
|
||
public int CurrentSelectedInput { get { return _currentSelectedInput; } } | ||
public int Output { get { return _output; } } | ||
public bool CurrentMute {get { return _currentMute; } } | ||
|
||
public NamedComponentControl InputControl | ||
{ | ||
get { return _inputControl; } | ||
private set | ||
{ | ||
if (_inputControl == value) | ||
return; | ||
|
||
UnsubscribeInputControl(_inputControl); | ||
_inputControl = value; | ||
SubscribeInputControl(_inputControl); | ||
} | ||
} | ||
|
||
public NamedComponentControl MuteControl | ||
{ | ||
get { return _muteControl; } | ||
private set | ||
{ | ||
if (_muteControl == value) | ||
return; | ||
|
||
UnsubscribeMuteControl(_muteControl); | ||
_muteControl = value; | ||
SubscribeMuteControl(_muteControl); | ||
} | ||
} | ||
|
||
public void Initialize(string coreId, string componentName, int output) | ||
{ | ||
_output = output; | ||
|
||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
if (component == null) | ||
{ | ||
InputControl = null; | ||
MuteControl = null; | ||
return; | ||
} | ||
|
||
InputControl = component.LazyLoadComponentControl(ControlNameUtils.GetRouterSelectName(_output)); | ||
MuteControl = component.LazyLoadComponentControl(ControlNameUtils.GetRouterMuteName(_output)); | ||
} | ||
|
||
public void InputSelect(int input) | ||
{ | ||
if (InputControl != null) | ||
InputControl.SendChangeDoubleValue(input); | ||
} | ||
|
||
public void OutputMute(bool value) | ||
{ | ||
if (MuteControl != null) | ||
MuteControl.SendChangeBoolValue(value); | ||
} | ||
|
||
/// <summary> | ||
/// Sets the current mute state. | ||
/// </summary> | ||
/// <param name="value">The state to set the mute.</param> | ||
public void OutputMute(ushort value) | ||
{ | ||
OutputMute(value.BoolFromSplus()); | ||
} | ||
|
||
#region Input Control Callbacks | ||
|
||
private void SubscribeInputControl(NamedComponentControl inputControl) | ||
{ | ||
if (inputControl == null) | ||
return; | ||
|
||
inputControl.OnStateChanged += InputControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeInputControl(NamedComponentControl inputControl) | ||
{ | ||
if (inputControl == null) | ||
return; | ||
|
||
inputControl.OnStateChanged -= InputControlOnStateChanged; | ||
} | ||
|
||
private void InputControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
_currentSelectedInput = Convert.ToInt16(args.Value); | ||
|
||
var callback = newRouterInputChange; | ||
if (callback != null) | ||
callback(ComponentName, Convert.ToUInt16(_currentSelectedInput)); | ||
} | ||
|
||
#endregion | ||
|
||
#region Mute Control Callbacks | ||
|
||
private void SubscribeMuteControl(NamedComponentControl muteControl) | ||
{ | ||
if (muteControl == null) | ||
return; | ||
|
||
muteControl.OnStateChanged += MuteControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeMuteControl(NamedComponentControl muteControl) | ||
{ | ||
if (muteControl == null) | ||
return; | ||
|
||
muteControl.OnStateChanged -= MuteControlOnStateChanged; | ||
} | ||
|
||
private void MuteControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
_currentMute = args.BoolValue; | ||
|
||
var callback = newOutputMuteChange; | ||
if (callback != null) | ||
callback(ComponentName, _currentMute.BoolToSplus()); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,304 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public class QsysSignalPresence : AbstractQsysComponent | ||
{ | ||
private const int INCREMENT_VALUE = 6553; | ||
|
||
public delegate void SignalPresenceChange(SimplSharpString cName, ushort index, ushort value); | ||
public delegate void PeakThresholdChange(SimplSharpString cName, SimplSharpString value); | ||
public delegate void HoldTimeChange(SimplSharpString cName, SimplSharpString value); | ||
public delegate void InfiniteHoldChange(SimplSharpString cName, ushort value); | ||
public SignalPresenceChange newSignalPresenceChange { get; set; } | ||
public PeakThresholdChange newPeakThresholdChange { get; set; } | ||
public HoldTimeChange newHoldTimeChange { get; set; } | ||
public InfiniteHoldChange newInfiniteHoldChange { get; set; } | ||
|
||
private ushort _count; | ||
public ushort Threshold { get; private set; } | ||
public ushort HoldTime { get; private set; } | ||
public bool InfiniteHoldValue { get; private set; } | ||
|
||
private NamedComponentControl _thresholdControl; | ||
private NamedComponentControl _holdTimeControl; | ||
private NamedComponentControl _infiniteHoldControl; | ||
private readonly Dictionary<NamedComponentControl, int> _signalPresenceControls; | ||
|
||
public NamedComponentControl ThresholdControl | ||
{ | ||
get { return _thresholdControl; } | ||
private set | ||
{ | ||
if (_thresholdControl == value) | ||
return; | ||
|
||
UnsubscribeThresholdControl(_thresholdControl); | ||
_thresholdControl = value; | ||
SubscribeThresholdControl(_thresholdControl); | ||
} | ||
} | ||
|
||
public NamedComponentControl HoldTimeControl | ||
{ | ||
get { return _holdTimeControl; } | ||
private set | ||
{ | ||
if (_holdTimeControl == value) | ||
return; | ||
|
||
UnsubscribeHoldTimeControl(_holdTimeControl); | ||
_holdTimeControl = value; | ||
SubscribeHoldTimeControl(_holdTimeControl); | ||
} | ||
} | ||
|
||
public NamedComponentControl InfiniteHoldControl | ||
{ | ||
get { return _infiniteHoldControl; } | ||
private set | ||
{ | ||
if (_infiniteHoldControl == value) | ||
return; | ||
|
||
UnsubscribeInfiniteHoldControl(_infiniteHoldControl); | ||
_infiniteHoldControl = value; | ||
SubscribeInfiniteHoldControl(_infiniteHoldControl); | ||
} | ||
} | ||
|
||
public QsysSignalPresence() | ||
{ | ||
_signalPresenceControls = new Dictionary<NamedComponentControl, int>(); | ||
} | ||
|
||
|
||
public void Initialize(string coreId, string componentName, ushort count) | ||
{ | ||
_count = count; | ||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
lock (_signalPresenceControls) | ||
{ | ||
ThresholdControl = null; | ||
HoldTimeControl = null; | ||
InfiniteHoldControl = null; | ||
|
||
foreach (var control in _signalPresenceControls.Keys) | ||
UnsubscribeSignalPresenceControl(control); | ||
_signalPresenceControls.Clear(); | ||
|
||
if (component == null) | ||
return; | ||
|
||
ThresholdControl = component.LazyLoadComponentControl(ControlNameUtils.GetThresholdControlName()); | ||
HoldTimeControl = component.LazyLoadComponentControl(ControlNameUtils.GetHoldTimeControlName()); | ||
InfiniteHoldControl = component.LazyLoadComponentControl(ControlNameUtils.GetInfiniteHoldControlName()); | ||
|
||
for (int i = 1; i <= _count; i++) | ||
{ | ||
var control = component.LazyLoadComponentControl(ControlNameUtils.GetSignalPresenceMeterName(i, _count)); | ||
_signalPresenceControls.Add(control, i); | ||
SubscribeSignalPresenceControl(control); | ||
} | ||
} | ||
} | ||
|
||
#region S+ Control | ||
|
||
public void ThresholdIncrement() | ||
{ | ||
if (ThresholdControl == null) | ||
return; | ||
|
||
double newThreshold = SimplUtils.ScaleToDouble(Math.Min((Threshold + INCREMENT_VALUE), ushort.MaxValue)); | ||
ThresholdControl.SendChangePosition(newThreshold); | ||
} | ||
|
||
public void ThresholdDecrement() | ||
{ | ||
if (ThresholdControl == null) | ||
return; | ||
|
||
double newThreshold = SimplUtils.ScaleToDouble(Math.Max(Threshold - INCREMENT_VALUE, ushort.MinValue)); | ||
ThresholdControl.SendChangePosition(newThreshold); | ||
} | ||
|
||
public void HoldTimeIncrement() | ||
{ | ||
if (HoldTimeControl == null) | ||
return; | ||
|
||
double newHoldtime = SimplUtils.ScaleToDouble(Math.Min(HoldTime + INCREMENT_VALUE, ushort.MaxValue)); | ||
HoldTimeControl.SendChangePosition(newHoldtime); | ||
} | ||
|
||
public void HoldTimeDecrement() | ||
{ | ||
if (HoldTimeControl == null) | ||
return; | ||
|
||
double newHoldtime = SimplUtils.ScaleToDouble(Math.Max(HoldTime - INCREMENT_VALUE, ushort.MinValue)); | ||
HoldTimeControl.SendChangePosition(newHoldtime); | ||
} | ||
|
||
public void InfiniteHold(bool value) | ||
{ | ||
if (InfiniteHoldControl != null) | ||
InfiniteHoldControl.SendChangeDoubleValue(Convert.ToDouble(value)); | ||
} | ||
|
||
public void InfiniteHold(ushort value) | ||
{ | ||
if (Component == null) | ||
return; | ||
|
||
switch (value) | ||
{ | ||
case (0): | ||
InfiniteHold(false); | ||
break; | ||
case (1): | ||
InfiniteHold(true); | ||
break; | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region Threshold Control Callbacks | ||
|
||
private void SubscribeThresholdControl(NamedComponentControl thresholdControl) | ||
{ | ||
if (thresholdControl == null) | ||
return; | ||
|
||
thresholdControl.OnStateChanged += ThresholdControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeThresholdControl(NamedComponentControl thresholdControl) | ||
{ | ||
if (thresholdControl == null) | ||
return; | ||
|
||
thresholdControl.OnStateChanged -= ThresholdControlOnStateChanged; | ||
} | ||
|
||
private void ThresholdControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
Threshold = SimplUtils.ScaleToUshort(args.Position); | ||
|
||
var callback = newPeakThresholdChange; | ||
if (callback != null) | ||
callback(ComponentName, args.StringValue); | ||
} | ||
|
||
#endregion | ||
|
||
#region HoldTime Control Callbacks | ||
|
||
private void SubscribeHoldTimeControl(NamedComponentControl holdTimeControl) | ||
{ | ||
if (holdTimeControl == null) | ||
return; | ||
|
||
holdTimeControl.OnStateChanged += HoldTimeControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeHoldTimeControl(NamedComponentControl holdTimeControl) | ||
{ | ||
if (holdTimeControl == null) | ||
return; | ||
|
||
holdTimeControl.OnStateChanged -= HoldTimeControlOnStateChanged; | ||
} | ||
|
||
private void HoldTimeControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
HoldTime = SimplUtils.ScaleToUshort(args.Position); | ||
|
||
var callback = newHoldTimeChange; | ||
if (callback != null) | ||
callback(ComponentName, args.StringValue); | ||
} | ||
|
||
#endregion | ||
|
||
#region Infinite Hold Control Callbacks | ||
|
||
private void SubscribeInfiniteHoldControl(NamedComponentControl infiniteHoldControl) | ||
{ | ||
if (infiniteHoldControl == null) | ||
return; | ||
|
||
infiniteHoldControl.OnStateChanged += InfiniteHoldControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeInfiniteHoldControl(NamedComponentControl infiniteHoldControl) | ||
{ | ||
if (infiniteHoldControl == null) | ||
return; | ||
|
||
infiniteHoldControl.OnStateChanged -= InfiniteHoldControlOnStateChanged; | ||
} | ||
|
||
private void InfiniteHoldControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
InfiniteHoldValue = args.BoolValue; | ||
|
||
var callback = newInfiniteHoldChange; | ||
if (callback != null) | ||
callback(ComponentName, InfiniteHoldValue.BoolToSplus()); | ||
} | ||
|
||
#endregion | ||
|
||
#region Signal Presence Control Callbacks | ||
|
||
private void SubscribeSignalPresenceControl(NamedComponentControl signalPresenceControl) | ||
{ | ||
if (signalPresenceControl == null) | ||
return; | ||
|
||
signalPresenceControl.OnStateChanged += SignalPresenceControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeSignalPresenceControl(NamedComponentControl signalPresenceControl) | ||
{ | ||
if (signalPresenceControl == null) | ||
return; | ||
|
||
signalPresenceControl.OnStateChanged -= SignalPresenceControlOnStateChanged; | ||
} | ||
|
||
private void SignalPresenceControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
var control = sender as NamedComponentControl; | ||
|
||
if (control == null) | ||
return; | ||
|
||
int index; | ||
lock (_signalPresenceControls) | ||
{ | ||
if (!_signalPresenceControls.TryGetValue(control, out index)) | ||
return; | ||
} | ||
|
||
var callback = newSignalPresenceChange; | ||
if (callback != null) | ||
callback(ComponentName, (ushort)index, args.BoolValue.BoolToSplus()); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
| ||
using System.Collections.Generic; | ||
using Crestron.SimplSharp; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedComponents | ||
{ | ||
public class QsysSnapshot : AbstractQsysComponent | ||
{ | ||
public delegate void SnapshotUpdate(SimplSharpString cName, ushort snapshot); | ||
|
||
public SnapshotUpdate onRecalledSnapshot { get; set; } | ||
public SnapshotUpdate onUnrecalledSnapshot { get; set; } | ||
|
||
private readonly Dictionary<NamedComponentControl, int> _snapshotControls; | ||
|
||
public int SnapshotCount { get; private set; } | ||
|
||
public QsysSnapshot() | ||
{ | ||
_snapshotControls = new Dictionary<NamedComponentControl, int>(); | ||
} | ||
|
||
public void Initialize(string coreId, string componentName, ushort snapshotCount) | ||
{ | ||
SnapshotCount = snapshotCount; | ||
InternalInitialize(coreId, componentName); | ||
} | ||
|
||
protected override void HandleComponentUpdated(NamedComponent component) | ||
{ | ||
base.HandleComponentUpdated(component); | ||
|
||
lock (_snapshotControls) | ||
{ | ||
foreach (var control in _snapshotControls.Keys) | ||
UnsubscribeSnapshotControl(control); | ||
_snapshotControls.Clear(); | ||
|
||
if (component == null) | ||
return; | ||
|
||
for (int i = 1; i <= SnapshotCount; i++) | ||
{ | ||
var control = component.LazyLoadComponentControl(ControlNameUtils.GetSnapshotLoadControlName(i)); | ||
_snapshotControls.Add(control, i); | ||
SubscribeSnapshotControl(control); | ||
} | ||
} | ||
} | ||
|
||
#region Snapshot Control Callbacks | ||
|
||
private void SubscribeSnapshotControl(NamedComponentControl snapshotControl) | ||
{ | ||
if (snapshotControl == null) | ||
return; | ||
|
||
snapshotControl.OnStateChanged += SnapshotControlOnStateChanged; | ||
} | ||
|
||
private void UnsubscribeSnapshotControl(NamedComponentControl snapshotControl) | ||
{ | ||
if (snapshotControl == null) | ||
return; | ||
|
||
snapshotControl.OnStateChanged -= SnapshotControlOnStateChanged; | ||
} | ||
|
||
private void SnapshotControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
var control = sender as NamedComponentControl; | ||
if (control == null) | ||
return; | ||
|
||
int index; | ||
|
||
lock (_snapshotControls) | ||
{ | ||
if (!_snapshotControls.TryGetValue(control, out index)) | ||
return; | ||
} | ||
|
||
bool state = args.BoolValue; | ||
|
||
var callback = state ? onRecalledSnapshot : onUnrecalledSnapshot; | ||
if (callback != null) | ||
callback(ComponentName, (ushort)index); | ||
|
||
} | ||
|
||
#endregion | ||
|
||
public void LoadSnapshot(ushort number) | ||
{ | ||
if (Component != null) | ||
Component.SendChangeDoubleValue(ControlNameUtils.GetSnapshotLoadControlName(number), 1); | ||
} | ||
|
||
public void SaveSnapshot(ushort number) | ||
{ | ||
if (Component != null) | ||
Component.SendChangeDoubleValue(ControlNameUtils.GetSnapshotSaveControlName(number), 1); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace QscQsys.NamedComponents | ||
{ | ||
public class QsysSoftphoneController : QsysPotsController | ||
{ | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Crestron.SimplSharp; | ||
using ExtensionMethods; | ||
using JetBrains.Annotations; | ||
using QscQsys.Intermediaries; | ||
using QscQsys.Utils; | ||
|
||
namespace QscQsys.NamedControls | ||
{ | ||
[PublicAPI("S+")] | ||
public sealed class QsysNamedControl: IDisposable | ||
{ | ||
public delegate void NamedControlUIntChange(SimplSharpString cName, ushort uIntData); | ||
public delegate void NamedControlIntChange(SimplSharpString cName, short intData); | ||
public delegate void NamedControlStringChange(SimplSharpString cNmae, SimplSharpString stringData); | ||
public delegate void NamdControlListChange(SimplSharpString cName, ushort itemsCount, SimplSharpString xsig); | ||
public delegate void NamedControlListSelectedItem(ushort index, SimplSharpString name); | ||
[PublicAPI("S+")] | ||
public NamedControlUIntChange newNamedControlUIntChange { get; set; } | ||
[PublicAPI("S+")] | ||
public NamedControlIntChange newNamedControlIntChange { get; set; } | ||
[PublicAPI("S+")] | ||
public NamedControlStringChange newNamedControlStringChange { get; set; } | ||
[PublicAPI("S+")] | ||
public NamdControlListChange newNamedControlListChange { get; set; } | ||
[PublicAPI("S+")] | ||
public NamedControlListSelectedItem newNameControlListSelectedItemChange { get; set; } | ||
|
||
private NamedControl _control; | ||
private bool _disposed; | ||
private readonly List<string> _listData; | ||
|
||
[PublicAPI] | ||
public string ControlName { get; private set; } | ||
private string CoreId { get; set; } | ||
private bool IsInitialized { get; set; } | ||
private bool IsInteger { get; set; } | ||
private bool IsList { get; set; } | ||
|
||
public QsysNamedControl() | ||
{ | ||
_listData = new List<string>(); | ||
} | ||
|
||
public NamedControl Control | ||
{ | ||
get { return _control; } | ||
private set | ||
{ | ||
if (_control == value) | ||
return; | ||
|
||
Unsubscribe(_control); | ||
_control = value; | ||
Subscribe(_control); | ||
|
||
if (_control != null) | ||
UpdateState(_control.State); | ||
} | ||
} | ||
|
||
[PublicAPI("S+")] | ||
public void Initialize(string coreId, string name, ushort type) | ||
{ | ||
if (IsInitialized) | ||
return; | ||
IsInitialized = true; | ||
|
||
ControlName = name; | ||
CoreId = coreId; | ||
if (type == 1) | ||
{ | ||
IsInteger = true; | ||
} | ||
else if (type == 2) | ||
{ | ||
IsList = true; | ||
} | ||
|
||
QsysCoreManager.CoreAdded += QsysCoreManager_CoreAdded; | ||
RegisterWithCore(); | ||
} | ||
|
||
#region Set Values | ||
|
||
[PublicAPI("S+")] | ||
public void SetUnsignedInteger(ushort value, ushort scaled) | ||
{ | ||
if (Control == null) | ||
return; | ||
|
||
if (scaled == 1) | ||
Control.SendChangePosition(SimplUtils.ScaleToDouble(value)); | ||
else | ||
Control.SendChangeDoubleValue(value); | ||
} | ||
|
||
[PublicAPI("S+")] | ||
public void SetSignedInteger(int value, ushort scaled) | ||
{ | ||
if (Control == null) | ||
return; | ||
|
||
if (scaled == 1) | ||
Control.SendChangePosition(SimplUtils.ScaleToDouble(value)); | ||
else | ||
Control.SendChangeDoubleValue(value); | ||
} | ||
|
||
[PublicAPI("S+")] | ||
public void SetBoolean(ushort value) | ||
{ | ||
if (Control == null) | ||
return; | ||
|
||
Control.SendChangeBoolValue(value.BoolFromSplus()); | ||
} | ||
|
||
[PublicAPI("S+")] | ||
public void SetString(string value) | ||
{ | ||
if (Control == null) | ||
return; | ||
|
||
Control.SendChangeStringValue(value); | ||
} | ||
|
||
[PublicAPI("S+")] | ||
public void SelectListItem(int index) | ||
{ | ||
if (Control == null) | ||
return; | ||
|
||
if (index < 0 || index > _listData.Count) | ||
return; | ||
|
||
Control.SendChangeStringValue(_listData[index]); | ||
} | ||
|
||
#endregion | ||
|
||
#region Update States | ||
|
||
private void UpdateState(QsysStateData state) | ||
{ | ||
if (state == null) | ||
return; | ||
|
||
if (!IsInteger && !IsList) | ||
{ | ||
UpdateStringState(state); | ||
} | ||
else if (IsInteger) | ||
{ | ||
UpdatateIntegerState(state); | ||
} | ||
else if (IsList) | ||
{ | ||
UpdateListState(state); | ||
} | ||
} | ||
|
||
private void UpdateListState(QsysStateData state) | ||
{ | ||
_listData.Clear(); | ||
_listData.AddRange(state.Choices); | ||
|
||
var listSelectedCallback = newNameControlListSelectedItemChange; | ||
if (listSelectedCallback != null) | ||
{ | ||
listSelectedCallback(Convert.ToUInt16(_listData.FindIndex(x => x == state.StringValue) + 1), | ||
state.StringValue); | ||
} | ||
|
||
var listItemCallback = newNamedControlListChange; | ||
if (listItemCallback != null) | ||
{ | ||
for (int i = 0; i < _listData.Count; i++) | ||
{ | ||
var encodedBytes = XSig.GetBytes(i + 1, _listData[i]); | ||
listItemCallback(ControlName, Convert.ToUInt16(_listData.Count), | ||
Encoding.GetEncoding(28591).GetString(encodedBytes, 0, encodedBytes.Length)); | ||
} | ||
} | ||
} | ||
|
||
private void UpdatateIntegerState(QsysStateData state) | ||
{ | ||
var positionCallback = newNamedControlUIntChange; | ||
var valueCallback = newNamedControlIntChange; | ||
switch (state.Type) | ||
{ | ||
case "position": | ||
|
||
if (positionCallback != null) | ||
positionCallback(ControlName, SimplUtils.ScaleToUshort(state.Position)); | ||
break; | ||
case "value": | ||
|
||
if (valueCallback != null) | ||
valueCallback(ControlName, (short)state.Value); | ||
break; | ||
case "change": | ||
if (positionCallback != null) | ||
positionCallback(ControlName, SimplUtils.ScaleToUshort(state.Position)); | ||
if (valueCallback != null) | ||
valueCallback(ControlName, (short)state.Value); | ||
break; | ||
} | ||
} | ||
|
||
private void UpdateStringState(QsysStateData state) | ||
{ | ||
var stringCallback = newNamedControlStringChange; | ||
if (stringCallback != null) | ||
stringCallback(ControlName, state.StringValue); | ||
} | ||
|
||
#endregion | ||
|
||
#region NamedControl Callbacks | ||
|
||
private void Subscribe(NamedControl control) | ||
{ | ||
if (control == null) | ||
return; | ||
|
||
control.OnStateChanged += ControlOnStateChanged; | ||
} | ||
|
||
private void Unsubscribe(NamedControl control) | ||
{ | ||
if (control == null) | ||
return; | ||
|
||
control.OnStateChanged -= ControlOnStateChanged; | ||
} | ||
|
||
private void ControlOnStateChanged(object sender, QsysInternalEventsArgs args) | ||
{ | ||
UpdateState(args.Data); | ||
} | ||
|
||
#endregion | ||
|
||
#region CoreManager Callbacks | ||
|
||
void QsysCoreManager_CoreAdded(object sender, CoreEventArgs e) | ||
{ | ||
if (e.CoreId == CoreId) | ||
RegisterWithCore(); | ||
} | ||
|
||
private void RegisterWithCore() | ||
{ | ||
Control = null; | ||
|
||
QsysCore core; | ||
if (QsysCoreManager.TryGetCore(CoreId, out core)) | ||
Control = core.LazyLoadNamedControl(ControlName); | ||
} | ||
|
||
#endregion | ||
|
||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
} | ||
|
||
private void Dispose(bool disposing) | ||
{ | ||
if (_disposed) return; | ||
|
||
_disposed = true; | ||
if (disposing) | ||
{ | ||
QsysCoreManager.CoreAdded -= QsysCoreManager_CoreAdded; | ||
Control = null; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.