mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/AI: Factory functions cleanup
- Get rid of fugly void pointers
- Streamlined AI selection code, using Permissible as it should've been instead of harcoded checks on the selector code
- Moved IdleMovementGenerator singleton to factory code
(cherry picked from commit ce3787f190)
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
// AggressorAI
|
||||
/////////////////
|
||||
|
||||
int AggressorAI::Permissible(const Creature* creature)
|
||||
int32 AggressorAI::Permissible(Creature const* creature)
|
||||
{
|
||||
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
|
||||
if (!creature->IsCivilian() && !creature->IsNeutralToAll())
|
||||
@@ -344,3 +344,11 @@ void VehicleAI::CheckConditions(uint32 diff)
|
||||
else
|
||||
m_ConditionsTimer -= diff;
|
||||
}
|
||||
|
||||
int32 VehicleAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->IsVehicle())
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class TC_GAME_API AggressorAI : public CreatureAI
|
||||
explicit AggressorAI(Creature* c) : CreatureAI(c) { }
|
||||
|
||||
void UpdateAI(uint32) override;
|
||||
static int Permissible(const Creature*);
|
||||
static int32 Permissible(Creature const* creature);
|
||||
};
|
||||
|
||||
typedef std::vector<uint32> SpellVct;
|
||||
@@ -45,7 +45,7 @@ class TC_GAME_API CombatAI : public CreatureAI
|
||||
void UpdateAI(uint32 diff) override;
|
||||
void SpellInterrupted(uint32 spellId, uint32 unTimeMs) override;
|
||||
|
||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
|
||||
protected:
|
||||
EventMap events;
|
||||
@@ -71,7 +71,7 @@ struct TC_GAME_API ArcherAI : public CreatureAI
|
||||
void AttackStart(Unit* who) override;
|
||||
void UpdateAI(uint32 diff) override;
|
||||
|
||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
|
||||
protected:
|
||||
float m_minRange;
|
||||
@@ -85,7 +85,7 @@ struct TC_GAME_API TurretAI : public CreatureAI
|
||||
void AttackStart(Unit* who) override;
|
||||
void UpdateAI(uint32 diff) override;
|
||||
|
||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
|
||||
protected:
|
||||
float m_minRange;
|
||||
@@ -104,7 +104,7 @@ struct TC_GAME_API VehicleAI : public CreatureAI
|
||||
void AttackStart(Unit*) override { }
|
||||
void OnCharmed(bool apply) override;
|
||||
|
||||
static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
static int32 Permissible(Creature const* creature);
|
||||
|
||||
private:
|
||||
void LoadConditions();
|
||||
|
||||
@@ -20,11 +20,8 @@
|
||||
#include "GameObject.h"
|
||||
#include "QuestDef.h"
|
||||
|
||||
//GameObjectAI::GameObjectAI(GameObject* g) : go(g) { }
|
||||
int GameObjectAI::Permissible(const GameObject* go)
|
||||
int32 GameObjectAI::Permissible(GameObject const* /*go*/)
|
||||
{
|
||||
if (go->GetAIName() == "GameObjectAI")
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
@@ -35,7 +32,7 @@ uint32 GameObjectAI::GetDialogStatus(Player* /*player*/)
|
||||
|
||||
NullGameObjectAI::NullGameObjectAI(GameObject* g) : GameObjectAI(g) { }
|
||||
|
||||
int NullGameObjectAI::Permissible(GameObject const* /*go*/)
|
||||
int32 NullGameObjectAI::Permissible(GameObject const* /*go*/)
|
||||
{
|
||||
return PERMIT_BASE_IDLE;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class TC_GAME_API GameObjectAI
|
||||
virtual void SetGUID(uint64 /*guid*/, int32 /*id = 0 */) { }
|
||||
virtual uint64 GetGUID(int32 /*id = 0 */) const { return 0; }
|
||||
|
||||
static int Permissible(GameObject const* go);
|
||||
static int32 Permissible(GameObject const* /*go*/);
|
||||
|
||||
// Called when a player opens a gossip dialog with the gameobject.
|
||||
virtual bool GossipHello(Player* /*player*/, bool /*reportUse*/) { return false; }
|
||||
@@ -88,6 +88,6 @@ class TC_GAME_API NullGameObjectAI : public GameObjectAI
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override { }
|
||||
|
||||
static int Permissible(GameObject const* /*go*/);
|
||||
static int32 Permissible(GameObject const* /*go*/);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -26,10 +26,10 @@ GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
}
|
||||
|
||||
int GuardAI::Permissible(Creature const* creature)
|
||||
int32 GuardAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->IsGuard())
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class TC_GAME_API GuardAI : public ScriptedAI
|
||||
public:
|
||||
explicit GuardAI(Creature* creature);
|
||||
|
||||
static int Permissible(Creature const* creature);
|
||||
static int32 Permissible(Creature const* creature);
|
||||
void UpdateAI(uint32 diff) override;
|
||||
bool CanSeeAlways(WorldObject const* obj) override;
|
||||
|
||||
|
||||
@@ -22,6 +22,17 @@ PassiveAI::PassiveAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASS
|
||||
PossessedAI::PossessedAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
|
||||
NullCreatureAI::NullCreatureAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
|
||||
|
||||
int32 NullCreatureAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK))
|
||||
return PERMIT_BASE_PROACTIVE + 50;
|
||||
|
||||
if (creature->IsTrigger())
|
||||
return PERMIT_BASE_REACTIVE;
|
||||
|
||||
return PERMIT_BASE_IDLE;
|
||||
}
|
||||
|
||||
void PassiveAI::UpdateAI(uint32)
|
||||
{
|
||||
if (me->IsInCombat() && me->getAttackers().empty())
|
||||
@@ -76,8 +87,24 @@ void CritterAI::EnterEvadeMode(EvadeReason why)
|
||||
CreatureAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
int32 CritterAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
void TriggerAI::IsSummonedBy(Unit* summoner)
|
||||
{
|
||||
if (me->m_spells[0])
|
||||
me->CastSpell(me, me->m_spells[0], false, nullptr, nullptr, summoner->GetGUID());
|
||||
}
|
||||
|
||||
int32 TriggerAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->IsTrigger() && creature->m_spells[0])
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class TC_GAME_API PassiveAI : public CreatureAI
|
||||
void AttackStart(Unit*) override { }
|
||||
void UpdateAI(uint32) override;
|
||||
|
||||
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
|
||||
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
};
|
||||
|
||||
class TC_GAME_API PossessedAI : public CreatureAI
|
||||
@@ -47,7 +47,7 @@ class TC_GAME_API PossessedAI : public CreatureAI
|
||||
|
||||
void OnCharmed(bool /*apply*/) override;
|
||||
|
||||
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
|
||||
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
};
|
||||
|
||||
class TC_GAME_API NullCreatureAI : public CreatureAI
|
||||
@@ -61,7 +61,7 @@ class TC_GAME_API NullCreatureAI : public CreatureAI
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override { }
|
||||
void OnCharmed(bool /*apply*/) override { }
|
||||
|
||||
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
|
||||
static int32 Permissible(Creature const* creature);
|
||||
};
|
||||
|
||||
class TC_GAME_API CritterAI : public PassiveAI
|
||||
@@ -71,6 +71,8 @@ class TC_GAME_API CritterAI : public PassiveAI
|
||||
|
||||
void DamageTaken(Unit* done_by, uint32& /*damage*/) override;
|
||||
void EnterEvadeMode(EvadeReason why) override;
|
||||
|
||||
static int32 Permissible(Creature const* creature);
|
||||
};
|
||||
|
||||
class TC_GAME_API TriggerAI : public NullCreatureAI
|
||||
@@ -78,6 +80,8 @@ class TC_GAME_API TriggerAI : public NullCreatureAI
|
||||
public:
|
||||
explicit TriggerAI(Creature* c) : NullCreatureAI(c) { }
|
||||
void IsSummonedBy(Unit* summoner) override;
|
||||
|
||||
static int32 Permissible(Creature const* creature);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,11 +31,18 @@
|
||||
#include "SpellMgr.h"
|
||||
#include "Util.h"
|
||||
|
||||
int PetAI::Permissible(const Creature* creature)
|
||||
int32 PetAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->IsPet())
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
|
||||
if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
{
|
||||
if (reinterpret_cast<Guardian const*>(creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
return PERMIT_BASE_REACTIVE;
|
||||
}
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class TC_GAME_API PetAI : public CreatureAI
|
||||
explicit PetAI(Creature* c);
|
||||
|
||||
void UpdateAI(uint32) override;
|
||||
static int Permissible(const Creature*);
|
||||
static int32 Permissible(Creature const* creature);
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override;
|
||||
void AttackStart(Unit* target) override;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "ReactorAI.h"
|
||||
#include "Creature.h"
|
||||
|
||||
int ReactorAI::Permissible(const Creature* creature)
|
||||
int32 ReactorAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->IsCivilian() || creature->IsNeutralToAll())
|
||||
return PERMIT_BASE_REACTIVE;
|
||||
|
||||
@@ -29,6 +29,6 @@ class TC_GAME_API ReactorAI : public CreatureAI
|
||||
void MoveInLineOfSight(Unit*) override { }
|
||||
void UpdateAI(uint32 diff) override;
|
||||
|
||||
static int Permissible(const Creature*);
|
||||
static int32 Permissible(Creature const* creature);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "CellImpl.h"
|
||||
|
||||
int TotemAI::Permissible(Creature const* creature)
|
||||
int32 TotemAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->IsTotem())
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
@@ -35,7 +35,7 @@ class TC_GAME_API TotemAI : public CreatureAI
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override;
|
||||
|
||||
void UpdateAI(uint32 diff) override;
|
||||
static int Permissible(Creature const* creature);
|
||||
static int32 Permissible(Creature const* creature);
|
||||
|
||||
private:
|
||||
ObjectGuid i_victimGuid;
|
||||
|
||||
@@ -204,7 +204,7 @@ class TC_GAME_API CreatureAI : public UnitAI
|
||||
bool m_MoveInLineOfSight_locked;
|
||||
};
|
||||
|
||||
enum Permitions
|
||||
enum Permitions : int32
|
||||
{
|
||||
PERMIT_BASE_NO = -1,
|
||||
PERMIT_BASE_IDLE = 1,
|
||||
|
||||
@@ -18,66 +18,34 @@
|
||||
#ifndef TRINITY_CREATUREAIFACTORY_H
|
||||
#define TRINITY_CREATUREAIFACTORY_H
|
||||
|
||||
//#include "Policies/Singleton.h"
|
||||
#include "ObjectRegistry.h"
|
||||
#include "FactoryHolder.h"
|
||||
#include "GameObjectAI.h"
|
||||
|
||||
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
||||
typedef FactoryHolder<CreatureAI, Creature> CreatureAICreator;
|
||||
|
||||
struct SelectableAI : public CreatureAICreator, public Permissible<Creature>
|
||||
{
|
||||
SelectableAI(const char* id) : FactoryHolder<CreatureAI>(id) { }
|
||||
SelectableAI(std::string const& name) : CreatureAICreator(name), Permissible<Creature>() { }
|
||||
};
|
||||
|
||||
template<class REAL_AI>
|
||||
struct CreatureAIFactory : public SelectableAI
|
||||
{
|
||||
CreatureAIFactory(const char* name) : SelectableAI(name) { }
|
||||
CreatureAIFactory(std::string const& name) : SelectableAI(name) { }
|
||||
|
||||
CreatureAI* Create(void*) const override;
|
||||
inline CreatureAI* Create(Creature* c) const override
|
||||
{
|
||||
return new REAL_AI(c);
|
||||
}
|
||||
|
||||
int Permit(const Creature* c) const override { return REAL_AI::Permissible(c); }
|
||||
int32 Permit(Creature const* c) const override
|
||||
{
|
||||
return REAL_AI::Permissible(c);
|
||||
}
|
||||
};
|
||||
|
||||
template<class REAL_AI>
|
||||
inline CreatureAI*
|
||||
CreatureAIFactory<REAL_AI>::Create(void* data) const
|
||||
{
|
||||
Creature* creature = reinterpret_cast<Creature*>(data);
|
||||
return (new REAL_AI(creature));
|
||||
}
|
||||
|
||||
typedef FactoryHolder<CreatureAI> CreatureAICreator;
|
||||
typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry;
|
||||
typedef CreatureAICreator::FactoryHolderRegistry CreatureAIRegistry;
|
||||
|
||||
#define sCreatureAIRegistry CreatureAIRegistry::instance()
|
||||
|
||||
//GO
|
||||
struct SelectableGameObjectAI : public FactoryHolder<GameObjectAI>, public Permissible<GameObject>
|
||||
{
|
||||
SelectableGameObjectAI(const char* id) : FactoryHolder<GameObjectAI>(id) { }
|
||||
};
|
||||
|
||||
template<class REAL_GO_AI>
|
||||
struct GameObjectAIFactory : public SelectableGameObjectAI
|
||||
{
|
||||
GameObjectAIFactory(const char* name) : SelectableGameObjectAI(name) { }
|
||||
|
||||
GameObjectAI* Create(void*) const override;
|
||||
|
||||
int Permit(const GameObject* g) const override { return REAL_GO_AI::Permissible(g); }
|
||||
};
|
||||
|
||||
template<class REAL_GO_AI>
|
||||
inline GameObjectAI*
|
||||
GameObjectAIFactory<REAL_GO_AI>::Create(void* data) const
|
||||
{
|
||||
GameObject* go = reinterpret_cast<GameObject*>(data);
|
||||
return (new REAL_GO_AI(go));
|
||||
}
|
||||
|
||||
typedef FactoryHolder<GameObjectAI> GameObjectAICreator;
|
||||
typedef FactoryHolder<GameObjectAI>::FactoryHolderRegistry GameObjectAIRegistry;
|
||||
|
||||
#define sGameObjectAIRegistry GameObjectAIRegistry::instance()
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
#include "PetAI.h"
|
||||
#include "TotemAI.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "MovementGeneratorImpl.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "CreatureAIRegistry.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
#include "GameObjectAIFactory.h"
|
||||
#include "SmartAI.h"
|
||||
|
||||
namespace AIRegistry
|
||||
@@ -47,10 +48,12 @@ namespace AIRegistry
|
||||
(new CreatureAIFactory<VehicleAI>("VehicleAI"))->RegisterSelf();
|
||||
(new CreatureAIFactory<SmartAI>("SmartAI"))->RegisterSelf();
|
||||
|
||||
(new GameObjectAIFactory<NullGameObjectAI>("NullGameObjectAI"))->RegisterSelf();
|
||||
(new GameObjectAIFactory<GameObjectAI>("GameObjectAI"))->RegisterSelf();
|
||||
(new GameObjectAIFactory<SmartGameObjectAI>("SmartGameObjectAI"))->RegisterSelf();
|
||||
|
||||
(new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
|
||||
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
||||
(new IdleMovementFactory())->RegisterSelf();
|
||||
(new MovementGeneratorFactory<RandomMovementGenerator<Creature>>(RANDOM_MOTION_TYPE))->RegisterSelf();
|
||||
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature>>(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,130 +17,100 @@
|
||||
|
||||
#include "Creature.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "GameObject.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
#include "Log.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
|
||||
#include "GameObject.h"
|
||||
#include "GameObjectAIFactory.h"
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
namespace FactorySelector
|
||||
{
|
||||
CreatureAI* selectAI(Creature* creature)
|
||||
template <class T>
|
||||
struct PermissibleOrderPred
|
||||
{
|
||||
const CreatureAICreator* ai_factory = NULL;
|
||||
public:
|
||||
PermissibleOrderPred(T const* obj) : _obj(obj) { }
|
||||
|
||||
if (creature->IsPet())
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
|
||||
template <class Value>
|
||||
bool operator()(Value const& left, Value const& right) const
|
||||
{
|
||||
Permissible<T> const* leftPermit = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(left.second.get()));
|
||||
Permissible<T> const* rightPermit = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(right.second.get()));
|
||||
|
||||
//scriptname in db
|
||||
return leftPermit->Permit(_obj) < rightPermit->Permit(_obj);
|
||||
}
|
||||
|
||||
private:
|
||||
T const* const _obj;
|
||||
};
|
||||
|
||||
CreatureAI* SelectAI(Creature* creature)
|
||||
{
|
||||
CreatureAICreator const* ai_factory = nullptr;
|
||||
|
||||
// scriptname in db
|
||||
if (!ai_factory)
|
||||
if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
|
||||
return scriptedAI;
|
||||
|
||||
// AIname in db
|
||||
std::string ainame=creature->GetAIName();
|
||||
if (!ai_factory && !ainame.empty())
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem(ainame);
|
||||
|
||||
// select by NPC flags
|
||||
if (!ai_factory)
|
||||
{
|
||||
if (creature->IsVehicle())
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("VehicleAI");
|
||||
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
|
||||
else if (creature->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK))
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
|
||||
else if (creature->IsGuard())
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("GuardAI");
|
||||
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
|
||||
else if (creature->IsTotem())
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("TotemAI");
|
||||
else if (creature->IsTrigger())
|
||||
{
|
||||
if (creature->m_spells[0])
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("TriggerAI");
|
||||
else
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
|
||||
}
|
||||
else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("CritterAI");
|
||||
}
|
||||
std::string const& aiName = creature->GetAIName();
|
||||
if (!ai_factory && !aiName.empty())
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem(aiName);
|
||||
|
||||
// select by permit check
|
||||
if (!ai_factory)
|
||||
{
|
||||
int best_val = -1;
|
||||
typedef CreatureAIRegistry::RegistryMapType RMT;
|
||||
RMT const& l = sCreatureAIRegistry->GetRegisteredItems();
|
||||
for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const CreatureAICreator* factory = iter->second;
|
||||
const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory);
|
||||
ASSERT(p);
|
||||
int val = p->Permit(creature);
|
||||
if (val > best_val)
|
||||
{
|
||||
best_val = val;
|
||||
ai_factory = p;
|
||||
}
|
||||
}
|
||||
CreatureAIRegistry::RegistryMapType const& items = sCreatureAIRegistry->GetRegisteredItems();
|
||||
auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<Creature>(creature));
|
||||
if (itr != items.end())
|
||||
ai_factory = itr->second.get();
|
||||
}
|
||||
|
||||
// select NullCreatureAI if not another cases
|
||||
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
|
||||
if (!ai_factory)
|
||||
ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
|
||||
|
||||
TC_LOG_DEBUG("scripts", "Creature %s (%s DB GUID: " UI64FMTD ") is using AI type: %s.", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetSpawnId(), ainame.c_str());
|
||||
return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature));
|
||||
return ASSERT_NOTNULL(ai_factory)->Create(creature);
|
||||
}
|
||||
|
||||
MovementGenerator* selectMovementGenerator(Creature* creature)
|
||||
MovementGenerator* SelectMovementGenerator(Unit* unit)
|
||||
{
|
||||
MovementGeneratorRegistry& mv_registry(*MovementGeneratorRegistry::instance());
|
||||
ASSERT(creature->GetCreatureTemplate());
|
||||
const MovementGeneratorCreator* mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType());
|
||||
MovementGeneratorType type = IDLE_MOTION_TYPE;
|
||||
if (unit->GetTypeId() == TYPEID_UNIT)
|
||||
type = unit->ToCreature()->GetDefaultMovementType();
|
||||
|
||||
/* if (mv_factory == NULL)
|
||||
{
|
||||
int best_val = -1;
|
||||
StringVector l;
|
||||
mv_registry.GetRegisteredItems(l);
|
||||
for (StringVector::iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str());
|
||||
const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory);
|
||||
ASSERT(p != NULL);
|
||||
int val = p->Permit(creature);
|
||||
if (val > best_val)
|
||||
{
|
||||
best_val = val;
|
||||
mv_factory = p;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return (mv_factory == NULL ? NULL : mv_factory->Create(creature));
|
||||
MovementGeneratorCreator const* mv_factory = sMovementGeneratorRegistry->GetRegistryItem(type);
|
||||
return ASSERT_NOTNULL(mv_factory)->Create(unit);
|
||||
}
|
||||
|
||||
GameObjectAI* SelectGameObjectAI(GameObject* go)
|
||||
{
|
||||
GameObjectAICreator const* ai_factory = NULL;
|
||||
GameObjectAICreator const* ai_factory = nullptr;
|
||||
|
||||
// scriptname in db
|
||||
if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
|
||||
return scriptedAI;
|
||||
|
||||
ai_factory = sGameObjectAIRegistry->GetRegistryItem(go->GetAIName());
|
||||
// AIname in db
|
||||
std::string const& aiName = go->GetAIName();
|
||||
if (!ai_factory && !aiName.empty())
|
||||
ai_factory = sGameObjectAIRegistry->GetRegistryItem(aiName);
|
||||
|
||||
//future goAI types go here
|
||||
// select by permit check
|
||||
if (!ai_factory)
|
||||
{
|
||||
GameObjectAIRegistry::RegistryMapType const& items = sGameObjectAIRegistry->GetRegisteredItems();
|
||||
auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<GameObject>(go));
|
||||
if (itr != items.end())
|
||||
ai_factory = itr->second.get();
|
||||
}
|
||||
|
||||
std::string ainame = (ai_factory == NULL || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key();
|
||||
if (!ai_factory)
|
||||
ai_factory = sGameObjectAIRegistry->GetRegistryItem("NullGameObjectAI");
|
||||
|
||||
TC_LOG_DEBUG("scripts", "%s used AI is %s.", go->GetGUID().ToString().c_str(), ainame.c_str());
|
||||
|
||||
return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go));
|
||||
return ASSERT_NOTNULL(ai_factory)->Create(go);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,13 +21,14 @@
|
||||
class CreatureAI;
|
||||
class Creature;
|
||||
class MovementGenerator;
|
||||
class Unit;
|
||||
class GameObjectAI;
|
||||
class GameObject;
|
||||
|
||||
namespace FactorySelector
|
||||
{
|
||||
TC_GAME_API CreatureAI* selectAI(Creature*);
|
||||
TC_GAME_API MovementGenerator* selectMovementGenerator(Creature*);
|
||||
TC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject*);
|
||||
TC_GAME_API CreatureAI* SelectAI(Creature* creature);
|
||||
TC_GAME_API MovementGenerator* SelectMovementGenerator(Unit* unit);
|
||||
TC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject* go);
|
||||
}
|
||||
#endif
|
||||
|
||||
54
src/server/game/AI/GameObjectAIFactory.h
Normal file
54
src/server/game/AI/GameObjectAIFactory.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_GAMEOBJECTAIFACTORY_H
|
||||
#define TRINITY_GAMEOBJECTAIFACTORY_H
|
||||
|
||||
#include "ObjectRegistry.h"
|
||||
#include "FactoryHolder.h"
|
||||
|
||||
class GameObject;
|
||||
class GameObjectAI;
|
||||
|
||||
typedef FactoryHolder<GameObjectAI, GameObject> GameObjectAICreator;
|
||||
|
||||
struct SelectableGameObjectAI : public GameObjectAICreator, public Permissible<GameObject>
|
||||
{
|
||||
SelectableGameObjectAI(std::string const& name) : GameObjectAICreator(name), Permissible<GameObject>() { }
|
||||
};
|
||||
|
||||
template<class REAL_GO_AI>
|
||||
struct GameObjectAIFactory : public SelectableGameObjectAI
|
||||
{
|
||||
GameObjectAIFactory(std::string const& name) : SelectableGameObjectAI(name) { }
|
||||
|
||||
GameObjectAI* Create(GameObject* go) const override
|
||||
{
|
||||
return new REAL_GO_AI(go);
|
||||
}
|
||||
|
||||
int32 Permit(GameObject const* go) const override
|
||||
{
|
||||
return REAL_GO_AI::Permissible(go);
|
||||
}
|
||||
};
|
||||
|
||||
typedef GameObjectAICreator::FactoryHolderRegistry GameObjectAIRegistry;
|
||||
|
||||
#define sGameObjectAIRegistry GameObjectAIRegistry::instance()
|
||||
|
||||
#endif
|
||||
@@ -596,13 +596,6 @@ void SmartAI::JustRespawned()
|
||||
mFollowCreditType = 0;
|
||||
}
|
||||
|
||||
int SmartAI::Permissible(const Creature* creature)
|
||||
{
|
||||
if (creature->GetAIName() == "SmartAI")
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
void SmartAI::JustReachedHome()
|
||||
{
|
||||
GetScript()->OnReset();
|
||||
@@ -966,13 +959,6 @@ void SmartAI::CheckConditions(uint32 diff)
|
||||
mConditionsTimer -= diff;
|
||||
}
|
||||
|
||||
int SmartGameObjectAI::Permissible(const GameObject* g)
|
||||
{
|
||||
if (g->GetAIName() == "SmartGameObjectAI")
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
void SmartGameObjectAI::UpdateAI(uint32 diff)
|
||||
{
|
||||
GetScript()->OnUpdate(diff);
|
||||
|
||||
@@ -158,7 +158,7 @@ class TC_GAME_API SmartAI : public CreatureAI
|
||||
ObjectGuid GetGUID(int32 id = 0) const override;
|
||||
|
||||
//core related
|
||||
static int Permissible(const Creature*);
|
||||
static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
|
||||
|
||||
// Called at movepoint reached
|
||||
void MovepointReached(uint32 id);
|
||||
@@ -258,7 +258,7 @@ class TC_GAME_API SmartGameObjectAI : public GameObjectAI
|
||||
void InitializeAI() override;
|
||||
void Reset() override;
|
||||
SmartScript* GetScript() { return &mScript; }
|
||||
static int Permissible(const GameObject* g);
|
||||
static int32 Permissible(GameObject const* /*go*/) { return PERMIT_BASE_NO; }
|
||||
|
||||
bool GossipHello(Player* player, bool reportUse) override;
|
||||
bool GossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override;
|
||||
|
||||
@@ -978,7 +978,7 @@ bool Creature::AIM_Create(CreatureAI* ai /*= nullptr*/)
|
||||
|
||||
Motion_Initialize();
|
||||
|
||||
i_AI = ai ? ai : FactorySelector::selectAI(this);
|
||||
i_AI = ai ? ai : FactorySelector::SelectAI(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2810,7 +2810,7 @@ uint8 Creature::GetLevelForTarget(WorldObject const* target) const
|
||||
return Unit::GetLevelForTarget(target);
|
||||
}
|
||||
|
||||
std::string Creature::GetAIName() const
|
||||
std::string const& Creature::GetAIName() const
|
||||
{
|
||||
return sObjectMgr->GetCreatureTemplate(GetEntry())->AIName;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
CreatureData const* GetCreatureData() const { return m_creatureData; }
|
||||
CreatureAddon const* GetCreatureAddon() const;
|
||||
|
||||
std::string GetAIName() const;
|
||||
std::string const& GetAIName() const;
|
||||
std::string GetScriptName() const;
|
||||
uint32 GetScriptId() const;
|
||||
|
||||
|
||||
@@ -166,12 +166,9 @@ bool GameObject::AIM_Initialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GameObject::GetAIName() const
|
||||
std::string const& GameObject::GetAIName() const
|
||||
{
|
||||
if (GameObjectTemplate const* got = sObjectMgr->GetGameObjectTemplate(GetEntry()))
|
||||
return got->AIName;
|
||||
|
||||
return "";
|
||||
return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName;
|
||||
}
|
||||
|
||||
void GameObject::CleanupsBeforeDelete(bool finalCleanup)
|
||||
|
||||
@@ -283,7 +283,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
uint32 GetScriptId() const;
|
||||
GameObjectAI* AI() const { return m_AI; }
|
||||
|
||||
std::string GetAIName() const;
|
||||
std::string const& GetAIName() const;
|
||||
void SetDisplayId(uint32 displayid);
|
||||
uint32 GetDisplayId() const { return m_gameObjectData->DisplayID; }
|
||||
uint8 GetNameSetId() const;
|
||||
|
||||
@@ -35,9 +35,14 @@
|
||||
#include "MoveSplineInit.h"
|
||||
#include "PathGenerator.h"
|
||||
|
||||
inline MovementGenerator* GetIdleMovementGenerator()
|
||||
{
|
||||
return sMovementGeneratorRegistry->GetRegistryItem(IDLE_MOTION_TYPE)->Create();
|
||||
}
|
||||
|
||||
inline bool IsStatic(MovementGenerator* movement)
|
||||
{
|
||||
return (movement == &si_idleMovement);
|
||||
return (movement == GetIdleMovementGenerator());
|
||||
}
|
||||
|
||||
MotionMaster::~MotionMaster()
|
||||
@@ -75,15 +80,7 @@ void MotionMaster::Initialize()
|
||||
// set new default movement generator
|
||||
void MotionMaster::InitDefault()
|
||||
{
|
||||
if (_owner->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
MovementGenerator* movement = FactorySelector::selectMovementGenerator(_owner->ToCreature());
|
||||
Mutate(movement == nullptr ? &si_idleMovement : movement, MOTION_SLOT_IDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
|
||||
}
|
||||
Mutate(FactorySelector::SelectMovementGenerator(_owner), MOTION_SLOT_IDLE);
|
||||
}
|
||||
|
||||
void MotionMaster::UpdateMotion(uint32 diff)
|
||||
@@ -198,7 +195,7 @@ void MotionMaster::MoveIdle()
|
||||
{
|
||||
//! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active
|
||||
if (empty() || !IsStatic(top()))
|
||||
Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
|
||||
Mutate(GetIdleMovementGenerator(), MOTION_SLOT_IDLE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveTargetedHome()
|
||||
|
||||
@@ -16,5 +16,12 @@
|
||||
*/
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
#include "IdleMovementGenerator.h"
|
||||
|
||||
MovementGenerator::~MovementGenerator() { }
|
||||
|
||||
MovementGenerator* IdleMovementFactory::Create(Unit* /*object*/) const
|
||||
{
|
||||
static IdleMovementGenerator instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
@@ -69,20 +69,28 @@ class MovementGeneratorMedium : public MovementGenerator
|
||||
}
|
||||
};
|
||||
|
||||
struct SelectableMovement : public FactoryHolder<MovementGenerator, MovementGeneratorType>
|
||||
{
|
||||
SelectableMovement(MovementGeneratorType movementGeneratorType) : FactoryHolder<MovementGenerator, MovementGeneratorType>(movementGeneratorType) { }
|
||||
};
|
||||
typedef FactoryHolder<MovementGenerator, Unit, MovementGeneratorType> MovementGeneratorCreator;
|
||||
|
||||
template<class Movement>
|
||||
struct MovementGeneratorFactory : public SelectableMovement
|
||||
struct MovementGeneratorFactory : public MovementGeneratorCreator
|
||||
{
|
||||
MovementGeneratorFactory(MovementGeneratorType movementGeneratorType) : SelectableMovement(movementGeneratorType) { }
|
||||
MovementGeneratorFactory(MovementGeneratorType movementGeneratorType) : MovementGeneratorCreator(movementGeneratorType) { }
|
||||
|
||||
MovementGenerator* Create(void *) const override;
|
||||
MovementGenerator* Create(Unit* /*object*/) const override
|
||||
{
|
||||
return new Movement();
|
||||
}
|
||||
};
|
||||
|
||||
typedef FactoryHolder<MovementGenerator, MovementGeneratorType> MovementGeneratorCreator;
|
||||
typedef FactoryHolder<MovementGenerator, MovementGeneratorType>::FactoryHolderRegistry MovementGeneratorRegistry;
|
||||
struct IdleMovementFactory : public MovementGeneratorCreator
|
||||
{
|
||||
IdleMovementFactory() : MovementGeneratorCreator(IDLE_MOTION_TYPE) { }
|
||||
|
||||
MovementGenerator* Create(Unit* object) const override;
|
||||
};
|
||||
|
||||
typedef MovementGeneratorCreator::FactoryHolderRegistry MovementGeneratorRegistry;
|
||||
|
||||
#define sMovementGeneratorRegistry MovementGeneratorRegistry::instance()
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_MOVEMENTGENERATOR_IMPL_H
|
||||
#define TRINITY_MOVEMENTGENERATOR_IMPL_H
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
|
||||
template<class Movement>
|
||||
inline MovementGenerator* MovementGeneratorFactory<Movement>::Create(void * /*data*/) const
|
||||
{
|
||||
return (new Movement());
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,8 +20,6 @@
|
||||
#include "Creature.h"
|
||||
#include <G3D/g3dmath.h>
|
||||
|
||||
IdleMovementGenerator si_idleMovement;
|
||||
|
||||
// StopMoving is needed to make unit stop if its last movement generator expires
|
||||
// But it should not be sent otherwise there are many redundent packets
|
||||
void IdleMovementGenerator::Initialize(Unit* owner)
|
||||
|
||||
@@ -31,8 +31,6 @@ class IdleMovementGenerator : public MovementGenerator
|
||||
MovementGeneratorType GetMovementGeneratorType() const override { return IDLE_MOTION_TYPE; }
|
||||
};
|
||||
|
||||
TC_GAME_API extern IdleMovementGenerator si_idleMovement;
|
||||
|
||||
class RotateMovementGenerator : public MovementGenerator
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -24,23 +24,22 @@
|
||||
|
||||
/** FactoryHolder holds a factory object of a specific type
|
||||
*/
|
||||
template<class T, class Key = std::string>
|
||||
template<class T, class O, class Key = std::string>
|
||||
class FactoryHolder
|
||||
{
|
||||
public:
|
||||
typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry;
|
||||
typedef ObjectRegistry<FactoryHolder<T, O, Key>, Key> FactoryHolderRegistry;
|
||||
|
||||
FactoryHolder(Key k) : i_key(k) { }
|
||||
explicit FactoryHolder(Key const& k) : _key(k) { }
|
||||
virtual ~FactoryHolder() { }
|
||||
inline Key key() const { return i_key; }
|
||||
inline Key GetKey() const { return _key; }
|
||||
|
||||
void RegisterSelf(void) { FactoryHolderRegistry::instance()->InsertItem(this, i_key); }
|
||||
void DeregisterSelf(void) { FactoryHolderRegistry::instance()->RemoveItem(this, false); }
|
||||
void RegisterSelf() { FactoryHolderRegistry::instance()->InsertItem(this, _key); }
|
||||
|
||||
/// Abstract Factory create method
|
||||
virtual T* Create(void *data = NULL) const = 0;
|
||||
virtual T* Create(O* object = nullptr) const = 0;
|
||||
private:
|
||||
Key i_key;
|
||||
Key const _key;
|
||||
};
|
||||
|
||||
/** Permissible is a classic way of letting the object decide
|
||||
@@ -52,6 +51,6 @@ class Permissible
|
||||
{
|
||||
public:
|
||||
virtual ~Permissible() { }
|
||||
virtual int Permit(const T *) const = 0;
|
||||
virtual int32 Permit(T const*) const = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -23,14 +23,15 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
/** ObjectRegistry holds all registry item of the same type
|
||||
*/
|
||||
template<class T, class Key = std::string>
|
||||
class ObjectRegistry
|
||||
class ObjectRegistry final
|
||||
{
|
||||
public:
|
||||
typedef std::map<Key, T*> RegistryMapType;
|
||||
typedef std::map<Key, std::unique_ptr<T>> RegistryMapType;
|
||||
|
||||
static ObjectRegistry<T, Key>* instance()
|
||||
{
|
||||
@@ -39,71 +40,41 @@ class ObjectRegistry
|
||||
}
|
||||
|
||||
/// Returns a registry item
|
||||
const T* GetRegistryItem(Key key) const
|
||||
T const* GetRegistryItem(Key const& key) const
|
||||
{
|
||||
typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key);
|
||||
return( iter == i_registeredObjects.end() ? NULL : iter->second );
|
||||
auto itr = _registeredObjects.find(key);
|
||||
if (itr == _registeredObjects.end())
|
||||
return nullptr;
|
||||
return itr->second.get();
|
||||
}
|
||||
|
||||
/// Inserts a registry item
|
||||
bool InsertItem(T *obj, Key key, bool _override = false)
|
||||
bool InsertItem(T* obj, Key const& key, bool force = false)
|
||||
{
|
||||
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
|
||||
if ( iter != i_registeredObjects.end() )
|
||||
auto itr = _registeredObjects.find(key);
|
||||
if (itr != _registeredObjects.end())
|
||||
{
|
||||
if ( !_override )
|
||||
if (!force)
|
||||
return false;
|
||||
delete iter->second;
|
||||
i_registeredObjects.erase(iter);
|
||||
_registeredObjects.erase(itr);
|
||||
}
|
||||
|
||||
i_registeredObjects[key] = obj;
|
||||
_registeredObjects.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(obj));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Removes a registry item
|
||||
void RemoveItem(Key key, bool delete_object = true)
|
||||
{
|
||||
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
|
||||
if ( iter != i_registeredObjects.end() )
|
||||
{
|
||||
if ( delete_object )
|
||||
delete iter->second;
|
||||
i_registeredObjects.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if registry contains an item
|
||||
bool HasItem(Key key) const
|
||||
{
|
||||
return (i_registeredObjects.find(key) != i_registeredObjects.end());
|
||||
}
|
||||
|
||||
/// Inefficiently return a vector of registered items
|
||||
unsigned int GetRegisteredItems(std::vector<Key> &l) const
|
||||
{
|
||||
unsigned int sz = l.size();
|
||||
l.resize(sz + i_registeredObjects.size());
|
||||
for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
|
||||
l[sz++] = iter->first;
|
||||
return i_registeredObjects.size();
|
||||
}
|
||||
|
||||
/// Return the map of registered items
|
||||
RegistryMapType const &GetRegisteredItems() const
|
||||
RegistryMapType const& GetRegisteredItems() const
|
||||
{
|
||||
return i_registeredObjects;
|
||||
return _registeredObjects;
|
||||
}
|
||||
|
||||
ObjectRegistry() { }
|
||||
~ObjectRegistry()
|
||||
{
|
||||
for (typename RegistryMapType::iterator iter=i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
|
||||
delete iter->second;
|
||||
i_registeredObjects.clear();
|
||||
}
|
||||
private:
|
||||
RegistryMapType i_registeredObjects;
|
||||
RegistryMapType _registeredObjects;
|
||||
|
||||
// non instanceable, only static
|
||||
ObjectRegistry() { }
|
||||
~ObjectRegistry() { }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user