diff --git a/source/core/Entity.hpp b/source/core/Entity.hpp index 124c3e3e..c0f584ad 100644 --- a/source/core/Entity.hpp +++ b/source/core/Entity.hpp @@ -18,130 +18,103 @@ class WorldBase; class Entity { private: - WorldBase *world_ptr = nullptr; ///< Track the world this entity is in (private to - ///< protect pointer) + WorldBase * world_ptr = nullptr; ///< Track the world this entity is in (private to protect pointer) + protected: - const size_t id = 0; ///< Unique ID for this entity (zero is use for "no ID") - std::string name; ///< Name for this entity (E.g., "Player 1" or "+2 Sword") - GridPosition position; ///< Where on the grid is this entity? - - struct PropertyBase { - virtual ~PropertyBase() {} - }; - - template - struct Property : public PropertyBase { - T value; - Property(const T &in) : value(in) {} - Property(T &&in) : value(in) {} - }; - - /// Every entity can have a simple set of properties (with values) associated - /// with it. - std::unordered_map> property_map; - - // -- Helper Functions -- - - template - Property &AsProperty(const std::string &name) const { - assert(HasProperty(name)); - PropertyBase *raw_ptr = property_map.at(name).get(); - assert(dynamic_cast *>(raw_ptr)); - auto property_ptr = static_cast *>(raw_ptr); - return *property_ptr; - } + const size_t id=0; ///< Unique ID for this entity (zero is use for "no ID") + std::string name; ///< Name for this entity (E.g., "Player 1" or "+2 Sword") + GridPosition position; ///< Where on the grid is this entity? + + struct PropertyBase { + virtual ~PropertyBase() { } + }; + + template + struct Property : public PropertyBase { + T value; + Property(const T & in) : value(in) { } + Property(T && in) : value(in) { } + }; + + /// Every entity can have a simple set of properties (with values) associated with it. + std::unordered_map> property_map; + + // -- Helper Functions -- + + template + Property & AsProperty(const std::string & name) const { + assert( HasProperty(name) ); + PropertyBase * raw_ptr = property_map.at(name).get(); + assert( dynamic_cast *>(raw_ptr) ); + auto property_ptr = static_cast *>(raw_ptr); + return *property_ptr; + } public: - Entity(size_t id, const std::string &name) : id(id), name(name) {} - Entity(const Entity &) = - delete; // Entities must be unique and shouldn't be copied. - Entity(Entity &&) = default; - virtual ~Entity() = default; - - Entity &operator=(const Entity &) = - delete; // Entities must be unique and shouldn't be copied. - Entity & - operator=(Entity &&) = delete; // Entities should never have IDs change. - - // -- Accessors -- - [[nodiscard]] size_t GetID() const { return id; } - [[nodiscard]] const std::string &GetName() const { return name; } - [[nodiscard]] GridPosition GetPosition() const { return position; } - [[nodiscard]] WorldBase &GetWorld() const { - assert(world_ptr); - return *world_ptr; - } - [[nodiscard]] bool HasWorld() const { - return world_ptr != nullptr; + Entity(size_t id, const std::string & name) : id(id), name(name) { } + Entity(const Entity &) = delete; // Entities must be unique and shouldn't be copied. + Entity(Entity &&) = default; + virtual ~Entity() = default; + + Entity & operator=(const Entity &) = delete; // Entities must be unique and shouldn't be copied. + Entity & operator=(Entity &&) = delete; // Entities should never have IDs change. + + // -- Accessors -- + [[nodiscard]] size_t GetID() const { return id; } + [[nodiscard]] const std::string & GetName() const { return name; } + [[nodiscard]] GridPosition GetPosition() const { return position; } + [[nodiscard]] WorldBase & GetWorld() const { assert(world_ptr); return *world_ptr; } + + [[nodiscard]] bool HasWorld() const { return world_ptr != nullptr;} + Entity & SetName(const std::string in_name) { name = in_name; return *this; } + Entity & SetPosition(GridPosition in_pos) { position = in_pos; return *this; } + Entity & SetPosition(double x, double y) { position = GridPosition{x,y}; return *this; } + virtual Entity & SetWorld(WorldBase & in_world) { world_ptr = &in_world; return *this; } + + virtual bool IsAgent() const { return false; } ///< Is Entity an autonomous agent? + virtual bool IsItem() const { return false; } ///< Is Entity an item? + virtual bool IsInterface() const { return false; } ///< Is Entity an interface for a human? + + + // -- Property Management -- + + /// Does this agent have a property with the specified name? + [[nodiscard]] bool HasProperty(const std::string & name) const { + return property_map.count(name); } - Entity &SetName(const std::string in_name) { - name = in_name; - return *this; - } - Entity &SetPosition(GridPosition in_pos) { - position = in_pos; - return *this; - } - Entity &SetPosition(double x, double y) { - position = GridPosition{x, y}; - return *this; - } - virtual Entity &SetWorld(WorldBase &in_world) { - world_ptr = &in_world; - return *this; - } - - virtual bool IsAgent() const { - return false; - } ///< Is Entity an autonomous agent? - virtual bool IsItem() const { return false; } ///< Is Entity an item? - virtual bool IsInterface() const { - return false; - } ///< Is Entity an interface for a human? - - // -- Property Management -- - - /// Does this agent have a property with the specified name? - [[nodiscard]] bool HasProperty(const std::string &name) const { - return property_map.count(name); - } - - /// Return the current value of the specified property. - template - [[nodiscard]] const T &GetProperty(const std::string &name) const { - assert(HasProperty(name)); // Break if property does not already exist. - return AsProperty(name).value; - } - - /// Change the value of the specified property (will create if needed) - template - Entity &SetProperty(const std::string &name, const T &value) { - if (HasProperty(name)) { - AsProperty(name).value = value; - } else { - property_map[name] = std::make_unique>(value); - } - return *this; - } - - /// Allow for setting multiple properties at once. - Entity &SetProperties() { return *this; } - - template - Entity &SetProperties(const std::string &name, VALUE_T &&value, - EXTRA_Ts &&...extras) { - SetProperty(name, - std::forward(value)); // Set the first property... - return SetProperties( - std::forward(extras)...); // And any additional properties... - } - - /// Completely remove a property from an Entity. - Entity &RemoveProperty(const std::string &name) { - property_map.erase(name); - return *this; - } + /// Return the current value of the specified property. + template + [[nodiscard]] const T & GetProperty(const std::string & name) const { + assert(HasProperty(name)); // Break if property does not already exist. + return AsProperty(name).value; + } + + /// Change the value of the specified property (will create if needed) + template + Entity & SetProperty(const std::string & name, const T & value) { + if (HasProperty(name)) { + AsProperty(name).value = value; + } else { + property_map[name] = std::make_unique>(value); + } + return *this; + } + + /// Allow for setting multiple properties at once. + Entity & SetProperties() { return *this; } + + template + Entity & SetProperties(const std::string & name, VALUE_T && value, EXTRA_Ts &&... extras) { + SetProperty(name, std::forward(value)); // Set the first property... + return SetProperties(std::forward(extras)...); // And any additional properties... + } + + /// Completely remove a property from an Entity. + Entity & RemoveProperty(const std::string & name) { + property_map.erase(name); + return *this; + } }; } // End of namespace cse491