using System.Collections; using System.Collections.Generic; using GameNetworkLayer.Shared; using Svelto.Context; using Svelto.ECS; namespace CLre.API.Synergy { class ClientMessagingEngine: Engines.GameObsoleteEnginePostBuild, IWaitForFrameworkDestruction, IWaitForFrameworkInitialization { private struct MessageQueueItem { public SerializedCLreMessage msg; public NetworkDispatcherCode code; } private Utility.Reflection.INetMsgClientSender_SendMessage _sendMessage; private Utility.Reflection.INetMsgClientListener_RegisterListener _registerListener; private Queue _messageQueue = new Queue(10); private bool _isRunning = false; public override void Ready() { //Utility.Logging.MetaLog("Building send message delegate"); _sendMessage = Utility.Reflection.MethodAsDelegate>( "GameNetworkLayer.Client.NetMessageClientSender:SendMessage", generics: new [] {typeof(SerializedCLreMessage)}, instance: MainLevel_BuildClasses_Patch.netMessageSender); //Utility.Logging.MetaLog("Building register listener delegate"); _registerListener = Utility.Reflection.MethodAsDelegate>( "GameNetworkLayer.Client.NetMessageClientListener:RegisterListener", generics: new [] {typeof(SerializedCLreMessage)}, instance: MainLevel_BuildClasses_Patch.netMessageListener); _registerListener(Message.CLre_MESSAGE_NETCODE, OnMessageReceived); } private void OnMessageReceived(ref SerializedCLreMessage data) { Message.HandleMessageReceive(ref data); } internal void EnqueueMessage(ref SerializedCLreMessage msg) { _messageQueue.Enqueue(new MessageQueueItem { msg = msg, code = Message.CLre_MESSAGE_NETCODE, }); } public override IEntitiesDB entitiesDB { get; set; } public override IEntityFactory entityFactory { get; set; } public ClientMessagingEngine(): base() { App.Client.GameJoin += (_, __) => { MessageSender().Run(); }; } public IEnumerator MessageSender() { while (!_isRunning) { yield return null; } while (_isRunning) { while (_messageQueue.Count != 0) { MessageQueueItem item = _messageQueue.Dequeue(); API.Utility.Logging.MetaLog($"Sending message with id {item.msg.Id}"); _sendMessage(item.code, ref item.msg); } yield return null; } } public void OnFrameworkDestroyed() { _isRunning = false; } public void OnFrameworkInitialized() { _isRunning = true; } } }