Code refactoring for cleaner view model design

This commit is contained in:
watsonb8
2019-11-29 12:37:57 -05:00
parent 3398d145ac
commit 85ab39defd
15 changed files with 351 additions and 123 deletions

View File

@ -6,9 +6,12 @@ using Aurora.Proto.Events;
using Aurora.Proto.Party;
using Aurora.Proto.Playback;
using Aurora.Proto.Sync;
using Aurora.Services.ClientService.Events;
using System.Collections.Generic;
namespace Aurora.Services.ClientService
{
public class ClientService : BaseService<ClientService>
{
private RemotePartyService.RemotePartyServiceClient _remotePartyClient;
@ -23,7 +26,11 @@ namespace Aurora.Services.ClientService
{
}
public EventReceivedEventHandler EventReceived;
public MediaPausedEventHandler OnMediaPaused;
public NewMediaPlayingEventHandler OnNewMediaPlaying;
public PartyMemberJoinedEventHandler OnPartyMemberJoined;
public PartyMemberLeftEventHandler OnPartyMemberLeft;
public MediaResumedEventHandler OnMediaResumed;
public RemotePartyService.RemotePartyServiceClient RemotePartyClient
{
@ -99,16 +106,36 @@ namespace Aurora.Services.ClientService
while (!_eventCancellationTokenSource.Token.IsCancellationRequested &&
await eventStream.ResponseStream.MoveNext(_eventCancellationTokenSource.Token))
{
BaseEvent e = new BaseEvent(eventStream.ResponseStream.Current);
if (this.EventReceived != null)
try
{
this.EventReceived.Invoke(this, new EventReceivedEventArgs(e));
BaseEvent e = new BaseEvent(eventStream.ResponseStream.Current);
Dictionary<BaseEvent.DerivedEventOneofCase, EventInfo> events = new Dictionary<BaseEvent.DerivedEventOneofCase, EventInfo>()
{
{BaseEvent.DerivedEventOneofCase.MediaPausedEvent, new EventInfo(this.OnMediaPaused, typeof(MediaPausedEventArgs))},
{BaseEvent.DerivedEventOneofCase.MediaResumedEvent, new EventInfo(this.OnMediaResumed, typeof(MediaResumedEventArgs))},
{BaseEvent.DerivedEventOneofCase.NewMediaPlayingEvent, new EventInfo(this.OnNewMediaPlaying, typeof(NewMediaPlayingEventArgs))},
{BaseEvent.DerivedEventOneofCase.PartyMemberJoinedEvent, new EventInfo(this.OnPartyMemberJoined, typeof(PartyMemberJoinedEventArgs))},
{BaseEvent.DerivedEventOneofCase.PartyMemberLeftEvent, new EventInfo(this.OnPartyMemberLeft, typeof(PartyMemberLeftEventArgs))}
};
events.TryGetValue(e.DerivedEventCase, out EventInfo eventInfo);
if (eventInfo != null && eventInfo.Handler != null)
{
eventInfo.Handler.DynamicInvoke(new object[] { this, Activator.CreateInstance(eventInfo.ArgsType, new object[] { e }) });
}
}
catch (Exception ex)
{
Console.WriteLine("Exception while parsing event ---" + ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("EXCEPTION --- " + ex.Message));
Console.WriteLine(string.Format("EXCEPTION while parsing events --- " + ex.Message));
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Threading.Tasks;
using System.Threading;
using Grpc.Core;
using Aurora.Proto.Events;
using Aurora.Proto.Party;
using Aurora.Proto.Playback;
using Aurora.Proto.Sync;
using Aurora.Services.ClientService.Events;
using System.Collections.Generic;
namespace Aurora.Services.ClientService
{
public class EventInfo
{
public EventInfo(Delegate handler, Type argsType)
{
this.Handler = handler;
ArgsType = argsType;
}
public Delegate Handler { get; private set; }
public Type ArgsType { get; private set; }
}
}

View File

@ -1,16 +0,0 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService
{
public delegate void EventReceivedEventHandler(object sender, EventReceivedEventArgs e);
public class EventReceivedEventArgs
{
public BaseEvent BaseEvent { get; private set; }
public EventReceivedEventArgs(BaseEvent e)
{
BaseEvent = e;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void MediaPausedEventHandler(object sender, MediaPausedEventArgs e);
public class MediaPausedEventArgs
{
public MediaPausedEvent Event { get; private set; }
public MediaPausedEventArgs(BaseEvent e)
{
Event = e.MediaPausedEvent;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService
{
public delegate void MediaResumedEventHandler(object sender, MediaResumedEventArgs e);
public class MediaResumedEventArgs
{
public MediaResumedEvent Event { get; private set; }
public MediaResumedEventArgs(BaseEvent e)
{
Event = e.MediaResumedEvent;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void NewMediaPlayingEventHandler(object sender, NewMediaPlayingEventArgs e);
public class NewMediaPlayingEventArgs
{
public NewMediaPlayingEvent Event { get; private set; }
public NewMediaPlayingEventArgs(BaseEvent e)
{
Event = e.NewMediaPlayingEvent;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void PartyMemberJoinedEventHandler(object sender, PartyMemberJoinedEventArgs e);
public class PartyMemberJoinedEventArgs
{
public PartyMemberJoinedEvent Event { get; private set; }
public PartyMemberJoinedEventArgs(BaseEvent e)
{
Event = e.PartyMemberJoinedEvent;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using Aurora.Proto.Events;
namespace Aurora.Services.ClientService.Events
{
public delegate void PartyMemberLeftEventHandler(object sender, PartyMemberLeftEventArgs e);
public class PartyMemberLeftEventArgs
{
public PartyMemberLeftEvent Event { get; private set; }
public PartyMemberLeftEventArgs(BaseEvent e)
{
Event = e.PartyMemberLeftEvent;
}
}
}

View File

@ -1,16 +1,9 @@
using System;
using System.IO;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Google.Protobuf.Reflection;
using Aurora.Proto.Events;
using Aurora.Models;
namespace Aurora.Services.EventManager
{
@ -183,8 +176,6 @@ namespace Aurora.Services.EventManager
{
foreach (KeyValuePair<string, List<EventType>> pair in _subscriptionList)
{
Console.WriteLine("SERVER - Invoking action for client: " + pair.Key);
Task.Delay(1000);
//If action list contains an action for id, invoke
if (actionsCopy.ContainsKey(pair.Key))

View File

@ -4,6 +4,8 @@ using System.Threading;
using Grpc.Core;
using Aurora.Models.Media;
using Aurora.Proto.Sync;
using Aurora.Proto.Events;
using Aurora.Proto.Party;
using LibVLCSharp.Shared;
namespace Aurora.Services.PlayerService
@ -110,14 +112,14 @@ namespace Aurora.Services.PlayerService
RemoteAudio media = _currentMedia as RemoteAudio;
if (!media.FromHost)
{
RemoteSyncService.RemoteSyncServiceClient _remoteSyncClient = media.RemoteSyncClient;
RemoteSyncService.RemoteSyncServiceClient remoteSyncClient = media.RemoteSyncClient;
//Sync playback in a separate task
//Task completes when host stops syncing (when a song is complete)
Task syncTask = new Task(async () =>
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
using (AsyncServerStreamingCall<Sync> syncStream = _remoteSyncClient
using (AsyncServerStreamingCall<Sync> syncStream = remoteSyncClient
.GetMediaSync(new Proto.General.Empty()))
{
try
@ -154,6 +156,7 @@ namespace Aurora.Services.PlayerService
});
syncTask.Start();
// Task syncTask = Task.Run(() => Sync(remoteSyncClient));
}
}
@ -163,6 +166,50 @@ namespace Aurora.Services.PlayerService
}
}
/// <summary>
/// Async method to synchronize music playback with host
/// </summary>
/// <param name="remoteSyncClient"></param>
/// <returns></returns>
private async Task Sync(RemoteSyncService.RemoteSyncServiceClient remoteSyncClient)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
using (AsyncServerStreamingCall<Sync> syncStream = remoteSyncClient
.GetMediaSync(new Proto.General.Empty()))
{
try
{
while (await syncStream.ResponseStream.MoveNext(cancellationTokenSource.Token))
{
Sync sync = new Sync(syncStream.ResponseStream.Current);
if (sync != null)
{
//Adjust position based on sync
DateTime localTime = Utils.TimeUtils.GetNetworkTime();
//Get offset converted to milliseconds
float offset = ((localTime.Ticks - sync.ServerTime) * 100) / (1000 * 1000);
float length = CurrentMediaLength;
float newPosition = (sync.TrackTime + offset) / length;
//Adjust position if greater than 10 percent difference
float oldPosition = _mediaPlayer.Position;
if (newPosition - oldPosition > 0.001 ||
newPosition - oldPosition < -0.001)
{
_mediaPlayer.Position = newPosition;
Console.WriteLine("Audio synced");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception caught while attempting to sync: " + ex.Message);
}
}
}
/// <summary>
/// Pause currently loaded media.
/// </summary>
@ -191,7 +238,6 @@ namespace Aurora.Services.PlayerService
{
PlaybackStateChanged.Invoke(this, new PlaybackStateChangedEventArgs(oldState, _state));
}
}
public void Enqueue(BaseMedia song)