diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp new file mode 100644 index 000000000..01c6c7a7b --- /dev/null +++ b/SDK/include/NDK/BaseComponent.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_BASECOMPONENT_HPP +#define NDK_BASECOMPONENT_HPP + +#include + +namespace Ndk +{ + class NDK_API BaseComponent + { + public: + BaseComponent(nzUInt32 componentId); + virtual ~BaseComponent(); + + nzUInt32 GetComponentId() const; + + static nzUInt32 GetNextId(); + + protected: + nzUInt32 m_componentId; + + private: + static nzUInt32 s_nextId; + }; +} + +#include + +#endif // NDK_BASECOMPONENT_HPP diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl new file mode 100644 index 000000000..a068e77ae --- /dev/null +++ b/SDK/include/NDK/BaseComponent.inl @@ -0,0 +1,21 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +namespace Ndk +{ + inline BaseComponent::BaseComponent(nzUInt32 componentId) : + m_componentId(componentId) + { + } + + inline nzUInt32 BaseComponent::GetComponentId() const + { + return m_componentId; + } + + inline nzUInt32 BaseComponent::GetNextId() + { + return s_nextId++; + } +} diff --git a/SDK/include/NDK/Component.hpp b/SDK/include/NDK/Component.hpp new file mode 100644 index 000000000..861725959 --- /dev/null +++ b/SDK/include/NDK/Component.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_COMPONENT_HPP +#define NDK_COMPONENT_HPP + +#include +#include + +namespace Ndk +{ + template + class Component : public BaseComponent + { + public: + Component(); + virtual ~Component(); + + static nzUInt32 GetId(); + }; +} + +#include + +#endif // NDK_COMPONENT_HPP diff --git a/SDK/include/NDK/Component.inl b/SDK/include/NDK/Component.inl new file mode 100644 index 000000000..65b751d7b --- /dev/null +++ b/SDK/include/NDK/Component.inl @@ -0,0 +1,21 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +namespace Ndk +{ + template + Component::Component() : + BaseComponent(GetId()) + { + } + + template + Component::~Component() = default; + + template + nzUInt32 Component::GetId() + { + return ComponentType::ComponentId; + } +} diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index 510038afd..f5385e5d4 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -8,6 +8,8 @@ #define NDK_ENTITY_HPP #include +#include +#include #include namespace Ndk @@ -27,15 +29,24 @@ namespace Ndk Entity(Entity&& entity); ~Entity(); + template Component& AddComponent(Args&&... args); + EntityHandle CreateHandle(); + template Component& GetComponent(); + template const Component& GetComponent() const; Id GetId() const; World* GetWorld() const; + template bool HasComponent() const; + void Kill(); bool IsValid() const; + void RemoveAllComponent(); + template void RemoveComponent(); + Entity& operator=(const Entity&) = delete; Entity& operator=(Entity&&) = delete; @@ -48,6 +59,7 @@ namespace Ndk void RegisterHandle(EntityHandle* handle); void UnregisterHandle(EntityHandle* handle); + std::vector> m_components; std::vector m_handles; Id m_id; World* m_world; diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index ec4da9ba3..a77894d0c 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -3,7 +3,9 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include #include +#include #include namespace Ndk @@ -14,6 +16,60 @@ namespace Ndk { } + template + C& Entity::AddComponent(Args&&... args) + { + static_assert(std::is_base_of(), "C is not a component"); + + // Nous supprimons l'ancien component, s'il existe + RemoveComponent(); + + // Récupération de l'identification du component, qui va nous servir d'indice + nzUInt32 componentId = C::ComponentId; + + // Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component + if (m_components.size() <= componentId) + m_components.resize(componentId + 1); + + // Allocation et affectation du component + std::unique_ptr ptr(new C(std::forward(args)...)); + C* component = ptr.get(); + + m_components[componentId] = std::move(ptr); + + return *component; + } + + template + C& Entity::GetComponent() + { + ///DOC: Lance une exception si le component n'est pas présent + static_assert(std::is_base_of(), "C is not a component"); + + if (!HasComponent()) + throw std::runtime_error("Tried to get a non-present component"); + + BaseComponent* component = m_components[C::ComponentId].get(); + NazaraAssert(component, "Invalid component pointer"); + + return *static_cast(component); + } + + template + const C& Entity::GetComponent() const + { + ///DOC: Lance une exception si le component n'est pas présent + static_assert(std::is_base_of(), "C is not a component"); + + if (!HasComponent()) + throw std::runtime_error("Tried to get a non-present component"); + + BaseComponent* component = m_components[C::ComponentId].get(); + NazaraAssert(component, "Invalid component pointer"); + + return *static_cast(component); + } + inline Entity::Id Entity::GetId() const { return m_id; @@ -24,6 +80,29 @@ namespace Ndk return m_world; } + template + bool Entity::HasComponent() const + { + static_assert(std::is_base_of(), "C is not a component"); + + nzUInt32 componentId = C::ComponentId; + return m_components.size() > componentId && m_components[componentId]; + } + + inline void Entity::RemoveAllComponent() + { + m_components.clear(); + } + + template + void Entity::RemoveComponent() + { + static_assert(std::is_base_of(), "C is not a component"); + + if (HasComponent()) + m_components[C::ComponentId].reset(); + } + inline void Entity::RegisterHandle(EntityHandle* handle) { ///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois diff --git a/SDK/src/NDK/BaseComponent.cpp b/SDK/src/NDK/BaseComponent.cpp new file mode 100644 index 000000000..3d215d30f --- /dev/null +++ b/SDK/src/NDK/BaseComponent.cpp @@ -0,0 +1,10 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include + +namespace Ndk +{ + BaseComponent::~BaseComponent() = default; + + nzUInt32 BaseComponent::s_nextId = 0; +}