mirror of
https://github.com/jwetzell/QControlKit.git
synced 2026-08-20 14:39:05 +00:00
Basic workspace connection and Cue Lists fetching working
This commit is contained in:
+41
-4
@@ -1,23 +1,60 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio Version 16
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSharp", "QSharp\QSharp.csproj", "{51CD2579-79C9-49A9-B68D-93CBE878BAA1}"
|
VisualStudioVersion = 16.0.30128.74
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QSharp", "QSharp\QSharp.csproj", "{51CD2579-79C9-49A9-B68D-93CBE878BAA1}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSharpDemo", "QSharpDemo\QSharpDemo.csproj", "{8518D042-D511-4DBB-8406-5B11B2777ED2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QSharpDemo", "QSharpDemo\QSharpDemo.csproj", "{8518D042-D511-4DBB-8406-5B11B2777ED2}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|ARM = Debug|ARM
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|ARM = Release|ARM
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|Any CPU.Build.0 = Release|Any CPU
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{51CD2579-79C9-49A9-B68D-93CBE878BAA1}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{8518D042-D511-4DBB-8406-5B11B2777ED2}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {E5BF7535-FB56-4373-89F2-B0ABBD010092}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace QSharp
|
||||||
|
{
|
||||||
|
public class QServerFoundArgs : EventArgs
|
||||||
|
{
|
||||||
|
public QServer server { get; set; }
|
||||||
|
}
|
||||||
|
public class QWorkspacesUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
public List<QWorkspaceInfo> Workspaces { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QWorkspaceUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QWorkspaceSettingsUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string settingsType { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QWorkspaceLightDashboardUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QWorkspaceConnectedArgs : EventArgs
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QWorkspaceDisconnectedArgs : EventArgs
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QWorkspaceConnectionErrorArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string status { get; set; }
|
||||||
|
}
|
||||||
|
public class QQLabPreferencesUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string key { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QCueUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QCueListsUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
public JToken data { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QCueNeedsUpdatedArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string cueID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QCueListChangedPlaybackPositionArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string cueID { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
namespace QSharp
|
||||||
|
{
|
||||||
|
public delegate void QServerFoundHandler(object source, QServerFoundArgs args);
|
||||||
|
|
||||||
|
public delegate void QWorkspacesUpdatedHandler(object source, QWorkspacesUpdatedArgs args);
|
||||||
|
|
||||||
|
public delegate void QWorkspaceUpdatedHandler(object source, QWorkspaceUpdatedArgs args);
|
||||||
|
public delegate void QWorkspaceSettingsUpdatedHandler(object source, QWorkspaceSettingsUpdatedArgs args);
|
||||||
|
public delegate void QWorkspaceLightDashboardUpdatedHandler(object source, QWorkspaceLightDashboardUpdatedArgs args);
|
||||||
|
public delegate void QWorkspaceConnectedHandler(object source, QWorkspaceConnectedArgs args);
|
||||||
|
public delegate void QWorkspaceDisconnectedHandler(object source, QWorkspaceDisconnectedArgs args);
|
||||||
|
public delegate void QWorkspaceConnectionErrorHandler(object source, QWorkspaceConnectionErrorArgs args);
|
||||||
|
public delegate void QQLabPreferencesUpdatedHandler(object source, QQLabPreferencesUpdatedArgs args);
|
||||||
|
|
||||||
|
|
||||||
|
public delegate void QCueUpdatedHandler(object source, QCueUpdatedArgs args);
|
||||||
|
public delegate void QCueListsUpdatesHandler(object source, QCueListsUpdatedArgs args);
|
||||||
|
public delegate void QCueNeedsUpdatedHandler(object source, QCueNeedsUpdatedArgs args);
|
||||||
|
public delegate void QCueListChangedPlaybackPositionHandler(object source, QCueListChangedPlaybackPositionArgs args);
|
||||||
|
}
|
||||||
+37
-17
@@ -6,49 +6,50 @@ namespace QSharp
|
|||||||
{
|
{
|
||||||
public class QBrowser
|
public class QBrowser
|
||||||
{
|
{
|
||||||
const string UDPServiceType = "_qlab._udp.local.";
|
|
||||||
const string TCPServiceType = "_qlab._tcp.local.";
|
|
||||||
|
|
||||||
const int udpPort = 53000;
|
ZeroconfResolver.ResolverListener zeroconfTCPBrowser;
|
||||||
|
|
||||||
IObservable<IZeroconfHost> netServices;
|
public ObservableCollection<QServer> servers = new ObservableCollection<QServer>();
|
||||||
ZeroconfResolver.ResolverListener netServiceTCPBrowser;
|
|
||||||
|
public event QServerFoundHandler ServerFound;
|
||||||
|
|
||||||
ObservableCollection<QServer> servers = new ObservableCollection<QServer>();
|
|
||||||
|
|
||||||
public QBrowser()
|
public QBrowser()
|
||||||
{
|
{
|
||||||
|
|
||||||
Console.WriteLine("QBrowser Init");
|
Console.WriteLine("QBrowser Init");
|
||||||
netServiceTCPBrowser = ZeroconfResolver.CreateListener(TCPServiceType);
|
zeroconfTCPBrowser = ZeroconfResolver.CreateListener(QBonjour.TCPService);
|
||||||
netServiceTCPBrowser.ServiceFound += ServerFound;
|
zeroconfTCPBrowser.ServiceFound += ZeroconfHostFound;
|
||||||
netServiceTCPBrowser.ServiceLost += ServerLost;
|
zeroconfTCPBrowser.ServiceLost += ZeroconfHostLost;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ServerLost(object sender, IZeroconfHost e)
|
private void ZeroconfHostLost(object sender, IZeroconfHost e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Lost {e.DisplayName} : {e.IPAddress}");
|
Console.WriteLine($"Lost {e.DisplayName} : {e.IPAddress}");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ServerFound(object sender, IZeroconfHost e)
|
private void ZeroconfHostFound(object sender, IZeroconfHost e)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
foreach(var service in e.Services)
|
foreach(var service in e.Services)
|
||||||
{
|
{
|
||||||
if (service.Key.Equals(TCPServiceType))
|
if (service.Key.Equals(QBonjour.TCPService))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Found {e.DisplayName} : {e.IPAddress} : {service.Value.Port}");
|
Console.WriteLine($"Found {e.DisplayName} : {e.IPAddress} : {service.Value.Port}");
|
||||||
|
|
||||||
QServer server = getServerFromAddress(e.IPAddress);
|
QServer server = serverForAddress(e.IPAddress);
|
||||||
|
|
||||||
if(server == null)
|
if(server == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("New Server Found so adding");
|
Console.WriteLine("New Server Found so adding");
|
||||||
QServer serverToAdd = new QServer(e.IPAddress, service.Value.Port, e.DisplayName);
|
QServer serverToAdd = new QServer(e.IPAddress, service.Value.Port);
|
||||||
|
serverToAdd.name = e.DisplayName;
|
||||||
|
serverToAdd.zeroconfHost = e;
|
||||||
servers.Add(serverToAdd);
|
servers.Add(serverToAdd);
|
||||||
serverToAdd.refreshWorkspaces();
|
serverToAdd.refreshWorkspaces();
|
||||||
|
OnServerFound(serverToAdd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -60,9 +61,8 @@ namespace QSharp
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QServer getServerFromAddress(string address)
|
public QServer serverForAddress(string address)
|
||||||
{
|
{
|
||||||
QServer foundServer = null;
|
|
||||||
foreach(var server in servers)
|
foreach(var server in servers)
|
||||||
{
|
{
|
||||||
if (server.host.Equals(address))
|
if (server.host.Equals(address))
|
||||||
@@ -71,7 +71,27 @@ namespace QSharp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundServer;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QServer serverForIZeroconfHost(IZeroconfHost zeroconfHost)
|
||||||
|
{
|
||||||
|
foreach (var server in servers)
|
||||||
|
{
|
||||||
|
if (server.zeroconfHost == zeroconfHost)
|
||||||
|
{
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnServerFound(QServer server)
|
||||||
|
{
|
||||||
|
if (ServerFound != null)
|
||||||
|
ServerFound(this, new QServerFoundArgs { server = server });
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+179
-31
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using SharpOSC;
|
using SharpOSC;
|
||||||
|
|
||||||
namespace QSharp
|
namespace QSharp
|
||||||
@@ -9,62 +11,208 @@ namespace QSharp
|
|||||||
{
|
{
|
||||||
TCPClient tcpClient;
|
TCPClient tcpClient;
|
||||||
|
|
||||||
public class WorkspacesUpdatedArgs : EventArgs
|
public event QWorkspacesUpdatedHandler WorkspacesUpdated;
|
||||||
{
|
|
||||||
public List<QWorkspaceInfo> Workspaces { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public event QCueUpdatedHandler CueUpdated;
|
||||||
|
public event QCueListsUpdatesHandler CueListsUpdated;
|
||||||
|
public event QCueNeedsUpdatedHandler CueNeedsUpdated;
|
||||||
|
|
||||||
public delegate void WorkspacesUpdatedHandler(object source, WorkspacesUpdatedArgs args);
|
public event QCueListChangedPlaybackPositionHandler CueListChangedPlaybackPosition;
|
||||||
public event WorkspacesUpdatedHandler WorkspacesUpdated;
|
|
||||||
|
public event QWorkspaceUpdatedHandler WorkspaceUpdated;
|
||||||
|
public event QWorkspaceSettingsUpdatedHandler WorkspaceSettingsUpdated;
|
||||||
|
|
||||||
|
public event QWorkspaceLightDashboardUpdatedHandler WorkspaceLightDashboardUpdated;
|
||||||
|
public event QQLabPreferencesUpdatedHandler QLabPreferencesUpdated;
|
||||||
|
|
||||||
|
public event QWorkspaceDisconnectedHandler WorkspaceDisconnected;
|
||||||
|
public event QWorkspaceConnectedHandler WorkspaceConnected;
|
||||||
|
public event QWorkspaceConnectionErrorHandler WorkspaceConnectionError;
|
||||||
|
|
||||||
public QClient(string host, int port)
|
public QClient(string host, int port)
|
||||||
{
|
{
|
||||||
tcpClient = new TCPClient(host, port);
|
tcpClient = new TCPClient(host, port);
|
||||||
tcpClient.Connect();
|
Console.WriteLine($"[QClient] setup connection to: <{host}:{port}>");
|
||||||
Console.WriteLine($"QClient setup {host}:{port}");
|
tcpClient.MessageReceived += ProcessMessage;
|
||||||
tcpClient.MessageReceived += ResponseReceived;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResponseReceived(object source, MessageEventArgs args)
|
|
||||||
|
public bool IsConnnected { get { return tcpClient.IsConnected; } }
|
||||||
|
|
||||||
|
public bool connect()
|
||||||
{
|
{
|
||||||
OscMessage msg = args.Message;
|
return tcpClient.Connect();
|
||||||
foreach (var obj in msg.Arguments)
|
|
||||||
{
|
|
||||||
QResponse response = JsonConvert.DeserializeObject<QResponse>(obj.ToString());
|
|
||||||
|
|
||||||
switch (response.getReplyType())
|
|
||||||
{
|
|
||||||
case "WORKSPACES":
|
|
||||||
Console.WriteLine("WORKSPACES RECEIVED");
|
|
||||||
OnWorkspacesUpdated(response);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void disconnect()
|
||||||
|
{
|
||||||
|
tcpClient.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void sendMessage(string address, params object[] args)
|
public void sendMessage(string address, params object[] args)
|
||||||
{
|
{
|
||||||
tcpClient.Send(new OscMessage(address, args));
|
tcpClient.Send(new OscMessage(address, args));
|
||||||
Console.WriteLine($"QClient send message {address}");
|
// Console.WriteLine($"QClient send message {address}");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnWorkspacesUpdated(QResponse response)
|
private void ProcessMessage(object source, MessageEventArgs args)
|
||||||
|
{
|
||||||
|
|
||||||
|
QMessage message = new QMessage(args.Message);
|
||||||
|
|
||||||
|
if (message.IsReply)
|
||||||
|
{
|
||||||
|
JToken data = message.response;
|
||||||
|
//special case, want to update cue properties
|
||||||
|
if (message.IsReplyFromCue)
|
||||||
|
{
|
||||||
|
//todo check data type?
|
||||||
|
}
|
||||||
|
else if (message.IsReplyFromCueLists)
|
||||||
|
{
|
||||||
|
OnCueListsUpdated(message.response);
|
||||||
|
}
|
||||||
|
else if (message.IsWorkspacesInfo)
|
||||||
|
{
|
||||||
|
OnWorkspacesUpdated(message);
|
||||||
|
}
|
||||||
|
else if (message.IsConnect)
|
||||||
|
{
|
||||||
|
if (message.response.ToString() == "ok")
|
||||||
|
OnWorkspaceConnected();
|
||||||
|
else
|
||||||
|
OnWorkspaceConnectionError(message.response.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[client] unhandled reply message: {message.address}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(message.IsUpdate) {
|
||||||
|
if (message.IsCueUpdate)
|
||||||
|
{
|
||||||
|
OnCueNeedsUpdated(message.cueID);
|
||||||
|
}
|
||||||
|
else if (message.IsPlaybackPositionUpdate)
|
||||||
|
{
|
||||||
|
OnCueListChangedPlaybackPosition(message.cueID);
|
||||||
|
}
|
||||||
|
else if (message.IsWorkspaceUpdate)
|
||||||
|
{
|
||||||
|
OnWorkspaceUpdated();
|
||||||
|
}
|
||||||
|
else if (message.IsWorkspaceSettingsUpdate)
|
||||||
|
{
|
||||||
|
string settingsType = message.AddressParts.Last();
|
||||||
|
if (settingsType == null)
|
||||||
|
return;
|
||||||
|
OnWorkspaceSettingsUpdated(settingsType);
|
||||||
|
}
|
||||||
|
else if (message.IsLightDashboardUpdate)
|
||||||
|
{
|
||||||
|
//need to do checks for 4.2 or newer
|
||||||
|
OnWorkspaceLightDashboardUpdated();
|
||||||
|
}
|
||||||
|
else if ( message.IsPreferencesUpdate)
|
||||||
|
{
|
||||||
|
//need to do checks for 4.2 or newer
|
||||||
|
|
||||||
|
string key = message.AddressParts.Last();
|
||||||
|
if (key == null)
|
||||||
|
return;
|
||||||
|
OnQLabPreferencesUpdated(key);
|
||||||
|
}
|
||||||
|
else if (message.IsDisconnect)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[client] disconnect message received: {message.address}");
|
||||||
|
OnWorkspaceDisconnected();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[client] unhandled update message: {message.address}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[client] unhandled message: {message.address}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnCueNeedsUpdated(string cueID)
|
||||||
|
{
|
||||||
|
if (CueNeedsUpdated != null)
|
||||||
|
CueNeedsUpdated(this, new QCueNeedsUpdatedArgs { cueID = cueID });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnCueListsUpdated(JToken response)
|
||||||
|
{
|
||||||
|
if (CueListsUpdated != null)
|
||||||
|
CueListsUpdated(this, new QCueListsUpdatedArgs { data = response });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnCueListChangedPlaybackPosition(string cueID)
|
||||||
|
{
|
||||||
|
if (CueListChangedPlaybackPosition != null)
|
||||||
|
CueListChangedPlaybackPosition(this, new QCueListChangedPlaybackPositionArgs { cueID = cueID });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnWorkspaceUpdated()
|
||||||
|
{
|
||||||
|
if (WorkspaceUpdated != null)
|
||||||
|
WorkspaceUpdated(this, new QWorkspaceUpdatedArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnWorkspaceSettingsUpdated(string settingsType)
|
||||||
|
{
|
||||||
|
if (WorkspaceSettingsUpdated != null)
|
||||||
|
WorkspaceSettingsUpdated(this, new QWorkspaceSettingsUpdatedArgs { settingsType = settingsType});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnWorkspaceLightDashboardUpdated()
|
||||||
|
{
|
||||||
|
if (WorkspaceLightDashboardUpdated != null)
|
||||||
|
WorkspaceLightDashboardUpdated(this, new QWorkspaceLightDashboardUpdatedArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnQLabPreferencesUpdated(string key)
|
||||||
|
{
|
||||||
|
if (QLabPreferencesUpdated != null)
|
||||||
|
QLabPreferencesUpdated(this, new QQLabPreferencesUpdatedArgs { key = key });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnWorkspaceDisconnected()
|
||||||
|
{
|
||||||
|
if (WorkspaceDisconnected != null)
|
||||||
|
WorkspaceDisconnected(this, new QWorkspaceDisconnectedArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnWorkspaceConnected()
|
||||||
|
{
|
||||||
|
if (WorkspaceConnected != null)
|
||||||
|
WorkspaceConnected(this, new QWorkspaceConnectedArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnWorkspaceConnectionError(string status)
|
||||||
|
{
|
||||||
|
if (WorkspaceConnectionError != null)
|
||||||
|
WorkspaceConnectionError(this, new QWorkspaceConnectionErrorArgs { status = status});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnWorkspacesUpdated(QMessage message)
|
||||||
{
|
{
|
||||||
if(WorkspacesUpdated != null)
|
if(WorkspacesUpdated != null)
|
||||||
{
|
{
|
||||||
List<QWorkspaceInfo> workspaces = new List<QWorkspaceInfo>();
|
List<QWorkspaceInfo> workspaces = new List<QWorkspaceInfo>();
|
||||||
foreach (var item in response.data)
|
foreach (var item in message.response)
|
||||||
{
|
{
|
||||||
QWorkspaceInfo workspacefound = JsonConvert.DeserializeObject<QWorkspaceInfo>(item.ToString());
|
QWorkspaceInfo workspacefound = JsonConvert.DeserializeObject<QWorkspaceInfo>(item.ToString());
|
||||||
workspaces.Add(workspacefound);
|
workspaces.Add(workspacefound);
|
||||||
Console.WriteLine(workspacefound.displayName);
|
|
||||||
}
|
}
|
||||||
WorkspacesUpdated(this, new WorkspacesUpdatedArgs { Workspaces = workspaces });
|
WorkspacesUpdated(this, new QWorkspacesUpdatedArgs { Workspaces = workspaces });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+668
-5
@@ -1,19 +1,682 @@
|
|||||||
using System.Collections.Generic;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace QSharp
|
namespace QSharp
|
||||||
{
|
{
|
||||||
public class QCue
|
public class QCue
|
||||||
{
|
{
|
||||||
Dictionary<string,object> cueData = new Dictionary<string,object>();
|
|
||||||
|
public QWorkspace workspace;
|
||||||
|
public Dictionary<string, object> cueData;
|
||||||
|
public List<QCue> childCues;
|
||||||
|
public Dictionary<string, QCue> childCuesUIDMap;
|
||||||
|
|
||||||
|
public int sortIndex;
|
||||||
|
|
||||||
|
private bool needsSortChildCues;//?
|
||||||
|
private bool needsNotifyCueUpdated;//?
|
||||||
|
|
||||||
|
public bool ignoreUpdates;
|
||||||
|
|
||||||
|
|
||||||
public QCue()
|
public QCue()
|
||||||
{
|
{
|
||||||
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public object propertyForKey(string key)
|
public QCue(QWorkspace workspace)
|
||||||
{
|
{
|
||||||
if (cueData.ContainsKey(key))
|
init();
|
||||||
return cueData[key];
|
this.workspace = workspace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QCue(JToken dict, QWorkspace workspace)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
this.workspace = workspace;
|
||||||
|
|
||||||
|
JToken children = dict[QOSCKey.Cues];
|
||||||
|
if(children != null && children.Type == JTokenType.Array)
|
||||||
|
{
|
||||||
|
//Console.WriteLine($"[cue] new cue being created with {children.Count()} childCues");
|
||||||
|
foreach (var aChildDict in children)
|
||||||
|
{
|
||||||
|
string uid = (string)aChildDict[QOSCKey.UID];
|
||||||
|
//Console.WriteLine($"[cue] childDict with uid: {uid} being processed");
|
||||||
|
if (uid == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QCue child = new QCue(aChildDict, workspace);
|
||||||
|
|
||||||
|
childCues.Add(child);
|
||||||
|
childCuesUIDMap.Add(uid, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePropertiesWithDictionary(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
cueData = new Dictionary<string, object> {
|
||||||
|
{ QOSCKey.Flagged, false },
|
||||||
|
{ QOSCKey.Armed, false },
|
||||||
|
{ QOSCKey.PreWait, false },
|
||||||
|
{ QOSCKey.PercentPreWaitElapsed, false },
|
||||||
|
{ QOSCKey.PercentActionElapsed, false },
|
||||||
|
{ QOSCKey.PostWait, false },
|
||||||
|
{ QOSCKey.PercentPostWaitElapsed, false },
|
||||||
|
{ QOSCKey.IsPanicking, false },
|
||||||
|
{ QOSCKey.IsTailingOut, false },
|
||||||
|
{ QOSCKey.IsRunning, false },
|
||||||
|
{ QOSCKey.IsLoaded, false },
|
||||||
|
{ QOSCKey.IsPaused, false },
|
||||||
|
{ QOSCKey.IsBroken, false },
|
||||||
|
{ QOSCKey.IsOverridden, false },
|
||||||
|
{ QOSCKey.ContinueMode, false }
|
||||||
|
};
|
||||||
|
//TODO init cueData with some keys
|
||||||
|
|
||||||
|
childCues = new List<QCue>();
|
||||||
|
childCuesUIDMap = new Dictionary<string, QCue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string description
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return $"(Cue: {this}) name: {name} [id:{uid} number:{number} type: {type}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//isEqual?
|
||||||
|
//hash?
|
||||||
|
//compare?
|
||||||
|
public bool isEqualToCue(QCue cue) { throw new NotImplementedException(); }
|
||||||
|
public void setWorkspace(QWorkspace workspace)
|
||||||
|
{
|
||||||
|
if(this.workspace != workspace)
|
||||||
|
{
|
||||||
|
this.workspace = workspace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void addChildCue(QCue cue)
|
||||||
|
{
|
||||||
|
string uid = propertyForKey(QOSCKey.UID).ToString();
|
||||||
|
addChildCue(cue, uid);
|
||||||
|
}
|
||||||
|
public void addChildCue(QCue cue, string uid)
|
||||||
|
{
|
||||||
|
if (uid.Length == 0)
|
||||||
|
return;
|
||||||
|
childCues.Add(cue);
|
||||||
|
childCuesUIDMap.Add(uid, cue);
|
||||||
|
//some sorting of the childCues needs to be done?
|
||||||
|
//reset sorting index
|
||||||
|
}
|
||||||
|
public void removeChildCue(QCue cue) { throw new NotImplementedException(); }
|
||||||
|
public void removeAllChildCues() { throw new NotImplementedException(); }
|
||||||
|
public void removeChildCuesWithIDs(List<string> uids) { throw new NotImplementedException(); }
|
||||||
|
|
||||||
|
//copied: yes
|
||||||
|
//implemented: no
|
||||||
|
#region Class Methods
|
||||||
|
public string iconForType(string type) { throw new NotImplementedException(); }
|
||||||
|
public bool cueTypeIsAudio(string type) { throw new NotImplementedException(); }
|
||||||
|
public bool cueTypeIsVideo(string type) { throw new NotImplementedException(); }
|
||||||
|
public bool cueTypeIsGroup(string type) { throw new NotImplementedException(); }
|
||||||
|
public bool cueTypeIsCueList(string type) { throw new NotImplementedException(); }
|
||||||
|
public List<string> fadeModeTitles() { throw new NotImplementedException(); }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//KVC Compliance... do I need this?
|
||||||
|
|
||||||
|
//copied: yes
|
||||||
|
//implemented: not all
|
||||||
|
#region Convenience Accessors
|
||||||
|
public List<QCue> cues
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
List<QCue> cues = (List<QCue>)propertyForKey(QOSCKey.Cues);
|
||||||
|
if (cues == null)
|
||||||
|
return new List<QCue>();
|
||||||
|
return cues;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string parentID
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return propertyForKey(QOSCKey.Parent).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string playbackPositionID() { throw new NotImplementedException(); }
|
||||||
|
public string name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return propertyForKey(QOSCKey.Name).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string number
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return propertyForKey(QOSCKey.Number).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string uid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return propertyForKey(QOSCKey.UID).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string listName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return propertyForKey(QOSCKey.ListName).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string type
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return propertyForKey(QOSCKey.Type).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string notes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return propertyForKey(QOSCKey.Notes).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsFlagged
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (bool)propertyForKey(QOSCKey.Flagged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsOverridden
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (bool)propertyForKey("OSCNameKey");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsBroken
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (bool)propertyForKey("OSCNameKey");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsRunning
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (bool)propertyForKey("OSCNameKey");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsTailingOut
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (bool)propertyForKey("OSCNameKey");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsPanicking
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (bool)propertyForKey("OSCNameKey");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsGroup
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (type.Equals(QCueType.Group))
|
||||||
|
return true;
|
||||||
|
if (type.Equals(QCueType.CueList))
|
||||||
|
return true;
|
||||||
|
if (type.Equals(QCueType.Cart))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsCueList
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if ( type.Equals(QCueType.CueList))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string displayName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string number = this.number;
|
||||||
|
if (number.Length > 0)
|
||||||
|
return $"{number} \u00b7 {nonEmptyName}";
|
||||||
|
else
|
||||||
|
return nonEmptyName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string nonEmptyName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
string nonEmptyName;
|
||||||
|
if (name != null && !name.Equals(""))
|
||||||
|
nonEmptyName = name;
|
||||||
|
else if (listName != null && !listName.Equals(""))
|
||||||
|
nonEmptyName = listName;
|
||||||
|
else
|
||||||
|
nonEmptyName = $"Untitled {type} Cue";
|
||||||
|
|
||||||
|
return nonEmptyName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string workspaceName{ get { return workspace.name; } }
|
||||||
|
public double currentDuration
|
||||||
|
{
|
||||||
|
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//try v4 current duration key first
|
||||||
|
if (propertyForKey(QOSCKey.CurrentDuration) != null)
|
||||||
|
return (double)propertyForKey(QOSCKey.CurrentDuration);
|
||||||
|
else
|
||||||
|
return (double)propertyForKey(QOSCKey.Duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string audioFadeModeName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
if (type.Equals(QCueType.Fade))
|
||||||
|
return "";
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string geoFadeModeName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
if (type.Equals(QCueType.Fade))
|
||||||
|
return "";
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string surfaceName{ get { return propertyForKey("surfaceName").ToString(); } }
|
||||||
|
public string patchName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return (string)propertyForKey("patchDecription");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: THIS IS WHERE THINGS START TO GET TRICKY!
|
||||||
|
|
||||||
|
//TODO add object color method
|
||||||
|
public string color { get { return propertyForKey(QOSCKey.ColorName).ToString(); } }
|
||||||
|
|
||||||
|
//TODO add quaternion property and setter
|
||||||
|
|
||||||
|
public Size surfaceSize() { throw new NotImplementedException(); }
|
||||||
|
public Size cueSize() { throw new NotImplementedException(); }
|
||||||
|
public List<string> availableSurfaceName() { throw new NotImplementedException(); }
|
||||||
|
public List<string> propertyKeys
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//TODO add null check?
|
||||||
|
return cueData.Keys.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasChildren
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return cues.Count > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public QCue firstCue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return cues.First();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public QCue lastCue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return cues.Last();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setIgnoreUpdates(bool ignoreUpdates)
|
||||||
|
{
|
||||||
|
if(this.ignoreUpdates != ignoreUpdates)
|
||||||
|
{
|
||||||
|
this.ignoreUpdates = ignoreUpdates;
|
||||||
|
|
||||||
|
if (!this.ignoreUpdates)
|
||||||
|
{
|
||||||
|
//TODO: update local with QLab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//Copied: Yes
|
||||||
|
//Implemented: Not all
|
||||||
|
#region Mutators
|
||||||
|
public void setCues(List<QCue> cues)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public void setName() { }
|
||||||
|
public void setNumber() { }
|
||||||
|
public void setUid() { }
|
||||||
|
public void setListName() { }
|
||||||
|
public void setType() { }
|
||||||
|
public void setFlagged() { }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//Copied: Yes
|
||||||
|
//Implemented: Not all
|
||||||
|
#region Update Methods
|
||||||
|
public bool updatePropertiesWithDictionary(JToken dict)
|
||||||
|
{
|
||||||
|
return updatePropertiesWithDictionary(dict, true);
|
||||||
|
}
|
||||||
|
public bool updatePropertiesWithDictionary(JToken dict, bool notify)
|
||||||
|
{
|
||||||
|
bool cueUpdated = false;
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
JObject dictObj = (JObject)dict;
|
||||||
|
foreach (var obj in dictObj)
|
||||||
|
{
|
||||||
|
//Console.WriteLine($"[cue] found property {obj.Key} ");
|
||||||
|
JToken value = obj.Value;
|
||||||
|
if (obj.Key.Equals(QOSCKey.Cues))
|
||||||
|
{
|
||||||
|
if (value.Type != JTokenType.Array)
|
||||||
|
continue;
|
||||||
|
updateChildCuesWithPropertiesArray(value, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool didSetProptery = setProperty(value, obj.Key, false);
|
||||||
|
if (didSetProptery)
|
||||||
|
cueUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cueUpdated)
|
||||||
|
return false;
|
||||||
|
if (notify)
|
||||||
|
Console.WriteLine("should notify cue updated.");
|
||||||
|
//something about notifying cueUpdated ? OnCueUpdated event handler maybe?
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//enqueue updated notification?
|
||||||
|
public void updateChildCuesWithPropertiesArray(JToken value, bool removeUnused)
|
||||||
|
{
|
||||||
|
if (!workspace.connected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<string> previousUids = null;
|
||||||
|
if (removeUnused)
|
||||||
|
previousUids = allChildCueUids();
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
foreach (var dict in value)
|
||||||
|
{
|
||||||
|
string uid = (string)dict[QOSCKey.UID];
|
||||||
|
if (uid == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (removeUnused)
|
||||||
|
previousUids.Remove(uid);
|
||||||
|
|
||||||
|
QCue child = cueWithID(uid, false);
|
||||||
|
|
||||||
|
if (child != null)
|
||||||
|
{
|
||||||
|
bool didUpdateProperties = updatePropertiesWithDictionary(dict);
|
||||||
|
if (didUpdateProperties)
|
||||||
|
needsNotifyCueUpdated = true;
|
||||||
|
|
||||||
|
if (child.sortIndex != index)
|
||||||
|
{
|
||||||
|
child.sortIndex = index;
|
||||||
|
|
||||||
|
needsSortChildCues = true;
|
||||||
|
needsNotifyCueUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child = new QCue(dict, workspace);
|
||||||
|
child.sortIndex = index;
|
||||||
|
addChildCue(child, uid);
|
||||||
|
needsNotifyCueUpdated = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: TEST?!
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Methods Copied: Yes
|
||||||
|
//Methods Implemented: Not all
|
||||||
|
#region Children Cues
|
||||||
|
public List<string> allChildCueUids()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
public QCue cueAtIndex(int index)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return new QCue();
|
||||||
|
}
|
||||||
|
public QCue cueWithID(string uid)
|
||||||
|
{
|
||||||
|
return cueWithID(uid, true);
|
||||||
|
}
|
||||||
|
public QCue cueWithID(string uid, bool includeChildren)
|
||||||
|
{
|
||||||
|
//Console.WriteLine($"[cue] searching for cue with id: {uid} - includeChildren: {includeChildren}");
|
||||||
|
if(childCuesUIDMap.ContainsKey(uid))
|
||||||
|
return childCuesUIDMap[uid];
|
||||||
|
|
||||||
|
if (!includeChildren)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
foreach(var cue in cues)
|
||||||
|
{
|
||||||
|
if (!cue.IsGroup)
|
||||||
|
continue;
|
||||||
|
QCue childCue = cue.cueWithID(uid, includeChildren);
|
||||||
|
if (childCue != null)
|
||||||
|
return childCue;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
public QCue cueWithNumber(string number)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return new QCue();
|
||||||
|
}
|
||||||
|
public object propertyForKey(string key)
|
||||||
|
{
|
||||||
|
//TODO: implerment special key checks color, surfaceName, patchDescription,
|
||||||
|
if (key.Equals(QOSCKey.Cues))
|
||||||
|
{
|
||||||
|
return childCues;
|
||||||
|
}
|
||||||
|
if (cueData.ContainsKey(key))
|
||||||
|
{
|
||||||
|
return cueData[key];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool setProperty(object value, string key)
|
||||||
|
{
|
||||||
|
return setProperty( value, key, workspace.defaultSendUpdatesOSC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool setProperty(object value, string key, bool osc)
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
object existingValue = null;
|
||||||
|
if(cueData.ContainsKey(key))
|
||||||
|
existingValue = cueData[key];
|
||||||
|
|
||||||
|
if(existingValue != null)
|
||||||
|
{
|
||||||
|
if (existingValue == value || existingValue.Equals(value))
|
||||||
|
{
|
||||||
|
//Console.WriteLine($"[cue] skipping set property: {key} with type: {value.GetType()} and value: {value}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Console.WriteLine($"[cue] attempting set property: {key} with type: {value.GetType()} and value: {value}");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (workspace.connectedToQLab3 && key.Equals(QOSCKey.Type) && existingValue.Equals(QCueType.CueList) && value.Equals(QCueType.Group))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (key.Equals(QOSCKey.Cues))
|
||||||
|
{
|
||||||
|
if (value.GetType() != typeof(List<QCue>))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
Dictionary<string,QCue> newChildCuesUIDMap = new Dictionary<string, QCue>();
|
||||||
|
int index = 0;
|
||||||
|
string uid = null;
|
||||||
|
|
||||||
|
foreach(var aCue in (List<QCue>)value)
|
||||||
|
{
|
||||||
|
uid = aCue.uid;
|
||||||
|
if (uid == null)
|
||||||
|
continue;
|
||||||
|
aCue.sortIndex = index;
|
||||||
|
newChildCuesUIDMap.Add(uid, aCue);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
childCues = (List<QCue>)value;
|
||||||
|
childCuesUIDMap = newChildCuesUIDMap;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(key.Equals(QOSCKey.PlaybackPositionId))
|
||||||
|
{
|
||||||
|
if (!IsCueList)
|
||||||
|
return false;
|
||||||
|
if (value != null && value.GetType() != typeof(string))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (value.Equals("none"))
|
||||||
|
value = null;
|
||||||
|
if (value != null)
|
||||||
|
cueData[key] = value;
|
||||||
|
else
|
||||||
|
cueData.Remove(key);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
cueData[key] = value;
|
||||||
|
else
|
||||||
|
cueData.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Console.WriteLine($"[cue] set property: {key} with type: {value.GetType()} and value: {value}");
|
||||||
|
//check for type key and update icon? do I want to do this here?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//Methods Copied: Yes
|
||||||
|
//Methods Implemented: Yes
|
||||||
|
#region Actions
|
||||||
|
public void start() { workspace.startCue(this); }
|
||||||
|
public void stop() { workspace.stopCue(this); }
|
||||||
|
public void pause() { workspace.pauseCue(this); }
|
||||||
|
public void reset() { workspace.resetCue(this); }
|
||||||
|
public void load() { workspace.loadCue(this); }
|
||||||
|
public void resume() { workspace.resumeCue(this); }
|
||||||
|
public void hardStop() { workspace.hardStopCue(this); }
|
||||||
|
public void hardPause() { workspace.hardPauseCue(this); }
|
||||||
|
public void togglePause() { workspace.togglePauseCue(this); }
|
||||||
|
public void preview() { workspace.previewCue(this); }
|
||||||
|
public void panic() { workspace.panicCue(this); }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Printing
|
||||||
|
public void Print()
|
||||||
|
{
|
||||||
|
if (IsCueList)
|
||||||
|
{
|
||||||
|
if(cues != null && cues.Count() > 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine(displayName);
|
||||||
|
foreach(var cue in cues)
|
||||||
|
{
|
||||||
|
cue.Print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{displayName} : {color}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace QSharp
|
||||||
|
{
|
||||||
|
static class QBonjour
|
||||||
|
{
|
||||||
|
public const string TCPService = "_qlab._tcp.local.";
|
||||||
|
public const string UDPService = "_qlab._udp.local.";
|
||||||
|
}
|
||||||
|
static class QCueType
|
||||||
|
{
|
||||||
|
public const string Cue = "Cue";
|
||||||
|
public const string CueList = "Cue List";
|
||||||
|
public const string Cart = "Cart";
|
||||||
|
public const string Group = "Group";
|
||||||
|
public const string Audio = "";
|
||||||
|
public const string Mic = "Mic";
|
||||||
|
public const string Video = "Video";
|
||||||
|
public const string Camera = "Camera";
|
||||||
|
public const string Text = "Text";
|
||||||
|
public const string Light = "Light";
|
||||||
|
public const string Fade = "Fade";
|
||||||
|
public const string Network = "Network";
|
||||||
|
public const string MIDI = "MIDI";
|
||||||
|
public const string MIDIFile = "MIDI File";
|
||||||
|
public const string Timecode = "Timecode";
|
||||||
|
public const string Start = "Start";
|
||||||
|
public const string Stop = "Stop";
|
||||||
|
public const string Pause = "Paus";
|
||||||
|
public const string Load = "Load";
|
||||||
|
public const string Reset = "Reset";
|
||||||
|
public const string Devamp = "Devamp";
|
||||||
|
public const string Goto = "GoTo";
|
||||||
|
public const string Target = "Target";
|
||||||
|
public const string Arm = "Arm";
|
||||||
|
public const string Disarm = "Disarm";
|
||||||
|
public const string Wait = "Wait";
|
||||||
|
public const string Memo = "Memo";
|
||||||
|
public const string Script = "Script";
|
||||||
|
public const string Stagetracker = "Stagetracker";
|
||||||
|
|
||||||
|
//v3
|
||||||
|
public const string OSC = "OSC";
|
||||||
|
public const string Titles = "Titles";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class QOSCKey
|
||||||
|
{
|
||||||
|
public const string UID = "uniqueID";
|
||||||
|
public const string Type = "type";
|
||||||
|
public const string Parent = "parent";
|
||||||
|
public const string Name = "name";
|
||||||
|
public const string Number = "number";
|
||||||
|
public const string Notes = "notes";
|
||||||
|
public const string FileTarget = "fileTarget";
|
||||||
|
public const string CueTargetNumber = "cueTargetNumber";
|
||||||
|
public const string CurrentCueTarget = "currentCueTarget";
|
||||||
|
public const string ColorName = "colorName";
|
||||||
|
public const string Flagged = "flagged";
|
||||||
|
public const string Armed = "armed";
|
||||||
|
public const string ContinueMode = "continueMode";
|
||||||
|
public const string PreWait = "preWait";
|
||||||
|
public const string PostWait = "postWait";
|
||||||
|
public const string CurrentDuration = "currentDuration";
|
||||||
|
public const string PercentPreWaitElapsed = "percentPreWaitElapsed";
|
||||||
|
public const string PercentPostWaitElapsed = "percentPostWaitElapsed";
|
||||||
|
public const string PercentActionElapsed = "percentActionElapsed";
|
||||||
|
public const string PreWaitElapsed = "preWaitElapsed";
|
||||||
|
public const string PostWaitElapsed = "postWaitElapsed";
|
||||||
|
public const string ActionElapsed = "actionElapsed";
|
||||||
|
public const string GroupMode = "mode";
|
||||||
|
public const string CartPosition = "cartPosition";
|
||||||
|
public const string CartRows = "cartRows";
|
||||||
|
public const string CartColumns = "cartColumns";
|
||||||
|
public const string HasFileTargets = "hasFileTargets";
|
||||||
|
public const string HasCueTargets = "hasCueTargets";
|
||||||
|
public const string AllowsEditingDuration = "allowsEditingDuration";
|
||||||
|
public const string IsPanicking = "isPanicking";
|
||||||
|
public const string IsTailingOut = "isTailingOut";
|
||||||
|
public const string IsRunning = "isRunning";
|
||||||
|
public const string IsLoaded = "isLoaded";
|
||||||
|
public const string IsPaused = "isPaused";
|
||||||
|
public const string IsBroken = "isBroken";
|
||||||
|
public const string IsOverridden = "isOverridden";
|
||||||
|
public const string TranslationX = "translationX";
|
||||||
|
public const string TranslationY = "translationY";
|
||||||
|
public const string ScaleX = "scaleX";
|
||||||
|
public const string ScaleY = "scaleY";
|
||||||
|
public const string OriginX = "originX";
|
||||||
|
public const string OriginY = "originY";
|
||||||
|
public const string Quaternion = "quaternion";
|
||||||
|
public const string SurfaceSize = "surfaceSize";
|
||||||
|
public const string CueSize = "cueSize";
|
||||||
|
public const string PreserveAspectRatio = "preserveAspectRatio";
|
||||||
|
public const string Layer = "layer";
|
||||||
|
public const string Patch = "patch";
|
||||||
|
public const string PatchList = "patchList";
|
||||||
|
public const string SurfaceList = "surfaceList";
|
||||||
|
public const string Cues = "cues";
|
||||||
|
public const string ListName = "listName";
|
||||||
|
public const string SurfaceID = "surfaceID";
|
||||||
|
public const string FullSurface = "fullSurface";
|
||||||
|
public const string Opacity = "opacity";
|
||||||
|
public const string RotationZ = "rotationZ";
|
||||||
|
public const string RotationY = "rotationY";
|
||||||
|
public const string RotationX = "rotationX";
|
||||||
|
public const string PlaybackPositionId = "playbackPositionId";
|
||||||
|
public const string StartNextCueWhenSliceEnds = "startNextCueWhenSliceEnds";
|
||||||
|
public const string StopTargetWhenSliceEnds = "stopTargetWhenSliceEnds";
|
||||||
|
public const string SliderLevel = "sliderLevel";
|
||||||
|
|
||||||
|
// v3
|
||||||
|
public const string Duration = "duration";
|
||||||
|
public const string FullScreen = "fullScreen";
|
||||||
|
}
|
||||||
|
|
||||||
|
static class QIdentifiers
|
||||||
|
{
|
||||||
|
// Identifiers for "fake" cues
|
||||||
|
public const string RootCue = "__root__";
|
||||||
|
public const string ActiveCues = "__active__";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//these should really be enums
|
||||||
|
static class QFadeMode
|
||||||
|
{
|
||||||
|
public const int Absolute = 0;
|
||||||
|
public const int Relative = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class QContinueMode
|
||||||
|
{
|
||||||
|
public const int NoContinue = 0;
|
||||||
|
public const int AutoContinue = 1;
|
||||||
|
public const int AutoFollow = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using SharpOSC;
|
||||||
|
|
||||||
|
namespace QSharp
|
||||||
|
{
|
||||||
|
public class QMessage
|
||||||
|
{
|
||||||
|
|
||||||
|
private OscMessage OSCMessage;
|
||||||
|
|
||||||
|
public QMessage(OscMessage oscMessage)
|
||||||
|
{
|
||||||
|
OSCMessage = oscMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string description
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//string join probably won't work might need to cast argument objects to strings first
|
||||||
|
return $"address: {address}, arguments: {string.Join(" - ", arguments)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Message Type Checks
|
||||||
|
public bool IsReply { get { return OSCMessage.Address.StartsWith("/reply"); } }
|
||||||
|
|
||||||
|
// /reply/cue_id/1/action
|
||||||
|
public bool IsReplyFromCue { get{ return OSCMessage.Address.StartsWith("/reply/cue_id"); } }
|
||||||
|
public bool IsReplyFromCueLists { get { return IsReply && OSCMessage.Address.EndsWith("cueLists"); } }
|
||||||
|
|
||||||
|
public bool IsUpdate { get{ return OSCMessage.Address.StartsWith("/update"); } }
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsWorkspaceUpdate {
|
||||||
|
get {
|
||||||
|
// /update/workspace/{workspace_id}
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 3 && parts[1].Equals("workspace"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsWorkspacesInfo {
|
||||||
|
get {
|
||||||
|
// /workspaces
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 2 && parts[1] == "workspaces");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsWorkspaceSettingsUpdate {
|
||||||
|
get {
|
||||||
|
// /update/workspace/{workspace_id}/settings/{settings_controller}
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 5 && parts[1].Equals("workspace") && parts[3].Equals("settings"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsLightDashboardUpdate {
|
||||||
|
get {
|
||||||
|
// /update/workspace/{workspace_id}/dashboard
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 4 && parts[1].Equals("workspace") && parts[3].Equals("dashboard"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsCueUpdate {
|
||||||
|
get {
|
||||||
|
// /update/workspace/{workspace_id}/cue_id/{cue_id}
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 5 && parts[1].Equals("workspace") && parts[3].Equals("cue_id"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsPlaybackPositionUpdate {
|
||||||
|
get {
|
||||||
|
// /update/workspace/{workspace_id}/cueList/{cue_list_id}/playbackPosition {cue_id}
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 6 && address.EndsWith("/playbakPosition"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsPreferencesUpdate {
|
||||||
|
get {
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 4 && parts[3].Equals("preferences"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDisconnect {
|
||||||
|
get {
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 4 && parts[3].Equals("disconnect"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsConnect
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string[] parts = AddressParts;
|
||||||
|
return (parts.Length == 4 && parts[3].Equals("connect"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public string address { get { return OSCMessage.Address; } }
|
||||||
|
|
||||||
|
public string replyAddress { get{ return IsReply ? address.Substring("/reply".Length) : address; } }
|
||||||
|
|
||||||
|
public string addressWithoutWorkspace
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string[] AddressParts { get { return address.Split("/",StringSplitOptions.RemoveEmptyEntries); } }
|
||||||
|
|
||||||
|
public JToken response
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
JObject responseObj = JObject.Parse((string)arguments[0]);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
return responseObj["data"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Object> arguments { get { return OSCMessage.Arguments; } }
|
||||||
|
|
||||||
|
public string cueID
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsCueUpdate)
|
||||||
|
{
|
||||||
|
return AddressParts[4];
|
||||||
|
}else if (IsPlaybackPositionUpdate)
|
||||||
|
{
|
||||||
|
//TODO: check string cast
|
||||||
|
return arguments.Count > 0 ? (string)arguments[0] : null;
|
||||||
|
}else if (IsReplyFromCue)
|
||||||
|
{
|
||||||
|
return AddressParts[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace QSharp
|
|
||||||
{
|
|
||||||
public class QResponse
|
|
||||||
{
|
|
||||||
private const string WORKSPACES_REGEX = @"/workspaces";
|
|
||||||
public string status { get; set; }
|
|
||||||
public string address { get; set; }
|
|
||||||
public object[] data { get; set; }
|
|
||||||
|
|
||||||
public string getReplyType()
|
|
||||||
{
|
|
||||||
Console.WriteLine($"QRESPONSE - Address to match: '{address}'");
|
|
||||||
Match m = Regex.Match(address, WORKSPACES_REGEX);
|
|
||||||
if (m.Success)
|
|
||||||
return "WORKSPACES";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+33
-19
@@ -1,53 +1,67 @@
|
|||||||
//General information about a QLab Workspace
|
//General information about a QLab Workspace
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Zeroconf;
|
||||||
|
|
||||||
namespace QSharp
|
namespace QSharp
|
||||||
{
|
{
|
||||||
public class QServer
|
public class QServer
|
||||||
{
|
{
|
||||||
private QClient qClient;
|
private QClient client;
|
||||||
|
|
||||||
public string host;
|
public string host;
|
||||||
public int port;
|
public int port;
|
||||||
public string name;
|
public string name;
|
||||||
|
public IZeroconfHost zeroconfHost;
|
||||||
List<QWorkspace> workspaces = new List<QWorkspace>();
|
List<QWorkspace> workspaces = new List<QWorkspace>();
|
||||||
|
|
||||||
public QServer(string host, int port, string name)
|
public QServer(string host, int port)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.name = name;
|
|
||||||
|
|
||||||
qClient = new QClient(host, port);
|
client = new QClient(host, port);
|
||||||
qClient.WorkspacesUpdated += OnWorkspacesUpdated;
|
client.WorkspacesUpdated += OnWorkspacesUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnWorkspacesUpdated(object source, QClient.WorkspacesUpdatedArgs args)
|
public string description { get { return $"{name} - {host} - {port}"; } }
|
||||||
{
|
|
||||||
foreach(var workspace in args.Workspaces)
|
|
||||||
{
|
|
||||||
QWorkspace existingWorkspace = workspaceWithID(workspace.uniqueID);
|
|
||||||
if(existingWorkspace == null)
|
|
||||||
{
|
|
||||||
QWorkspace workspaceToAdd = new QWorkspace(workspace, this);
|
|
||||||
workspaces.Add(workspaceToAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refreshWorkspaces()
|
public void refreshWorkspaces()
|
||||||
{
|
{
|
||||||
qClient.sendMessage("/workspaces");
|
if (!client.connect())
|
||||||
|
{
|
||||||
|
System.Console.WriteLine($"Error: QServer unable to connect to QLab Server: {host}:{port}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client.sendMessage("/workspaces");
|
||||||
}
|
}
|
||||||
|
|
||||||
public QWorkspace workspaceWithID(string uniqueID)
|
public QWorkspace workspaceWithID(string uniqueID)
|
||||||
{
|
{
|
||||||
foreach(var workspace in workspaces)
|
foreach(var workspace in workspaces)
|
||||||
{
|
{
|
||||||
if (workspace.getUniqueID().Equals(uniqueID))
|
if (workspace.uniqueID.Equals(uniqueID))
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region EventHandlers
|
||||||
|
private void OnWorkspacesUpdated(object source, QWorkspacesUpdatedArgs args)
|
||||||
|
{
|
||||||
|
foreach (var workspace in args.Workspaces)
|
||||||
|
{
|
||||||
|
QWorkspace existingWorkspace = workspaceWithID(workspace.uniqueID);
|
||||||
|
if (existingWorkspace == null)
|
||||||
|
{
|
||||||
|
QWorkspace workspaceToAdd = new QWorkspace(workspace, this);
|
||||||
|
workspaces.Add(workspaceToAdd);
|
||||||
|
workspaceToAdd.connectWithPasscode("1234");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+322
-38
@@ -1,4 +1,9 @@
|
|||||||
//TODO: connect methods, cue property fetch methods, everything else
|
//TODO: connect methods, cue property fetch methods, everything else
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
namespace QSharp
|
namespace QSharp
|
||||||
{
|
{
|
||||||
public class QWorkspace
|
public class QWorkspace
|
||||||
@@ -7,11 +12,20 @@ namespace QSharp
|
|||||||
private QServer server;
|
private QServer server;
|
||||||
private QClient client;
|
private QClient client;
|
||||||
|
|
||||||
private string name;
|
public string name;
|
||||||
private string uniqueID;
|
public string uniqueID;
|
||||||
private bool connected;
|
public bool connected;
|
||||||
private bool hasPasscode;
|
private bool hasPasscode;
|
||||||
private string oscPrefix;
|
private string passcode;
|
||||||
|
|
||||||
|
private QCue root;
|
||||||
|
|
||||||
|
private Timer heartbeatTimer;
|
||||||
|
private int heartbeatAttempts;
|
||||||
|
|
||||||
|
public bool defaultSendUpdatesOSC;
|
||||||
|
|
||||||
|
public string version;
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
@@ -20,26 +34,42 @@ namespace QSharp
|
|||||||
connected = false;
|
connected = false;
|
||||||
|
|
||||||
hasPasscode = false;
|
hasPasscode = false;
|
||||||
|
defaultSendUpdatesOSC = false;
|
||||||
|
|
||||||
|
root = new QCue(this);
|
||||||
|
root.setProperty(QIdentifiers.RootCue, QOSCKey.UID, false);
|
||||||
|
root.setProperty("Cue Lists", QOSCKey.Name, false);
|
||||||
|
root.setProperty(QCueType.CueList, QOSCKey.Type, false);
|
||||||
|
|
||||||
//TODO: add version
|
//TODO: add version
|
||||||
|
version = "3.0.0";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QWorkspace(QWorkspaceInfo workspaceInfo, QServer server)
|
public QWorkspace(QWorkspaceInfo workspaceInfo, QServer server)
|
||||||
{
|
{
|
||||||
if(workspaceInfo.uniqueID.Length > 0)
|
Init();
|
||||||
{
|
|
||||||
uniqueID = workspaceInfo.uniqueID;
|
if(workspaceInfo.uniqueID.Length > 0)
|
||||||
oscPrefix = workspacePrefix();
|
uniqueID = workspaceInfo.uniqueID;
|
||||||
}
|
|
||||||
|
if (workspaceInfo.version.Length > 0)
|
||||||
|
version = workspaceInfo.version;
|
||||||
|
|
||||||
//TODO add version if it has one if no version then it is QLab 3?
|
|
||||||
updateWithWorkspaceInfo(workspaceInfo);
|
updateWithWorkspaceInfo(workspaceInfo);
|
||||||
|
|
||||||
client = new QClient(server.host, server.port);
|
client = new QClient(server.host, server.port);
|
||||||
this.server = server;
|
|
||||||
|
|
||||||
|
client.WorkspaceConnected += OnWorkspaceConnection;
|
||||||
|
client.WorkspaceConnectionError += OnWorkspaceConnectionError;
|
||||||
|
client.WorkspaceDisconnected += OnWorkspaceDisconnected;
|
||||||
|
client.CueListsUpdated += OnCueListsUpdated;
|
||||||
|
|
||||||
|
this.server = server;
|
||||||
|
Console.WriteLine($"[workspace] <{name}> initizalied for server: {server.name} ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//updateWithDictionary
|
||||||
public bool updateWithWorkspaceInfo(QWorkspaceInfo workspaceInfo) {
|
public bool updateWithWorkspaceInfo(QWorkspaceInfo workspaceInfo) {
|
||||||
bool didUpdate = false;
|
bool didUpdate = false;
|
||||||
if(workspaceInfo.displayName.Length > 0 && !workspaceInfo.displayName.Equals(this.name))
|
if(workspaceInfo.displayName.Length > 0 && !workspaceInfo.displayName.Equals(this.name))
|
||||||
@@ -55,61 +85,315 @@ namespace QSharp
|
|||||||
return didUpdate;
|
return didUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string description { get { return $"{name} : {uniqueID}"; } }
|
||||||
|
|
||||||
|
public string nameWithoutPathExtension { get { return name; } } //TODO
|
||||||
|
|
||||||
|
public string serverName { get { return server.name; } }
|
||||||
|
|
||||||
|
public string fullName { get { return $"{name} ({server.name})"; } }
|
||||||
|
|
||||||
public string getUniqueID()
|
public QCue firstCue { get { return firstCueList.firstCue; } }
|
||||||
|
public QCue firstCueList { get { return root.firstCue; } }
|
||||||
|
public string fullNameWithCueList(QCue cueList) { return ""; }
|
||||||
|
//TODO other convenience methods
|
||||||
|
|
||||||
|
public bool connectedToQLab3 { get { return false; } } //TODO implement the version system
|
||||||
|
|
||||||
|
#region Connection/reconnection
|
||||||
|
|
||||||
|
public void connectWithPasscode(string passcode)
|
||||||
{
|
{
|
||||||
return uniqueID;
|
//TODO
|
||||||
|
|
||||||
|
if (!client.connect())
|
||||||
|
{
|
||||||
|
System.Console.WriteLine($"[workspace] *** Error: couldn't connect to server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Console.WriteLine("[workspace] connecting...");
|
||||||
|
client.sendMessage($"{workspacePrefix}/connect",passcode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region OSC address helpers
|
private void finishConnection()
|
||||||
private string addressForCue(QCue cue, string action)
|
|
||||||
{
|
{
|
||||||
return $"{oscPrefix}/cue_id/{cue.propertyForKey("uniqueId")}/{action}";
|
//TODO
|
||||||
|
System.Console.WriteLine($"[workspace] connected to <{name}> running on QLab version <{version}>");
|
||||||
|
connected = true;
|
||||||
|
startReceivingUpdates();
|
||||||
|
//fetchQLabVersion();
|
||||||
|
fetchCueLists();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string addressForWildcardNumber(string number, string action) {
|
public void reconnect()
|
||||||
return $"{oscPrefix}/cue/{number}/{action}";
|
{
|
||||||
|
if (connected)
|
||||||
|
return;
|
||||||
|
connectWithPasscode(passcode);
|
||||||
|
|
||||||
|
//todo
|
||||||
}
|
}
|
||||||
|
|
||||||
private string workspacePrefix()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
return $"/workspace/{uniqueID}";
|
//TODO
|
||||||
|
Console.WriteLine($"[workspace] disconnect: {name}");
|
||||||
|
stopHeartbeat();
|
||||||
|
stopReceivingUpdates();
|
||||||
|
disconnectFromWorkspace();
|
||||||
|
|
||||||
|
connected = false;
|
||||||
|
|
||||||
|
client.disconnect();
|
||||||
|
//root.removeAllChildCues();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void temporarilyDisconnect()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Cues
|
||||||
|
public QCue cueWithId(string uid)
|
||||||
|
{
|
||||||
|
return root.cueWithID(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QCue cueWithNumber(string number)
|
||||||
|
{
|
||||||
|
return root.cueWithNumber(number);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Workspace Methods
|
#region Workspace Methods
|
||||||
public void disconnectFromWorkspace() { client.sendMessage($"{oscPrefix}/disconnect"); }
|
public void disconnectFromWorkspace() { client.sendMessage($"{workspacePrefix}/disconnect"); }
|
||||||
public void startReceivingUpdates() { client.sendMessage($"{oscPrefix}/updates", 1); }
|
public void startReceivingUpdates() { client.sendMessage($"{workspacePrefix}/updates", 1); }
|
||||||
public void stopReceivingUpdates() { client.sendMessage($"{oscPrefix}/updates", 0); }
|
public void stopReceivingUpdates() { client.sendMessage($"{workspacePrefix}/updates", 0); }
|
||||||
public void enableAlwaysReply() { client.sendMessage($"{oscPrefix}/alwaysReply", 1); }
|
public void enableAlwaysReply() { client.sendMessage($"{workspacePrefix}/alwaysReply", 1); }
|
||||||
public void disableAlwaysReply() { client.sendMessage($"{oscPrefix}/alwaysReply", 0); }
|
public void disableAlwaysReply() { client.sendMessage($"{workspacePrefix}/alwaysReply", 0); }
|
||||||
|
public void fetchQLabVersion() { client.sendMessage($"{workspacePrefix}/version"); } //TODO: EventHandler for this
|
||||||
|
public void fetchCueLists() { client.sendMessage($"{workspacePrefix}/cueLists"); } //TODO: EventHandler for CueListUpdated
|
||||||
|
public void fetchPlaybackPositionForCue(QCue cue) { client.sendMessage(addressForCue(cue, QOSCKey.PlaybackPositionId)); } //EventHandler for this? can I use the CueListPlaybackPosition one?
|
||||||
|
public void go() { client.sendMessage($"{workspacePrefix}/go"); }
|
||||||
|
public void save() { client.sendMessage($"{workspacePrefix}/save"); }
|
||||||
|
public void undo() { client.sendMessage($"{workspacePrefix}/undo"); }
|
||||||
|
public void redo() { client.sendMessage($"{workspacePrefix}/redo"); }
|
||||||
|
public void resetAll() { client.sendMessage($"{workspacePrefix}/reset"); }
|
||||||
|
public void pauseAll() { client.sendMessage($"{workspacePrefix}/pause"); }
|
||||||
|
public void resumeAll() { client.sendMessage($"{workspacePrefix}/resume"); }
|
||||||
|
public void stopAll() { client.sendMessage($"{workspacePrefix}/stop"); }
|
||||||
|
public void panicAll() { client.sendMessage($"{workspacePrefix}/panic"); }
|
||||||
|
#endregion
|
||||||
|
|
||||||
public void fetchQLabVersion() {
|
#region Heartbeat
|
||||||
|
//TODO
|
||||||
|
public void startHeartbeat()
|
||||||
|
{
|
||||||
|
clearHeartbeatTimeout();
|
||||||
|
sendHeartbeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopHeartbeat()
|
||||||
|
{
|
||||||
|
clearHeartbeatTimeout();
|
||||||
|
heartbeatAttempts = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearHeartbeatTimeout()
|
||||||
|
{
|
||||||
|
heartbeatTimer.Stop();
|
||||||
|
heartbeatTimer = null;
|
||||||
|
heartbeatAttempts = 0;
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchCueLists()
|
public void sendHeartbeat()
|
||||||
|
{
|
||||||
|
client.sendMessage("/thump");
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public void heartbeatTimeout(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchPlaybackPositionForCue()
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Cue Actions
|
||||||
|
public void startCue(QCue cue) { client.sendMessage(addressForCue(cue, "start")); }
|
||||||
|
public void stopCue(QCue cue) { client.sendMessage(addressForCue(cue, "stop")); }
|
||||||
|
public void pauseCue(QCue cue) { client.sendMessage(addressForCue(cue, "pause")); } //TODO: immediately update local for snappier whatever
|
||||||
|
public void loadCue(QCue cue) { client.sendMessage(addressForCue(cue, "load")); }
|
||||||
|
public void resetCue(QCue cue) { client.sendMessage(addressForCue(cue, "reset")); }
|
||||||
|
public void deleteCue(QCue cue) { client.sendMessage(addressForCue(cue, "")); }
|
||||||
|
public void resumeCue(QCue cue) { client.sendMessage(addressForCue(cue, "resume")); }
|
||||||
|
public void hardStopCue(QCue cue) { client.sendMessage(addressForCue(cue, "hardStop")); }
|
||||||
|
public void hardPauseCue(QCue cue) { client.sendMessage(addressForCue(cue, "hardPause")); } //TODO: immediately update local for snappier whatever
|
||||||
|
public void togglePauseCue(QCue cue) { client.sendMessage(addressForCue(cue, "togglePause")); }
|
||||||
|
public void previewCue(QCue cue) { client.sendMessage(addressForCue(cue, "preview")); }
|
||||||
|
public void panicCue(QCue cue) { client.sendMessage(addressForCue(cue, "panic")); } //TODO: immediately update local for snappier whatever
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Cue Getters/Setters
|
||||||
|
//TODO
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Property Fetching
|
||||||
|
//TODO
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region OSC address helpers
|
||||||
|
public void sendMessage(string address, params object[] args)
|
||||||
{
|
{
|
||||||
//TODO
|
//check for workspace prefix?
|
||||||
|
client.sendMessage(address, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void go() { client.sendMessage($"{oscPrefix}/go"); }
|
private string addressForCue(QCue cue, string action)
|
||||||
public void save() { client.sendMessage($"{oscPrefix}/save"); }
|
{
|
||||||
public void undo() { client.sendMessage($"{oscPrefix}/undo"); }
|
return $"{workspacePrefix}/cue_id/{cue.propertyForKey("uniqueId")}/{action}";
|
||||||
public void redo() { client.sendMessage($"{oscPrefix}/redo"); }
|
}
|
||||||
public void resetAll() { client.sendMessage($"{oscPrefix}/reset"); }
|
|
||||||
public void pauseAll() { client.sendMessage($"{oscPrefix}/pause"); }
|
private string addressForWildcardNumber(string number, string action) {
|
||||||
public void resumeAll() { client.sendMessage($"{oscPrefix}/resume"); }
|
return $"{workspacePrefix}/cue/{number}/{action}";
|
||||||
public void stopAll() { client.sendMessage($"{oscPrefix}/stop"); }
|
}
|
||||||
public void panicAll() { client.sendMessage($"{oscPrefix}/panic"); }
|
|
||||||
|
private string workspacePrefix
|
||||||
|
{
|
||||||
|
get { return $"/workspace/{uniqueID}"; }
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public string workspaceID
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return uniqueID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Event Handling
|
||||||
|
private void OnWorkspaceConnectionError(object source, QWorkspaceConnectionErrorArgs args)
|
||||||
|
{
|
||||||
|
if (args.status.Equals("badpass"))
|
||||||
|
Console.WriteLine($"[workspace] *** Error: Password for workspace {name} was incorrect!");
|
||||||
|
else
|
||||||
|
Console.WriteLine($"[workspace] *** Error: Unable to connect to workspace: {name} on server: {server.name}");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnWorkspaceConnection(object source, QWorkspaceConnectedArgs args)
|
||||||
|
{
|
||||||
|
finishConnection();
|
||||||
|
Console.WriteLine($"[workspace] Connection finished this is the first cue in this workspace {root.firstCue.displayName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnWorkspaceDisconnected(object source, QWorkspaceDisconnectedArgs args)
|
||||||
|
{
|
||||||
|
//this might not be called with TCP?
|
||||||
|
Console.WriteLine($"[workspace] *** Workspace has indicated it is disconnecting");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCueListsUpdated(object source, QCueListsUpdatedArgs args)
|
||||||
|
{
|
||||||
|
bool rootCueUpdated = false;
|
||||||
|
List<QCue> currentCueLists = new List<QCue>(args.data.Count());
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
foreach (var aCueList in args.data)
|
||||||
|
{
|
||||||
|
string uid = aCueList[QOSCKey.UID].ToString();
|
||||||
|
if (uid == null)
|
||||||
|
continue;
|
||||||
|
QCue cueList = root.cueWithID(uid, false);
|
||||||
|
|
||||||
|
if(cueList != null)
|
||||||
|
{
|
||||||
|
if(cueList.sortIndex != index)
|
||||||
|
{
|
||||||
|
cueList.sortIndex = index;
|
||||||
|
rootCueUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cueList = new QCue(aCueList, this);
|
||||||
|
cueList.sortIndex = index;
|
||||||
|
if (connectedToQLab3)
|
||||||
|
cueList.setProperty(QCueType.CueList, QOSCKey.Type);
|
||||||
|
rootCueUpdated = true;
|
||||||
|
}
|
||||||
|
currentCueLists.Add(cueList);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
QCue activeCuesList = root.cueWithID(QIdentifiers.ActiveCues, false);
|
||||||
|
if(activeCuesList != null)
|
||||||
|
{
|
||||||
|
if (activeCuesList.sortIndex != index)
|
||||||
|
{
|
||||||
|
activeCuesList.setProperty(QIdentifiers.ActiveCues, QOSCKey.UID, false);
|
||||||
|
activeCuesList.setProperty("Active Cues", QOSCKey.Name, false);
|
||||||
|
activeCuesList.setProperty(QCueType.CueList, QOSCKey.Type, false);
|
||||||
|
|
||||||
|
rootCueUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activeCuesList = new QCue(this);
|
||||||
|
activeCuesList.setProperty(QIdentifiers.ActiveCues, QOSCKey.UID, false);
|
||||||
|
activeCuesList.setProperty("Active Cues", QOSCKey.Name, false);
|
||||||
|
activeCuesList.setProperty(QCueType.CueList, QOSCKey.Type, false);
|
||||||
|
rootCueUpdated = true;
|
||||||
|
}
|
||||||
|
currentCueLists.Add(activeCuesList);
|
||||||
|
|
||||||
|
if (root.cues.Count() != currentCueLists.Count())
|
||||||
|
rootCueUpdated = true;
|
||||||
|
|
||||||
|
root.setProperty(currentCueLists, QOSCKey.Cues);
|
||||||
|
|
||||||
|
if (rootCueUpdated)
|
||||||
|
{
|
||||||
|
//add Event handled? use CueUpdated one?
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"[workspace] cueLists finished processing. root updated? {rootCueUpdated}");
|
||||||
|
|
||||||
|
Print();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//OnWorkspaceUpdated
|
||||||
|
//OnWorkspaceSettingsUpdated
|
||||||
|
//LightDashboardUpdated
|
||||||
|
//PreferencesUpdated
|
||||||
|
//CueNeedsUpdated
|
||||||
|
//CueUpdated
|
||||||
|
//ClientShouldDisconnect
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Printing
|
||||||
|
public void Print()
|
||||||
|
{
|
||||||
|
foreach(var cueList in root.cues)
|
||||||
|
{
|
||||||
|
cueList.Print();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,22 @@ namespace SharpOSC
|
|||||||
_address = address;
|
_address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Connect()
|
public bool Connect()
|
||||||
{
|
{
|
||||||
client = new TcpClient(Address, Port);
|
try
|
||||||
Console.WriteLine($"TCPClient - connect called for <{Address}:{Port}>");
|
{
|
||||||
Thread receivingThread = new Thread(ReceiveLoop);
|
client = new TcpClient(Address, Port);
|
||||||
receivingThread.Start();
|
Thread receivingThread = new Thread(ReceiveLoop);
|
||||||
|
receivingThread.Start();
|
||||||
|
//Console.WriteLine($"TCPClient - connected to <{Address}:{Port}>");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
//Console.WriteLine(e.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(byte[] message)
|
public void Send(byte[] message)
|
||||||
@@ -67,6 +77,14 @@ namespace SharpOSC
|
|||||||
Send(data);
|
Send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsConnected
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return client.Connected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ReceiveLoop()
|
public void ReceiveLoop()
|
||||||
{
|
{
|
||||||
while (client.Connected)
|
while (client.Connected)
|
||||||
@@ -109,7 +127,7 @@ namespace SharpOSC
|
|||||||
}
|
}
|
||||||
} catch(Exception e)
|
} catch(Exception e)
|
||||||
{
|
{
|
||||||
//Log.Debug("TCPSENDER - Receive Exception: " + e.ToString());
|
//Console.WriteLine("TCPSENDER - Receive Exception: " + e.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ namespace qControlDemo
|
|||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||||
Console.WriteLine("qControlDemo Started");
|
Console.WriteLine("qControlDemo Started");
|
||||||
QBrowser browser = new QBrowser();
|
QBrowser browser = new QBrowser();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Thread.Sleep(100000000);
|
Thread.Sleep(100000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Terminal.Gui" Version="0.81.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\QSharp\QSharp.csproj" />
|
<ProjectReference Include="..\QSharp\QSharp.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user