From 2176ca4488b16e3680564e0f0f6861f498cefc56 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 5 Nov 2022 13:50:27 -0500 Subject: [PATCH] TCP Work, Log cleanup, Message parsing --- QControlKit/QBrowser.cs | 16 +- QControlKit/QClient.cs | 48 +++--- QControlKit/QControlKit.csproj | 3 +- QControlKit/QCue.cs | 28 +++- QControlKit/QServer.cs | 17 +- QControlKit/QWorkspace.cs | 42 +++-- QControlKit/SharpOSC/SlipFrame.cs | 1 + QControlKit/SharpOSC/TCPClient.cs | 153 ++++++++---------- .../QControlKitXamDemo.iOS/AppDelegate.cs | 4 +- .../QControlKitXamDemo/CueListPage.xaml.cs | 16 +- .../QControlKitXamDemo/MainPage.xaml.cs | 2 +- .../ViewModels/QBrowserViewModel.cs | 13 +- .../ViewModels/QCueViewModel.cs | 12 +- .../ViewModels/QServerViewModel.cs | 3 + 14 files changed, 200 insertions(+), 158 deletions(-) diff --git a/QControlKit/QBrowser.cs b/QControlKit/QBrowser.cs index 69cbb09..def1cb4 100644 --- a/QControlKit/QBrowser.cs +++ b/QControlKit/QBrowser.cs @@ -13,6 +13,8 @@ namespace QControlKit { public class QBrowser { + private ILogger _log = Log.Logger.ForContext(); + public ObservableCollection servers = new ObservableCollection(); public event QServerFoundHandler ServerFound; @@ -26,17 +28,17 @@ namespace QControlKit public async void ProbeForQLabInstances() { - Log.Debug("[qbrowser] probing for instances"); + _log.Debug("probing for instances"); IReadOnlyList results = await ZeroconfResolver.ResolveAsync(QBonjour.TCPService,TimeSpan.FromSeconds(3)); 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) { - Log.Debug($"[qbrowser] found {service.Key}:{service.Value}"); + _log.Debug($"found {service.Key}:{service.Value}"); if (service.Key.Equals(QBonjour.TCPService)) { @@ -44,7 +46,7 @@ namespace QControlKit 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); serverToAdd.name = zeroconfHost.DisplayName; serverToAdd.zeroconfHost = zeroconfHost; @@ -70,9 +72,9 @@ namespace QControlKit 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(); - Log.Verbose($"[qbrowser] after server disconnect()"); + _log.Verbose($"after server disconnect()"); servers.Remove(server); OnServerLost(server); } @@ -122,7 +124,7 @@ namespace QControlKit public void Close() { - Log.Information($"[qbrowser] Close requested"); + _log.Information($"Close requested"); foreach (var server in servers) { server.disconnect(); diff --git a/QControlKit/QClient.cs b/QControlKit/QClient.cs index 87fc801..5f281a9 100644 --- a/QControlKit/QClient.cs +++ b/QControlKit/QClient.cs @@ -12,6 +12,8 @@ namespace QControlKit { public class QClient { + private ILogger _log = Log.Logger.ForContext(); + TCPClient tcpClient; public event QWorkspacesUpdatedHandler WorkspacesUpdated; @@ -35,7 +37,7 @@ namespace QControlKit public QClient(string host, int port) { tcpClient = new TCPClient(host, port); - Log.Debug($"[client] setup connection to: <{host}:{port}>"); + _log.Debug($"setup connection to: <{host}:{port}>"); tcpClient.MessageReceived += ProcessMessage; } @@ -52,15 +54,15 @@ namespace QControlKit public void disconnect() { - Log.Information($"[client] disconnecting from {tcpClient.Address}"); + _log.Information($"disconnecting from {tcpClient.Address}"); tcpClient.Close(); } public void sendMessage(string address, params object[] args) { - tcpClient.QueueForSending(new OscMessage(address, args)); - Log.Information($"[client] send message {address} : {args}"); + tcpClient.Send(new OscMessage(address, args)); + _log.Debug($"send message {address} : {args}"); } private void ProcessMessage(object source, MessageEventArgs args) @@ -87,20 +89,19 @@ namespace QControlKit string property = message.AddressParts.Last(); if (property == null) return; - if (property == QOSCKey.PlaybackPositionId) - { - OnCueListChangedPlaybackPosition(message.cueID, data.ToString()); - return; - } //create object manually since single value replies don't have dictionaries JObject properties = new JObject(); properties.Add(property, data); OnCueUpdated(message.cueID, properties); + if (property == QOSCKey.PlaybackPositionId) + { + OnCueListChangedPlaybackPosition(message.cueID, data.ToString()); + } } 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) { - if (message.response.ToString() == "ok") + if (message.response.ToString().Contains("ok")) OnWorkspaceConnected(); else OnWorkspaceConnectionError(message.response.ToString()); } else { - Log.Error($"[client] unhandled reply message: {message.address}"); + _log.Error($"unhandled reply message: {message.address}"); } } else if(message.IsUpdate) { @@ -153,7 +154,6 @@ namespace QControlKit else if ( message.IsPreferencesUpdate) { //need to do checks for 4.2 or newer - string key = message.AddressParts.Last(); if (key == null) return; @@ -165,65 +165,65 @@ namespace QControlKit } else { - Log.Error($"[client] unhandled update message: {message.address}"); + _log.Error($"unhandled update message: {message.address}"); } } else { - Log.Error($"[client] unhandled message: {message.address}"); + _log.Error($"unhandled message: {message.address}"); } } 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 }); } 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 }); } protected virtual void OnCueListsUpdated(JToken response) { - Log.Debug($"[client] Cue Lists Updated"); + _log.Debug($"Cue Lists Updated"); CueListsUpdated?.Invoke(this, new QCueListsUpdatedArgs { data = response }); } 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 }); } protected virtual void OnWorkspaceUpdated() { - //Log.Debug($"[client] Workspace Updated"); + _log.Debug($"Workspace Updated"); WorkspaceUpdated?.Invoke(this, new QWorkspaceUpdatedArgs()); } protected virtual void OnWorkspaceSettingsUpdated(string settingsType) { - Log.Debug($"[client] Workspace Settings Updated"); + _log.Debug($"Workspace Settings Updated"); WorkspaceSettingsUpdated?.Invoke(this, new QWorkspaceSettingsUpdatedArgs { settingsType = settingsType }); } protected virtual void OnWorkspaceLightDashboardUpdated() { - Log.Debug($"[client] Workspace Light Dashboard Updated"); + _log.Debug($"Workspace Light Dashboard Updated"); WorkspaceLightDashboardUpdated?.Invoke(this, new QWorkspaceLightDashboardUpdatedArgs()); } protected virtual void OnQLabPreferencesUpdated(string key) { - Log.Debug($"[client] QLab Preferences Updated"); + _log.Debug($"QLab Preferences Updated"); QLabPreferencesUpdated?.Invoke(this, new QQLabPreferencesUpdatedArgs { key = key }); } protected virtual void OnWorkspaceDisconnected() { - Log.Debug($"[client] Workspace Disconnected"); + _log.Debug($"Workspace Disconnected"); WorkspaceDisconnected?.Invoke(this, new QWorkspaceDisconnectedArgs()); } diff --git a/QControlKit/QControlKit.csproj b/QControlKit/QControlKit.csproj index e74fc3a..25cb773 100644 --- a/QControlKit/QControlKit.csproj +++ b/QControlKit/QControlKit.csproj @@ -17,7 +17,7 @@ - + @@ -32,5 +32,6 @@ + diff --git a/QControlKit/QCue.cs b/QControlKit/QCue.cs index 6fe560d..83c3f5b 100644 --- a/QControlKit/QCue.cs +++ b/QControlKit/QCue.cs @@ -12,6 +12,7 @@ namespace QControlKit { public class QCue : IComparable { + private ILogger _log = Log.Logger.ForContext(); public QWorkspace workspace; public Dictionary cueData; @@ -162,7 +163,7 @@ namespace QControlKit 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); childCuesUIDMap.Remove(aUid); } @@ -639,6 +640,8 @@ namespace QControlKit { bool cueUpdated = false; + _log.Verbose($"updatePropertiesWithDictionary() Called for cue"); + //TODO: pretty sure this is done JObject dictObj = (JObject)dict; List propertiesUpdated = new List(); @@ -647,14 +650,14 @@ namespace QControlKit JToken value = obj.Value; 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) continue; updateChildCuesWithPropertiesArray(value, false); } 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) continue; updateChildCuesWithPropertiesArray(value, true); @@ -668,7 +671,7 @@ namespace QControlKit { cueUpdated = true; 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) { 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)){ return (bool)prop; } @@ -893,7 +896,7 @@ namespace QControlKit } 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)) { @@ -992,9 +995,18 @@ namespace QControlKit #region Event Handling void OnCuePropertiesUpdated(List properties) { + _log.Verbose("OnCuePropertiesUpdated"); 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 }); } @@ -1011,7 +1023,7 @@ namespace QControlKit { string indent = new string(' ', level*2); - Log.Information($"{indent}\u00b7{displayName} - {uid}"); + _log.Information($"{indent}\u00b7{displayName} - {uid}"); if (IsGroup) { level++; diff --git a/QControlKit/QServer.cs b/QControlKit/QServer.cs index 0c07df0..c24e518 100644 --- a/QControlKit/QServer.cs +++ b/QControlKit/QServer.cs @@ -10,11 +10,13 @@ namespace QControlKit { public class QServer { + private ILogger _log = Log.Logger.ForContext(); + public event QServerUpdatedHandler ServerUpdated; public event QServerWorkspaceAddedHandler WorkspaceAdded; public event QServerWorkspaceRemovedHandler WorkspaceRemoved; - private QClient client; + private QClient _client; public string host { get; set; } public int port { get; set; } @@ -28,18 +30,21 @@ namespace QControlKit this.host = host; this.port = port; - client = new QClient(host, port); + _client = new QClient(host, port); client.WorkspacesUpdated += OnServerWorkspacesUpdated; 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 QClient client { + get { return _client; } + } + public void refreshWorkspaces() { client.sendMessage("/workspaces"); @@ -111,12 +116,12 @@ namespace QControlKit public void disconnect() { - Log.Information($"[server] disconnect requested for server <{name}>"); + _log.Information($"disconnect requested for server <{name}>"); foreach (var workspace in workspaces) { 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(); } } diff --git a/QControlKit/QWorkspace.cs b/QControlKit/QWorkspace.cs index e5754aa..e505ac5 100644 --- a/QControlKit/QWorkspace.cs +++ b/QControlKit/QWorkspace.cs @@ -10,6 +10,7 @@ namespace QControlKit { public class QWorkspace: IEquatable { + private ILogger _log = Log.Logger.ForContext(); private QServer server; private QClient client; @@ -64,7 +65,7 @@ namespace QControlKit updateWithWorkspaceInfo(workspaceInfo); - client = new QClient(server.host, server.port); + client = server.client; client.WorkspaceConnected += OnWorkspaceConnected; client.WorkspaceConnectionError += OnWorkspaceConnectionError; @@ -75,7 +76,7 @@ namespace QControlKit client.CueUpdated += OnCueUpdated; this.server = server; - Log.Debug($"[workspace] <{name}> on <{server.name}> initialized."); + _log.Debug($"<{name}> on <{server.name}> initialized."); } //updateWithDictionary @@ -164,18 +165,18 @@ namespace QControlKit 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) { - 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 }); return; } 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 }); return; } @@ -210,7 +211,7 @@ namespace QControlKit public void disconnect() { - Log.Information($"[workspace] disconnecting from <{name}>"); + _log.Information($"disconnecting from <{name}>"); if (!connected) return; stopReceivingUpdates(); @@ -417,11 +418,11 @@ namespace QControlKit { //clear passcode if there was one set in the connect() method this.passcode = null; - Log.Error($"[workspace] *** Password for workspace <{name}> was incorrect!"); + _log.Error($"*** Password for workspace <{name}> was incorrect!"); } 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 }); @@ -429,7 +430,7 @@ namespace QControlKit 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()); finishConnection(); } @@ -437,7 +438,7 @@ namespace QControlKit private void OnWorkspaceDisconnected(object source, QWorkspaceDisconnectedArgs args) { //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()); } @@ -506,7 +507,7 @@ namespace QControlKit //add Event handled? use CueUpdated one? } - Log.Debug($"[workspace] cueLists finished processing. root updated? {rootCueUpdated}"); + _log.Debug($"cueLists finished processing. root updated? {rootCueUpdated}"); OnWorkspaceUpdated(); @@ -524,7 +525,7 @@ namespace QControlKit 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 }); } @@ -538,7 +539,7 @@ namespace QControlKit { 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) { if (!cuelist.uid.Equals(QIdentifiers.ActiveCues)) @@ -560,10 +561,21 @@ namespace QControlKit private void OnCueUpdated(object source, QCueUpdatedArgs args) { + _log.Verbose($"OnCueUpdated: {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; + } + + if (cue.ignoreUpdates) + { + _log.Verbose($"Skipping updatePropertiesWithDictionary for cue: {args.cueID} because of ignoreUpdates setting"); + return; + } cue.updatePropertiesWithDictionary(args.data); } @@ -578,7 +590,7 @@ namespace QControlKit #region Printing public void Print() { - Log.Information($"[workspace] {name}"); + _log.Information($"{name}"); foreach (var cueList in root.cues) { cueList.Print(); diff --git a/QControlKit/SharpOSC/SlipFrame.cs b/QControlKit/SharpOSC/SlipFrame.cs index e326a75..237987d 100644 --- a/QControlKit/SharpOSC/SlipFrame.cs +++ b/QControlKit/SharpOSC/SlipFrame.cs @@ -26,6 +26,7 @@ namespace SharpOSC buffer.Add(data[i]); } } + return messages; } diff --git a/QControlKit/SharpOSC/TCPClient.cs b/QControlKit/SharpOSC/TCPClient.cs index 1954fd4..f240250 100644 --- a/QControlKit/SharpOSC/TCPClient.cs +++ b/QControlKit/SharpOSC/TCPClient.cs @@ -5,6 +5,7 @@ using System.Text; using System.Net.Sockets; using System.Threading; using Serilog; +using SuperSimpleTcp; namespace SharpOSC { @@ -19,6 +20,8 @@ namespace SharpOSC public class TCPClient { + private ILogger _log = Log.Logger.ForContext(); + public int Port { get { return _port; } @@ -32,18 +35,10 @@ namespace SharpOSC public delegate void MessageReceivedHandler(object source, MessageEventArgs args); public event MessageReceivedHandler MessageReceived; - private Queue SendQueue = new Queue(); - - private Thread receivingThread; - private Thread sendThread; - string _address; - TcpClient client; - byte END = 0xc0; - byte ESC = 0xdb; - byte ESC_END = 0xDC; - byte ESC_ESC = 0xDD; + SimpleTcpClient tcpClient; + public TCPClient(string address, int port) @@ -54,48 +49,81 @@ namespace SharpOSC public bool Connect() { + try { - client = new TcpClient(Address, Port); - receivingThread = new Thread(ReceiveLoop); - receivingThread.Start(); - - sendThread = new Thread(SendLoop); - sendThread.Start(); - - Log.Debug($"[tcpclient] connected to <{Address}:{Port}>"); + tcpClient = new SimpleTcpClient(Address, Port); + tcpClient.Events.Connected += ClientConnected; + tcpClient.Events.DataReceived += DataReceived; + tcpClient.Events.Disconnected += ClientDisconneted; + tcpClient.Logger += TCPLog; + tcpClient.Connect(); return true; } catch (Exception e) { - Log.Error(e.Message); + _log.Error(e.Message); 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 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(); - Send(packet); + _log.Error($"Exception parsing OSC message: {ex.ToString()}"); } } } + private void ClientConnected(object sender, ConnectionEventArgs e) + { + _log.Debug($"connected to <{Address}:{Port}>"); + } + public void Send(byte[] message) { byte[] slipData = SlipFrame.Encode(message); - NetworkStream netStream = client.GetStream(); - netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length); + tcpClient.Send(slipData.ToArray()); } public void Send(OscPacket packet) @@ -108,74 +136,25 @@ namespace SharpOSC { get { - if (client == null) + if (tcpClient == null) return false; else - return client.Connected; - } - } - - 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 responseData = new List(); - 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 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()); + return tcpClient.IsConnected; } } 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}"); - client.GetStream().Close(); - client.Close(); + _log.Debug($"closing connection to {Address}"); + tcpClient.Disconnect(); + tcpClient.Dispose(); } } } diff --git a/QControlKitXamDemo/QControlKitXamDemo.iOS/AppDelegate.cs b/QControlKitXamDemo/QControlKitXamDemo.iOS/AppDelegate.cs index d452bd0..31c8582 100644 --- a/QControlKitXamDemo/QControlKitXamDemo.iOS/AppDelegate.cs +++ b/QControlKitXamDemo/QControlKitXamDemo.iOS/AppDelegate.cs @@ -5,6 +5,8 @@ using System.Linq; using Foundation; using UIKit; using Serilog; +using Serilog.Events; + namespace QControlKitXamDemo.iOS { // 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) { 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()); return base.FinishedLaunching(app, options); diff --git a/QControlKitXamDemo/QControlKitXamDemo/CueListPage.xaml.cs b/QControlKitXamDemo/QControlKitXamDemo/CueListPage.xaml.cs index 482e43f..4bb6f3a 100644 --- a/QControlKitXamDemo/QControlKitXamDemo/CueListPage.xaml.cs +++ b/QControlKitXamDemo/QControlKitXamDemo/CueListPage.xaml.cs @@ -7,6 +7,7 @@ using Xamarin.Forms; using QControlKit.Events; using QControlKit.Constants; +using Serilog; 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) { if(connectedWorkspace.cueLists.Count > 0) @@ -71,6 +84,7 @@ namespace QControlKitXamDemo List cueAddTasks = new List(); foreach(var aCue in connectedWorkspace.cueLists) { + updateCuePropertes(aCue); Grid cueGrid = cueToGrid(aCue); cueGridDict.Add(aCue.uid, cueGrid); MainThread.InvokeOnMainThreadAsync(() => @@ -95,7 +109,7 @@ namespace QControlKitXamDemo HorizontalOptions = LayoutOptions.StartAndExpand, VerticalTextAlignment = TextAlignment.Center, }; - cueLabel.SetBinding(Label.TextProperty, "status", BindingMode.OneWay); + cueLabel.SetBinding(Label.TextProperty, "name", BindingMode.OneWay); var cueBackground = new Frame { BindingContext = qCueViewModel, diff --git a/QControlKitXamDemo/QControlKitXamDemo/MainPage.xaml.cs b/QControlKitXamDemo/QControlKitXamDemo/MainPage.xaml.cs index cecd380..e504b65 100644 --- a/QControlKitXamDemo/QControlKitXamDemo/MainPage.xaml.cs +++ b/QControlKitXamDemo/QControlKitXamDemo/MainPage.xaml.cs @@ -30,7 +30,7 @@ namespace QControlKitXamDemo qBrowserViewModel.autoUpdate = false; 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; if (selectedWorkspace.hasPasscode) diff --git a/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QBrowserViewModel.cs b/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QBrowserViewModel.cs index e5785ad..920a63d 100644 --- a/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QBrowserViewModel.cs +++ b/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QBrowserViewModel.cs @@ -13,11 +13,15 @@ namespace QControlKitXamDemo.ViewModels { public class QBrowserViewModel : INotifyPropertyChanged { + private ILogger _log = Log.Logger.ForContext(); + QBrowser browser; public event PropertyChangedEventHandler PropertyChanged; public bool autoUpdate = false; public ObservableCollection ServersGrouped { get; set; } + + bool connected = false; public QBrowserViewModel(QBrowser browser) { this.browser = browser; @@ -31,9 +35,10 @@ namespace QControlKitXamDemo.ViewModels { if (autoUpdate) { + _log.Verbose($"Auto Update is enabled running probe"); Device.BeginInvokeOnMainThread(() => { - Log.Debug("[QBrowserViewModel] QBrowser probe triggered"); + _log.Debug("QBrowser probe triggered"); this.browser.ProbeForQLabInstances(); }); } @@ -47,7 +52,7 @@ namespace QControlKitXamDemo.ViewModels { Device.BeginInvokeOnMainThread(() => { - Log.Debug($"[QBrowserViewModel] adding server: {args.server.description}"); + _log.Debug($"adding server: {args.server.description}"); ServersGrouped.Add(new QServerViewModel(args.server)); }); } @@ -70,7 +75,7 @@ namespace QControlKitXamDemo.ViewModels { Device.BeginInvokeOnMainThread(() => { - Log.Debug($"[QBrowserViewModel] removing server: {args.server.description}"); + _log.Debug($"removing server: {args.server.description}"); ServersGrouped.Remove(serverToRemove); }); } @@ -85,7 +90,7 @@ namespace QControlKitXamDemo.ViewModels { if (!autoUpdate) { - Log.Debug("[QBrowserViewModel] Manual Scan Initiated"); + _log.Debug("Manual Scan Initiated"); browser.ProbeForQLabInstances(); } } diff --git a/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QCueViewModel.cs b/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QCueViewModel.cs index c73c51d..69ec375 100644 --- a/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QCueViewModel.cs +++ b/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QCueViewModel.cs @@ -11,6 +11,8 @@ namespace QControlKitXamDemo.ViewModels { public class QCueViewModel : INotifyPropertyChanged { + private ILogger _log = Log.Logger.ForContext(); + QCue cue; bool isSelected = false; public event PropertyChangedEventHandler PropertyChanged; @@ -18,16 +20,20 @@ namespace QControlKitXamDemo.ViewModels public QCueViewModel(QCue cue, bool checkPlayback) { this.cue = cue; - if(checkPlayback) + if (checkPlayback) + { this.cue.workspace.CueListChangedPlaybackPosition += Workspace_CueListChangedPlaybackPosition; + } this.cue.CuePropertiesUpdated += OnCuePropertiesUpdated; } 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)) { OnPropertyChanged("name"); diff --git a/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QServerViewModel.cs b/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QServerViewModel.cs index 1e83cd4..73e6f28 100644 --- a/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QServerViewModel.cs +++ b/QControlKitXamDemo/QControlKitXamDemo/ViewModels/QServerViewModel.cs @@ -5,11 +5,14 @@ using Xamarin.Forms; using QControlKit; using QControlKit.Events; +using Serilog; namespace QControlKitXamDemo.ViewModels { public class QServerViewModel : ObservableCollection, INotifyPropertyChanged { + private ILogger _log = Log.Logger.ForContext(); + QServer server; public new event PropertyChangedEventHandler PropertyChanged; public string name