diff --git a/qController.Standard/.DS_Store b/qController.Standard/.DS_Store index b5a7aa7..64bb560 100644 Binary files a/qController.Standard/.DS_Store and b/qController.Standard/.DS_Store differ diff --git a/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs b/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs index e8ba353..930c5f8 100644 --- a/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs +++ b/qController.Standard/Classes/Cell/QSelectedCueOptionsCell.cs @@ -61,7 +61,7 @@ namespace qController }; mainSlider.ValueChanged += (sender, args) => { - qController.qSender.sendArgs("/cue/selected/sliderLevel/0", (float)args.NewValue); + qController.qClient.sendArgs("/cue/selected/sliderLevel/0", (float)args.NewValue); }; leftSlider = new Slider @@ -71,7 +71,7 @@ namespace qController }; leftSlider.ValueChanged += (sender, args) => { - qController.qSender.sendArgs("/cue/selected/sliderLevel/1", (float)args.NewValue); + qController.qClient.sendArgs("/cue/selected/sliderLevel/1", (float)args.NewValue); }; rightSlider = new Slider @@ -81,7 +81,7 @@ namespace qController }; rightSlider.ValueChanged += (sender, args) => { - qController.qSender.sendArgs("/cue/selected/sliderLevel/2", (float)args.NewValue); + qController.qClient.sendArgs("/cue/selected/sliderLevel/2", (float)args.NewValue); }; mainG.Children.Add(mainSlider, 1, 0); mainG.Children.Add(leftSlider, 1, 1); diff --git a/qController.Standard/Classes/Communication/QClient.cs b/qController.Standard/Classes/Communication/QClient.cs new file mode 100644 index 0000000..aca4cc0 --- /dev/null +++ b/qController.Standard/Classes/Communication/QClient.cs @@ -0,0 +1,45 @@ +using System; +using SharpOSC; +using Newtonsoft.Json; +namespace qController +{ + public class QClient + { + TCPSender tcpSender; + UDPSender udpSender; + + public QClient(string address, int port) + { + tcpSender = new TCPSender(address, port); + udpSender = new UDPSender(address, port); + } + + public void sendString(string address) + { + tcpSender.Send(new OscMessage(address)); + } + + public OscMessage sendAndReceiveString(string address) + { + return tcpSender.SendAndReceive(new OscMessage(address)); + } + + public OscMessage sendAndReceiveStringArgs(string address, params object[] args) + { + return tcpSender.SendAndReceive(new OscMessage(address, args)); + } + + public void sendStringUDP(string address) + { + udpSender.Send(new OscMessage(address)); + } + public void sendArgs(string address, object args) + { + tcpSender.Send(new OscMessage(address, args)); + } + public void sendArgsUDP(string address, object args) + { + udpSender.Send(new OscMessage(address, args)); + } + } +} diff --git a/qController.Standard/Classes/Communication/QController.cs b/qController.Standard/Classes/Communication/QController.cs index b2cd5c9..1e9968f 100644 --- a/qController.Standard/Classes/Communication/QController.cs +++ b/qController.Standard/Classes/Communication/QController.cs @@ -8,33 +8,32 @@ namespace qController public class QController { - public QSender qSender; - QReceiver qReceiver; QUpdater qUpdater; public QParser qParser; QCue selectedCue; - + public QClient qClient; + QWorkSpace qWorkspace; public QController(string address, int port) { - - qSender = new QSender(address, port); - qReceiver = new QReceiver(port+1, this); + qClient = new QClient(address, port); + qParser = new QParser(); qUpdater = new QUpdater(this); qUpdater.Start(); qParser.SelectedCueUpdated += this.OnSelectedCueUpdated; - qReceiver.MessageReceived += qParser.OnMessageReceived; + qParser.WorkspaceUpdated += this.OnWorkspaceUpdated; + } public void sendCommand(string cmd){ - qSender.sendString(cmd); + qClient.sendString(cmd); } public void sendCommandUDP(string cmd) { - qSender.sendStringUDP(cmd); + qClient.sendStringUDP(cmd); } public void updateCueValue(QCue cue, string property, object newValue){ // qSender.sendArgs("/cue_id/"+cue.uniqueID+"/"+property, newValue); @@ -46,8 +45,13 @@ namespace qController //Console.WriteLine("Selected Cue Updated: Name=" + selectedCue.listName); } + public void OnWorkspaceUpdated(object source, WorkspaceEventArgs args) + { + + qWorkspace = args.UpdatedWorkspace; + + } public void Kill(){ - qReceiver.Close(); qUpdater.Kill(); } } diff --git a/qController.Standard/Classes/Communication/QParser.cs b/qController.Standard/Classes/Communication/QParser.cs index b0eb13f..564deb8 100644 --- a/qController.Standard/Classes/Communication/QParser.cs +++ b/qController.Standard/Classes/Communication/QParser.cs @@ -1,6 +1,7 @@ using System; using SharpOSC; using Newtonsoft.Json.Linq; +using Newtonsoft.Json; namespace qController { @@ -21,7 +22,14 @@ namespace qController set; } } - + public class WorkspaceEventArgs : EventArgs + { + public QWorkSpace UpdatedWorkspace + { + get; + set; + } + } public class QParser { public QParser() @@ -31,9 +39,11 @@ namespace qController public delegate void SelectedCueUpdatedHandler(object source, CueEventArgs args); public delegate void AudioLevelsUpdatedHandler(object source, AudioLevelArgs args); + public delegate void WorkspaceUpdatedHandler(object source, WorkspaceEventArgs args); public event SelectedCueUpdatedHandler SelectedCueUpdated; public event AudioLevelsUpdatedHandler AudioLevelsUpdated; + public event WorkspaceUpdatedHandler WorkspaceUpdated; public void ParseMessage(OscMessage msg){ if (msg.Address.Contains("selectedCues")) @@ -42,19 +52,16 @@ namespace qController ParseNoteInfo(msg); else if (msg.Address.Contains("levels")) ParseLevelInfo(msg); - + else if (msg.Address.Contains("cueLists")) + ParseWorkspaceInfo(msg); + else + Console.WriteLine(msg.Address); } - - public void OnMessageReceived(object source, MessageEventArgs args){ - //Console.WriteLine("Packet Received"); - ParseMessage(args.Message); - } - public void ParseSelectedCueInfo(OscMessage msg){ JArray selectedCues = (JArray)OSC2JSON(msg); - if(selectedCues.Count > 0){ + if (selectedCues.Count > 0){ foreach(JObject item in selectedCues){ - QCue parsedCue = new QCue(item); + QCue parsedCue = JsonConvert.DeserializeObject(item.ToString()); OnSelectedCueUpdated(parsedCue); } @@ -72,11 +79,25 @@ namespace qController OnAudioLevelsUpdated(levels); } + public void ParseWorkspaceInfo(OscMessage msg) + { + if (msg.Arguments.Count > 0) + { + QWorkSpace workspace = JsonConvert.DeserializeObject(msg.Arguments[0].ToString()); + OnWorkspaceUpdated(workspace); + } + } + public JToken OSC2JSON(OscMessage Msg){ JObject json = JObject.Parse(Msg.Arguments.ToArray()[0].ToString()); return json.GetValue("data"); } + protected virtual void OnWorkspaceUpdated(QWorkSpace workspace) + { + if (WorkspaceUpdated != null) + WorkspaceUpdated(this, new WorkspaceEventArgs() { UpdatedWorkspace = workspace }); + } protected virtual void OnSelectedCueUpdated(QCue cue) { if (SelectedCueUpdated != null) diff --git a/qController.Standard/Classes/Communication/QReceiver.cs b/qController.Standard/Classes/Communication/QReceiver.cs index 56de886..a68cf2e 100644 --- a/qController.Standard/Classes/Communication/QReceiver.cs +++ b/qController.Standard/Classes/Communication/QReceiver.cs @@ -44,9 +44,8 @@ namespace qController messageReceived = (OscMessage)udpListener.Receive(); Thread.Sleep(1); } - Console.WriteLine("Received a message!"); - Console.WriteLine(messageReceived.Address); OnMessageReceived(messageReceived); + } Console.WriteLine("Loop Ended"); @@ -59,6 +58,7 @@ namespace qController } protected virtual void OnMessageReceived(OscMessage msg){ + Console.WriteLine("Message Received"); if (MessageReceived != null) MessageReceived(this, new MessageEventArgs(){Message = msg}); } diff --git a/qController.Standard/Classes/Communication/QUpdater.cs b/qController.Standard/Classes/Communication/QUpdater.cs index 2bb02a5..f2d4345 100644 --- a/qController.Standard/Classes/Communication/QUpdater.cs +++ b/qController.Standard/Classes/Communication/QUpdater.cs @@ -1,5 +1,6 @@ using System; using Xamarin.Forms; +using SharpOSC; namespace qController { public class QUpdater @@ -14,10 +15,21 @@ namespace qController public void Start(){ active = true; Device.StartTimer(TimeSpan.FromSeconds(0.01), () => { - qController.sendCommandUDP("/selectedCues"); - qController.sendCommandUDP("/cue/selected/levels"); + //qController.sendCommandUDP("/selectedCues"); + UpdateSelected(); + UpdateLevels(); return active; }); + + } + + public void UpdateSelected() + { + qController.qParser.ParseMessage(qController.qClient.sendAndReceiveString("/selectedCues")); + } + public void UpdateLevels() + { + qController.qParser.ParseMessage(qController.qClient.sendAndReceiveString("/cue/selected/levels")); } public void Kill(){ diff --git a/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs b/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs index ef47e5e..2cd1ba6 100644 --- a/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs +++ b/qController.Standard/Classes/Communication/SharpOSC/TCPSender.cs @@ -3,9 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; -using System.Net; using System.Threading; -using System.IO; namespace SharpOSC { @@ -22,8 +20,8 @@ namespace SharpOSC get { return _address; } } string _address; - TcpClient client; + Thread receivingThread; byte END = 0xc0; byte ESC = 0xdb; @@ -35,70 +33,106 @@ namespace SharpOSC { _port = port; _address = address; - } public void Send(byte[] message) { client = new TcpClient(Address, Port); - Console.WriteLine("Available: " + client.Available); - Console.WriteLine("Connected: " + client.Connected); - List slipData= new List(); - - byte[] esc_end = { ESC, ESC_END }; - byte[] esc_esc = { ESC, ESC_ESC }; - byte[] end = { END }; - - int length = message.Length; - for (int i = 0; i < length; i++) - { - if (message[i] == END) - { - slipData.AddRange(esc_end); - } else if (message[i] == ESC) - { - slipData.AddRange(esc_esc); - } - else - { - slipData.Add(message[i]); - } - } - slipData.AddRange(end); + byte[] slipData = SlipEncode(message); NetworkStream netStream = client.GetStream(); netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length); netStream.Close(); client.Close(); } - public void Receive() + public OscMessage Receive() { - NetworkStream netStream = client.GetStream(); - List responseData = new List(); - if (netStream.CanRead) + OscMessage response = new OscMessage("/null"); + try { - byte[] buffer = new byte[512]; - - int bytesRead = 0; - do + NetworkStream netStream = client.GetStream(); + netStream.ReadTimeout = 250; + List responseData = new List(); + if (netStream.CanRead) { - bytesRead = netStream.Read(buffer, 0, buffer.Length); - responseData.AddRange(buffer); + byte[] buffer = new byte[1024]; - } while (netStream.DataAvailable); - OscMessage response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray()); + int bytesRead = 0; + do + { + bytesRead = netStream.Read(buffer, 0, buffer.Length); + responseData.AddRange(buffer); + } while (netStream.DataAvailable); + response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray()); + netStream.Close(); + client.Close(); + } + } catch(Exception e) + { + Console.WriteLine(e.ToString()); } - netStream.Close(); + return response; } + + public OscMessage SendAndReceive(byte[] message) + { + client = new TcpClient(Address, Port); + byte[] slipData = SlipEncode(message); + NetworkStream netStream = client.GetStream(); + netStream.Write(slipData.ToArray(), 0, slipData.ToArray().Length); + OscMessage response = Receive(); + return response; + } + + public OscMessage SendAndReceive(OscPacket packet) + { + byte[] data = packet.GetBytes(); + OscMessage response = SendAndReceive(data); + return response; + } + public void StartReceiving() + { + receivingThread.Start(); + } + public void Send(OscPacket packet) { byte[] data = packet.GetBytes(); Send(data); } + public byte[] SlipEncode(byte[] data) + { + List slipData = new List(); + + byte[] esc_end = { ESC, ESC_END }; + byte[] esc_esc = { ESC, ESC_ESC }; + byte[] end = { END }; + + int length = data.Length; + for (int i = 0; i < length; i++) + { + if (data[i] == END) + { + slipData.AddRange(esc_end); + } + else if (data[i] == ESC) + { + slipData.AddRange(esc_esc); + } + else + { + slipData.Add(data[i]); + } + } + slipData.AddRange(end); + return slipData.ToArray(); + } + public void Close() { client.GetStream().Close(); + receivingThread.Abort(); client.Close(); } } diff --git a/qController.Standard/Classes/Cues/QCue.cs b/qController.Standard/Classes/Cues/QCue.cs index 7f78e74..e044a0d 100644 --- a/qController.Standard/Classes/Cues/QCue.cs +++ b/qController.Standard/Classes/Cues/QCue.cs @@ -4,26 +4,13 @@ namespace qController { public class QCue { - public string number; - public string uniqueID; - public bool flagged; - public string listName; - public string type; - public string colorName; - public string name; - public bool armed; - - public QCue(JObject json){ - //Console.WriteLine(json); - number = (string)json.GetValue("number"); - uniqueID = (string)json.GetValue("uniqueID"); - flagged = (bool)json.GetValue("flagged"); - listName = (string)json.GetValue("listName"); - type = (string)json.GetValue("type"); - colorName = (string)json.GetValue("colorName"); - name = (string)json.GetValue("name"); - armed = (bool)json.GetValue("armed"); - } - + public string number { get; set; } + public string uniqueID { get; set; } + public bool flagged { get; set; } + public string listName { get; set; } + public string type { get; set; } + public string colorName { get; set; } + public string name { get; set; } + public bool armed { get; set; } } } diff --git a/qController.Standard/Classes/Cues/QCueList.cs b/qController.Standard/Classes/Cues/QCueList.cs new file mode 100644 index 0000000..9d7883c --- /dev/null +++ b/qController.Standard/Classes/Cues/QCueList.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace qController +{ + public class QCueList + { + public string number { get; set; } + public string uniqueID { get; set; } + public List cues { get; set; } + public bool flagged { get; set; } + public string listName { get; set; } + public string type { get; set; } + public string colorName { get; set; } + public string name { get; set; } + public bool armed { get; set; } + } +} diff --git a/qController.Standard/Classes/Cues/QDefinitions.cs b/qController.Standard/Classes/Cues/QDefinitions.cs new file mode 100644 index 0000000..b990bbd --- /dev/null +++ b/qController.Standard/Classes/Cues/QDefinitions.cs @@ -0,0 +1,10 @@ +using System; +namespace qController.Classes.Cues +{ + public class QDefinitions + { + public QDefinitions() + { + } + } +} diff --git a/qController.Standard/Classes/Cues/QGroupCue.cs b/qController.Standard/Classes/Cues/QGroupCue.cs deleted file mode 100644 index f544fb4..0000000 --- a/qController.Standard/Classes/Cues/QGroupCue.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Newtonsoft.Json.Linq; -namespace qController -{ - public class QGroupCue : QCue - { - - public QGroupCue(JObject json) : base(json) - { - - } - } -} diff --git a/qController.Standard/Classes/Cues/QWorkSpace.cs b/qController.Standard/Classes/Cues/QWorkSpace.cs new file mode 100644 index 0000000..ae33751 --- /dev/null +++ b/qController.Standard/Classes/Cues/QWorkSpace.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace qController +{ + public class QWorkSpace + { + public string status { get; set; } + public List data { get; set; } + public string workspace_id { get; set; } + public string address { get; set; } + } +} diff --git a/qController.Standard/Pages/ControlPage.xaml.cs b/qController.Standard/Pages/ControlPage.xaml.cs index 2da1001..ce73183 100644 --- a/qController.Standard/Pages/ControlPage.xaml.cs +++ b/qController.Standard/Pages/ControlPage.xaml.cs @@ -18,6 +18,9 @@ namespace qController qController = new QController(address, 53000); qController.qParser.SelectedCueUpdated += SelectedCueUpdated; + qController.qParser.WorkspaceUpdated += WorkspaceUpdated; + + qController.qParser.ParseWorkspaceInfo(qController.qClient.sendAndReceiveString("/cueLists")); NavigationPage.SetHasNavigationBar(this, false); instanceName.Text = name; @@ -145,6 +148,18 @@ namespace qController }); } + public void WorkspaceUpdated(object sender, WorkspaceEventArgs e) + { + if(e.UpdatedWorkspace.data.Count > 0) + { + Device.BeginInvokeOnMainThread(() => + { + // + }); + Console.WriteLine("Workspace Updated: " + e.UpdatedWorkspace.workspace_id); + } + } + protected override void OnDisappearing() { base.OnDisappearing(); diff --git a/qController.Standard/qController.csproj b/qController.Standard/qController.csproj index b78845f..e6f31af 100644 --- a/qController.Standard/qController.csproj +++ b/qController.Standard/qController.csproj @@ -35,6 +35,8 @@ + +