mirror of
https://github.com/jwetzell/QControlKit.git
synced 2026-08-21 15:09:09 +00:00
TCP Work, Log cleanup, Message parsing
This commit is contained in:
@@ -13,6 +13,8 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
public class QBrowser
|
public class QBrowser
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QBrowser>();
|
||||||
|
|
||||||
public ObservableCollection<QServer> servers = new ObservableCollection<QServer>();
|
public ObservableCollection<QServer> servers = new ObservableCollection<QServer>();
|
||||||
|
|
||||||
public event QServerFoundHandler ServerFound;
|
public event QServerFoundHandler ServerFound;
|
||||||
@@ -26,17 +28,17 @@ namespace QControlKit
|
|||||||
|
|
||||||
public async void ProbeForQLabInstances()
|
public async void ProbeForQLabInstances()
|
||||||
{
|
{
|
||||||
Log.Debug("[qbrowser] probing for instances");
|
_log.Debug("probing for instances");
|
||||||
|
|
||||||
IReadOnlyList<IZeroconfHost> results = await
|
IReadOnlyList<IZeroconfHost> results = await
|
||||||
ZeroconfResolver.ResolveAsync(QBonjour.TCPService,TimeSpan.FromSeconds(3));
|
ZeroconfResolver.ResolveAsync(QBonjour.TCPService,TimeSpan.FromSeconds(3));
|
||||||
|
|
||||||
foreach (var zeroconfHost in results)
|
foreach (var zeroconfHost in results)
|
||||||
{
|
{
|
||||||
Log.Debug($"[qbrowser] found host {zeroconfHost.IPAddress}:{zeroconfHost.DisplayName}");
|
_log.Debug($"found host {zeroconfHost.IPAddress}:{zeroconfHost.DisplayName}");
|
||||||
foreach (var service in zeroconfHost.Services)
|
foreach (var service in zeroconfHost.Services)
|
||||||
{
|
{
|
||||||
Log.Debug($"[qbrowser] found {service.Key}:{service.Value}");
|
_log.Debug($"found {service.Key}:{service.Value}");
|
||||||
if (service.Key.Equals(QBonjour.TCPService))
|
if (service.Key.Equals(QBonjour.TCPService))
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ namespace QControlKit
|
|||||||
|
|
||||||
if (server == null)
|
if (server == null)
|
||||||
{
|
{
|
||||||
Log.Information($"[qbrowser] Found {zeroconfHost.DisplayName} : {zeroconfHost.IPAddress} : {service.Value.Port}");
|
_log.Information($"Found {zeroconfHost.DisplayName} : {zeroconfHost.IPAddress} : {service.Value.Port}");
|
||||||
QServer serverToAdd = new QServer(zeroconfHost.IPAddress, service.Value.Port);
|
QServer serverToAdd = new QServer(zeroconfHost.IPAddress, service.Value.Port);
|
||||||
serverToAdd.name = zeroconfHost.DisplayName;
|
serverToAdd.name = zeroconfHost.DisplayName;
|
||||||
serverToAdd.zeroconfHost = zeroconfHost;
|
serverToAdd.zeroconfHost = zeroconfHost;
|
||||||
@@ -70,9 +72,9 @@ namespace QControlKit
|
|||||||
|
|
||||||
if (found == null)
|
if (found == null)
|
||||||
{
|
{
|
||||||
Log.Information($"[qbrowser] Lost {server.name} : {server.host} : {server.port} disconnecting");
|
_log.Information($"Lost {server.name} : {server.host} : {server.port} disconnecting");
|
||||||
server.disconnect();
|
server.disconnect();
|
||||||
Log.Verbose($"[qbrowser] after server disconnect()");
|
_log.Verbose($"after server disconnect()");
|
||||||
servers.Remove(server);
|
servers.Remove(server);
|
||||||
OnServerLost(server);
|
OnServerLost(server);
|
||||||
}
|
}
|
||||||
@@ -122,7 +124,7 @@ namespace QControlKit
|
|||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Log.Information($"[qbrowser] Close requested");
|
_log.Information($"Close requested");
|
||||||
foreach (var server in servers)
|
foreach (var server in servers)
|
||||||
{
|
{
|
||||||
server.disconnect();
|
server.disconnect();
|
||||||
|
|||||||
+24
-24
@@ -12,6 +12,8 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
public class QClient
|
public class QClient
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QClient>();
|
||||||
|
|
||||||
TCPClient tcpClient;
|
TCPClient tcpClient;
|
||||||
|
|
||||||
public event QWorkspacesUpdatedHandler WorkspacesUpdated;
|
public event QWorkspacesUpdatedHandler WorkspacesUpdated;
|
||||||
@@ -35,7 +37,7 @@ namespace QControlKit
|
|||||||
public QClient(string host, int port)
|
public QClient(string host, int port)
|
||||||
{
|
{
|
||||||
tcpClient = new TCPClient(host, port);
|
tcpClient = new TCPClient(host, port);
|
||||||
Log.Debug($"[client] setup connection to: <{host}:{port}>");
|
_log.Debug($"setup connection to: <{host}:{port}>");
|
||||||
tcpClient.MessageReceived += ProcessMessage;
|
tcpClient.MessageReceived += ProcessMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,15 +54,15 @@ namespace QControlKit
|
|||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
Log.Information($"[client] disconnecting from {tcpClient.Address}");
|
_log.Information($"disconnecting from {tcpClient.Address}");
|
||||||
tcpClient.Close();
|
tcpClient.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void sendMessage(string address, params object[] args)
|
public void sendMessage(string address, params object[] args)
|
||||||
{
|
{
|
||||||
tcpClient.QueueForSending(new OscMessage(address, args));
|
tcpClient.Send(new OscMessage(address, args));
|
||||||
Log.Information($"[client] send message {address} : {args}");
|
_log.Debug($"send message {address} : {args}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessMessage(object source, MessageEventArgs args)
|
private void ProcessMessage(object source, MessageEventArgs args)
|
||||||
@@ -87,20 +89,19 @@ namespace QControlKit
|
|||||||
string property = message.AddressParts.Last();
|
string property = message.AddressParts.Last();
|
||||||
if (property == null)
|
if (property == null)
|
||||||
return;
|
return;
|
||||||
if (property == QOSCKey.PlaybackPositionId)
|
|
||||||
{
|
|
||||||
OnCueListChangedPlaybackPosition(message.cueID, data.ToString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//create object manually since single value replies don't have dictionaries
|
//create object manually since single value replies don't have dictionaries
|
||||||
JObject properties = new JObject();
|
JObject properties = new JObject();
|
||||||
properties.Add(property, data);
|
properties.Add(property, data);
|
||||||
|
|
||||||
OnCueUpdated(message.cueID, properties);
|
OnCueUpdated(message.cueID, properties);
|
||||||
|
if (property == QOSCKey.PlaybackPositionId)
|
||||||
|
{
|
||||||
|
OnCueListChangedPlaybackPosition(message.cueID, data.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error($"[client] unhandled reply from cue: Type: {data.Type} value: {message.response}");
|
_log.Error($"unhandled reply from cue: Type: {data.Type} value: {message.response}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -114,14 +115,14 @@ namespace QControlKit
|
|||||||
}
|
}
|
||||||
else if (message.IsConnect)
|
else if (message.IsConnect)
|
||||||
{
|
{
|
||||||
if (message.response.ToString() == "ok")
|
if (message.response.ToString().Contains("ok"))
|
||||||
OnWorkspaceConnected();
|
OnWorkspaceConnected();
|
||||||
else
|
else
|
||||||
OnWorkspaceConnectionError(message.response.ToString());
|
OnWorkspaceConnectionError(message.response.ToString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error($"[client] unhandled reply message: {message.address}");
|
_log.Error($"unhandled reply message: {message.address}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(message.IsUpdate) {
|
else if(message.IsUpdate) {
|
||||||
@@ -153,7 +154,6 @@ namespace QControlKit
|
|||||||
else if ( message.IsPreferencesUpdate)
|
else if ( message.IsPreferencesUpdate)
|
||||||
{
|
{
|
||||||
//need to do checks for 4.2 or newer
|
//need to do checks for 4.2 or newer
|
||||||
|
|
||||||
string key = message.AddressParts.Last();
|
string key = message.AddressParts.Last();
|
||||||
if (key == null)
|
if (key == null)
|
||||||
return;
|
return;
|
||||||
@@ -165,65 +165,65 @@ namespace QControlKit
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error($"[client] unhandled update message: {message.address}");
|
_log.Error($"unhandled update message: {message.address}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error($"[client] unhandled message: {message.address}");
|
_log.Error($"unhandled message: {message.address}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnCueUpdated(string cueID, JToken properties)
|
protected virtual void OnCueUpdated(string cueID, JToken properties)
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] cue updated: {cueID}");
|
_log.Debug($"cue updated: {cueID}");
|
||||||
CueUpdated?.Invoke(this, new QCueUpdatedArgs { cueID = cueID, data = properties });
|
CueUpdated?.Invoke(this, new QCueUpdatedArgs { cueID = cueID, data = properties });
|
||||||
}
|
}
|
||||||
protected virtual void OnCueNeedsUpdated(string cueID)
|
protected virtual void OnCueNeedsUpdated(string cueID)
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] cue needs updated: {cueID}");
|
_log.Debug($"cue needs updated: {cueID}");
|
||||||
CueNeedsUpdated?.Invoke(this, new QCueNeedsUpdatedArgs { cueID = cueID });
|
CueNeedsUpdated?.Invoke(this, new QCueNeedsUpdatedArgs { cueID = cueID });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnCueListsUpdated(JToken response)
|
protected virtual void OnCueListsUpdated(JToken response)
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] Cue Lists Updated");
|
_log.Debug($"Cue Lists Updated");
|
||||||
CueListsUpdated?.Invoke(this, new QCueListsUpdatedArgs { data = response });
|
CueListsUpdated?.Invoke(this, new QCueListsUpdatedArgs { data = response });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnCueListChangedPlaybackPosition(string cueListID, string cueID)
|
protected virtual void OnCueListChangedPlaybackPosition(string cueListID, string cueID)
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] CueList <{cueListID}> Playback Position Changed to <{cueID}>");
|
_log.Debug($"CueList <{cueListID}> Playback Position Changed to <{cueID}>");
|
||||||
CueListChangedPlaybackPosition?.Invoke(this, new QCueListChangedPlaybackPositionArgs { cueListID = cueListID, cueID = cueID });
|
CueListChangedPlaybackPosition?.Invoke(this, new QCueListChangedPlaybackPositionArgs { cueListID = cueListID, cueID = cueID });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnWorkspaceUpdated()
|
protected virtual void OnWorkspaceUpdated()
|
||||||
{
|
{
|
||||||
//Log.Debug($"[client] Workspace Updated");
|
_log.Debug($"Workspace Updated");
|
||||||
WorkspaceUpdated?.Invoke(this, new QWorkspaceUpdatedArgs());
|
WorkspaceUpdated?.Invoke(this, new QWorkspaceUpdatedArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnWorkspaceSettingsUpdated(string settingsType)
|
protected virtual void OnWorkspaceSettingsUpdated(string settingsType)
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] Workspace Settings Updated");
|
_log.Debug($"Workspace Settings Updated");
|
||||||
WorkspaceSettingsUpdated?.Invoke(this, new QWorkspaceSettingsUpdatedArgs { settingsType = settingsType });
|
WorkspaceSettingsUpdated?.Invoke(this, new QWorkspaceSettingsUpdatedArgs { settingsType = settingsType });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnWorkspaceLightDashboardUpdated()
|
protected virtual void OnWorkspaceLightDashboardUpdated()
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] Workspace Light Dashboard Updated");
|
_log.Debug($"Workspace Light Dashboard Updated");
|
||||||
WorkspaceLightDashboardUpdated?.Invoke(this, new QWorkspaceLightDashboardUpdatedArgs());
|
WorkspaceLightDashboardUpdated?.Invoke(this, new QWorkspaceLightDashboardUpdatedArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnQLabPreferencesUpdated(string key)
|
protected virtual void OnQLabPreferencesUpdated(string key)
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] QLab Preferences Updated");
|
_log.Debug($"QLab Preferences Updated");
|
||||||
QLabPreferencesUpdated?.Invoke(this, new QQLabPreferencesUpdatedArgs { key = key });
|
QLabPreferencesUpdated?.Invoke(this, new QQLabPreferencesUpdatedArgs { key = key });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnWorkspaceDisconnected()
|
protected virtual void OnWorkspaceDisconnected()
|
||||||
{
|
{
|
||||||
Log.Debug($"[client] Workspace Disconnected");
|
_log.Debug($"Workspace Disconnected");
|
||||||
WorkspaceDisconnected?.Invoke(this, new QWorkspaceDisconnectedArgs());
|
WorkspaceDisconnected?.Invoke(this, new QWorkspaceDisconnectedArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="SuperSimpleTcp" Version="3.0.0.2" />
|
<PackageReference Include="SuperSimpleTcp" Version="3.0.5" />
|
||||||
<PackageReference Include="Zeroconf" Version="3.5.11" />
|
<PackageReference Include="Zeroconf" Version="3.5.11" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -32,5 +32,6 @@
|
|||||||
<None Remove="SharpOSC\" />
|
<None Remove="SharpOSC\" />
|
||||||
<None Remove="SimpleTCP" />
|
<None Remove="SimpleTCP" />
|
||||||
<None Remove="SuperSimpleTcp" />
|
<None Remove="SuperSimpleTcp" />
|
||||||
|
<None Remove="WatsonTcp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
+20
-8
@@ -12,6 +12,7 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
public class QCue : IComparable
|
public class QCue : IComparable
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QCue>();
|
||||||
|
|
||||||
public QWorkspace workspace;
|
public QWorkspace workspace;
|
||||||
public Dictionary<string, object> cueData;
|
public Dictionary<string, object> cueData;
|
||||||
@@ -162,7 +163,7 @@ namespace QControlKit
|
|||||||
|
|
||||||
QCue cue = childCuesUIDMap[aUid];
|
QCue cue = childCuesUIDMap[aUid];
|
||||||
|
|
||||||
//Log.Debug($"Removing Child Cue From {listName} : {cue.uid} + {cue.listName}");
|
//_log.Debug($"Removing Child Cue From {listName} : {cue.uid} + {cue.listName}");
|
||||||
childCues.Remove(cue);
|
childCues.Remove(cue);
|
||||||
childCuesUIDMap.Remove(aUid);
|
childCuesUIDMap.Remove(aUid);
|
||||||
}
|
}
|
||||||
@@ -639,6 +640,8 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
bool cueUpdated = false;
|
bool cueUpdated = false;
|
||||||
|
|
||||||
|
_log.Verbose($"updatePropertiesWithDictionary() Called for cue");
|
||||||
|
|
||||||
//TODO: pretty sure this is done
|
//TODO: pretty sure this is done
|
||||||
JObject dictObj = (JObject)dict;
|
JObject dictObj = (JObject)dict;
|
||||||
List<string> propertiesUpdated = new List<string>();
|
List<string> propertiesUpdated = new List<string>();
|
||||||
@@ -647,14 +650,14 @@ namespace QControlKit
|
|||||||
JToken value = obj.Value;
|
JToken value = obj.Value;
|
||||||
if (obj.Key.Equals(QOSCKey.Cues))
|
if (obj.Key.Equals(QOSCKey.Cues))
|
||||||
{
|
{
|
||||||
//Log.Debug($"Cues OSC Key found in update message...updating child cues");
|
//_log.Debug($"Cues OSC Key found in update message...updating child cues");
|
||||||
if (value.Type != JTokenType.Array)
|
if (value.Type != JTokenType.Array)
|
||||||
continue;
|
continue;
|
||||||
updateChildCuesWithPropertiesArray(value, false);
|
updateChildCuesWithPropertiesArray(value, false);
|
||||||
}
|
}
|
||||||
else if(obj.Key.Equals(QOSCKey.Children) && IsGroup)
|
else if(obj.Key.Equals(QOSCKey.Children) && IsGroup)
|
||||||
{
|
{
|
||||||
//Log.Debug($"Children OSC Key found in update message for {uid} ...updating child and removing deleted ones.");
|
//_log.Debug($"Children OSC Key found in update message for {uid} ...updating child and removing deleted ones.");
|
||||||
if (value.Type != JTokenType.Array)
|
if (value.Type != JTokenType.Array)
|
||||||
continue;
|
continue;
|
||||||
updateChildCuesWithPropertiesArray(value, true);
|
updateChildCuesWithPropertiesArray(value, true);
|
||||||
@@ -668,7 +671,7 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
cueUpdated = true;
|
cueUpdated = true;
|
||||||
propertiesUpdated.Add(obj.Key);
|
propertiesUpdated.Add(obj.Key);
|
||||||
//Log.Debug($"[cue] cue property {obj.Key} updated with {obj.Value}");
|
//_log.Debug($"cue property {obj.Key} updated with {obj.Value}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -803,7 +806,7 @@ namespace QControlKit
|
|||||||
if (propertyForKey(key) != null)
|
if (propertyForKey(key) != null)
|
||||||
{
|
{
|
||||||
object prop = propertyForKey(key);
|
object prop = propertyForKey(key);
|
||||||
//Log.Warning($"{listName} IsBroken: {propertyForKey(QOSCKey.IsBroken).ToString()} {prop.GetType().ToString()}");
|
//_log.Warning($"{listName} IsBroken: {propertyForKey(QOSCKey.IsBroken).ToString()} {prop.GetType().ToString()}");
|
||||||
if(prop.GetType() == typeof(Boolean)){
|
if(prop.GetType() == typeof(Boolean)){
|
||||||
return (bool)prop;
|
return (bool)prop;
|
||||||
}
|
}
|
||||||
@@ -893,7 +896,7 @@ namespace QControlKit
|
|||||||
}
|
}
|
||||||
else if (key.Equals(QOSCKey.Children))
|
else if (key.Equals(QOSCKey.Children))
|
||||||
{
|
{
|
||||||
Log.Debug($"Children Cues property updated for: {this.displayName} : {this.uid}");
|
_log.Debug($"Children Cues property updated for: {this.displayName} : {this.uid}");
|
||||||
}
|
}
|
||||||
else if(key.Equals(QOSCKey.PlaybackPositionId))
|
else if(key.Equals(QOSCKey.PlaybackPositionId))
|
||||||
{
|
{
|
||||||
@@ -992,9 +995,18 @@ namespace QControlKit
|
|||||||
#region Event Handling
|
#region Event Handling
|
||||||
void OnCuePropertiesUpdated(List<string> properties)
|
void OnCuePropertiesUpdated(List<string> properties)
|
||||||
{
|
{
|
||||||
|
_log.Verbose("OnCuePropertiesUpdated");
|
||||||
if(parentID != null && parentID != "")
|
if(parentID != null && parentID != "")
|
||||||
{
|
{
|
||||||
workspace.fetchBasicPropertiesForCue(workspace.cueWithID(parentID));
|
QCue parentCue = workspace.cueWithID(parentID);
|
||||||
|
if(parentCue != null)
|
||||||
|
{
|
||||||
|
workspace.fetchBasicPropertiesForCue(workspace.cueWithID(parentID));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_log.Verbose($"parent cue with id: {parentID} can't be found this could be a problem");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CuePropertiesUpdated?.Invoke(this, new QCuePropertiesUpdatedArgs { properties = properties });
|
CuePropertiesUpdated?.Invoke(this, new QCuePropertiesUpdatedArgs { properties = properties });
|
||||||
}
|
}
|
||||||
@@ -1011,7 +1023,7 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
string indent = new string(' ', level*2);
|
string indent = new string(' ', level*2);
|
||||||
|
|
||||||
Log.Information($"{indent}\u00b7{displayName} - {uid}");
|
_log.Information($"{indent}\u00b7{displayName} - {uid}");
|
||||||
if (IsGroup)
|
if (IsGroup)
|
||||||
{
|
{
|
||||||
level++;
|
level++;
|
||||||
|
|||||||
+11
-6
@@ -10,11 +10,13 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
public class QServer
|
public class QServer
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QServer>();
|
||||||
|
|
||||||
public event QServerUpdatedHandler ServerUpdated;
|
public event QServerUpdatedHandler ServerUpdated;
|
||||||
public event QServerWorkspaceAddedHandler WorkspaceAdded;
|
public event QServerWorkspaceAddedHandler WorkspaceAdded;
|
||||||
public event QServerWorkspaceRemovedHandler WorkspaceRemoved;
|
public event QServerWorkspaceRemovedHandler WorkspaceRemoved;
|
||||||
|
|
||||||
private QClient client;
|
private QClient _client;
|
||||||
|
|
||||||
public string host { get; set; }
|
public string host { get; set; }
|
||||||
public int port { get; set; }
|
public int port { get; set; }
|
||||||
@@ -28,18 +30,21 @@ namespace QControlKit
|
|||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
|
|
||||||
client = new QClient(host, port);
|
_client = new QClient(host, port);
|
||||||
client.WorkspacesUpdated += OnServerWorkspacesUpdated;
|
client.WorkspacesUpdated += OnServerWorkspacesUpdated;
|
||||||
|
|
||||||
if (!client.connect())
|
if (!client.connect())
|
||||||
{
|
{
|
||||||
Log.Error($"[server] unable to connect to QLab Server: {host}:{port}");
|
_log.Error($"unable to connect to QLab Server: {host}:{port}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string description { get { return $"{name} - {host} - {port}"; } }
|
public string description { get { return $"{name} - {host} - {port}"; } }
|
||||||
|
|
||||||
|
public QClient client {
|
||||||
|
get { return _client; }
|
||||||
|
}
|
||||||
|
|
||||||
public void refreshWorkspaces()
|
public void refreshWorkspaces()
|
||||||
{
|
{
|
||||||
client.sendMessage("/workspaces");
|
client.sendMessage("/workspaces");
|
||||||
@@ -111,12 +116,12 @@ namespace QControlKit
|
|||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
Log.Information($"[server] disconnect requested for server <{name}>");
|
_log.Information($"disconnect requested for server <{name}>");
|
||||||
foreach (var workspace in workspaces)
|
foreach (var workspace in workspaces)
|
||||||
{
|
{
|
||||||
if (workspace.connected)
|
if (workspace.connected)
|
||||||
{
|
{
|
||||||
Log.Debug($"[server] Closing workspace <{workspace.name}> still connected to {name}");
|
_log.Debug($"Closing workspace <{workspace.name}> still connected to {name}");
|
||||||
workspace.disconnect();
|
workspace.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-15
@@ -10,6 +10,7 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
public class QWorkspace: IEquatable<QWorkspace>
|
public class QWorkspace: IEquatable<QWorkspace>
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QWorkspace>();
|
||||||
|
|
||||||
private QServer server;
|
private QServer server;
|
||||||
private QClient client;
|
private QClient client;
|
||||||
@@ -64,7 +65,7 @@ namespace QControlKit
|
|||||||
|
|
||||||
updateWithWorkspaceInfo(workspaceInfo);
|
updateWithWorkspaceInfo(workspaceInfo);
|
||||||
|
|
||||||
client = new QClient(server.host, server.port);
|
client = server.client;
|
||||||
|
|
||||||
client.WorkspaceConnected += OnWorkspaceConnected;
|
client.WorkspaceConnected += OnWorkspaceConnected;
|
||||||
client.WorkspaceConnectionError += OnWorkspaceConnectionError;
|
client.WorkspaceConnectionError += OnWorkspaceConnectionError;
|
||||||
@@ -75,7 +76,7 @@ namespace QControlKit
|
|||||||
client.CueUpdated += OnCueUpdated;
|
client.CueUpdated += OnCueUpdated;
|
||||||
|
|
||||||
this.server = server;
|
this.server = server;
|
||||||
Log.Debug($"[workspace] <{name}> on <{server.name}> initialized.");
|
_log.Debug($"<{name}> on <{server.name}> initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//updateWithDictionary
|
//updateWithDictionary
|
||||||
@@ -164,18 +165,18 @@ namespace QControlKit
|
|||||||
|
|
||||||
public void connect(string passcode = null)
|
public void connect(string passcode = null)
|
||||||
{
|
{
|
||||||
Log.Information($"[workspace] connecting to <{name}> @ {this.server.host}:{this.server.port}");
|
_log.Information($"connecting to <{name}> @ {this.server.host}:{this.server.port}");
|
||||||
|
|
||||||
if(hasPasscode && passcode == null)
|
if(hasPasscode && passcode == null)
|
||||||
{
|
{
|
||||||
Log.Error($"[workspace] *** workspace <{name}> requires a passcode but none was supplied.");
|
_log.Error($"*** workspace <{name}> requires a passcode but none was supplied.");
|
||||||
OnWorkspaceConnectionError(this, new QWorkspaceConnectionErrorArgs { status = QConnectionStatus.BadPass });
|
OnWorkspaceConnectionError(this, new QWorkspaceConnectionErrorArgs { status = QConnectionStatus.BadPass });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!client.connect())
|
if (!client.connect())
|
||||||
{
|
{
|
||||||
Log.Error($"[workspace] *** couldn't connect to server client is not connected.");
|
_log.Error($"*** couldn't connect to server client is not connected.");
|
||||||
OnWorkspaceConnectionError(this, new QWorkspaceConnectionErrorArgs { status = QConnectionStatus.Error });
|
OnWorkspaceConnectionError(this, new QWorkspaceConnectionErrorArgs { status = QConnectionStatus.Error });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -210,7 +211,7 @@ namespace QControlKit
|
|||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
Log.Information($"[workspace] disconnecting from <{name}>");
|
_log.Information($"disconnecting from <{name}>");
|
||||||
if (!connected)
|
if (!connected)
|
||||||
return;
|
return;
|
||||||
stopReceivingUpdates();
|
stopReceivingUpdates();
|
||||||
@@ -417,11 +418,11 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
//clear passcode if there was one set in the connect() method
|
//clear passcode if there was one set in the connect() method
|
||||||
this.passcode = null;
|
this.passcode = null;
|
||||||
Log.Error($"[workspace] *** Password for workspace <{name}> was incorrect!");
|
_log.Error($"*** Password for workspace <{name}> was incorrect!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error($"[workspace] *** Unable to connect to workspace: <{name}> on server: <{server.name}>");
|
_log.Error($"*** Unable to connect to workspace: <{name}> on server: <{server.name}>");
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkspaceConnectionError?.Invoke(this, new QWorkspaceConnectionErrorArgs { status = args.status });
|
WorkspaceConnectionError?.Invoke(this, new QWorkspaceConnectionErrorArgs { status = args.status });
|
||||||
@@ -429,7 +430,7 @@ namespace QControlKit
|
|||||||
|
|
||||||
private void OnWorkspaceConnected(object source, QWorkspaceConnectedArgs args)
|
private void OnWorkspaceConnected(object source, QWorkspaceConnectedArgs args)
|
||||||
{
|
{
|
||||||
Log.Information($"[workspace] Connection to <{name}> successful, finishing things up.");
|
_log.Information($"Connection to <{name}> successful, finishing things up.");
|
||||||
WorkspaceConnected?.Invoke(this, new QWorkspaceConnectedArgs());
|
WorkspaceConnected?.Invoke(this, new QWorkspaceConnectedArgs());
|
||||||
finishConnection();
|
finishConnection();
|
||||||
}
|
}
|
||||||
@@ -437,7 +438,7 @@ namespace QControlKit
|
|||||||
private void OnWorkspaceDisconnected(object source, QWorkspaceDisconnectedArgs args)
|
private void OnWorkspaceDisconnected(object source, QWorkspaceDisconnectedArgs args)
|
||||||
{
|
{
|
||||||
//this might not be called with TCP?
|
//this might not be called with TCP?
|
||||||
Log.Warning($"[workspace] *** Workspace has indicated it is disconnecting");
|
_log.Warning($"*** Workspace has indicated it is disconnecting");
|
||||||
WorkspaceDisconnected?.Invoke(this, new QWorkspaceDisconnectedArgs());
|
WorkspaceDisconnected?.Invoke(this, new QWorkspaceDisconnectedArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,7 +507,7 @@ namespace QControlKit
|
|||||||
//add Event handled? use CueUpdated one?
|
//add Event handled? use CueUpdated one?
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debug($"[workspace] cueLists finished processing. root updated? {rootCueUpdated}");
|
_log.Debug($"cueLists finished processing. root updated? {rootCueUpdated}");
|
||||||
|
|
||||||
|
|
||||||
OnWorkspaceUpdated();
|
OnWorkspaceUpdated();
|
||||||
@@ -524,7 +525,7 @@ namespace QControlKit
|
|||||||
cueList.setProperty(args.cueID, QOSCKey.PlaybackPositionId, false);
|
cueList.setProperty(args.cueID, QOSCKey.PlaybackPositionId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Information($"[workspace] cue list <{args.cueListID}> playback position changed to <{args.cueID}>");
|
_log.Information($"cue list <{args.cueListID}> playback position changed to <{args.cueID}>");
|
||||||
CueListChangedPlaybackPosition?.Invoke(this, new QCueListChangedPlaybackPositionArgs { cueListID = args.cueListID, cueID = args.cueID });
|
CueListChangedPlaybackPosition?.Invoke(this, new QCueListChangedPlaybackPositionArgs { cueListID = args.cueListID, cueID = args.cueID });
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -538,7 +539,7 @@ namespace QControlKit
|
|||||||
{
|
{
|
||||||
if (args.cueID.Equals(QIdentifiers.RootCueUpdate))
|
if (args.cueID.Equals(QIdentifiers.RootCueUpdate))
|
||||||
{
|
{
|
||||||
Log.Debug("[workspace] root cue update requested, updating all cue lists");
|
_log.Debug("root cue update requested, updating all cue lists");
|
||||||
foreach (var cuelist in this.cueLists)
|
foreach (var cuelist in this.cueLists)
|
||||||
{
|
{
|
||||||
if (!cuelist.uid.Equals(QIdentifiers.ActiveCues))
|
if (!cuelist.uid.Equals(QIdentifiers.ActiveCues))
|
||||||
@@ -560,10 +561,21 @@ namespace QControlKit
|
|||||||
|
|
||||||
private void OnCueUpdated(object source, QCueUpdatedArgs args)
|
private void OnCueUpdated(object source, QCueUpdatedArgs args)
|
||||||
{
|
{
|
||||||
|
_log.Verbose($"OnCueUpdated: {args.cueID}");
|
||||||
QCue cue = cueWithID(args.cueID);
|
QCue cue = cueWithID(args.cueID);
|
||||||
|
|
||||||
if (cue == null || cue.ignoreUpdates)
|
|
||||||
|
if(cue == null)
|
||||||
|
{
|
||||||
|
_log.Error($"Could not find cue to update, this is likely a problem.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cue.ignoreUpdates)
|
||||||
|
{
|
||||||
|
_log.Verbose($"Skipping updatePropertiesWithDictionary for cue: {args.cueID} because of ignoreUpdates setting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cue.updatePropertiesWithDictionary(args.data);
|
cue.updatePropertiesWithDictionary(args.data);
|
||||||
}
|
}
|
||||||
@@ -578,7 +590,7 @@ namespace QControlKit
|
|||||||
#region Printing
|
#region Printing
|
||||||
public void Print()
|
public void Print()
|
||||||
{
|
{
|
||||||
Log.Information($"[workspace] {name}");
|
_log.Information($"{name}");
|
||||||
foreach (var cueList in root.cues)
|
foreach (var cueList in root.cues)
|
||||||
{
|
{
|
||||||
cueList.Print();
|
cueList.Print();
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace SharpOSC
|
|||||||
buffer.Add(data[i]);
|
buffer.Add(data[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Text;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
using SuperSimpleTcp;
|
||||||
|
|
||||||
namespace SharpOSC
|
namespace SharpOSC
|
||||||
{
|
{
|
||||||
@@ -19,6 +20,8 @@ namespace SharpOSC
|
|||||||
|
|
||||||
public class TCPClient
|
public class TCPClient
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<TCPClient>();
|
||||||
|
|
||||||
public int Port
|
public int Port
|
||||||
{
|
{
|
||||||
get { return _port; }
|
get { return _port; }
|
||||||
@@ -32,18 +35,10 @@ namespace SharpOSC
|
|||||||
public delegate void MessageReceivedHandler(object source, MessageEventArgs args);
|
public delegate void MessageReceivedHandler(object source, MessageEventArgs args);
|
||||||
public event MessageReceivedHandler MessageReceived;
|
public event MessageReceivedHandler MessageReceived;
|
||||||
|
|
||||||
private Queue<OscPacket> SendQueue = new Queue<OscPacket>();
|
|
||||||
|
|
||||||
private Thread receivingThread;
|
|
||||||
private Thread sendThread;
|
|
||||||
|
|
||||||
string _address;
|
string _address;
|
||||||
TcpClient client;
|
|
||||||
|
|
||||||
byte END = 0xc0;
|
SimpleTcpClient tcpClient;
|
||||||
byte ESC = 0xdb;
|
|
||||||
byte ESC_END = 0xDC;
|
|
||||||
byte ESC_ESC = 0xDD;
|
|
||||||
|
|
||||||
|
|
||||||
public TCPClient(string address, int port)
|
public TCPClient(string address, int port)
|
||||||
@@ -54,48 +49,81 @@ namespace SharpOSC
|
|||||||
|
|
||||||
public bool Connect()
|
public bool Connect()
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
client = new TcpClient(Address, Port);
|
tcpClient = new SimpleTcpClient(Address, Port);
|
||||||
receivingThread = new Thread(ReceiveLoop);
|
tcpClient.Events.Connected += ClientConnected;
|
||||||
receivingThread.Start();
|
tcpClient.Events.DataReceived += DataReceived;
|
||||||
|
tcpClient.Events.Disconnected += ClientDisconneted;
|
||||||
sendThread = new Thread(SendLoop);
|
tcpClient.Logger += TCPLog;
|
||||||
sendThread.Start();
|
tcpClient.Connect();
|
||||||
|
|
||||||
Log.Debug($"[tcpclient] connected to <{Address}:{Port}>");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.Error(e.Message);
|
_log.Error(e.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueForSending(OscPacket packet)
|
private void TCPLog(string obj)
|
||||||
{
|
{
|
||||||
SendQueue.Enqueue(packet);
|
_log.Verbose($"{obj}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendLoop()
|
private void ClientDisconneted(object sender, ConnectionEventArgs e)
|
||||||
{
|
{
|
||||||
while (client != null && client.Connected)
|
_log.Verbose($"{e.IpPort} client disconnected: {e.Reason}");
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DataReceived(object sender, DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
_log.Verbose($"Raw Data Received contents: {Encoding.UTF8.GetString(e.Data.Array, 0, e.Data.Count)}");
|
||||||
|
_log.Verbose($"Raw Data Received size: {e.Data.Count}");
|
||||||
|
List<byte[]> messages = SlipFrame.Decode(e.Data.Array);
|
||||||
|
_log.Verbose($"Slip decoded {messages.Count} osc messages");
|
||||||
|
foreach (var message in messages)
|
||||||
{
|
{
|
||||||
if (SendQueue.Count > 0)
|
_log.Verbose($"Raw message contents: {Encoding.UTF8.GetString(message, 0, message.Length)}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OscPacket packet = OscPacket.GetPacket(message);
|
||||||
|
OscMessage responseMessage = (OscMessage)packet;
|
||||||
|
if (packet == null)
|
||||||
|
{
|
||||||
|
_log.Error("packet is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseMessage == null)
|
||||||
|
{
|
||||||
|
_log.Error("responeMessage is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
_log.Debug($"OSC Message Received: {responseMessage.Address}");
|
||||||
|
OnMessageReceived(responseMessage);
|
||||||
|
_log.Debug($"After OnMessageReceived Event");
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
OscPacket packet = SendQueue.Dequeue();
|
_log.Error($"Exception parsing OSC message: {ex.ToString()}");
|
||||||
Send(packet);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ClientConnected(object sender, ConnectionEventArgs e)
|
||||||
|
{
|
||||||
|
_log.Debug($"connected to <{Address}:{Port}>");
|
||||||
|
}
|
||||||
|
|
||||||
public void Send(byte[] message)
|
public void Send(byte[] message)
|
||||||
{
|
{
|
||||||
byte[] slipData = SlipFrame.Encode(message);
|
byte[] slipData = SlipFrame.Encode(message);
|
||||||
NetworkStream netStream = client.GetStream();
|
tcpClient.Send(slipData.ToArray());
|
||||||
netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(OscPacket packet)
|
public void Send(OscPacket packet)
|
||||||
@@ -108,74 +136,25 @@ namespace SharpOSC
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (client == null)
|
if (tcpClient == null)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return client.Connected;
|
return tcpClient.IsConnected;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReceiveLoop()
|
|
||||||
{
|
|
||||||
while (client != null && client.Connected)
|
|
||||||
{
|
|
||||||
Receive();
|
|
||||||
}
|
|
||||||
//Log.Debug("[tcpclient] - ReceiveLoop has exited");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Receive()
|
|
||||||
{
|
|
||||||
Random random = new Random();
|
|
||||||
int num = random.Next(1000);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
NetworkStream netStream = client.GetStream();
|
|
||||||
netStream.ReadTimeout = 250;
|
|
||||||
List<byte> responseData = new List<byte>();
|
|
||||||
if (netStream.CanRead)
|
|
||||||
{
|
|
||||||
//var watch = System.Diagnostics.Stopwatch.StartNew();
|
|
||||||
byte[] buffer = new byte[256];
|
|
||||||
|
|
||||||
int bytesRead = 0;
|
|
||||||
int reads = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
bytesRead = netStream.Read(buffer, 0, buffer.Length);
|
|
||||||
responseData.AddRange(buffer);
|
|
||||||
reads += 1;
|
|
||||||
Thread.Sleep(1);
|
|
||||||
//Log.Debug("Thread " + num + ": Bytes read: " + bytesRead + " - " + Encoding.UTF8.GetString(buffer));
|
|
||||||
} while (netStream.DataAvailable);
|
|
||||||
|
|
||||||
//Console.WriteLine("Raw TCP In: " + System.Text.Encoding.UTF8.GetString(responseData.ToArray()));
|
|
||||||
List<byte[]> messages = SlipFrame.Decode(responseData.ToArray());
|
|
||||||
foreach(var message in messages)
|
|
||||||
{
|
|
||||||
OscPacket packet = OscPacket.GetPacket(message);
|
|
||||||
OscMessage responseMessage = (OscMessage)packet;
|
|
||||||
//watch.Stop();
|
|
||||||
//Console.WriteLine($"TCPCLient - message receive took {watch.ElapsedMilliseconds}ms and {reads} reads");
|
|
||||||
OnMessageReceived(responseMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
//Console.WriteLine("TCPSENDER - Receive Exception: " + e.ToString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
if (client != null)
|
if (tcpClient != null)
|
||||||
{
|
{
|
||||||
if (client.Connected)
|
tcpClient.Events.Connected -= ClientConnected;
|
||||||
|
tcpClient.Events.DataReceived -= DataReceived;
|
||||||
|
tcpClient.Events.Disconnected -= ClientDisconneted;
|
||||||
|
if (tcpClient.IsConnected)
|
||||||
{
|
{
|
||||||
Log.Debug($"[tcpClient] closing connection to {Address}");
|
_log.Debug($"closing connection to {Address}");
|
||||||
client.GetStream().Close();
|
tcpClient.Disconnect();
|
||||||
client.Close();
|
tcpClient.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using System.Linq;
|
|||||||
using Foundation;
|
using Foundation;
|
||||||
using UIKit;
|
using UIKit;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace QControlKitXamDemo.iOS
|
namespace QControlKitXamDemo.iOS
|
||||||
{
|
{
|
||||||
// The UIApplicationDelegate for the application. This class is responsible for launching the
|
// The UIApplicationDelegate for the application. This class is responsible for launching the
|
||||||
@@ -23,7 +25,7 @@ namespace QControlKitXamDemo.iOS
|
|||||||
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
|
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
|
||||||
{
|
{
|
||||||
global::Xamarin.Forms.Forms.Init();
|
global::Xamarin.Forms.Forms.Init();
|
||||||
Log.Logger = new LoggerConfiguration().WriteTo.NSLog().MinimumLevel.Verbose().CreateLogger();
|
Log.Logger = new LoggerConfiguration().WriteTo.NSLog(outputTemplate: "[{Level}] ({SourceContext}) {Message}{NewLine}{Exception}").MinimumLevel.Verbose().CreateLogger();
|
||||||
LoadApplication(new App());
|
LoadApplication(new App());
|
||||||
|
|
||||||
return base.FinishedLaunching(app, options);
|
return base.FinishedLaunching(app, options);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Xamarin.Forms;
|
|||||||
|
|
||||||
using QControlKit.Events;
|
using QControlKit.Events;
|
||||||
using QControlKit.Constants;
|
using QControlKit.Constants;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace QControlKitXamDemo
|
namespace QControlKitXamDemo
|
||||||
{
|
{
|
||||||
@@ -64,6 +65,18 @@ namespace QControlKitXamDemo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateCuePropertes(QCue cue)
|
||||||
|
{
|
||||||
|
cue.workspace.fetchDefaultPropertiesForCue(cue);
|
||||||
|
if (cue.cues.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (QCue childCue in cue.cues)
|
||||||
|
{
|
||||||
|
childCue.workspace.fetchDefaultPropertiesForCue(childCue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Workspace_WorkspaceUpdated(object source, QWorkspaceUpdatedArgs args)
|
void Workspace_WorkspaceUpdated(object source, QWorkspaceUpdatedArgs args)
|
||||||
{
|
{
|
||||||
if(connectedWorkspace.cueLists.Count > 0)
|
if(connectedWorkspace.cueLists.Count > 0)
|
||||||
@@ -71,6 +84,7 @@ namespace QControlKitXamDemo
|
|||||||
List<Task> cueAddTasks = new List<Task>();
|
List<Task> cueAddTasks = new List<Task>();
|
||||||
foreach(var aCue in connectedWorkspace.cueLists)
|
foreach(var aCue in connectedWorkspace.cueLists)
|
||||||
{
|
{
|
||||||
|
updateCuePropertes(aCue);
|
||||||
Grid cueGrid = cueToGrid(aCue);
|
Grid cueGrid = cueToGrid(aCue);
|
||||||
cueGridDict.Add(aCue.uid, cueGrid);
|
cueGridDict.Add(aCue.uid, cueGrid);
|
||||||
MainThread.InvokeOnMainThreadAsync(() =>
|
MainThread.InvokeOnMainThreadAsync(() =>
|
||||||
@@ -95,7 +109,7 @@ namespace QControlKitXamDemo
|
|||||||
HorizontalOptions = LayoutOptions.StartAndExpand,
|
HorizontalOptions = LayoutOptions.StartAndExpand,
|
||||||
VerticalTextAlignment = TextAlignment.Center,
|
VerticalTextAlignment = TextAlignment.Center,
|
||||||
};
|
};
|
||||||
cueLabel.SetBinding(Label.TextProperty, "status", BindingMode.OneWay);
|
cueLabel.SetBinding(Label.TextProperty, "name", BindingMode.OneWay);
|
||||||
var cueBackground = new Frame
|
var cueBackground = new Frame
|
||||||
{
|
{
|
||||||
BindingContext = qCueViewModel,
|
BindingContext = qCueViewModel,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace QControlKitXamDemo
|
|||||||
|
|
||||||
qBrowserViewModel.autoUpdate = false;
|
qBrowserViewModel.autoUpdate = false;
|
||||||
QWorkspace selectedWorkspace = (e.SelectedItem as QWorkspaceViewModel).workspace;
|
QWorkspace selectedWorkspace = (e.SelectedItem as QWorkspaceViewModel).workspace;
|
||||||
Log.Debug($"[demo] workspace: {selectedWorkspace.nameWithoutPathExtension} has been selected");
|
Log.Debug($"workspace: {selectedWorkspace.nameWithoutPathExtension} has been selected");
|
||||||
((ListView)sender).SelectedItem = null;
|
((ListView)sender).SelectedItem = null;
|
||||||
|
|
||||||
if (selectedWorkspace.hasPasscode)
|
if (selectedWorkspace.hasPasscode)
|
||||||
|
|||||||
@@ -13,11 +13,15 @@ namespace QControlKitXamDemo.ViewModels
|
|||||||
{
|
{
|
||||||
public class QBrowserViewModel : INotifyPropertyChanged
|
public class QBrowserViewModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QBrowserViewModel>();
|
||||||
|
|
||||||
QBrowser browser;
|
QBrowser browser;
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
public bool autoUpdate = false;
|
public bool autoUpdate = false;
|
||||||
public ObservableCollection<QServerViewModel> ServersGrouped { get; set; }
|
public ObservableCollection<QServerViewModel> ServersGrouped { get; set; }
|
||||||
|
|
||||||
|
bool connected = false;
|
||||||
public QBrowserViewModel(QBrowser browser)
|
public QBrowserViewModel(QBrowser browser)
|
||||||
{
|
{
|
||||||
this.browser = browser;
|
this.browser = browser;
|
||||||
@@ -31,9 +35,10 @@ namespace QControlKitXamDemo.ViewModels
|
|||||||
{
|
{
|
||||||
if (autoUpdate)
|
if (autoUpdate)
|
||||||
{
|
{
|
||||||
|
_log.Verbose($"Auto Update is enabled running probe");
|
||||||
Device.BeginInvokeOnMainThread(() =>
|
Device.BeginInvokeOnMainThread(() =>
|
||||||
{
|
{
|
||||||
Log.Debug("[QBrowserViewModel] QBrowser probe triggered");
|
_log.Debug("QBrowser probe triggered");
|
||||||
this.browser.ProbeForQLabInstances();
|
this.browser.ProbeForQLabInstances();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -47,7 +52,7 @@ namespace QControlKitXamDemo.ViewModels
|
|||||||
{
|
{
|
||||||
Device.BeginInvokeOnMainThread(() =>
|
Device.BeginInvokeOnMainThread(() =>
|
||||||
{
|
{
|
||||||
Log.Debug($"[QBrowserViewModel] adding server: {args.server.description}");
|
_log.Debug($"adding server: {args.server.description}");
|
||||||
ServersGrouped.Add(new QServerViewModel(args.server));
|
ServersGrouped.Add(new QServerViewModel(args.server));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -70,7 +75,7 @@ namespace QControlKitXamDemo.ViewModels
|
|||||||
{
|
{
|
||||||
Device.BeginInvokeOnMainThread(() =>
|
Device.BeginInvokeOnMainThread(() =>
|
||||||
{
|
{
|
||||||
Log.Debug($"[QBrowserViewModel] removing server: {args.server.description}");
|
_log.Debug($"removing server: {args.server.description}");
|
||||||
ServersGrouped.Remove(serverToRemove);
|
ServersGrouped.Remove(serverToRemove);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -85,7 +90,7 @@ namespace QControlKitXamDemo.ViewModels
|
|||||||
{
|
{
|
||||||
if (!autoUpdate)
|
if (!autoUpdate)
|
||||||
{
|
{
|
||||||
Log.Debug("[QBrowserViewModel] Manual Scan Initiated");
|
_log.Debug("Manual Scan Initiated");
|
||||||
browser.ProbeForQLabInstances();
|
browser.ProbeForQLabInstances();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ namespace QControlKitXamDemo.ViewModels
|
|||||||
{
|
{
|
||||||
public class QCueViewModel : INotifyPropertyChanged
|
public class QCueViewModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QCueViewModel>();
|
||||||
|
|
||||||
QCue cue;
|
QCue cue;
|
||||||
bool isSelected = false;
|
bool isSelected = false;
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
@@ -18,16 +20,20 @@ namespace QControlKitXamDemo.ViewModels
|
|||||||
public QCueViewModel(QCue cue, bool checkPlayback)
|
public QCueViewModel(QCue cue, bool checkPlayback)
|
||||||
{
|
{
|
||||||
this.cue = cue;
|
this.cue = cue;
|
||||||
if(checkPlayback)
|
if (checkPlayback)
|
||||||
|
{
|
||||||
this.cue.workspace.CueListChangedPlaybackPosition += Workspace_CueListChangedPlaybackPosition;
|
this.cue.workspace.CueListChangedPlaybackPosition += Workspace_CueListChangedPlaybackPosition;
|
||||||
|
}
|
||||||
this.cue.CuePropertiesUpdated += OnCuePropertiesUpdated;
|
this.cue.CuePropertiesUpdated += OnCuePropertiesUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCuePropertiesUpdated(object source, QCuePropertiesUpdatedArgs args)
|
private void OnCuePropertiesUpdated(object source, QCuePropertiesUpdatedArgs args)
|
||||||
{
|
{
|
||||||
foreach(var property in args.properties)
|
_log.Debug($"properties updated from cue");
|
||||||
|
|
||||||
|
foreach (var property in args.properties)
|
||||||
{
|
{
|
||||||
Log.Debug($"[cueviewmodel] property <{property}> has been updated for cue {name}.");
|
_log.Debug($"property <{property}> has been updated for cue {name}.");
|
||||||
if (property.Equals(QOSCKey.Name) || property.Equals(QOSCKey.ListName))
|
if (property.Equals(QOSCKey.Name) || property.Equals(QOSCKey.ListName))
|
||||||
{
|
{
|
||||||
OnPropertyChanged("name");
|
OnPropertyChanged("name");
|
||||||
|
|||||||
@@ -5,11 +5,14 @@ using Xamarin.Forms;
|
|||||||
|
|
||||||
using QControlKit;
|
using QControlKit;
|
||||||
using QControlKit.Events;
|
using QControlKit.Events;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace QControlKitXamDemo.ViewModels
|
namespace QControlKitXamDemo.ViewModels
|
||||||
{
|
{
|
||||||
public class QServerViewModel : ObservableCollection<QWorkspaceViewModel>, INotifyPropertyChanged
|
public class QServerViewModel : ObservableCollection<QWorkspaceViewModel>, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
private ILogger _log = Log.Logger.ForContext<QServerViewModel>();
|
||||||
|
|
||||||
QServer server;
|
QServer server;
|
||||||
public new event PropertyChangedEventHandler PropertyChanged;
|
public new event PropertyChangedEventHandler PropertyChanged;
|
||||||
public string name
|
public string name
|
||||||
|
|||||||
Reference in New Issue
Block a user