WingMan – Rev 36

Subversion Repositories:
Rev:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ProtoBuf;
using WingMan.Communication;

namespace WingMan.Lobby
{
    public class LobbyMessageSynchronizer : IDisposable
    {
        public delegate void LobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e);

        public LobbyMessageSynchronizer(MqttCommunication mqttCommunication, TaskScheduler taskScheduler,
            CancellationToken cancellationToken)
        {
            MqttCommunication = mqttCommunication;
            CancellationToken = cancellationToken;
            TaskScheduler = taskScheduler;

            mqttCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
        }

        private MqttCommunication MqttCommunication { get; }

        private CancellationToken CancellationToken { get; }
        private TaskScheduler TaskScheduler { get; }

        public void Dispose()
        {
            MqttCommunication.OnMessageReceived -= MqttCommunicationOnOnMessageReceived;
        }

        public event LobbyMessageReceived OnLobbyMessageReceived;

        private async void MqttCommunicationOnOnMessageReceived(object sender,
            MqttCommunicationMessageReceivedEventArgs e)
        {
            if (e.Topic != "lobby")
                return;

            using (var memoryStream = new MemoryStream())
            {
                await e.PayloadStream.CopyToAsync(memoryStream);

                memoryStream.Position = 0L;

                var lobbyMessage = Serializer.Deserialize<LobbyMessage>(memoryStream);

                await Task.Delay(0)
                    .ContinueWith(
                        _ => OnLobbyMessageReceived?.Invoke(sender,
                            new LobbyMessageReceivedEventArgs(lobbyMessage.Nick, lobbyMessage.Message)),
                        CancellationToken, TaskContinuationOptions.None, TaskScheduler);
            }
        }

        public async Task Broadcast(string message)
        {
            using (var memoryStream = new MemoryStream())
            {
                Serializer.Serialize(memoryStream, new LobbyMessage(MqttCommunication.Nick, message));

                memoryStream.Position = 0L;

                await MqttCommunication.Broadcast("lobby", memoryStream.ToArray());
            }
        }
    }
}