Merge branch 'master' into graphics-next
This commit is contained in:
commit
26de5872eb
|
|
@ -37,7 +37,10 @@ namespace Nz
|
|||
HandledObject(HandledObject&& object) noexcept;
|
||||
~HandledObject();
|
||||
|
||||
ObjectHandle<T> CreateHandle();
|
||||
template<typename U = T>
|
||||
ObjectHandle<U> CreateHandle();
|
||||
|
||||
std::shared_ptr<const Detail::HandleData> GetHandleData();
|
||||
|
||||
HandledObject& operator=(const HandledObject& object);
|
||||
HandledObject& operator=(HandledObject&& object) noexcept;
|
||||
|
|
@ -48,7 +51,6 @@ namespace Nz
|
|||
void UnregisterAllHandles() noexcept;
|
||||
|
||||
private:
|
||||
std::shared_ptr<const Detail::HandleData> GetHandleData();
|
||||
void InitHandleData();
|
||||
|
||||
std::shared_ptr<Detail::HandleData> m_handleData;
|
||||
|
|
|
|||
|
|
@ -58,9 +58,20 @@ namespace Nz
|
|||
* \return ObjectHandle to this
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T> HandledObject<T>::CreateHandle()
|
||||
template<typename U>
|
||||
ObjectHandle<U> HandledObject<T>::CreateHandle()
|
||||
{
|
||||
return ObjectHandle<T>(static_cast<T*>(this));
|
||||
static_assert(std::is_base_of<T, U>::value, "Cannot retrieve a handle for a non-related class");
|
||||
return ObjectHandle<U>(static_cast<U*>(this));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<const Detail::HandleData> HandledObject<T>::GetHandleData()
|
||||
{
|
||||
if (!m_handleData)
|
||||
InitHandleData();
|
||||
|
||||
return std::shared_ptr<const Detail::HandleData>(m_handleData);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -112,15 +123,6 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<const Detail::HandleData> HandledObject<T>::GetHandleData()
|
||||
{
|
||||
if (!m_handleData)
|
||||
InitHandleData();
|
||||
|
||||
return std::shared_ptr<const Detail::HandleData>(m_handleData);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void HandledObject<T>::InitHandleData()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ namespace Nz
|
|||
public:
|
||||
ObjectHandle();
|
||||
explicit ObjectHandle(T* object);
|
||||
template<typename U> ObjectHandle(const ObjectHandle<U>& ref);
|
||||
template<typename U> ObjectHandle(ObjectHandle<U>&& ref);
|
||||
ObjectHandle(const ObjectHandle& handle) = default;
|
||||
ObjectHandle(ObjectHandle&& handle) noexcept;
|
||||
~ObjectHandle();
|
||||
|
|
@ -79,6 +81,11 @@ namespace Nz
|
|||
template<typename T> bool operator>=(const T& lhs, const ObjectHandle<T>& rhs);
|
||||
template<typename T> bool operator>=(const ObjectHandle<T>& lhs, const T& rhs);
|
||||
|
||||
template<typename T, typename U> ObjectHandle<T> ConstRefCast(const ObjectHandle<U>& ref);
|
||||
template<typename T, typename U> ObjectHandle<T> DynamicRefCast(const ObjectHandle<U>& ref);
|
||||
template<typename T, typename U> ObjectHandle<T> ReinterpretRefCast(const ObjectHandle<U>& ref);
|
||||
template<typename T, typename U> ObjectHandle<T> StaticRefCast(const ObjectHandle<U>& ref);
|
||||
|
||||
template<typename T> struct PointedType<ObjectHandle<T>> { using type = T; };
|
||||
template<typename T> struct PointedType<const ObjectHandle<T>> { using type = T; };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,15 +26,34 @@ namespace Nz
|
|||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
ObjectHandle<T>::ObjectHandle(const ObjectHandle<U>& ref) :
|
||||
m_handleData(ref.m_handleData)
|
||||
{
|
||||
static_assert(std::is_base_of<T, U>::value, "Can only implicitly convert from a derived to a base");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
ObjectHandle<T>::ObjectHandle(ObjectHandle<U>&& ref) :
|
||||
m_handleData(std::move(ref.m_handleData))
|
||||
{
|
||||
ref.m_handleData = Detail::HandleData::GetEmptyObject();
|
||||
|
||||
static_assert(std::is_base_of<T, U>::value, "Can only implicitly convert from a derived to a base");
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Constructs a ObjectHandle object by move semantic
|
||||
*
|
||||
* \param handle ObjectHandle to move into this
|
||||
*/
|
||||
template<typename T>
|
||||
ObjectHandle<T>::ObjectHandle(ObjectHandle&& handle) noexcept
|
||||
ObjectHandle<T>::ObjectHandle(ObjectHandle&& handle) noexcept :
|
||||
m_handleData(std::move(handle.m_handleData))
|
||||
{
|
||||
Reset(std::move(handle));
|
||||
handle.m_handleData = Detail::HandleData::GetEmptyObject();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -458,6 +477,60 @@ namespace Nz
|
|||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectHandle from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectHandle<T> ConstRefCast(const ObjectHandle<U>& ref)
|
||||
{
|
||||
return ObjectHandle<T>(const_cast<T*>(ref.GetObject()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectHandle from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectHandle<T> DynamicRefCast(const ObjectHandle<U>& ref)
|
||||
{
|
||||
return ObjectHandle<T>(dynamic_cast<T*>(ref.GetObject()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectHandle from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectHandle<T> ReinterpretRefCast(const ObjectHandle<U>& ref)
|
||||
{
|
||||
return ObjectHandle<T>(static_cast<T*>(ref.GetObject()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Casts an ObjectHandle from one type to another using static_cast
|
||||
* \return Reference to the casted object
|
||||
*
|
||||
* \param ref The reference to convert
|
||||
*
|
||||
* \remark It is an undefined behavior to cast between incompatible types
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ObjectHandle<T> StaticRefCast(const ObjectHandle<U>& ref)
|
||||
{
|
||||
return ObjectHandle<T>(static_cast<T*>(ref.GetObject()));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const ObjectHandle<T> ObjectHandle<T>::InvalidHandle;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace Ndk
|
|||
class NDK_API EntityList
|
||||
{
|
||||
friend Entity;
|
||||
friend World;
|
||||
|
||||
public:
|
||||
class iterator;
|
||||
|
|
@ -23,16 +24,16 @@ namespace Ndk
|
|||
using size_type = std::size_t;
|
||||
|
||||
inline EntityList();
|
||||
inline EntityList(const EntityList& entityList);
|
||||
inline EntityList(EntityList&& entityList) noexcept;
|
||||
inline ~EntityList();
|
||||
EntityList(const EntityList& entityList);
|
||||
EntityList(EntityList&& entityList) noexcept;
|
||||
~EntityList();
|
||||
|
||||
inline void Clear();
|
||||
void Clear();
|
||||
|
||||
inline bool Has(const Entity* entity) const;
|
||||
inline bool Has(EntityId entity) const;
|
||||
|
||||
inline void Insert(Entity* entity);
|
||||
void Insert(Entity* entity);
|
||||
|
||||
inline void Remove(Entity* entity);
|
||||
inline void Reserve(std::size_t entityCount);
|
||||
|
|
@ -50,6 +51,7 @@ namespace Ndk
|
|||
inline std::size_t FindNext(std::size_t currentId) const;
|
||||
inline World* GetWorld() const;
|
||||
inline void NotifyEntityDestruction(const Entity* entity);
|
||||
inline void SetWorld(World* world);
|
||||
|
||||
Nz::Bitset<Nz::UInt64> m_entityBits;
|
||||
World* m_world;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <NDK/EntityList.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
|
|
@ -21,52 +22,6 @@ namespace Ndk
|
|||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new entity list by copying another one
|
||||
*/
|
||||
inline EntityList::EntityList(const EntityList& entityList) :
|
||||
m_entityBits(entityList.m_entityBits),
|
||||
m_world(entityList.m_world)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->RegisterEntityList(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new entity list by moving a list into this one
|
||||
*/
|
||||
inline EntityList::EntityList(EntityList&& entityList) noexcept :
|
||||
m_entityBits(std::move(entityList.m_entityBits)),
|
||||
m_world(entityList.m_world)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
{
|
||||
entity->UnregisterEntityList(&entityList);
|
||||
entity->RegisterEntityList(this);
|
||||
}
|
||||
}
|
||||
|
||||
inline EntityList::~EntityList()
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Clears the set from every entities
|
||||
*
|
||||
* \remark This resets the implicit world member, allowing you to insert entities from a different world than previously
|
||||
*/
|
||||
inline void EntityList::Clear()
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
|
||||
m_entityBits.Clear();
|
||||
m_world = nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not the EntityList contains the entity
|
||||
* \return true If it is the case
|
||||
|
|
@ -93,29 +48,6 @@ namespace Ndk
|
|||
return m_entityBits.UnboundedTest(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Inserts the entity into the set
|
||||
*
|
||||
* Marks an entity as present in this entity list, it must belongs to the same world as others entities contained in this list.
|
||||
*
|
||||
* \param entity Valid pointer to an entity
|
||||
*
|
||||
* \remark If entity is already contained, no action is performed
|
||||
* \remark If any entity has been inserted since construction (or last Clear call), the entity must belong to the same world as the previously inserted entities
|
||||
*/
|
||||
inline void EntityList::Insert(Entity* entity)
|
||||
{
|
||||
NazaraAssert(entity, "Invalid entity");
|
||||
|
||||
if (!Has(entity))
|
||||
{
|
||||
entity->RegisterEntityList(this);
|
||||
|
||||
m_entityBits.UnboundedSet(entity->GetId(), true);
|
||||
m_world = entity->GetWorld();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Removes the entity from the set
|
||||
*
|
||||
|
|
@ -167,40 +99,6 @@ namespace Ndk
|
|||
return m_entityBits.Count();
|
||||
}
|
||||
|
||||
inline EntityList& EntityList::operator=(const EntityList& entityList)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
|
||||
m_entityBits = entityList.m_entityBits;
|
||||
m_world = entityList.m_world;
|
||||
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->RegisterEntityList(this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline EntityList& EntityList::operator=(EntityList&& entityList) noexcept
|
||||
{
|
||||
if (this == &entityList)
|
||||
return *this;
|
||||
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
|
||||
m_entityBits = std::move(entityList.m_entityBits);
|
||||
m_world = entityList.m_world;
|
||||
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
{
|
||||
entity->UnregisterEntityList(&entityList);
|
||||
entity->RegisterEntityList(this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline std::size_t EntityList::FindNext(std::size_t currentId) const
|
||||
{
|
||||
return m_entityBits.FindNext(currentId);
|
||||
|
|
@ -218,6 +116,11 @@ namespace Ndk
|
|||
m_entityBits.Reset(entity->GetId());
|
||||
}
|
||||
|
||||
inline void EntityList::SetWorld(World* world)
|
||||
{
|
||||
m_world = world;
|
||||
}
|
||||
|
||||
|
||||
inline EntityList::iterator::iterator(const EntityList* list, std::size_t nextId) :
|
||||
m_nextEntityId(nextId),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace Ndk
|
|||
{
|
||||
friend BaseSystem;
|
||||
friend Entity;
|
||||
friend EntityList;
|
||||
|
||||
public:
|
||||
using EntityVector = std::vector<EntityHandle>;
|
||||
|
|
@ -97,7 +98,9 @@ namespace Ndk
|
|||
inline void Invalidate();
|
||||
inline void Invalidate(EntityId id);
|
||||
inline void InvalidateSystemOrder();
|
||||
inline void RegisterEntityList(EntityList* list);
|
||||
void ReorderSystems();
|
||||
inline void UnregisterEntityList(EntityList* list);
|
||||
|
||||
struct DoubleBitset
|
||||
{
|
||||
|
|
@ -123,6 +126,7 @@ namespace Ndk
|
|||
std::vector<BaseSystem*> m_orderedSystems;
|
||||
std::vector<EntityBlock> m_entities;
|
||||
std::vector<EntityBlock*> m_entityBlocks;
|
||||
std::vector<EntityList*> m_referencedByLists;
|
||||
std::vector<std::unique_ptr<EntityBlock>> m_waitingEntities;
|
||||
EntityList m_aliveEntities;
|
||||
ProfilerData m_profilerData;
|
||||
|
|
|
|||
|
|
@ -443,24 +443,30 @@ namespace Ndk
|
|||
m_dirtyEntities = std::move(world.m_dirtyEntities);
|
||||
m_entityBlocks = std::move(world.m_entityBlocks);
|
||||
m_freeEntityIds = std::move(world.m_freeEntityIds);
|
||||
m_isProfilerEnabled = world.m_isProfilerEnabled;
|
||||
m_killedEntities = std::move(world.m_killedEntities);
|
||||
m_orderedSystems = std::move(world.m_orderedSystems);
|
||||
m_orderedSystemsUpdated = world.m_orderedSystemsUpdated;
|
||||
m_profilerData = std::move(world.m_profilerData);
|
||||
m_isProfilerEnabled = world.m_isProfilerEnabled;
|
||||
m_referencedByLists = std::move(world.m_referencedByLists);
|
||||
|
||||
m_entities = std::move(world.m_entities);
|
||||
for (EntityBlock& block : m_entities)
|
||||
block.entity.SetWorld(this);
|
||||
|
||||
for (EntityList* list : m_referencedByLists)
|
||||
list->SetWorld(this);
|
||||
|
||||
m_waitingEntities = std::move(world.m_waitingEntities);
|
||||
for (auto& blockPtr : m_waitingEntities)
|
||||
blockPtr->entity.SetWorld(this);
|
||||
|
||||
m_systems = std::move(world.m_systems);
|
||||
for (const auto& systemPtr : m_systems)
|
||||
{
|
||||
if (systemPtr)
|
||||
systemPtr->SetWorld(this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -480,4 +486,19 @@ namespace Ndk
|
|||
{
|
||||
m_orderedSystemsUpdated = false;
|
||||
}
|
||||
|
||||
inline void World::RegisterEntityList(EntityList* list)
|
||||
{
|
||||
m_referencedByLists.push_back(list);
|
||||
}
|
||||
|
||||
inline void World::UnregisterEntityList(EntityList* list)
|
||||
{
|
||||
auto it = std::find(m_referencedByLists.begin(), m_referencedByLists.end(), list);
|
||||
assert(it != m_referencedByLists.end());
|
||||
|
||||
// Swap and pop idiom
|
||||
*it = m_referencedByLists.back();
|
||||
m_referencedByLists.pop_back();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Linux | [
|
||||
{
|
||||
// http://developerweb.net/viewtopic.php?id=3196
|
||||
fd_set localSet;
|
||||
FD_ZERO(&localSet);
|
||||
FD_SET(handle, &localSet);
|
||||
// Wait until socket is available for writing or an error occurs (ie when connection succeeds or fails)
|
||||
pollfd descriptor;
|
||||
descriptor.events = POLLOUT;
|
||||
descriptor.fd = handle;
|
||||
descriptor.revents = 0;
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
||||
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
|
||||
|
||||
int ret = ::select(0, nullptr, &localSet, &localSet, (msTimeout != std::numeric_limits<UInt64>::max()) ? &tv : nullptr);
|
||||
if (ret > 0)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0) //< GetLastErrorCode() failed
|
||||
return SocketState_NotConnected;
|
||||
|
||||
if (code)
|
||||
int ret = ::poll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? int(msTimeout) : -1);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToSocketError(code);
|
||||
*error = TranslateErrnoToSocketError(GetLastErrorCode());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
}
|
||||
else if (ret == 0)
|
||||
else if (ret > 0)
|
||||
{
|
||||
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
if (error)
|
||||
*error = GetLastError(handle);
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (descriptor.revents & POLLOUT)
|
||||
return SocketState_Connected;
|
||||
else
|
||||
{
|
||||
NazaraWarning("Socket " + String::Number(handle) + " was returned by poll without POLLOUT nor error events (events: 0x" + String::Number(descriptor.revents, 16) + ')');
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Still connecting
|
||||
if (error)
|
||||
{
|
||||
if (msTimeout > 0)
|
||||
|
|
@ -456,18 +464,6 @@ namespace Nz
|
|||
|
||||
return SocketState_Connecting;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToSocketError(GetLastErrorCode());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return SocketState_Connected;
|
||||
}
|
||||
|
||||
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
|
||||
|
|
|
|||
|
|
@ -453,32 +453,40 @@ namespace Nz
|
|||
|
||||
SocketState SocketImpl::PollConnection(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error)
|
||||
{
|
||||
// http://developerweb.net/viewtopic.php?id=3196
|
||||
fd_set localSet;
|
||||
FD_ZERO(&localSet);
|
||||
FD_SET(handle, &localSet);
|
||||
// Wait until socket is available for writing or an error occurs (ie when connection succeeds or fails)
|
||||
WSAPOLLFD descriptor;
|
||||
descriptor.events = POLLWRNORM;
|
||||
descriptor.fd = handle;
|
||||
descriptor.revents = 0;
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
||||
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
|
||||
|
||||
int ret = ::select(0, nullptr, &localSet, &localSet, (msTimeout != std::numeric_limits<UInt64>::max()) ? &tv : nullptr);
|
||||
if (ret > 0)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0) //< GetLastErrorCode() failed
|
||||
return SocketState_NotConnected;
|
||||
|
||||
if (code)
|
||||
int ret = WSAPoll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? INT(msTimeout) : INT(-1));
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(code);
|
||||
*error = TranslateWSAErrorToSocketError(WSAGetLastError());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
}
|
||||
else if (ret == 0)
|
||||
else if (ret > 0)
|
||||
{
|
||||
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
if (error)
|
||||
*error = GetLastError(handle);
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (descriptor.revents & POLLWRNORM)
|
||||
return SocketState_Connected;
|
||||
else
|
||||
{
|
||||
NazaraWarning("Socket " + String::Number(handle) + " was returned by poll without POLLOUT nor error events (events: 0x" + String::Number(descriptor.revents, 16) + ')');
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Still connecting
|
||||
if (error)
|
||||
{
|
||||
if (msTimeout > 0)
|
||||
|
|
@ -489,18 +497,6 @@ namespace Nz
|
|||
|
||||
return SocketState_Connecting;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(WSAGetLastError());
|
||||
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = SocketError_NoError;
|
||||
|
||||
return SocketState_Connected;
|
||||
}
|
||||
|
||||
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ namespace Nz
|
|||
m_iconImage.GetWidth(),
|
||||
m_iconImage.GetHeight(),
|
||||
32,
|
||||
32 * m_iconImage.GetWidth(),
|
||||
SDL_PIXELFORMAT_BGRA8888
|
||||
4 * m_iconImage.GetWidth(),
|
||||
SDL_PIXELFORMAT_BGRA32
|
||||
);
|
||||
|
||||
if (!m_icon)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#include <Utfcpp/utf8.h>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -485,23 +488,26 @@ namespace Nz
|
|||
break;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->text.windowID)
|
||||
return 0;
|
||||
|
||||
evt.type = WindowEventType_TextEntered;
|
||||
evt.text.repeated = false;
|
||||
|
||||
for (decltype(evt.text.character) codepoint : ToUtf32String(event->text.text))
|
||||
utf8::unchecked::iterator<const char*> it(event->text.text);
|
||||
do
|
||||
{
|
||||
evt.text.character = codepoint;
|
||||
evt.text.character = *it;
|
||||
|
||||
window->m_parent->PushEvent(evt);
|
||||
}
|
||||
} while (*it++);
|
||||
|
||||
// prevent post switch event
|
||||
evt.type = WindowEventType::WindowEventType_Max;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_TEXTEDITING:
|
||||
if (SDL_GetWindowID(window->m_handle) != event->edit.windowID)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,149 @@
|
|||
|
||||
namespace Ndk
|
||||
{
|
||||
/*!
|
||||
* \brief Construct a new entity list by copying another one
|
||||
*/
|
||||
EntityList::EntityList(const EntityList& entityList) :
|
||||
m_entityBits(entityList.m_entityBits),
|
||||
m_world(entityList.m_world)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->RegisterEntityList(this);
|
||||
|
||||
if (m_world)
|
||||
m_world->RegisterEntityList(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new entity list by moving a list into this one
|
||||
*/
|
||||
EntityList::EntityList(EntityList&& entityList) noexcept :
|
||||
m_entityBits(std::move(entityList.m_entityBits)),
|
||||
m_world(entityList.m_world)
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
{
|
||||
entity->UnregisterEntityList(&entityList);
|
||||
entity->RegisterEntityList(this);
|
||||
}
|
||||
|
||||
if (m_world)
|
||||
{
|
||||
m_world->UnregisterEntityList(&entityList);
|
||||
m_world->RegisterEntityList(this);
|
||||
|
||||
entityList.m_world = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
EntityList::~EntityList()
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
|
||||
if (m_world)
|
||||
m_world->UnregisterEntityList(this);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Clears the set from every entities
|
||||
*
|
||||
* \remark This resets the implicit world member, allowing you to insert entities from a different world than previously
|
||||
*/
|
||||
void EntityList::Clear()
|
||||
{
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
|
||||
m_entityBits.Clear();
|
||||
|
||||
if (m_world)
|
||||
{
|
||||
m_world->UnregisterEntityList(this);
|
||||
m_world = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Inserts the entity into the set
|
||||
*
|
||||
* Marks an entity as present in this entity list, it must belongs to the same world as others entities contained in this list.
|
||||
*
|
||||
* \param entity Valid pointer to an entity
|
||||
*
|
||||
* \remark If entity is already contained, no action is performed
|
||||
* \remark If any entity has been inserted since construction (or last Clear call), the entity must belong to the same world as the previously inserted entities
|
||||
*/
|
||||
void EntityList::Insert(Entity* entity)
|
||||
{
|
||||
NazaraAssert(entity, "Invalid entity");
|
||||
|
||||
if (!Has(entity))
|
||||
{
|
||||
entity->RegisterEntityList(this);
|
||||
|
||||
m_entityBits.UnboundedSet(entity->GetId(), true);
|
||||
if (!m_world)
|
||||
{
|
||||
m_world = entity->GetWorld();
|
||||
m_world->RegisterEntityList(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EntityList& EntityList::operator=(const EntityList& entityList)
|
||||
{
|
||||
if (m_world)
|
||||
m_world->UnregisterEntityList(this);
|
||||
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
|
||||
m_entityBits = entityList.m_entityBits;
|
||||
m_world = entityList.m_world;
|
||||
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->RegisterEntityList(this);
|
||||
|
||||
if (m_world)
|
||||
m_world->RegisterEntityList(this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
EntityList& EntityList::operator=(EntityList&& entityList) noexcept
|
||||
{
|
||||
if (this == &entityList)
|
||||
return *this;
|
||||
|
||||
if (m_world)
|
||||
m_world->UnregisterEntityList(this);
|
||||
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
entity->UnregisterEntityList(this);
|
||||
|
||||
m_entityBits = std::move(entityList.m_entityBits);
|
||||
m_world = entityList.m_world;
|
||||
|
||||
if (m_world)
|
||||
{
|
||||
m_world->UnregisterEntityList(&entityList);
|
||||
m_world->RegisterEntityList(this);
|
||||
|
||||
entityList.m_world = nullptr;
|
||||
}
|
||||
|
||||
for (const Ndk::EntityHandle& entity : *this)
|
||||
{
|
||||
entity->UnregisterEntityList(&entityList);
|
||||
entity->RegisterEntityList(this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const EntityHandle& EntityList::iterator::operator*() const
|
||||
{
|
||||
return m_list->GetWorld()->GetEntity(static_cast<EntityId>(m_nextEntityId));
|
||||
|
|
|
|||
|
|
@ -125,6 +125,11 @@ namespace Ndk
|
|||
}
|
||||
m_entityBlocks.clear();
|
||||
|
||||
// Reset world for entity lists
|
||||
for (EntityList* list : m_referencedByLists)
|
||||
list->SetWorld(nullptr);
|
||||
m_referencedByLists.clear();
|
||||
|
||||
m_entities.clear();
|
||||
m_waitingEntities.clear();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue