Core: Add ByteArrayPool and PoolByteStream classes

This commit is contained in:
Lynix 2020-02-04 11:42:05 +01:00
parent 518b8697de
commit e35caebdcf
7 changed files with 207 additions and 3 deletions

View File

@ -221,6 +221,7 @@ Nazara Engine:
- ⚠ TextDrawers now use floating-point internally and to exposes their Bounds (AbstractTextDrawer::GetBounds() now returns a Rectf)
- Added [SimpleTextDrawer|RichTextDrawer] character and line spacing offset properties
- Added ENetHost::AllowsIncomingConnections(bool) to disable/re-enable server peers connection
- Added ByteArrayPool and PoolByteStream classes
Nazara Development Kit:
- Added ImageWidget (#139)

View File

@ -0,0 +1,43 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BYTEARRAYPOOL_HPP
#define NAZARA_BYTEARRAYPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/String.hpp>
#include <vector>
namespace Nz
{
class AbstractHash;
class NAZARA_CORE_API ByteArrayPool
{
public:
ByteArrayPool() = default;
ByteArrayPool(const ByteArrayPool&) = delete;
ByteArrayPool(ByteArrayPool&&) = default;
~ByteArrayPool() = default;
inline void Clear();
inline ByteArray GetByteArray(std::size_t capacity = 0);
inline void ReturnByteArray(ByteArray byteArray);
ByteArrayPool& operator=(const ByteArrayPool&) = delete;
ByteArrayPool& operator=(ByteArrayPool&&) = default;
private:
std::vector<ByteArray> m_byteArrays;
};
}
#include <Nazara/Core/ByteArrayPool.inl>
#endif // NAZARA_BYTEARRAYPOOL_HPP

View File

@ -0,0 +1,44 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ByteArrayPool.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
namespace Detail
{
bool SortByteArrayByCapacity(const ByteArray& byteArray, std::size_t refCapacity)
{
return refCapacity > byteArray.GetCapacity();
}
}
inline void ByteArrayPool::Clear()
{
m_byteArrays.clear();
}
inline ByteArray ByteArrayPool::GetByteArray(std::size_t capacity)
{
ByteArray ret;
auto it = std::lower_bound(m_byteArrays.begin(), m_byteArrays.end(), capacity, Detail::SortByteArrayByCapacity);
if (it != m_byteArrays.end())
{
ret = std::move(*it);
m_byteArrays.erase(it);
}
return ret;
}
inline void ByteArrayPool::ReturnByteArray(ByteArray byteArray)
{
auto it = std::lower_bound(m_byteArrays.begin(), m_byteArrays.end(), byteArray.GetCapacity(), Detail::SortByteArrayByCapacity);
m_byteArrays.emplace(it, std::move(byteArray));
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -0,0 +1,46 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_POOLBYTESTREAM_HPP
#define NAZARA_POOLBYTESTREAM_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Core/Config.hpp>
namespace Nz
{
class ByteArrayPool;
class NAZARA_CORE_API PoolByteStream : public ByteStream
{
friend class Network;
public:
inline PoolByteStream(ByteArrayPool& pool);
inline PoolByteStream(ByteArrayPool& pool, std::size_t capacity);
PoolByteStream(const PoolByteStream&) = delete;
PoolByteStream(PoolByteStream&& packet) = default;
inline ~PoolByteStream();
void Reset();
void Reset(std::size_t capacity);
PoolByteStream& operator=(const PoolByteStream&) = delete;
PoolByteStream& operator=(PoolByteStream&&) = delete;
private:
void OnEmptyStream() override;
ByteArrayPool& m_pool;
ByteArray m_buffer;
};
}
#include <Nazara/Core/PoolByteStream.inl>
#endif // NAZARA_POOLBYTESTREAM_HPP

View File

@ -0,0 +1,30 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/PoolByteStream.hpp>
#include <Nazara/Core/Error.hpp>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
inline PoolByteStream::PoolByteStream(ByteArrayPool& pool) :
m_pool(pool)
{
}
inline PoolByteStream::PoolByteStream(ByteArrayPool& pool, std::size_t capacity) :
PoolByteStream(pool)
{
Reset(capacity);
}
inline PoolByteStream::~PoolByteStream()
{
FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
Reset(); //< Returns the byte array (if any) to the pool
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -68,7 +68,7 @@ namespace Nz
void ByteStream::SetStream(ByteArray* byteArray, OpenModeFlags openMode)
{
std::unique_ptr<Stream> stream(new MemoryStream(byteArray, openMode));
std::unique_ptr<MemoryStream> stream = std::make_unique<MemoryStream>(byteArray, openMode);
SetStream(stream.get());
// SetStream reset our smart pointer, set it after calling it
@ -86,7 +86,7 @@ namespace Nz
void ByteStream::SetStream(void* ptr, Nz::UInt64 size)
{
std::unique_ptr<Stream> stream(new MemoryView(ptr, size));
std::unique_ptr<MemoryView> stream = std::make_unique<MemoryView>(ptr, size);
SetStream(stream.get());
// SetStream reset our smart pointer, set it after calling it
@ -104,7 +104,7 @@ namespace Nz
void ByteStream::SetStream(const void* ptr, Nz::UInt64 size)
{
std::unique_ptr<Stream> stream(new MemoryView(ptr, size));
std::unique_ptr<MemoryView> stream = std::make_unique<MemoryView>(ptr, size);
SetStream(stream.get());
// SetStream reset our smart pointer, set it after calling it

View File

@ -0,0 +1,40 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/PoolByteStream.hpp>
#include <Nazara/Core/ByteArrayPool.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::PoolByteStream
* \brief ByteStream allocated using a pool
*/
void PoolByteStream::Reset()
{
if (m_buffer.GetCapacity() > 0)
{
m_pool.ReturnByteArray(std::move(m_buffer));
m_buffer.Clear(false);
}
SetStream(static_cast<Nz::Stream*>(nullptr));
}
void PoolByteStream::Reset(std::size_t capacity)
{
if (m_buffer.GetCapacity() < capacity)
m_buffer = m_pool.GetByteArray(capacity);
SetStream(&m_buffer, Nz::OpenMode_ReadWrite);
}
void PoolByteStream::OnEmptyStream()
{
Reset(0);
}
}