* QControlKit.csproj:

* MainPage.xaml.cs:
* AppDelegate.cs:
* QControlKitXamDemo.csproj:
* QCueViewModel.cs:
* QControlKitXamDemo.iOS.csproj:
* QControlKitXamDemo.Android.csproj: Update Packages

* QServer.cs:
* QBrowser.cs:
* QWorkspace.cs:
* QEventArgs.cs:
* QEventHandlers.cs: Refine Server Found/Lost and Workspace
  Added/Removed
This commit is contained in:
2021-01-08 23:24:35 -06:00
parent b622462c0d
commit 87a9925668
12 changed files with 226 additions and 61 deletions
+11
View File
@@ -9,6 +9,17 @@ namespace QControlKit.Events
public QServer server { get; set; } public QServer server { get; set; }
} }
public class QServerWorkspaceChangedArgs : EventArgs
{
public QServer server { get; set; }
public QWorkspace workspace { get; set; }
}
public class QServerLostArgs : EventArgs
{
public QServer server { get; set; }
}
public class QServerUpdatedArgs : EventArgs public class QServerUpdatedArgs : EventArgs
{ {
public QServer server { get; set; } public QServer server { get; set; }
+3
View File
@@ -1,7 +1,10 @@
namespace QControlKit.Events namespace QControlKit.Events
{ {
public delegate void QServerFoundHandler(object source, QServerFoundArgs args); public delegate void QServerFoundHandler(object source, QServerFoundArgs args);
public delegate void QServerLostHandler(object source, QServerLostArgs args);
public delegate void QServerUpdatedHandler(object source, QServerUpdatedArgs args); public delegate void QServerUpdatedHandler(object source, QServerUpdatedArgs args);
public delegate void QServerWorkspaceAddedHandler(object source, QServerWorkspaceChangedArgs args);
public delegate void QServerWorkspaceRemovedHandler(object source, QServerWorkspaceChangedArgs args);
public delegate void QWorkspacesUpdatedHandler(object source, QWorkspacesUpdatedArgs args); public delegate void QWorkspacesUpdatedHandler(object source, QWorkspacesUpdatedArgs args);
+55 -33
View File
@@ -5,61 +5,79 @@ using Serilog;
using QControlKit.Constants; using QControlKit.Constants;
using QControlKit.Events; using QControlKit.Events;
using System;
using System.Collections.Generic;
using System.Linq;
namespace QControlKit namespace QControlKit
{ {
public class QBrowser public class QBrowser
{ {
ZeroconfResolver.ResolverListener zeroconfTCPBrowser;
public ObservableCollection<QServer> servers = new ObservableCollection<QServer>(); public ObservableCollection<QServer> servers = new ObservableCollection<QServer>();
public event QServerFoundHandler ServerFound; public event QServerFoundHandler ServerFound;
public event QServerLostHandler ServerLost;
public event QServerUpdatedHandler ServerUpdatedWorkspaces; public event QServerUpdatedHandler ServerUpdatedWorkspaces;
public QBrowser() public QBrowser()
{ {
zeroconfTCPBrowser = ZeroconfResolver.CreateListener(QBonjour.TCPService); ProbeForQLabInstances();
zeroconfTCPBrowser.ServiceFound += ZeroconfHostFound;
zeroconfTCPBrowser.ServiceLost += ZeroconfHostLost;
} }
private void ZeroconfHostLost(object sender, IZeroconfHost e) public async void ProbeForQLabInstances()
{ {
Log.Information($"[browser] Lost {e.DisplayName} : {e.IPAddress}"); IReadOnlyList<IZeroconfHost> results = await
ZeroconfResolver.ResolveAsync(QBonjour.TCPService,TimeSpan.FromSeconds(3));
} foreach (var zeroconfHost in results)
private void ZeroconfHostFound(object sender, IZeroconfHost e)
{
foreach(var service in e.Services)
{ {
if (service.Key.Equals(QBonjour.TCPService)) foreach (var service in zeroconfHost.Services)
{ {
Log.Information($"Found {e.DisplayName} : {e.IPAddress} : {service.Value.Port}"); if (service.Key.Equals(QBonjour.TCPService))
QServer server = serverForAddress(e.IPAddress);
if(server == null)
{ {
QServer serverToAdd = new QServer(e.IPAddress, service.Value.Port);
serverToAdd.name = e.DisplayName; QServer server = serverForAddress(zeroconfHost.IPAddress);
serverToAdd.zeroconfHost = e;
servers.Add(serverToAdd); if (server == null)
serverToAdd.refreshWorkspaces(); {
serverToAdd.ServerUpdated += OnServerUpdatedWorkspace; Log.Information($"[qbrowser] Found {zeroconfHost.DisplayName} : {zeroconfHost.IPAddress} : {service.Value.Port}");
OnServerFound(serverToAdd); QServer serverToAdd = new QServer(zeroconfHost.IPAddress, service.Value.Port);
} serverToAdd.name = zeroconfHost.DisplayName;
else serverToAdd.zeroconfHost = zeroconfHost;
{ servers.Add(serverToAdd);
server.name = e.DisplayName; serverToAdd.refreshWorkspaces();
serverToAdd.ServerUpdated += OnServerUpdatedWorkspace;
OnServerFound(serverToAdd);
}
else
{
server.name = zeroconfHost.DisplayName;
server.refreshWorkspaces();
}
} }
} }
} }
List<QServer> qServers = servers.ToList();
foreach(var server in qServers)
{
bool serverToBeRemoved = true;
foreach(var zeroconfHost in results){
QServer existingServer = serverForAddress(zeroconfHost.IPAddress);
if(server != null)
{
serverToBeRemoved = false;
}
}
if (serverToBeRemoved)
{
server.disconnect();
servers.Remove(server);
Log.Information($"[qbrowser] Lost {server.name} : {server.host} : {server.port}");
OnServerLost(server);
}
}
} }
public QServer serverForAddress(string address) public QServer serverForAddress(string address)
@@ -93,6 +111,11 @@ namespace QControlKit
ServerFound?.Invoke(this, new QServerFoundArgs { server = server }); ServerFound?.Invoke(this, new QServerFoundArgs { server = server });
} }
protected virtual void OnServerLost(QServer server)
{
ServerLost?.Invoke(this, new QServerLostArgs { server = server });
}
protected virtual void OnServerUpdatedWorkspace(object source, QServerUpdatedArgs args) protected virtual void OnServerUpdatedWorkspace(object source, QServerUpdatedArgs args)
{ {
ServerUpdatedWorkspaces?.Invoke(this, args); ServerUpdatedWorkspaces?.Invoke(this, args);
@@ -104,7 +127,6 @@ namespace QControlKit
{ {
server.disconnect(); server.disconnect();
} }
zeroconfTCPBrowser.Dispose();
} }
} }
} }
+1 -1
View File
@@ -6,7 +6,7 @@
<Authors>Joel Wetzell</Authors> <Authors>Joel Wetzell</Authors>
<Version>1.0.0-devel</Version> <Version>1.0.0-devel</Version>
<PackOnBuild>true</PackOnBuild> <PackOnBuild>true</PackOnBuild>
<PackageVersion>0.0.6</PackageVersion> <PackageVersion>0.0.11</PackageVersion>
<PackageId>QControlKit</PackageId> <PackageId>QControlKit</PackageId>
</PropertyGroup> </PropertyGroup>
+35 -1
View File
@@ -3,12 +3,16 @@ using System.Collections.Generic;
using Zeroconf; using Zeroconf;
using QControlKit.Events; using QControlKit.Events;
using System.Collections.ObjectModel;
using System.Linq;
namespace QControlKit namespace QControlKit
{ {
public class QServer public class QServer
{ {
public event QServerUpdatedHandler ServerUpdated; public event QServerUpdatedHandler ServerUpdated;
public event QServerWorkspaceAddedHandler WorkspaceAdded;
public event QServerWorkspaceRemovedHandler WorkspaceRemoved;
private QClient client; private QClient client;
@@ -17,7 +21,7 @@ namespace QControlKit
public string name { get; set; } public string name { get; set; }
public string version { get; set; } public string version { get; set; }
public IZeroconfHost zeroconfHost; public IZeroconfHost zeroconfHost;
public List<QWorkspace> workspaces = new List<QWorkspace>(); public ObservableCollection<QWorkspace> workspaces = new ObservableCollection<QWorkspace>();
public QServer(string host, int port) public QServer(string host, int port)
{ {
@@ -61,14 +65,44 @@ namespace QControlKit
{ {
QWorkspace workspaceToAdd = new QWorkspace(workspace, this); QWorkspace workspaceToAdd = new QWorkspace(workspace, this);
workspaces.Add(workspaceToAdd); workspaces.Add(workspaceToAdd);
OnServerAddedWorkspace(workspaceToAdd);
//set server version to the version of first workspace found...kind of hacky but eh //set server version to the version of first workspace found...kind of hacky but eh
if (version == null) if (version == null)
version = workspaceToAdd.version; version = workspaceToAdd.version;
} }
} }
List<QWorkspace> tempWorkspaces = workspaces.ToList();
for(int i = 0;i< tempWorkspaces.Count;i++)
{
QWorkspace workspace = workspaces[i];
bool toBeRemoved = true;
foreach (var foundWorkspace in args.Workspaces)
{
if(workspace.uniqueID == foundWorkspace.uniqueID)
{
toBeRemoved = false;
}
}
if (toBeRemoved)
{
workspace.disconnect();
workspaces.Remove(workspace);
OnServerRemovedWorkspace(workspace);
}
}
OnServerUpdated(this); OnServerUpdated(this);
} }
protected virtual void OnServerAddedWorkspace(QWorkspace workspace)
{
WorkspaceAdded?.Invoke(this, new QServerWorkspaceChangedArgs { server = this, workspace = workspace });
}
protected virtual void OnServerRemovedWorkspace(QWorkspace workspace)
{
WorkspaceRemoved?.Invoke(this, new QServerWorkspaceChangedArgs { server = this, workspace = workspace });
}
protected virtual void OnServerUpdated(QServer server) protected virtual void OnServerUpdated(QServer server)
{ {
ServerUpdated?.Invoke(this, new QServerUpdatedArgs { server = server }); ServerUpdated?.Invoke(this, new QServerUpdatedArgs { server = server });
+22 -1
View File
@@ -11,7 +11,7 @@ using QControlKit.Constants;
namespace QControlKit namespace QControlKit
{ {
public class QWorkspace public class QWorkspace: IEquatable<QWorkspace>
{ {
private QServer server; private QServer server;
@@ -216,6 +216,8 @@ namespace QControlKit
public void disconnect() public void disconnect()
{ {
Log.Information($"[workspace] disconnecting from <{name}>"); Log.Information($"[workspace] disconnecting from <{name}>");
if (!connected)
return;
if (heartbeatTimer != null) if (heartbeatTimer != null)
stopHeartbeat(); stopHeartbeat();
stopReceivingUpdates(); stopReceivingUpdates();
@@ -578,6 +580,25 @@ namespace QControlKit
cueList.Print(); cueList.Print();
} }
} }
#endregion #endregion
public override bool Equals(object obj)
{
if (obj == null) return false;
QWorkspace objAsPart = obj as QWorkspace;
if (objAsPart == null) return false;
else return Equals(objAsPart);
}
public override int GetHashCode()
{
return this.uniqueID.GetHashCode();
}
public bool Equals(QWorkspace other)
{
return this.uniqueID.Equals(other.uniqueID);
}
} }
} }
@@ -56,8 +56,8 @@
<PackageReference Include="Serilog.Sinks.Xamarin"> <PackageReference Include="Serilog.Sinks.Xamarin">
<Version>0.2.0.64</Version> <Version>0.2.0.64</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1560" /> <PackageReference Include="Xamarin.Forms" Version="5.0.0.1874" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" /> <PackageReference Include="Xamarin.Essentials" Version="1.6.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MainActivity.cs" /> <Compile Include="MainActivity.cs" />
@@ -23,7 +23,7 @@ namespace QControlKitXamDemo.iOS
public override bool FinishedLaunching(UIApplication app, NSDictionary options) public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{ {
global::Xamarin.Forms.Forms.Init(); global::Xamarin.Forms.Forms.Init();
Log.Logger = new LoggerConfiguration().WriteTo.NSLog().MinimumLevel.Debug().CreateLogger(); Log.Logger = new LoggerConfiguration().WriteTo.NSLog().MinimumLevel.Information().CreateLogger();
LoadApplication(new App()); LoadApplication(new App());
return base.FinishedLaunching(app, options); return base.FinishedLaunching(app, options);
@@ -61,6 +61,7 @@
<MtouchArch>ARM64</MtouchArch> <MtouchArch>ARM64</MtouchArch>
<CodesignKey>iPhone Developer</CodesignKey> <CodesignKey>iPhone Developer</CodesignKey>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
@@ -129,8 +130,8 @@
<PackageReference Include="Serilog.Sinks.Xamarin"> <PackageReference Include="Serilog.Sinks.Xamarin">
<Version>0.2.0.64</Version> <Version>0.2.0.64</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1560" /> <PackageReference Include="Xamarin.Forms" Version="5.0.0.1874" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" /> <PackageReference Include="Xamarin.Essentials" Version="1.6.0" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<ItemGroup> <ItemGroup>
@@ -4,8 +4,9 @@ using Xamarin.Forms;
using QControlKit; using QControlKit;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using QControlKit.Events; using QControlKit.Events;
using System.Threading.Tasks;
namespace QControlKitXamDemo namespace QControlKitXamDemo
{ {
@@ -20,9 +21,91 @@ namespace QControlKitXamDemo
InitializeComponent(); InitializeComponent();
serverListView.ItemsSource = servers; serverListView.ItemsSource = servers;
QBrowser browser = new QBrowser(); QBrowser browser = new QBrowser();
browser.ServerUpdatedWorkspaces += Browser_ServerUpdatedWorkspaces; browser.ServerLost += Browser_ServerLost;
browser.ServerFound += Browser_ServerFound;
serverListView.ItemSelected += ServerListView_ItemSelected; serverListView.ItemSelected += ServerListView_ItemSelected;
Device.StartTimer(TimeSpan.FromSeconds(5), () =>
{
Task.Run(async () =>
{
browser.ProbeForQLabInstances();
});
return true;
});
}
private void Browser_ServerFound(object source, QServerFoundArgs args)
{
List<ServerGroup> serverGroups = servers.ToList();
bool serverFound = false;
foreach (var serverGroup in serverGroups)
{
if (serverGroup.host == args.server.host)
{
serverFound = true;
}
}
if (!serverFound)
{
Device.BeginInvokeOnMainThread(() =>
{
ServerGroup serverGroup = new ServerGroup(args.server.name);
args.server.WorkspaceAdded += Server_WorkspaceAdded;
args.server.WorkspaceRemoved += Server_WorkspaceRemoved;
serverGroup.host = args.server.host;
servers.Add(serverGroup);
});
}
}
private void Server_WorkspaceRemoved(object source, QServerWorkspaceChangedArgs args)
{
foreach (var server in servers)
{
if (server.host == args.server.host)
{
Device.BeginInvokeOnMainThread(() =>
{
server.Remove(args.workspace);
});
}
}
}
private void Server_WorkspaceAdded(object source, QServerWorkspaceChangedArgs args)
{
foreach(var server in servers)
{
if(server.host == args.server.host)
{
Device.BeginInvokeOnMainThread(() =>
{
server.Add(args.workspace);
});
}
}
}
private void Browser_ServerLost(object source, QServerLostArgs args)
{
List<ServerGroup> serverGroups = servers.ToList();
foreach(var serverGroup in serverGroups)
{
if(serverGroup.host == args.server.host)
{
Device.BeginInvokeOnMainThread(() =>
{
servers.Remove(serverGroup);
});
}
}
} }
async void ServerListView_ItemSelected(object sender, SelectedItemChangedEventArgs e) async void ServerListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
@@ -48,26 +131,16 @@ namespace QControlKitXamDemo
serverListView.SelectedItem = null; serverListView.SelectedItem = null;
} }
} }
private void Browser_ServerUpdatedWorkspaces(object source, QServerUpdatedArgs args)
{
ServerGroup serverGroup = new ServerGroup(args.server.name);
serverGroup.AddRange(args.server.workspaces);
Device.BeginInvokeOnMainThread(() =>
{
servers.Add(serverGroup);
});
}
} }
public class ServerGroup : List<QWorkspace>{ public class ServerGroup : ObservableCollection<QWorkspace>{
public string name { get; set; } public string name { get; set; }
public string host { get; set; }
public ServerGroup(string name) public ServerGroup(string name)
{ {
this.name = name; this.name = name;
} }
} }
} }
@@ -12,8 +12,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog" Version="2.10.0" /> <PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1560" /> <PackageReference Include="Xamarin.Forms" Version="5.0.0.1874" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" /> <PackageReference Include="Xamarin.Essentials" Version="1.6.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -2,7 +2,7 @@
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Xamarin.Forms; using Xamarin.Forms;
using Serilog;
using QControlKit.Events; using QControlKit.Events;
using QControlKit.Constants; using QControlKit.Constants;
@@ -26,7 +26,7 @@ namespace QControlKitXamDemo.ViewModels
{ {
foreach(var property in args.properties) foreach(var property in args.properties)
{ {
//Log.Debug($"[cueviewmodel] property <{property}> has been updated."); Log.Debug($"[cueviewmodel] property <{property}> has been updated.");
if (property.Equals(QOSCKey.Name) || property.Equals(QOSCKey.ListName)) if (property.Equals(QOSCKey.Name) || property.Equals(QOSCKey.ListName))
{ {
OnPropertyChanged("name"); OnPropertyChanged("name");