RemoteToolsOutboxThread.cpp 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "RemoteToolsOutboxThread.h"
  9. #include <Source/AutoGen/RemoteTools.AutoPackets.h>
  10. #include <RemoteToolsSystemComponent.h>
  11. #include <AzFramework/Network/IRemoteTools.h>
  12. #include <AzNetworking/Framework/INetworking.h>
  13. #include <AzNetworking/Framework/INetworkInterface.h>
  14. namespace RemoteTools
  15. {
  16. RemoteToolsOutboxThread::RemoteToolsOutboxThread(int updateRate)
  17. : TimedThread("RemoteTools::RemoteToolsOutboxThread", AZ::TimeMs(updateRate))
  18. {
  19. ;
  20. }
  21. RemoteToolsOutboxThread::~RemoteToolsOutboxThread()
  22. {
  23. Stop();
  24. Join();
  25. }
  26. void RemoteToolsOutboxThread::PushOutboxMessage(
  27. AzNetworking::INetworkInterface* netInterface,
  28. AzNetworking::ConnectionId connectionId, OutboundToolingDatum&& datum)
  29. {
  30. m_outboxMutex.lock();
  31. auto& message = m_outbox.emplace_back();
  32. message.netInterface = netInterface;
  33. message.connectionId = connectionId;
  34. message.datum = datum;
  35. m_outboxMutex.unlock();
  36. }
  37. uint32_t RemoteToolsOutboxThread::GetPendingMessageCount()
  38. {
  39. return aznumeric_cast<uint32_t>(m_outbox.size());
  40. }
  41. void RemoteToolsOutboxThread::OnStop()
  42. {
  43. m_outboxMutex.lock();
  44. m_outbox.clear();
  45. m_outboxMutex.unlock();
  46. }
  47. void RemoteToolsOutboxThread::OnUpdate([[maybe_unused]] AZ::TimeMs updateRateMs)
  48. {
  49. // Send outbound data
  50. size_t maxMsgsToSend = m_outbox.size();
  51. if (maxMsgsToSend > 0)
  52. {
  53. for (size_t iSend = 0; iSend < maxMsgsToSend; ++iSend)
  54. {
  55. // Lock outbox to prevent a read/write race
  56. m_outboxMutex.lock();
  57. auto& outBoxElem = m_outbox.front();
  58. auto& outBoxDatum = outBoxElem.datum.second;
  59. uint8_t* outBuffer = reinterpret_cast<uint8_t*>(outBoxDatum.data());
  60. const size_t totalSize = outBoxDatum.size();
  61. size_t outSize = outBoxDatum.size();
  62. while (outSize > 0 && outBoxElem.netInterface != nullptr)
  63. {
  64. // Fragment the message into RemoteToolsMessageBuffer packet sized chunks and send
  65. size_t bufferSize = AZStd::min(outSize, aznumeric_cast<size_t>(RemoteToolsBufferSize));
  66. RemoteToolsPackets::RemoteToolsMessage tmPacket;
  67. tmPacket.SetPersistentId(outBoxElem.datum.first);
  68. tmPacket.SetSize(aznumeric_cast<uint32_t>(totalSize));
  69. RemoteToolsMessageBuffer encodingBuffer;
  70. encodingBuffer.CopyValues(outBuffer + (totalSize - outSize), bufferSize);
  71. tmPacket.SetMessageBuffer(encodingBuffer);
  72. outSize -= bufferSize;
  73. outBoxElem.netInterface->SendReliablePacket(outBoxElem.connectionId, tmPacket);
  74. }
  75. m_outbox.pop_front();
  76. m_outboxMutex.unlock();
  77. }
  78. }
  79. }
  80. } // namespace RemoteTools