Use map to store peer and ticks in network item manager

This commit is contained in:
Benau 2018-06-08 14:24:21 +08:00
parent 8a534bb795
commit b9bf3fa125
4 changed files with 48 additions and 29 deletions

View File

@ -30,10 +30,12 @@
#include <assert.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
class Kart;
class STKPeer;
/**
* \ingroup items
@ -129,7 +131,8 @@ public:
bool randomItemsForArena(const AlignedArray<btTransform>& pos);
// ------------------------------------------------------------------------
/** Only used in the NetworkItemManager. */
virtual void setItemConfirmationTime(int host_id, int ticks)
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
int ticks)
{
assert(false);
}

View File

@ -20,8 +20,11 @@
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp"
#include "network/game_setup.hpp"
#include "network/network_config.hpp"
#include "network/protocols/game_protocol.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
#include "network/rewind_manager.hpp"
#include "network/stk_host.hpp"
@ -42,16 +45,19 @@ NetworkItemManager::NetworkItemManager()
: Rewinder(/*can be deleted*/false),
ItemManager()
{
m_last_confirmed_item_ticks.lock();
m_last_confirmed_item_ticks.getData().clear();
m_last_confirmed_item_ticks.clear();
if (NetworkConfig::get()->isServer())
{
m_last_confirmed_item_ticks.getData()
.resize(STKHost::get()->getPeerCount(), 0);
auto peers = STKHost::get()->getPeers();
for (auto& p : peers)
{
if (!p->isValidated())
continue;
m_last_confirmed_item_ticks[p] = 0;
}
}
m_last_confirmed_item_ticks.unlock();
} // NetworkItemManager
//-----------------------------------------------------------------------------
@ -141,23 +147,32 @@ Item* NetworkItemManager::dropNewItem(ItemState::ItemType type,
/** Called by the GameProtocol when a confirmation for an item event is
* received by a host. Once all hosts have confirmed an event, it can be
* deleted and won't be send to any clients again.
* \param host_id Host identification of the host confirming the latest
* event time received.
* \param peer Peer confirming the latest event time received.
* \param ticks Time at which the last event was received.
*/
void NetworkItemManager::setItemConfirmationTime(int host_id, int ticks)
void NetworkItemManager::setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
int ticks)
{
assert(NetworkConfig::get()->isServer());
m_last_confirmed_item_ticks.lock();
if (ticks > m_last_confirmed_item_ticks.getData()[host_id])
m_last_confirmed_item_ticks.getData()[host_id] = ticks;
if (ticks > m_last_confirmed_item_ticks.at(peer))
m_last_confirmed_item_ticks.at(peer) = ticks;
// Now discard unneeded events, i.e. all events that have
// been confirmed by all clients:
int min_time = 999999;
for (auto i : m_last_confirmed_item_ticks.getData())
if (i < min_time) min_time = i;
m_last_confirmed_item_ticks.unlock();
// Now discard unneeded events and expired (disconnected) peer, i.e. all
// events that have been confirmed by all clients:
int min_time = std::numeric_limits<int32_t>::max();
for (auto it = m_last_confirmed_item_ticks.begin();
it != m_last_confirmed_item_ticks.end();)
{
if (it->first.expired())
{
it = m_last_confirmed_item_ticks.erase(it);
}
else
{
if (it->second < min_time) min_time = it->second;
it++;
}
}
// Find the last entry before the minimal confirmed time.
// Since the event list is sorted, all events up to this
@ -169,7 +184,6 @@ void NetworkItemManager::setItemConfirmationTime(int host_id, int ticks)
m_item_events.getData().erase(m_item_events.getData().begin(), p);
m_item_events.unlock();
// TODO: Get informed when a client drops out!!!
} // setItemConfirmationTime
//-----------------------------------------------------------------------------
@ -290,7 +304,6 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
if(iei.isItemCollection())
{
int index = iei.getIndex();
ItemState *item_state = m_confirmed_state[index];
// An item on the track was collected:
AbstractKart *kart = World::getWorld()->getKart(iei.getKartId());
m_confirmed_state[index]->collected(kart);

View File

@ -25,6 +25,11 @@
#include "utils/cpp2011.hpp"
#include "utils/synchronised.hpp"
#include <map>
#include <memory>
class STKPeer;
/** \ingroup items
* The network item manager is responsible for handling all network related
* item manager tasks - synchronisation between clients and servers. It
@ -47,7 +52,8 @@ private:
int m_confirmed_state_time;
/** Stores on the server the latest confirmed tick from each client. */
Synchronised< std::vector<int> > m_last_confirmed_item_ticks;
std::map<std::weak_ptr<STKPeer>, int32_t,
std::owner_less<std::weak_ptr<STKPeer> > > m_last_confirmed_item_ticks;
/** List of all items events. */
Synchronised< std::vector<ItemEventInfo> > m_item_events;
@ -65,7 +71,8 @@ public:
void saveInitialState();
virtual void reset();
virtual void setItemConfirmationTime(int host_id, int ticks) OVERRIDE;
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
int ticks) OVERRIDE;
virtual void collectedItem(Item *item, AbstractKart *kart) OVERRIDE;
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
const Vec3 *xyz=NULL) OVERRIDE;

View File

@ -101,9 +101,6 @@ bool GameProtocol::notifyEventAsynchronous(Event* event)
NetworkString &data = event->data();
uint8_t message_type = data.getUInt8();
if (message_type != GP_CONTROLLER_ACTION &&
message_type != GP_STATE)
printf("");
switch (message_type)
{
case GP_CONTROLLER_ACTION: handleControllerAction(event); break;
@ -298,10 +295,9 @@ void GameProtocol::sendItemEventConfirmation(int ticks)
void GameProtocol::handleItemEventConfirmation(Event *event)
{
assert(NetworkConfig::get()->isServer());
int host_id = event->getPeer()->getHostId();
int ticks = event->data().getTime();
NetworkItemManager::get()->setItemConfirmationTime(host_id, ticks);
int ticks = event->data().getTime();
NetworkItemManager::get()->setItemConfirmationTime(event->getPeerSP(),
ticks);
} // handleItemEventConfirmation
// ----------------------------------------------------------------------------