Removes interest stuff from GridMate

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
Esteban Papp
2021-12-13 15:06:20 -08:00
parent 10ecb525fe
commit e28a0eaec7
11 changed files with 1 additions and 645 deletions
@@ -1,132 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef GM_REPLICA_INTERESTDEFS_H
#define GM_REPLICA_INTERESTDEFS_H
#include <AzCore/base.h>
#include <GridMate/Replica/ReplicaCommon.h>
#include <GridMate/Containers/vector.h>
#include <GridMate/Containers/unordered_set.h>
#include <GridMate/Containers/unordered_map.h>
#include <AzCore/std/sort.h>
namespace GridMate
{
/**
* Bitmask used internally in InterestManager to check which handler is responsible for a given interest match
*/
using InterestHandlerSlot = AZ::u32;
/**
* Rule identifier (unique within the session)
*/
using RuleNetworkId = AZ::u64;
///////////////////////////////////////////////////////////////////////////
using InterestPeerSet = unordered_set<PeerId>;
/**
* InterestMatchResult: a structure to gather new matches from handlers.
* Passed to handler within matching context when handler's Match method is invoked.
* User must fill the structure with changes that handler recalculated.
*
* Specifically, the changes should have all the replicas that had their list of associated peers modified.
* Each entry replica - new full list of associated peers.
*/
class InterestMatchResult : public unordered_map<ReplicaId, InterestPeerSet>
{
public:
using unordered_map::unordered_map;
/*
* An expensive debug trace helper, prints sorted mapping between replica id's and associated peers.
*/
void PrintMatchResult(const char* name) const;
};
///////////////////////////////////////////////////////////////////////////
/**
* Base class for interest rules
*/
class InterestRule
{
public:
explicit InterestRule(PeerId peerId, RuleNetworkId netId)
: m_peerId(peerId)
, m_netId(netId)
{}
PeerId GetPeerId() const { return m_peerId; }
RuleNetworkId GetNetworkId() const { return m_netId; }
protected:
PeerId m_peerId; ///< the peer this rule is bound to
RuleNetworkId m_netId; ///< network id
};
///////////////////////////////////////////////////////////////////////////
/**
* Base class for interest attributes
*/
class InterestAttribute
{
public:
explicit InterestAttribute(ReplicaId replicaId)
: m_replicaId(replicaId)
{}
ReplicaId GetReplicaId() const { return m_replicaId; }
protected:
ReplicaId m_replicaId; ///< Replica id this attribute is bound to
};
///////////////////////////////////////////////////////////////////////////
#if !defined(AZ_DEBUG_BUILD)
AZ_INLINE void InterestMatchResult::PrintMatchResult(const char*) const {}
#else
AZ_INLINE void InterestMatchResult::PrintMatchResult(const char* name) const
{
if (size() == 0)
{
AZ_TracePrintf("GridMate", "InterestMatchResult %s empty \n", name);
return;
}
AZStd::vector<value_type> sorted;
for (auto& r : *this)
{
sorted.push_back(r);
}
auto sortByReplicaId = [](const value_type& one, const value_type& another)
{
return one.first < another.first;
};
AZStd::sort(sorted.begin(), sorted.end(), sortByReplicaId);
AZ_TracePrintf("GridMate", "InterestMatchResult %s \n", name);
for (auto& match : sorted)
{
auto repId = match.first;
AZ_TracePrintf("GridMate", "\t\t\t for repId %d ", repId);
// unsorted list of peers
for (auto& peerId : match.second)
{
AZ_TracePrintf("", "peer %d", peerId);
}
AZ_TracePrintf("", "\n");
}
}
#endif
} // GridMate
#endif // GM_REPLICA_INTERESTDEFS_H
@@ -1,53 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef GM_REPLICA_INTERESTEVENTS_H
#define GM_REPLICA_INTERESTEVENTS_H
#if defined(GM_INTEREST_MANAGER)
#include <AzCore/base.h>
#include <GridMate/Replica/ReplicaCommon.h>
#include <GridMate/containers/unordered_set.h>
#include <GridMate/containers/unordered_map.h>
#include <GridMate/EBus.h>
namespace GridMate
{
/**
* EBus for interest manager's events.
* Notifies subscribers about new interest matches and new mismatches happened.
*/
class InterestManagerEvents
: public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
typedef AZStd::recursive_mutex MutexType;
typedef void* BusIdType;
typedef SysContAlloc AllocatorType;
virtual ~InterestManagerEvents() {}
/**
* Called when new pair of replica and peer matched their interest
*/
virtual void OnInterestMatched(ReplicaId replicaId, PeerId peerId) { (void) replicaId; (void) peerId; }
/**
* Called when pair of replica and peer mismatched interest (only called if the pair was previously matching)
*/
virtual void OnInterestUnmatched(ReplicaId replicaId, PeerId peerId) { (void) replicaId; (void) peerId; }
};
typedef AZ::EBus<InterestManagerEvents> InterestManagerEventsBus;
}
#endif // GM_INTEREST_MANAGER
#endif
@@ -1,243 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <GridMate/Replica/Interest/InterestManager.h>
#include <GridMate/Replica/Interest/RulesHandler.h>
#include <GridMate/Replica/Interest/InterestQueryResult.h>
#include <GridMate/Replica/ReplicaMgr.h>
#include <AzCore/std/containers/array.h>
namespace GridMate
{
static const unsigned k_maxHandlers = sizeof(GridMate::InterestHandlerSlot) * CHAR_BIT;
/**
* Hashing utils
*/
struct ReplicaHashByPeer
{
AZ_FORCE_INLINE AZStd::size_t operator()(const ReplicaTarget* t) const
{
static_assert(sizeof(AZStd::size_t) >= sizeof(ReplicaPeer*), "Types sizes mismatch");
return reinterpret_cast<AZStd::size_t>(t->GetPeer());
}
};
struct ReplicaEqualToByPeer
{
AZ_FORCE_INLINE bool operator()(const ReplicaTarget* left, const ReplicaTarget* right) const
{
return left->GetPeer() == right->GetPeer();
}
};
struct ReplicaHashByPeerId
{
AZ_FORCE_INLINE AZStd::size_t operator()(PeerId peerId) const
{
static_assert(sizeof(AZStd::size_t) >= sizeof(PeerId), "Types sizes mismatch");
return static_cast<AZStd::size_t>(peerId);
}
};
struct ReplicaEqualToByPeerId
{
AZ_FORCE_INLINE bool operator()(PeerId peerId, const ReplicaTarget* right) const
{
return peerId == right->GetPeer()->GetId();
}
};
///////////////////////////////////////////////////////////////////////////
/**
* InterestManager
*/
InterestManager::InterestManager()
: m_rm(nullptr)
, m_freeSlots(~0u)
{
}
void InterestManager::Init(const InterestManagerDesc& desc)
{
m_rm = desc.m_rm;
AZ_Assert(m_rm, "Invalid replica manager");
}
bool InterestManager::IsReady() const
{
return m_rm != nullptr;
}
InterestManager::~InterestManager()
{
while (!m_handlers.empty())
{
m_handlers.back()->OnRulesHandlerUnregistered(this);
m_handlers.pop_back();
}
}
void InterestManager::RegisterHandler(BaseRulesHandler* handler)
{
AZ_Assert(handler, "Invalid rules handler");
for (BaseRulesHandler* h : m_handlers)
{
if (h == handler)
{
AZ_TracePrintf("GridMate", "Rules handler %p is already registered", handler);
return;
}
}
InterestHandlerSlot slot = GetNewSlot();
if (!slot)
{
AZ_TracePrintf("GridMate", "Too many rules handlers, max=%u\n", k_maxHandlers);
return;
}
handler->m_slot = slot;
m_handlers.push_back(handler);
handler->OnRulesHandlerRegistered(this);
}
void InterestManager::UnregisterHandler(BaseRulesHandler* handler)
{
AZ_Assert(handler, "Invalid rules handler");
for (auto it = m_handlers.begin(); it != m_handlers.end(); ++it)
{
if (*it == handler)
{
handler->OnRulesHandlerUnregistered(this);
m_handlers.erase(it);
return;
}
}
AZ_Assert(false, "Handler was not registered");
}
void InterestManager::Update()
{
// Updating all handlers
for (BaseRulesHandler* handler : m_handlers)
{
handler->Update();
}
// merging results from every handler
for (BaseRulesHandler* handler : m_handlers)
{
const InterestMatchResult& result = handler->GetLastResult();
for (auto& match : result)
{
ReplicaPtr replica = m_rm->FindReplica(match.first);
if (!replica) // replica was destroyed: ignoring this match
{
continue;
}
unordered_set<ReplicaTarget*, ReplicaHashByPeer, ReplicaEqualToByPeer> targets;
for (ReplicaTarget& targetObj : replica->m_targets)
{
targets.insert(&targetObj);
if (!match.second.count(targetObj.GetPeer()->GetId()))
{
targetObj.m_slotMask &= ~handler->m_slot;
if (!targetObj.m_slotMask)
{
targetObj.m_flags |= ReplicaTarget::TargetRemoved;
m_rm->OnReplicaChanged(replica);
}
}
}
for (const PeerId& peerId : match.second)
{
ReplicaTarget* rt = nullptr;
auto it = targets.find_as(peerId, ReplicaHashByPeerId(), ReplicaEqualToByPeerId());
if (it == targets.end())
{
ReplicaPeer* peer = m_rm->FindPeer(peerId);
if (!ShouldForward(replica.get(), peer))
{
continue;
}
rt = ReplicaTarget::AddReplicaTarget(peer, replica.get());
rt->SetNew(true);
m_rm->OnReplicaChanged(replica);
}
else
{
rt = *it;
}
rt->m_slotMask |= handler->m_slot;
rt->m_flags &= ~ReplicaTarget::TargetRemoved;
}
}
}
}
bool InterestManager::ShouldForward(Replica* replica, ReplicaPeer* peer) const
{
if (!peer) // invalid peer
{
return false;
}
if (replica->IsPrimary()) // own the replica?
{
return true;
}
if (m_rm->GetLocalPeerId() == peer->GetId() || peer->GetId() == replica->m_upstreamHop->GetId()) // forwarding to local peer or to owner?
{
return false;
}
if (m_rm->IsSyncHost() && !(replica->m_upstreamHop->GetMode() == Mode_Peer && peer->GetMode() == Mode_Peer)) // we are host and replica' owner and target are not connected
{
return true;
}
return false;
}
InterestHandlerSlot InterestManager::GetNewSlot()
{
InterestHandlerSlot s = m_freeSlots;
for (unsigned i = 0; s && i < k_maxHandlers; ++i, s >>= 1)
{
if (s & 1)
{
InterestHandlerSlot slot = (1 << i);
m_freeSlots &= ~slot;
return slot;
}
}
return 0;
}
void InterestManager::FreeSlot(InterestHandlerSlot slot)
{
m_freeSlots |= slot;
}
///////////////////////////////////////////////////////////////////////////
}
@@ -1,91 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef GM_REPLICA_INTERESTMANAGER_H
#define GM_REPLICA_INTERESTMANAGER_H
#include <GridMate/Containers/list.h>
#include <GridMate/Replica/Interest/InterestDefs.h>
namespace GridMate
{
class BaseRulesHandler;
/**
* Interest manager initialization parameters
*/
struct InterestManagerDesc
{
ReplicaManager* m_rm; ///< Replica manager instance
InterestManagerDesc()
: m_rm(nullptr)
{
}
};
/**
* InterestManager: responsible for matching of replicas and peers pairs based on rules and attribute provided.
* InterestManager allows registration of up to 32 custom rules handler. Each rules handler is responsible of matching attributes
* and rules that user provides. InterestManager is responsible for merging results of matching from every registered handler and
* maintaining valid forwarding targets cache on every Replica.
*/
class InterestManager
{
public:
GM_CLASS_ALLOCATOR(InterestManager);
InterestManager();
~InterestManager();
/**
* Initialize manager with a descriptor
*/
void Init(const InterestManagerDesc& desc);
/**
* Returns true if InterestManager is initialized and is ready to use
*/
bool IsReady() const;
/**
* Register new handler with a given type and instance
*/
void RegisterHandler(BaseRulesHandler* handler);
/**
* Unregister handler
*/
void UnregisterHandler(BaseRulesHandler* handler);
/**
* Call to update current replica->peers cache
*/
void Update();
/**
* Returns replica manager IM is bount to
*/
ReplicaManager* GetReplicaManager() { return m_rm; }
private:
InterestManager(const InterestManager&) = delete;
InterestManager& operator=(const InterestManager&) = delete;
InterestHandlerSlot GetNewSlot();
void FreeSlot(InterestHandlerSlot slot);
bool ShouldForward(Replica* replica, ReplicaPeer* peer) const;
ReplicaManager* m_rm;
vector<BaseRulesHandler*> m_handlers;
InterestHandlerSlot m_freeSlots;
};
} // namespace GridMate
#endif // GM_REPLICA_INTERESTMANAGER_H
@@ -1,25 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
/*
#include <GridMate/Replica/Interest/InterestQueryResult.h>
namespace GridMate
{
InterestQueryResult::InterestQueryResult()
{
}
InterestQueryResult::PeerList& InterestQueryResult::Insert(ReplicaId repId)
{
auto it = m_matches.insert_key(repId);
return it.first->second;
}
} // namespace GridMate
*/
@@ -1,25 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef GM_REPLICA_INTERESTQUERYRESULT_H
#define GM_REPLICA_INTERESTQUERYRESULT_H
/*
#include <AzCore/base.h>
#include <GridMate/containers/vector.h>
#include <GridMate/containers/unordered_map.h>
#include <GridMate/Replica/Interest/InterestDefs.h>
#include <GridMate/Replica/ReplicaCommon.h>
namespace GridMate
{
using InterestPeerList = vector<PeerId>;
using InterestQueryResult = unordered_map<ReplicaId, InterestPeerList>;
} // GridMate
*/
#endif // GM_REPLICA_INTERESTQUERYRESULT_H
@@ -1,65 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef GM_REPLICA_RULES_HANDLER_H
#define GM_REPLICA_RULES_HANDLER_H
#include <GridMate/Replica/ReplicaCommon.h>
#include <GridMate/Replica/Interest/InterestDefs.h>
namespace GridMate
{
class InterestManager;
/**
* BaseRulesHandler: base handler class
* RulesHandler's job is to provide InterestManager with matching pairs of attributes and rules.
*/
class BaseRulesHandler
{
public:
BaseRulesHandler()
: m_slot(0)
{}
virtual ~BaseRulesHandler() { };
/**
* Ticked by interest manager to retrieve new matches or mismatches of interests
*/
virtual void Update() = 0;
/**
* Returns result of a previous update
* This only returns changes that happened on the previous tick not the whole world state
*/
virtual const InterestMatchResult& GetLastResult() = 0;
/**
* Called by InterestManager when the given handler instance is registered
*/
virtual void OnRulesHandlerRegistered(InterestManager* manager) = 0;
/**
* Called by InterestManager when the given handler is unregistered
*/
virtual void OnRulesHandlerUnregistered(InterestManager* manager) = 0;
/**
* Returns interest mananger this handler is bound to, or nullptr if it's unbound
*/
virtual InterestManager* GetManager() = 0;
private:
friend class InterestManager;
InterestHandlerSlot m_slot;
};
} // namespace GridMate
#endif // GM_REPLICA_RULES_HANDLER_H
@@ -29,8 +29,7 @@ namespace GridMate
class ReplicaStatus;
class ReplicaTask;
class InterestManager;
//-------------------------------------------------------------------------
// Replica
//-------------------------------------------------------------------------
@@ -55,7 +54,6 @@ namespace GridMate
friend class ReplicaMarshalNewTask;
friend class InterestManager;
friend class ReplicaTarget;
enum Flags
@@ -329,7 +329,6 @@ namespace GridMate
friend class ReplicaUpdateTaskBase;
friend class ReplicaDestroyPeerTask;
friend class SendLimitProcessPolicy;
friend class InterestManager;
typedef unordered_map<int, void*> UserContextMapType;
typedef unordered_map<ReplicaId, ReplicaPtr> ReplicaMap;
@@ -46,8 +46,6 @@ namespace GridMate
*/
class ReplicaTarget
{
friend class InterestManager;
public:
static ReplicaTarget* AddReplicaTarget(ReplicaPeer* peer, Replica* replica);
@@ -78,11 +78,6 @@ set(FILES
Replica/Tasks/ReplicaProcessPolicy.cpp
Replica/Tasks/ReplicaProcessPolicy.h
Replica/Tasks/ReplicaPriorityPolicy.h
Replica/Interest/InterestDefs.h
Replica/Interest/InterestManager.cpp
Replica/Interest/InterestManager.h
Replica/Interest/InterestQueryResult.h
Replica/Interest/RulesHandler.h
Serialize/Buffer.cpp
Serialize/Buffer.h
Serialize/PackedSize.h