Skip to content

Commit

Permalink
Simplifies extensibility
Browse files Browse the repository at this point in the history
  • Loading branch information
kakone committed Jun 24, 2018
1 parent 808cbb6 commit 63c93b2
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 118 deletions.
2 changes: 1 addition & 1 deletion GoogleCast.SampleApp/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace GoogleCast.SampleApp
class MainViewModel : ViewModelBase
{
/// <summary>
/// Initializes a new instance of MainViewModel class
/// Initializes a new instance of <see cref="MainViewModel"/> class
/// </summary>
/// <param name="deviceLocator">GoogleCast device locator</param>
/// <param name="sender">GoogleCast sender</param>
Expand Down
2 changes: 1 addition & 1 deletion GoogleCast.SampleApp/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace GoogleCast.SampleApp
public partial class MainWindow : Window
{
/// <summary>
/// Initializes a new instance of MainWindow class
/// Initializes a new instance of <see cref="MainWindow"/> class
/// </summary>
public MainWindow()
{
Expand Down
2 changes: 1 addition & 1 deletion GoogleCast/Channels/ConnectionChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace GoogleCast.Channels
class ConnectionChannel : Channel, IConnectionChannel
{
/// <summary>
/// Initializes a new instance of ConnectionChannel class
/// Initializes a new instance of <see cref="ConnectionChannel"/> class
/// </summary>
public ConnectionChannel() : base("tp.connection")
{
Expand Down
2 changes: 1 addition & 1 deletion GoogleCast/Channels/HeartbeatChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace GoogleCast.Channels
class HeartbeatChannel : Channel, IHeartbeatChannel
{
/// <summary>
/// Initializes a new instance of HeartbeatChannel class
/// Initializes a new instance of <see cref="HeartbeatChannel"/> class
/// </summary>
public HeartbeatChannel() : base("tp.heartbeat")
{
Expand Down
31 changes: 15 additions & 16 deletions GoogleCast/Channels/MediaChannel.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using GoogleCast.Messages;
using GoogleCast.Messages.Media;
using GoogleCast.Models.Media;
using GoogleCast.Models.Receiver;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -15,7 +14,7 @@ namespace GoogleCast.Channels
class MediaChannel : StatusChannel<IEnumerable<MediaStatus>, MediaStatusMessage, GetStatusMessage>, IMediaChannel
{
/// <summary>
/// Initializes a new instance of MediaChannel class
/// Initializes a new instance of <see cref="MediaChannel"/> class
/// </summary>
public MediaChannel() : base("media")
{
Expand All @@ -31,9 +30,19 @@ private IReceiverChannel ReceiverChannel
get { return Sender.GetChannel<IReceiverChannel>(); }
}

private async Task<MediaStatus> SendAsync(IMessageWithId message, Application application)
private async Task<MediaStatus> SendAsync(IMessageWithId message)
{
application = (application ?? await ReceiverChannel.EnsureConnection(Namespace));
var application = await ReceiverChannel.EnsureConnection(Namespace);
switch (message)
{
case SessionMessage sessionMessage:
sessionMessage.SessionId = application.SessionId;
break;
case MediaSessionMessage mediaSessionMessage:
SetMediaSessionId(mediaSessionMessage);
break;
}

try
{
return (await SendAsync<MediaStatusMessage>(message, application.TransportId)).Status?.FirstOrDefault();
Expand All @@ -50,12 +59,6 @@ private void SetMediaSessionId(MediaSessionMessage message)
message.MediaSessionId = Status?.First().MediaSessionId ?? throw new ArgumentNullException("MediaSessionId");
}

private async Task<MediaStatus> SendAsync(MediaSessionMessage message)
{
SetMediaSessionId(message);
return await SendAsync(message, null);
}

/// <summary>
/// Creates a GetStatusMessage
/// </summary>
Expand All @@ -76,14 +79,12 @@ protected override GetStatusMessage CreateGetStatusMessage()
/// <returns>media status</returns>
public async Task<MediaStatus> LoadAsync(MediaInformation media, bool autoPlay = true, params int[] activeTrackIds)
{
var application = await ReceiverChannel.EnsureConnection(Namespace);
return await SendAsync(new LoadMessage()
{
SessionId = application.SessionId,
Media = media,
AutoPlay = autoPlay,
ActiveTrackIds = activeTrackIds
}, application);
});
}

/// <summary>
Expand All @@ -110,13 +111,11 @@ public Task<MediaStatus> QueueLoadAsync(RepeatMode repeatMode, params QueueItem[

private async Task<MediaStatus> QueueLoadAsync(RepeatMode repeatMode, IEnumerable<QueueItem> queueItems)
{
var application = await ReceiverChannel.EnsureConnection(Namespace);
return await SendAsync(new QueueLoadMessage()
{
SessionId = application.SessionId,
RepeatMode = repeatMode,
Items = queueItems
}, application);
});
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion GoogleCast/Channels/ReceiverChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace GoogleCast.Channels
class ReceiverChannel : StatusChannel<ReceiverStatus, ReceiverStatusMessage, GetStatusMessage>, IReceiverChannel
{
/// <summary>
/// Initializes a new instance of ReceiverChannel class
/// Initializes a new instance of <see cref="ReceiverChannel"/> class
/// </summary>
public ReceiverChannel() : base("receiver")
{
Expand Down
6 changes: 3 additions & 3 deletions GoogleCast/GoogleCast.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
<PackageProjectUrl>https://github.com/kakone/GoogleCast</PackageProjectUrl>
<PackageTags>google cast chromecast</PackageTags>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<AssemblyVersion>1.6.0.0</AssemblyVersion>
<FileVersion>1.6.0.0</FileVersion>
<Version>1.6.0</Version>
<AssemblyVersion>1.6.1.0</AssemblyVersion>
<FileVersion>1.6.1.0</FileVersion>
<Version>1.6.1</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand Down
12 changes: 12 additions & 0 deletions GoogleCast/IMessageTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;

namespace GoogleCast
{
/// <summary>
/// Interface for message types dictionary
/// </summary>
public interface IMessageTypes : IDictionary<string, Type>
{
}
}
37 changes: 37 additions & 0 deletions GoogleCast/MessageTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using GoogleCast.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace GoogleCast
{
/// <summary>
/// Dictionary of message types
/// </summary>
public class MessageTypes : Dictionary<string, Type>, IMessageTypes
{
/// <summary>
/// Initializes a new instance of <see cref="MessageTypes"/> class
/// </summary>
public MessageTypes()
{
AddMessageTypes(Assembly.GetExecutingAssembly());
}

/// <summary>
/// Adds all the message types of a given assembly
/// </summary>
/// <param name="assembly">assembly</param>
public void AddMessageTypes(Assembly assembly)
{
var messageInterfaceType = typeof(IMessage);
var receptionMessageAttributeType = typeof(ReceptionMessageAttribute);
foreach (var type in assembly.GetTypes().Where(t =>
t.IsClass && !t.IsAbstract && t.IsDefined(receptionMessageAttributeType) && messageInterfaceType.IsAssignableFrom(t)))
{
Add(Message.GetMessageType(type), type);
}
}
}
}
18 changes: 14 additions & 4 deletions GoogleCast/Messages/Message.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.Serialization;
using System;
using System.Runtime.Serialization;

namespace GoogleCast.Messages
{
Expand All @@ -13,14 +14,23 @@ public abstract class Message : IMessage
/// </summary>
public Message()
{
var type = GetType().Name;
Type = type.Substring(0, type.LastIndexOf(nameof(Message))).ToUnderscoreUpperInvariant();
Type = GetMessageType(GetType());
}

/// <summary>
/// Gets or sets the message type
/// Gets the message type
/// </summary>
[DataMember(Name = "type")]
public string Type { get; set; }

/// <summary>
/// Gets the message type
/// </summary>
/// <returns>message class type</returns>
public static string GetMessageType(Type type)
{
var typeName = type.Name;
return typeName.Substring(0, typeName.LastIndexOf(nameof(Message))).ToUnderscoreUpperInvariant();
}
}
}
3 changes: 2 additions & 1 deletion GoogleCast/Messages/ReceptionMessageAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ namespace GoogleCast.Messages
/// <summary>
/// Attribute for received messages
/// </summary>
class ReceptionMessageAttribute : Attribute
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ReceptionMessageAttribute : Attribute
{
}
}
51 changes: 19 additions & 32 deletions GoogleCast/Sender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,52 +31,37 @@ public class Sender : ISender
public event EventHandler Disconnected;

/// <summary>
/// Initializes a new instance of Sender class
/// Initializes a new instance of <see cref="Sender"/> class
/// </summary>
public Sender() : this(ServiceCollection.Default)
public Sender() : this(new ServiceCollection().AddGoogleCast().BuildServiceProvider())
{
}

/// <summary>
/// Initializes a new instance of Sender class
/// Initializes a new instance of <see cref="Sender"/> class
/// </summary>
/// <param name="serviceCollection">collection of service descriptors</param>
public Sender(IServiceCollection serviceCollection)
/// <param name="serviceProvider">collection of service descriptors</param>
public Sender(IServiceProvider serviceProvider)
{
var serviceProvider = serviceCollection.BuildServiceProvider();
Init(serviceProvider.GetServices<IChannel>(), serviceProvider.GetServices<IMessage>());
}

/// <summary>
/// Initializes a new instance of Sender class
/// </summary>
/// <param name="channels">the channels collection</param>
/// <param name="messages">messages that can be received</param>
public Sender(IEnumerable<IChannel> channels, IEnumerable<IMessage> messages)
{
Init(channels, messages);
ServiceProvider = serviceProvider;
var channels = serviceProvider.GetServices<IChannel>();
Channels = channels;
foreach (var channel in channels)
{
channel.Sender = this;
}
}

private IReceiver Receiver { get; set; }
private IDictionary<string, Type> MessageTypes { get; set; }
private IServiceProvider ServiceProvider { get; }
private IEnumerable<IChannel> Channels { get; set; }
private IReceiver Receiver { get; set; }
private Stream NetworkStream { get; set; }
private TcpClient TcpClient { get; set; }
private SemaphoreSlim SendSemaphoreSlim { get; } = new SemaphoreSlim(1, 1);
private SemaphoreSlim EnsureConnectionSemaphoreSlim { get; } = new SemaphoreSlim(1, 1);
private ConcurrentDictionary<int, object> WaitingTasks { get; } = new ConcurrentDictionary<int, object>();
private TaskCompletionSource<bool> ReceiveTcs { get; set; }

private void Init(IEnumerable<IChannel> channels, IEnumerable<IMessage> messages)
{
MessageTypes = messages.Where(t => !String.IsNullOrEmpty(t.Type)).ToDictionary(m => m.Type, m => m.GetType());
Channels = channels;
foreach (var channel in channels)
{
channel.Sender = this;
}
}

/// <summary>
/// Disconnects
/// </summary>
Expand Down Expand Up @@ -172,6 +157,8 @@ private void Receive()
{
try
{
var channels = Channels;
var messageTypes = ServiceProvider.GetService<IMessageTypes>();
while (true)
{
var buffer = await ReadAsync(4);
Expand All @@ -190,16 +177,16 @@ private void Receive()
var payload = (castMessage.PayloadType == PayloadType.Binary ?
Encoding.UTF8.GetString(castMessage.PayloadBinary) : castMessage.PayloadUtf8);
Debug.WriteLine($"RECEIVED: {castMessage.Namespace} : {payload}");
var channel = Channels.FirstOrDefault(c => c.Namespace == castMessage.Namespace);
var channel = channels.FirstOrDefault(c => c.Namespace == castMessage.Namespace);
if (channel != null)
{
var message = JsonSerializer.Deserialize<MessageWithId>(payload);
if (MessageTypes.TryGetValue(message.Type, out Type type))
if (messageTypes.TryGetValue(message.Type, out Type type))
{
try
{
var response = (IMessage)JsonSerializer.Deserialize(type, payload);
await channel.OnMessageReceivedAsync((IMessage)JsonSerializer.Deserialize(type, payload));
await channel.OnMessageReceivedAsync(response);
TaskCompletionSourceInvoke(message, "SetResult", response);
}
catch (Exception ex)
Expand Down
38 changes: 0 additions & 38 deletions GoogleCast/ServiceCollection.cs

This file was deleted.

Loading

0 comments on commit 63c93b2

Please sign in to comment.