// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Scripting/ScriptingObject.h"
#include "Engine/Serialization/ReadStream.h"
#include "Engine/Serialization/WriteStream.h"
class INetworkSerializable;
///
/// Objects and values serialization stream for sending data over network. Uses memory buffer for both read and write operations.
///
API_CLASS(sealed, Namespace = "FlaxEngine.Networking") class FLAXENGINE_API NetworkStream final : public ScriptingObject, public ReadStream, public WriteStream
{
DECLARE_SCRIPTING_TYPE(NetworkStream);
private:
byte* _buffer = nullptr;
byte* _position = nullptr;
uint32 _length = 0;
bool _allocated = false;
public:
~NetworkStream();
///
/// The ClientId of the network client that is a data sender. Can be used to detect who send the incoming RPC or replication data. Set to the current client when writing data.
///
API_FIELD(ReadOnly) uint32 SenderId = 0;
///
/// Gets the pointer to the native stream memory buffer.
///
API_PROPERTY() byte* GetBuffer() const
{
return _buffer;
}
///
/// Initializes the stream for writing. Allocates the memory or reuses already existing memory. Resets the current stream position to beginning.
///
/// The minimum capacity (in bytes) for the memory buffer used for data storage.
API_FUNCTION() void Initialize(uint32 minCapacity = 1024);
///
/// Initializes the stream for reading.
///
/// The allocated memory.
/// The allocated memory length (bytes count).
API_FUNCTION() void Initialize(byte* buffer, uint32 length);
///
/// Writes bytes to the stream
///
/// Data to write
/// Amount of bytes to write
API_FUNCTION() FORCE_INLINE void WriteData(const void* data, int32 bytes)
{
WriteBytes(data, bytes);
}
///
/// Reads bytes from the stream
///
/// Data to write
/// Amount of bytes to write
API_FUNCTION() FORCE_INLINE void ReadData(void* data, int32 bytes)
{
ReadBytes(data, bytes);
}
using ReadStream::Read;
void Read(INetworkSerializable& obj);
void Read(INetworkSerializable* obj);
using WriteStream::Write;
void Write(INetworkSerializable& obj);
void Write(INetworkSerializable* obj);
public:
// [Stream]
void Flush() override;
void Close() override;
uint32 GetLength() override;
uint32 GetPosition() override;
void SetPosition(uint32 seek) override;
// [ReadStream]
void ReadBytes(void* data, uint32 bytes) override;
// [WriteStream]
void WriteBytes(const void* data, uint32 bytes) override;
};