// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Types.h" #include "NetworkConfig.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/ScriptingObjectReference.h" /// /// Low-level network peer class. Provides server-client communication functions, message processing and sending. /// API_CLASS(sealed, NoSpawn, Namespace="FlaxEngine.Networking") class FLAXENGINE_API NetworkPeer final : public ScriptingObject { DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(NetworkPeer, ScriptingObject); // List with all active peers. API_FIELD(ReadOnly) static Array Peers; public: int HostId = -1; NetworkConfig Config; uint8* MessageBuffer = nullptr; Array MessagePool; public: /// /// Low-level network transport driver used by this peer. /// API_FIELD() INetworkDriver* NetworkDriver = nullptr; public: /// /// Starts listening for incoming connections. /// Once this is called, this peer becomes a server. /// /// True when succeeded. API_FUNCTION() bool Listen(); /// /// Starts connection handshake with the end point specified in the structure. /// Once this is called, this peer becomes a client. /// /// True when succeeded. API_FUNCTION() bool Connect(); /// /// Disconnects from the server. /// /// Can be used only by the client! API_FUNCTION() void Disconnect(); /// /// Disconnects given connection from the server. /// /// Can be used only by the server! API_FUNCTION() void Disconnect(const NetworkConnection& connection); /// /// Tries to pop an network event from the queue. /// /// The reference to event structure. /// True when succeeded and the event can be processed. /// If this returns message event, make sure to recycle the message using function after processing it! API_FUNCTION() bool PopEvent(API_PARAM(Out) NetworkEvent& eventRef); /// /// Acquires new message from the pool. /// Cannot acquire more messages than the limit specified in the structure. /// /// The acquired message. /// Make sure to recycle the message to this peer once it is no longer needed! API_FUNCTION() NetworkMessage CreateMessage(); /// /// Returns given message to the pool. /// /// Make sure that this message belongs to the peer and has not been recycled already (debug build checks for this)! API_FUNCTION() void RecycleMessage(const NetworkMessage& message); /// /// Acquires new message from the pool and setups it for sending. /// /// The acquired message. API_FUNCTION() NetworkMessage BeginSendMessage(); /// /// Aborts given message send. This effectively deinitializes the message and returns it to the pool. /// /// The message. API_FUNCTION() void AbortSendMessage(const NetworkMessage& message); /// /// Sends given message over specified channel to the server. /// /// The channel to send the message over. /// The message. /// Can be used only by the client! /// /// Do not recycle the message after calling this. /// This function automatically recycles the message. /// API_FUNCTION() bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message); /// /// Sends given message over specified channel to the given client connection (target). /// /// The channel to send the message over. /// The message. /// The client connection to send the message to. /// Can be used only by the server! /// /// Do not recycle the message after calling this. /// This function automatically recycles the message. /// API_FUNCTION() bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target); /// /// Sends given message over specified channel to the given client connection (target). /// /// The channel to send the message over. /// The message. /// The connections list to send the message to. /// Can be used only by the server! /// /// Do not recycle the message after calling this. /// This function automatically recycles the message. /// API_FUNCTION() bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array& targets); /// /// Creates new peer using given configuration. /// /// The configuration to create and setup new peer. /// The peer. /// Peer should be destroyed using once it is no longer in use. Returns null if failed to create a peer (eg. config is invalid). API_FUNCTION() static NetworkPeer* CreatePeer(const NetworkConfig& config); /// /// Shutdowns and destroys given peer. /// /// The peer to destroy. API_FUNCTION() static void ShutdownPeer(NetworkPeer* peer); public: bool IsValid() const { return NetworkDriver != nullptr && HostId >= 0; } uint8* GetMessageBuffer(const uint32 messageId) const { // Calculate and return the buffer slice using previously calculated slice. return MessageBuffer + Config.MessageSize * messageId; } public: FORCE_INLINE bool operator==(const NetworkPeer& other) const { return HostId == other.HostId; } FORCE_INLINE bool operator!=(const NetworkPeer& other) const { return HostId != other.HostId; } private: bool Initialize(const NetworkConfig& config); void Shutdown(); void CreateMessageBuffers(); void DisposeMessageBuffers(); };