Added Components

Former-commit-id: 02f9e9892b58a725697b83e7b75127db5b3a27f4
This commit is contained in:
Lynix 2015-03-01 01:53:49 +01:00
parent dd56dd6e29
commit 699b580516
7 changed files with 205 additions and 0 deletions

View File

@ -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 <NDK/Prerequesites.hpp>
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 <NDK/BaseComponent.inl>
#endif // NDK_BASECOMPONENT_HPP

View File

@ -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++;
}
}

View File

@ -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 <NDK/Prerequesites.hpp>
#include <NDK/BaseComponent.hpp>
namespace Ndk
{
template<typename ComponentType>
class Component : public BaseComponent
{
public:
Component();
virtual ~Component();
static nzUInt32 GetId();
};
}
#include <NDK/Component.inl>
#endif // NDK_COMPONENT_HPP

View File

@ -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<typename ComponentType>
Component<ComponentType>::Component() :
BaseComponent(GetId())
{
}
template<typename ComponentType>
Component<ComponentType>::~Component() = default;
template<typename ComponentType>
nzUInt32 Component<ComponentType>::GetId()
{
return ComponentType::ComponentId;
}
}

View File

@ -8,6 +8,8 @@
#define NDK_ENTITY_HPP #define NDK_ENTITY_HPP
#include <NDK/Prerequesites.hpp> #include <NDK/Prerequesites.hpp>
#include <NDK/BaseComponent.hpp>
#include <memory>
#include <vector> #include <vector>
namespace Ndk namespace Ndk
@ -27,15 +29,24 @@ namespace Ndk
Entity(Entity&& entity); Entity(Entity&& entity);
~Entity(); ~Entity();
template<typename Component, typename... Args> Component& AddComponent(Args&&... args);
EntityHandle CreateHandle(); EntityHandle CreateHandle();
template<typename Component> Component& GetComponent();
template<typename Component> const Component& GetComponent() const;
Id GetId() const; Id GetId() const;
World* GetWorld() const; World* GetWorld() const;
template<typename Component> bool HasComponent() const;
void Kill(); void Kill();
bool IsValid() const; bool IsValid() const;
void RemoveAllComponent();
template<typename Component> void RemoveComponent();
Entity& operator=(const Entity&) = delete; Entity& operator=(const Entity&) = delete;
Entity& operator=(Entity&&) = delete; Entity& operator=(Entity&&) = delete;
@ -48,6 +59,7 @@ namespace Ndk
void RegisterHandle(EntityHandle* handle); void RegisterHandle(EntityHandle* handle);
void UnregisterHandle(EntityHandle* handle); void UnregisterHandle(EntityHandle* handle);
std::vector<std::unique_ptr<BaseComponent>> m_components;
std::vector<EntityHandle*> m_handles; std::vector<EntityHandle*> m_handles;
Id m_id; Id m_id;
World* m_world; World* m_world;

View File

@ -3,7 +3,9 @@
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp // For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/World.hpp> #include <NDK/World.hpp>
#include <Nazara/Core/Error.hpp>
#include <algorithm> #include <algorithm>
#include <stdexcept>
#include <utility> #include <utility>
namespace Ndk namespace Ndk
@ -14,6 +16,60 @@ namespace Ndk
{ {
} }
template<typename C, typename... Args>
C& Entity::AddComponent(Args&&... args)
{
static_assert(std::is_base_of<BaseComponent, C>(), "C is not a component");
// Nous supprimons l'ancien component, s'il existe
RemoveComponent<C>();
// 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<C> ptr(new C(std::forward(args)...));
C* component = ptr.get();
m_components[componentId] = std::move(ptr);
return *component;
}
template<typename C>
C& Entity::GetComponent()
{
///DOC: Lance une exception si le component n'est pas présent
static_assert(std::is_base_of<BaseComponent, C>(), "C is not a component");
if (!HasComponent<C>())
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<C*>(component);
}
template<typename C>
const C& Entity::GetComponent() const
{
///DOC: Lance une exception si le component n'est pas présent
static_assert(std::is_base_of<BaseComponent, C>(), "C is not a component");
if (!HasComponent<C>())
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<C*>(component);
}
inline Entity::Id Entity::GetId() const inline Entity::Id Entity::GetId() const
{ {
return m_id; return m_id;
@ -24,6 +80,29 @@ namespace Ndk
return m_world; return m_world;
} }
template<typename C>
bool Entity::HasComponent() const
{
static_assert(std::is_base_of<BaseComponent, C>(), "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<typename C>
void Entity::RemoveComponent()
{
static_assert(std::is_base_of<BaseComponent, C>(), "C is not a component");
if (HasComponent<C>())
m_components[C::ComponentId].reset();
}
inline void Entity::RegisterHandle(EntityHandle* handle) 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 ///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois

View File

@ -0,0 +1,10 @@
// This file was automatically generated on 26 May 2014 at 01:05:31
#include <NDK/BaseComponent.hpp>
namespace Ndk
{
BaseComponent::~BaseComponent() = default;
nzUInt32 BaseComponent::s_nextId = 0;
}