Adding components

This commit is contained in:
Zoe Roux
2021-05-14 17:37:14 +02:00
parent 9578e4e580
commit d6aaf30c3b
8 changed files with 195 additions and 42 deletions
+1 -1
View File
@@ -19,6 +19,6 @@ add_library(wal
sources/Events/EventManager.hpp
sources/Exception/WalError.cpp
sources/Exception/WalError.hpp
)
sources/Entity/Entity.cpp sources/Component/Component.cpp)
target_include_directories(wal PUBLIC sources)
+43
View File
@@ -0,0 +1,43 @@
//
// Created by Zoe Roux on 2021-05-14.
//
#include "Component/Component.hpp"
namespace WAL
{
Component::Component(std::string name, Entity &entity)
: _name(std::move(name)),
_entity(entity)
{ }
std::string Component::getName() const
{
return this->_name;
}
bool Component::isDisabled() const
{
return this->_disabled;
}
void Component::setDisable(bool disabled)
{
this->_disabled = disabled;
}
const std::vector<std::type_index> &Component::getDependencies() const
{
return this->_dependencies;
}
void Component::onStart()
{
//TODO handle events here
}
void Component::onStop()
{
//TODO handle events here
}
}
+27 -19
View File
@@ -5,6 +5,7 @@
#include <vector>
#include <string>
#include <typeindex>
namespace WAL
{
@@ -18,35 +19,42 @@ namespace WAL
//! @brief The name of this component
std::string _name;
//! @brief Is this component disabled?
bool _disabled;
bool _disabled = false;
protected:
//! @brief The entity that own this component
Entity &_entity;
//! @brief The list of dependencies of this component.
// TODO check if there is a better type than strings
std::vector<std::string> _dependencies;
std::vector<std::type_index> _dependencies;
//! @brief A component can't be instantiated, it should be derived.
explicit Component(std::string name, Entity &entity);
//! @brief A component can't be instantiated, it should be derived.
Component(const Component &) = default;
public:
//! @brief A component can't be assigned
Component &operator=(const Component &) = delete;
//! @brief A virtual destructor
virtual ~Component() = default;
//! @brief Clone a component for another or the same entity.
//! @param entity The entity that owns the ne component.
virtual Component *clone(Entity &entity) const = 0;
//! @brief Get the name of this component
std::string _getName() const;
std::string getName() const;
//! @brief Used if the component is disabled
bool isDisable() const;
bool isDisabled() const;
//! @brief Disable this component.
void setDisable(bool disabled);
//! @brief Get the dependencies of this component.
const std::vector<std::type_index> &getDependencies() const;
//! @brief The entity or this component has just been enabled.
//! @param entity The entity that has this component
virtual void onStart(Entity &entity);
virtual void onStart();
//! @brief The entity or this component has just been disable.
//! @param entity The entity that has this component
virtual void onStop(Entity &entity);
//! @brief A virtual destructor (that also calls onStop)
virtual ~Component();
protected:
//! @brief A component can't be instantiated, it should be derived.
Component() = default;
//! @brief A component can't be instantiated, it should be derived.
Component(const Component &) = default;
//! @brief A component can't be instantiated, it should be derived.
Component &operator=(const Component &) = default;
virtual void onStop();
};
}
+55
View File
@@ -0,0 +1,55 @@
//
// Created by Zoe Roux on 2021-05-14.
//
#include "Entity/Entity.hpp"
#include <utility>
namespace WAL
{
unsigned Entity::nextID = 0;
Entity::Entity(std::string name)
: _uid(Entity::nextID++),
_name(std::move(name))
{ }
Entity::Entity(const Entity &other)
: _uid(Entity::nextID++),
_name(other._name),
_disabled(other._disabled)
{
for (const auto &cmp : other._components)
this->addComponent(*cmp);
}
unsigned Entity::getUid() const
{
return this->_uid;
}
std::string Entity::getName() const
{
return this->_name;
}
bool Entity::isDisable() const
{
return this->_disabled;
}
void Entity::setDisable(bool disabled)
{
this->_disabled = disabled;
}
Entity &Entity::addComponent(const Component &component)
{
// TODO handle duplicates
// if (this->hasComponent<T>())
// throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists.");
this->_components.emplace_back(component.clone(*this));
return *this;
}
}
+54 -8
View File
@@ -4,7 +4,10 @@
#include <string>
#include <vector>
#include <typeinfo>
#include <memory>
#include "Component/Component.hpp"
#include "Exception/WalError.hpp"
namespace WAL
{
@@ -17,9 +20,12 @@ namespace WAL
//! @brief An entity name (this is useful for debugging)
std::string _name;
//! @brief Is this entity enabled?
bool _disabled;
bool _disabled = false;
//! @brief The list of the components of this entity
std::vector<Component> _components;
std::vector<std::unique_ptr<Component>> _components = {};
//! @brief This ID will be the one of the next entity created.
static unsigned nextID;
public:
//! @brief Get the ID of the entity.
unsigned getUid() const;
@@ -33,30 +39,70 @@ namespace WAL
void setDisable(bool disabled);
//! @brief Get a component of a specific type
//! @throw ComponentNotFoundError if the component could not be found
//! @throw NotFoundError if the component could not be found
template<typename T>
T getComponent();
T getComponent()
{
const std::type_info &type = typeid(T);
auto &existing = std::find(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) {
return typeid(*cmp) == type;
});
if (existing == this->_components.end())
throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\".");
return *existing;
}
template<typename T>
bool hasComponent() const
{
const std::type_info &type = typeid(T);
auto existing = std::find(this->_components.begin(), this->_components.end(), [&type] (const auto &cmp) {
return typeid(*cmp) == type;
});
return existing != this->_components.end();
}
//! @brief Add a component to this entity. The component is constructed in place.
//! @throw DuplicateError is thrown if a component with the same type already exist.
//! @return This entity is returned
template<typename T, class ...Types>
Entity &addComponent(Types ...params);
Entity &addComponent(Types ...params)
{
if (this->hasComponent<T>())
throw DuplicateError("A component of the type \"" + std::string(typeid(T).name()) + "\" already exists.");
this->_components.push_back(std::make_unique(params...));
return *this;
}
//! @brief Copy a component to this entity.
//! @return This entity is returned.
Entity &addComponent(const Component &component);
//! @brief Remove a specific component (by type).
//! @throw NotFoundError is thrown if the component could not be found.
//! @return This entity is returned.
template<typename T>
Entity &removeComponent();
Entity &removeComponent()
{
const std::type_info &type = typeid(T);
auto &existing =std::find(this->_components.begin(), this->_components.end(), [&type] (auto &cmp) {
return typeid(*cmp) == type;
});
if (existing == this->_components.end())
throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\".");
this->_components.erase(existing);
return *this;
}
//! @brief A default constructor
Entity(const std::string &name);
explicit Entity(std::string name);
//! @brief An entity is copyable
Entity(const Entity &);
//! @brief An entity is movable.
Entity(Entity &&) = default;
//! @brief A default destructor
~Entity() = default;
//! @brief An entity is assignable
Entity &operator=(const Entity &);
Entity &operator=(const Entity &) = default;
};
}
+1 -1
View File
@@ -10,7 +10,7 @@ namespace WAL
: std::runtime_error(what)
{}
SystemExistError::SystemExistError(const std::string &what)
DuplicateError::DuplicateError(const std::string &what)
: WalError(what)
{}
+6 -6
View File
@@ -24,18 +24,18 @@ namespace WAL
WalError &operator=(const WalError &) = default;
};
//! @brief An exception informing the user that a system already exists.
class SystemExistError : public WalError
//! @brief An exception informing the user that something already exists.
class DuplicateError : public WalError
{
public:
//! @brief Create a new wal exception
explicit SystemExistError(const std::string &what);
explicit DuplicateError(const std::string &what);
//! @brief A wal exception is copy constructable
SystemExistError(const SystemExistError &) = default;
DuplicateError(const DuplicateError &) = default;
//! @brief A default destructor
~SystemExistError() override = default;
~DuplicateError() override = default;
//! @brief A default assignment operator
SystemExistError &operator=(const SystemExistError &) = default;
DuplicateError &operator=(const DuplicateError &) = default;
};
//! @brief An exception informing the user that something could not be found
+8 -7
View File
@@ -37,10 +37,10 @@ namespace WAL
{
const std::type_info &type = typeid(T);
auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) {
return typeid(sys) == type;
return typeid(*sys) == type;
});
if (existing != this->_systems.end())
throw SystemExistError("A system of the type \"" + std::string(type.name()) + "\" already exists.");
throw DuplicateError("A system of the type \"" + std::string(type.name()) + "\" already exists.");
this->_systems.push_back(std::make_unique(params...));
return *this;
}
@@ -52,10 +52,10 @@ namespace WAL
{
const std::type_info &type = typeid(T);
auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) {
return typeid(sys) == type;
return typeid(*sys) == type;
});
if (existing != this->_systems.end())
throw SystemExistError("A system of the type \"" + std::string(type.name()) + "\" already exists.");
throw DuplicateError("A system of the type \"" + std::string(type.name()) + "\" already exists.");
this->_systems.push_back(std::make_unique(system));
return *this;
}
@@ -66,10 +66,11 @@ namespace WAL
{
const std::type_info &type = typeid(T);
auto &existing =std::find(this->_systems.begin(), this->_systems.end(), [&type] (auto &sys) {
return typeid(sys) == type;
return typeid(*sys) == type;
});
if (existing == this->_systems.end())
throw NotFoundError("No system could be found with the type \"" + std::string(type.name()) + "\".");
this->_systems.erase(existing);
return *this;
}
@@ -85,7 +86,7 @@ namespace WAL
WAL(const WAL &) = delete;
//! @brief A default destructor
~WAL() = default;
//! @brief A default assignment operator
WAL &operator=(const WAL &) = default;
//! @brief A WAL can't be assigned.
WAL &operator=(const WAL &) = delete;
};
}