Delay EntityChangedWorld players' callback until Entity fully linked to world (#3330)
Otherwise, some API calls just don't seem to happen .gitignore tweak for test executables
This commit is contained in:
parent
07c5f09ecf
commit
e9d1a942d1
1
.gitignore
vendored
1
.gitignore
vendored
@ -68,6 +68,7 @@ Makefile
|
|||||||
*.a
|
*.a
|
||||||
*.d
|
*.d
|
||||||
*.so
|
*.so
|
||||||
|
tests/*/*-exe
|
||||||
BuildInfo.h
|
BuildInfo.h
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
|
@ -1827,8 +1827,7 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
|
|||||||
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
|
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
|
||||||
);
|
);
|
||||||
ParentChunk->RemoveEntity(this);
|
ParentChunk->RemoveEntity(this);
|
||||||
a_World->AddPlayer(this);
|
a_World->AddPlayer(this, &a_OldWorld); // New world will appropriate and announce client at his next tick
|
||||||
cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, a_OldWorld);
|
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2990,10 +2990,10 @@ void cWorld::CollectPickupsByPlayer(cPlayer & a_Player)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::AddPlayer(cPlayer * a_Player)
|
void cWorld::AddPlayer(cPlayer * a_Player, cWorld * a_OldWorld)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayersToAdd);
|
cCSLock Lock(m_CSPlayersToAdd);
|
||||||
m_PlayersToAdd.push_back(a_Player);
|
m_PlayersToAdd.emplace_back(a_Player, a_OldWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3010,7 +3010,10 @@ void cWorld::RemovePlayer(cPlayer * a_Player, bool a_RemoveFromChunk)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayersToAdd);
|
cCSLock Lock(m_CSPlayersToAdd);
|
||||||
m_PlayersToAdd.remove(a_Player);
|
m_PlayersToAdd.remove_if([&](const std::pair< cPlayer *, cWorld * > & value) -> bool
|
||||||
|
{
|
||||||
|
return (value.first == a_Player);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
@ -3895,7 +3898,7 @@ void cWorld::AddQueuedPlayers(void)
|
|||||||
ASSERT(m_TickThread.IsCurrentThread());
|
ASSERT(m_TickThread.IsCurrentThread());
|
||||||
|
|
||||||
// Grab the list of players to add, it has to be locked to access it:
|
// Grab the list of players to add, it has to be locked to access it:
|
||||||
cPlayerList PlayersToAdd;
|
cAwaitingPlayerList PlayersToAdd;
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayersToAdd);
|
cCSLock Lock(m_CSPlayersToAdd);
|
||||||
std::swap(PlayersToAdd, m_PlayersToAdd);
|
std::swap(PlayersToAdd, m_PlayersToAdd);
|
||||||
@ -3904,8 +3907,9 @@ void cWorld::AddQueuedPlayers(void)
|
|||||||
// Add all the players in the grabbed list:
|
// Add all the players in the grabbed list:
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
for (auto Player : PlayersToAdd)
|
for (auto & AwaitingPlayer : PlayersToAdd)
|
||||||
{
|
{
|
||||||
|
auto & Player = AwaitingPlayer.first;
|
||||||
ASSERT(std::find(m_Players.begin(), m_Players.end(), Player) == m_Players.end()); // Is it already in the list? HOW?
|
ASSERT(std::find(m_Players.begin(), m_Players.end(), Player) == m_Players.end()); // Is it already in the list? HOW?
|
||||||
LOGD("Adding player %s to world \"%s\".", Player->GetName().c_str(), m_WorldName.c_str());
|
LOGD("Adding player %s to world \"%s\".", Player->GetName().c_str(), m_WorldName.c_str());
|
||||||
|
|
||||||
@ -3922,9 +3926,10 @@ void cWorld::AddQueuedPlayers(void)
|
|||||||
// Add all the players' clienthandles:
|
// Add all the players' clienthandles:
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSClients);
|
cCSLock Lock(m_CSClients);
|
||||||
for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
|
for (auto & AwaitingPlayer : PlayersToAdd)
|
||||||
{
|
{
|
||||||
cClientHandlePtr Client = (*itr)->GetClientHandlePtr();
|
auto & Player = AwaitingPlayer.first;
|
||||||
|
cClientHandlePtr Client = Player->GetClientHandlePtr();
|
||||||
if (Client != nullptr)
|
if (Client != nullptr)
|
||||||
{
|
{
|
||||||
m_Clients.push_back(Client);
|
m_Clients.push_back(Client);
|
||||||
@ -3933,16 +3938,26 @@ void cWorld::AddQueuedPlayers(void)
|
|||||||
} // Lock(m_CSClients)
|
} // Lock(m_CSClients)
|
||||||
|
|
||||||
// Stream chunks to all eligible clients:
|
// Stream chunks to all eligible clients:
|
||||||
for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
|
for (auto & AwaitingPlayer : PlayersToAdd)
|
||||||
{
|
{
|
||||||
cClientHandle * Client = (*itr)->GetClientHandle();
|
auto & Player = AwaitingPlayer.first;
|
||||||
|
cClientHandle * Client = Player->GetClientHandle();
|
||||||
if (Client != nullptr)
|
if (Client != nullptr)
|
||||||
{
|
{
|
||||||
Client->SendPlayerMoveLook();
|
Client->SendPlayerMoveLook();
|
||||||
Client->SendHealth();
|
Client->SendHealth();
|
||||||
Client->SendWholeInventory(*(*itr)->GetWindow());
|
Client->SendWholeInventory(*Player->GetWindow());
|
||||||
}
|
}
|
||||||
} // for itr - PlayersToAdd[]
|
} // for itr - PlayersToAdd[]
|
||||||
|
|
||||||
|
// Call EntityChangedWorld callback on all eligible clients
|
||||||
|
for (auto & AwaitingPlayer : PlayersToAdd)
|
||||||
|
{
|
||||||
|
if (AwaitingPlayer.second != nullptr)
|
||||||
|
{
|
||||||
|
cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*(static_cast <cEntity *>(AwaitingPlayer.first)), *AwaitingPlayer.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ class cBroadcaster;
|
|||||||
|
|
||||||
|
|
||||||
typedef std::list< cPlayer * > cPlayerList;
|
typedef std::list< cPlayer * > cPlayerList;
|
||||||
|
typedef std::list< std::pair< cPlayer *, cWorld * > > cAwaitingPlayerList;
|
||||||
|
|
||||||
typedef SharedPtr<cSetChunkData> cSetChunkDataPtr; // TODO: Change to unique_ptr once we go C++11
|
typedef SharedPtr<cSetChunkData> cSetChunkDataPtr; // TODO: Change to unique_ptr once we go C++11
|
||||||
typedef std::vector<cSetChunkDataPtr> cSetChunkDataPtrs;
|
typedef std::vector<cSetChunkDataPtr> cSetChunkDataPtrs;
|
||||||
@ -262,8 +263,9 @@ public:
|
|||||||
|
|
||||||
/** Adds the player to the world.
|
/** Adds the player to the world.
|
||||||
Uses a queue to store the player object until the Tick thread processes the addition event.
|
Uses a queue to store the player object until the Tick thread processes the addition event.
|
||||||
Also adds the player as an entity in the chunkmap, and the player's ClientHandle, if any, for ticking. */
|
Also adds the player as an entity in the chunkmap, and the player's ClientHandle, if any, for ticking.
|
||||||
void AddPlayer(cPlayer * a_Player);
|
If a_OldWorld is provided, a corresponding ENTITY_CHANGED_WORLD event is triggerred after the addition. */
|
||||||
|
void AddPlayer(cPlayer * a_Player, cWorld * a_OldWorld = nullptr);
|
||||||
|
|
||||||
/** Removes the player from the world.
|
/** Removes the player from the world.
|
||||||
Removes the player from the addition queue, too, if appropriate.
|
Removes the player from the addition queue, too, if appropriate.
|
||||||
@ -1006,7 +1008,7 @@ private:
|
|||||||
cCriticalSection m_CSPlayersToAdd;
|
cCriticalSection m_CSPlayersToAdd;
|
||||||
|
|
||||||
/** List of players that are scheduled for adding, waiting for the Tick thread to add them. */
|
/** List of players that are scheduled for adding, waiting for the Tick thread to add them. */
|
||||||
cPlayerList m_PlayersToAdd;
|
cAwaitingPlayerList m_PlayersToAdd;
|
||||||
|
|
||||||
/** CS protecting m_SetChunkDataQueue. */
|
/** CS protecting m_SetChunkDataQueue. */
|
||||||
cCriticalSection m_CSSetChunkDataQueue;
|
cCriticalSection m_CSSetChunkDataQueue;
|
||||||
|
Loading…
Reference in New Issue
Block a user