Merge branch 'master' into graphics-next
This commit is contained in:
@@ -420,32 +420,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)
|
||||
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 ret = ::poll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? int(msTimeout) : -1);
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0) //< GetLastErrorCode() failed
|
||||
return SocketState_NotConnected;
|
||||
if (error)
|
||||
*error = TranslateErrnoToSocketError(GetLastErrorCode());
|
||||
|
||||
if (code)
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (ret > 0)
|
||||
{
|
||||
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateErrnoToSocketError(code);
|
||||
*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 if (ret == 0)
|
||||
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 ret = WSAPoll(&descriptor, 1, (msTimeout != std::numeric_limits<UInt64>::max()) ? INT(msTimeout) : INT(-1));
|
||||
if (ret == SOCKET_ERROR)
|
||||
{
|
||||
int code = GetLastErrorCode(handle, error);
|
||||
if (code < 0) //< GetLastErrorCode() failed
|
||||
return SocketState_NotConnected;
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(WSAGetLastError());
|
||||
|
||||
if (code)
|
||||
return SocketState_NotConnected;
|
||||
}
|
||||
else if (ret > 0)
|
||||
{
|
||||
if (descriptor.revents & (POLLERR | POLLHUP))
|
||||
{
|
||||
if (error)
|
||||
*error = TranslateWSAErrorToSocketError(code);
|
||||
*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 if (ret == 0)
|
||||
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,9 +24,9 @@ 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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user