Add generic handlers
Former-commit-id: 8fc343d3a056de8031cf453748b8801d50d3710e
This commit is contained in:
parent
a2f6e54104
commit
a77ad42fcb
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef NDK_BASECOMPONENT_HPP
|
#ifndef NDK_BASECOMPONENT_HPP
|
||||||
#define NDK_BASECOMPONENT_HPP
|
#define NDK_BASECOMPONENT_HPP
|
||||||
|
|
||||||
#include <NDK/EntityHandle.hpp>
|
#include <NDK/Entity.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#define NDK_BASESYSTEM_HPP
|
#define NDK_BASESYSTEM_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/Bitset.hpp>
|
#include <Nazara/Core/Bitset.hpp>
|
||||||
#include <NDK/EntityHandle.hpp>
|
#include <NDK/Entity.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define NDK_ENTITY_HPP
|
#define NDK_ENTITY_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/Bitset.hpp>
|
#include <Nazara/Core/Bitset.hpp>
|
||||||
|
#include <Nazara/Core/HandledObject.hpp>
|
||||||
#include <NDK/Algorithm.hpp>
|
#include <NDK/Algorithm.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -15,13 +16,14 @@
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
class BaseComponent;
|
class BaseComponent;
|
||||||
class EntityHandle;
|
class Entity;
|
||||||
class World;
|
class World;
|
||||||
|
|
||||||
class NDK_API Entity
|
using EntityHandle = Nz::ObjectHandle<Entity>;
|
||||||
|
|
||||||
|
class NDK_API Entity : public Nz::HandledObject<Entity>
|
||||||
{
|
{
|
||||||
friend class BaseSystem;
|
friend class BaseSystem;
|
||||||
friend EntityHandle;
|
|
||||||
friend World;
|
friend World;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -32,8 +34,6 @@ namespace Ndk
|
||||||
BaseComponent& AddComponent(std::unique_ptr<BaseComponent>&& component);
|
BaseComponent& AddComponent(std::unique_ptr<BaseComponent>&& component);
|
||||||
template<typename ComponentType, typename... Args> ComponentType& AddComponent(Args&&... args);
|
template<typename ComponentType, typename... Args> ComponentType& AddComponent(Args&&... args);
|
||||||
|
|
||||||
EntityHandle CreateHandle();
|
|
||||||
|
|
||||||
inline void Enable(bool enable);
|
inline void Enable(bool enable);
|
||||||
|
|
||||||
inline BaseComponent& GetComponent(ComponentIndex index);
|
inline BaseComponent& GetComponent(ComponentIndex index);
|
||||||
|
|
@ -56,6 +56,8 @@ namespace Ndk
|
||||||
void RemoveComponent(ComponentIndex index);
|
void RemoveComponent(ComponentIndex index);
|
||||||
template<typename ComponentType> void RemoveComponent();
|
template<typename ComponentType> void RemoveComponent();
|
||||||
|
|
||||||
|
inline Nz::String ToString() const;
|
||||||
|
|
||||||
Entity& operator=(const Entity&) = delete;
|
Entity& operator=(const Entity&) = delete;
|
||||||
Entity& operator=(Entity&&) = delete;
|
Entity& operator=(Entity&&) = delete;
|
||||||
|
|
||||||
|
|
@ -65,16 +67,13 @@ namespace Ndk
|
||||||
void Create();
|
void Create();
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
inline void RegisterHandle(EntityHandle* handle);
|
|
||||||
inline void RegisterSystem(SystemIndex index);
|
inline void RegisterSystem(SystemIndex index);
|
||||||
|
|
||||||
inline void SetWorld(World* world) noexcept;
|
inline void SetWorld(World* world) noexcept;
|
||||||
|
|
||||||
inline void UnregisterHandle(EntityHandle* handle);
|
|
||||||
inline void UnregisterSystem(SystemIndex index);
|
inline void UnregisterSystem(SystemIndex index);
|
||||||
|
|
||||||
std::vector<std::unique_ptr<BaseComponent>> m_components;
|
std::vector<std::unique_ptr<BaseComponent>> m_components;
|
||||||
std::vector<EntityHandle*> m_handles;
|
|
||||||
Nz::Bitset<> m_componentBits;
|
Nz::Bitset<> m_componentBits;
|
||||||
Nz::Bitset<> m_systemBits;
|
Nz::Bitset<> m_systemBits;
|
||||||
EntityId m_id;
|
EntityId m_id;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// 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 <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Core/StringStream.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
@ -102,10 +103,10 @@ namespace Ndk
|
||||||
RemoveComponent(index);
|
RemoveComponent(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Entity::RegisterHandle(EntityHandle* handle)
|
inline Nz::String Entity::ToString() const
|
||||||
{
|
{
|
||||||
///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois
|
Nz::StringStream ss;
|
||||||
m_handles.push_back(handle);
|
return ss << "Entity(" << GetId() << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Entity::RegisterSystem(SystemIndex index)
|
inline void Entity::RegisterSystem(SystemIndex index)
|
||||||
|
|
@ -120,18 +121,24 @@ namespace Ndk
|
||||||
m_world = world;
|
m_world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Entity::UnregisterHandle(EntityHandle* handle)
|
|
||||||
{
|
|
||||||
///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash
|
|
||||||
auto it = std::find(m_handles.begin(), m_handles.end(), handle);
|
|
||||||
|
|
||||||
// On échange cet élément avec le dernier, et on diminue la taille du vector de 1
|
|
||||||
std::swap(*it, m_handles.back());
|
|
||||||
m_handles.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Entity::UnregisterSystem(SystemIndex index)
|
inline void Entity::UnregisterSystem(SystemIndex index)
|
||||||
{
|
{
|
||||||
m_systemBits.UnboundedReset(index);
|
m_systemBits.UnboundedReset(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
struct hash<Ndk::EntityHandle>
|
||||||
|
{
|
||||||
|
size_t operator()(const Ndk::EntityHandle& handle) const
|
||||||
|
{
|
||||||
|
// Hasher le pointeur fonctionnerait jusqu'à ce que l'entité soit mise à jour et déplacée
|
||||||
|
// pour cette raison, nous devons hasher l'ID de l'entité (qui reste constante)
|
||||||
|
Ndk::EntityId id = (handle.IsValid()) ? handle->GetId() : std::numeric_limits<Ndk::EntityId>::max();
|
||||||
|
|
||||||
|
return hash<Ndk::EntityId>()(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
// 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_ENTITYHANDLE_HPP
|
|
||||||
#define NDK_ENTITYHANDLE_HPP
|
|
||||||
|
|
||||||
#include <NDK/Entity.hpp>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
namespace Ndk
|
|
||||||
{
|
|
||||||
class EntityHandle
|
|
||||||
{
|
|
||||||
friend Entity;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EntityHandle();
|
|
||||||
explicit EntityHandle(Entity* entity);
|
|
||||||
EntityHandle(const EntityHandle& handle);
|
|
||||||
EntityHandle(EntityHandle&& handle);
|
|
||||||
~EntityHandle();
|
|
||||||
|
|
||||||
Entity* GetEntity() const;
|
|
||||||
|
|
||||||
bool IsValid() const;
|
|
||||||
|
|
||||||
void Reset(Entity* entity = nullptr);
|
|
||||||
void Reset(const EntityHandle& handle);
|
|
||||||
void Reset(EntityHandle&& handle);
|
|
||||||
|
|
||||||
EntityHandle& Swap(EntityHandle& handle);
|
|
||||||
|
|
||||||
Nz::String ToString() const;
|
|
||||||
|
|
||||||
operator bool() const;
|
|
||||||
operator Entity*() const;
|
|
||||||
Entity* operator->() const;
|
|
||||||
|
|
||||||
EntityHandle& operator=(Entity* entity);
|
|
||||||
EntityHandle& operator=(const EntityHandle& handle);
|
|
||||||
EntityHandle& operator=(EntityHandle&& handle);
|
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& out, const EntityHandle& handle);
|
|
||||||
|
|
||||||
friend bool operator==(const EntityHandle& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator==(const Entity& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator==(const EntityHandle& lhs, const Entity& rhs);
|
|
||||||
|
|
||||||
friend bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator!=(const Entity& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator!=(const EntityHandle& lhs, const Entity& rhs);
|
|
||||||
|
|
||||||
friend bool operator<(const EntityHandle& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator<(const Entity& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator<(const EntityHandle& lhs, const Entity& rhs);
|
|
||||||
|
|
||||||
friend bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator<=(const Entity& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator<=(const EntityHandle& lhs, const Entity& rhs);
|
|
||||||
|
|
||||||
friend bool operator>(const EntityHandle& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator>(const Entity& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator>(const EntityHandle& lhs, const Entity& rhs);
|
|
||||||
|
|
||||||
friend bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator>=(const Entity& lhs, const EntityHandle& rhs);
|
|
||||||
friend bool operator>=(const EntityHandle& lhs, const Entity& rhs);
|
|
||||||
|
|
||||||
static const EntityHandle InvalidHandle;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void OnEntityDestroyed();
|
|
||||||
void OnEntityMoved(Entity* newEntity);
|
|
||||||
|
|
||||||
Entity* m_entity;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <NDK/EntityHandle.inl>
|
|
||||||
|
|
||||||
#endif // NDK_ENTITYHANDLE_HPP
|
|
||||||
|
|
@ -1,280 +0,0 @@
|
||||||
// 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
|
|
||||||
|
|
||||||
#include <Nazara/Core/StringStream.hpp>
|
|
||||||
#include <functional>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace Ndk
|
|
||||||
{
|
|
||||||
inline EntityHandle::EntityHandle() :
|
|
||||||
m_entity(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle::EntityHandle(Entity* entity) :
|
|
||||||
EntityHandle()
|
|
||||||
{
|
|
||||||
Reset(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle::EntityHandle(const EntityHandle& handle) :
|
|
||||||
EntityHandle()
|
|
||||||
{
|
|
||||||
Reset(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle::EntityHandle(EntityHandle&& handle) :
|
|
||||||
EntityHandle()
|
|
||||||
{
|
|
||||||
Reset(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle::~EntityHandle()
|
|
||||||
{
|
|
||||||
Reset(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Entity* EntityHandle::GetEntity() const
|
|
||||||
{
|
|
||||||
return m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool EntityHandle::IsValid() const
|
|
||||||
{
|
|
||||||
return m_entity != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void EntityHandle::Reset(Entity* entity)
|
|
||||||
{
|
|
||||||
// Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle
|
|
||||||
if (m_entity)
|
|
||||||
m_entity->UnregisterHandle(this);
|
|
||||||
|
|
||||||
m_entity = entity;
|
|
||||||
if (m_entity)
|
|
||||||
// On informe la nouvelle entité que nous pointons sur elle
|
|
||||||
m_entity->RegisterHandle(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void EntityHandle::Reset(const EntityHandle& handle)
|
|
||||||
{
|
|
||||||
Reset(handle.GetEntity());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void EntityHandle::Reset(EntityHandle&& handle)
|
|
||||||
{
|
|
||||||
Reset(handle.GetEntity());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle& EntityHandle::Swap(EntityHandle& handle)
|
|
||||||
{
|
|
||||||
// Comme nous inversons les handles, nous devons prévenir les entités
|
|
||||||
// La version par défaut de swap (à base de move) aurait fonctionné,
|
|
||||||
// mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire).
|
|
||||||
if (m_entity)
|
|
||||||
{
|
|
||||||
m_entity->UnregisterHandle(this);
|
|
||||||
m_entity->RegisterHandle(&handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle.m_entity)
|
|
||||||
{
|
|
||||||
handle.m_entity->UnregisterHandle(&handle);
|
|
||||||
handle.m_entity->RegisterHandle(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// On effectue l'échange
|
|
||||||
std::swap(m_entity, handle.m_entity);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Nz::String EntityHandle::ToString() const
|
|
||||||
{
|
|
||||||
Nz::StringStream ss;
|
|
||||||
ss << "EntityHandle(";
|
|
||||||
if (IsValid())
|
|
||||||
ss << "Entity(" << m_entity->GetId() << ')';
|
|
||||||
else
|
|
||||||
ss << "Null entity";
|
|
||||||
|
|
||||||
ss << ')';
|
|
||||||
|
|
||||||
return ss;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle::operator bool() const
|
|
||||||
{
|
|
||||||
return IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle::operator Entity*() const
|
|
||||||
{
|
|
||||||
return m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Entity* EntityHandle::operator->() const
|
|
||||||
{
|
|
||||||
return m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle& EntityHandle::operator=(Entity* entity)
|
|
||||||
{
|
|
||||||
Reset(entity);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle& EntityHandle::operator=(const EntityHandle& handle)
|
|
||||||
{
|
|
||||||
Reset(handle);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EntityHandle& EntityHandle::operator=(EntityHandle&& handle)
|
|
||||||
{
|
|
||||||
Reset(std::move(handle));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void EntityHandle::OnEntityDestroyed()
|
|
||||||
{
|
|
||||||
// Un raccourci, un appel à Reset nous enlèverait de la liste des handles que nous ne pouvons pas modifier
|
|
||||||
// maintenant car elle est actuellement parcourue
|
|
||||||
m_entity = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void EntityHandle::OnEntityMoved(Entity* newEntity)
|
|
||||||
{
|
|
||||||
// L'entité a été déplacée (peut arriver lors d'un changement de taille du conteneur du monde)
|
|
||||||
// nous mettons à jour notre pointeur
|
|
||||||
m_entity = newEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const EntityHandle& handle)
|
|
||||||
{
|
|
||||||
out << "EntityHandle(";
|
|
||||||
if (handle.IsValid())
|
|
||||||
out << "Entity(" << handle->GetId() << ')';
|
|
||||||
else
|
|
||||||
out << "Null entity";
|
|
||||||
|
|
||||||
out << ')';
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const EntityHandle& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return lhs.m_entity == rhs.m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const Entity& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return &lhs == rhs.m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const EntityHandle& lhs, const Entity& rhs)
|
|
||||||
{
|
|
||||||
return lhs.m_entity == &rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const Entity& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const EntityHandle& lhs, const Entity& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const EntityHandle& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return lhs.m_entity < rhs.m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const Entity& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return &lhs < rhs.m_entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(const EntityHandle& lhs, const Entity& rhs)
|
|
||||||
{
|
|
||||||
return lhs.m_entity < &rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs > rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const Entity& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs > rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const EntityHandle& lhs, const Entity& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs > rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const EntityHandle& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return rhs < lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const Entity& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return rhs < lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const EntityHandle& lhs, const Entity& rhs)
|
|
||||||
{
|
|
||||||
return rhs < lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs < rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const Entity& lhs, const EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs < rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const EntityHandle& lhs, const Entity& rhs)
|
|
||||||
{
|
|
||||||
return !(lhs < rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template<>
|
|
||||||
struct hash<Ndk::EntityHandle>
|
|
||||||
{
|
|
||||||
size_t operator()(const Ndk::EntityHandle& handle) const
|
|
||||||
{
|
|
||||||
// Hasher le pointeur fonctionnerait jusqu'à ce que l'entité soit mise à jour et déplacée
|
|
||||||
// pour cette raison, nous devons hasher l'ID de l'entité (qui reste constante)
|
|
||||||
Ndk::EntityId id = (handle.IsValid()) ? handle->GetId() : std::numeric_limits<Ndk::EntityId>::max();
|
|
||||||
|
|
||||||
return hash<Ndk::EntityId>()(id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs)
|
|
||||||
{
|
|
||||||
lhs.Swap(rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Nazara/Core/Bitset.hpp>
|
#include <Nazara/Core/Bitset.hpp>
|
||||||
#include <NDK/Prerequesites.hpp>
|
#include <NDK/Prerequesites.hpp>
|
||||||
#include <NDK/EntityHandle.hpp>
|
#include <NDK/Entity.hpp>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef NDK_ENTITYOWNER_HPP
|
#ifndef NDK_ENTITYOWNER_HPP
|
||||||
#define NDK_ENTITYOWNER_HPP
|
#define NDK_ENTITYOWNER_HPP
|
||||||
|
|
||||||
#include <NDK/EntityHandle.hpp>
|
#include <NDK/Entity.hpp>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,16 +26,16 @@ namespace Ndk
|
||||||
|
|
||||||
inline void EntityOwner::Reset(Entity* entity)
|
inline void EntityOwner::Reset(Entity* entity)
|
||||||
{
|
{
|
||||||
if (m_entity)
|
if (m_object)
|
||||||
m_entity->Kill();
|
m_object->Kill();
|
||||||
|
|
||||||
EntityHandle::Reset(entity);
|
EntityHandle::Reset(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void EntityOwner::Reset(EntityOwner&& handle)
|
inline void EntityOwner::Reset(EntityOwner&& handle)
|
||||||
{
|
{
|
||||||
Reset(handle.GetEntity());
|
Reset(handle.GetObject());
|
||||||
handle.m_entity = nullptr;
|
handle.m_object = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline EntityOwner& EntityOwner::operator=(Entity* entity)
|
inline EntityOwner& EntityOwner::operator=(Entity* entity)
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,13 @@
|
||||||
|
|
||||||
#include <NDK/Entity.hpp>
|
#include <NDK/Entity.hpp>
|
||||||
#include <NDK/BaseComponent.hpp>
|
#include <NDK/BaseComponent.hpp>
|
||||||
#include <NDK/EntityHandle.hpp>
|
|
||||||
#include <NDK/World.hpp>
|
#include <NDK/World.hpp>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
Entity::Entity(Entity&& entity) :
|
Entity::Entity(Entity&& entity) :
|
||||||
|
HandledObject(std::move(entity)),
|
||||||
m_components(std::move(entity.m_components)),
|
m_components(std::move(entity.m_components)),
|
||||||
m_handles(std::move(entity.m_handles)),
|
|
||||||
m_componentBits(std::move(entity.m_componentBits)),
|
m_componentBits(std::move(entity.m_componentBits)),
|
||||||
m_systemBits(std::move(entity.m_systemBits)),
|
m_systemBits(std::move(entity.m_systemBits)),
|
||||||
m_id(entity.m_id),
|
m_id(entity.m_id),
|
||||||
|
|
@ -19,8 +18,6 @@ namespace Ndk
|
||||||
m_enabled(entity.m_enabled),
|
m_enabled(entity.m_enabled),
|
||||||
m_valid(entity.m_valid)
|
m_valid(entity.m_valid)
|
||||||
{
|
{
|
||||||
for (EntityHandle* handle : m_handles)
|
|
||||||
handle->OnEntityMoved(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity::Entity(World* world, EntityId id) :
|
Entity::Entity(World* world, EntityId id) :
|
||||||
|
|
@ -63,11 +60,6 @@ namespace Ndk
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityHandle Entity::CreateHandle()
|
|
||||||
{
|
|
||||||
return EntityHandle(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Entity::Kill()
|
void Entity::Kill()
|
||||||
{
|
{
|
||||||
m_world->KillEntity(this);
|
m_world->KillEntity(this);
|
||||||
|
|
@ -132,11 +124,7 @@ namespace Ndk
|
||||||
}
|
}
|
||||||
m_systemBits.Clear();
|
m_systemBits.Clear();
|
||||||
|
|
||||||
// On informe chaque handle de notre destruction pour éviter qu'il ne continue de pointer sur nous
|
UnregisterAllHandles();
|
||||||
for (EntityHandle* handle : m_handles)
|
|
||||||
handle->OnEntityDestroyed();
|
|
||||||
|
|
||||||
m_handles.clear();
|
|
||||||
|
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
// 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
|
|
||||||
|
|
||||||
#include <NDK/EntityHandle.hpp>
|
|
||||||
|
|
||||||
namespace Ndk
|
|
||||||
{
|
|
||||||
const EntityHandle EntityHandle::InvalidHandle;
|
|
||||||
}
|
|
||||||
|
|
@ -61,7 +61,7 @@ namespace Ndk
|
||||||
|
|
||||||
void World::Clear() noexcept
|
void World::Clear() noexcept
|
||||||
{
|
{
|
||||||
///DOC: Tous les handles sont correctement invalidés
|
///DOC: Tous les handles sont correctement invalidés, les entités sont immédiatement invalidées
|
||||||
|
|
||||||
// Destruction des entités d'abord, et des handles ensuite
|
// Destruction des entités d'abord, et des handles ensuite
|
||||||
// ceci pour éviter que les handles n'informent les entités inutilement lors de leur destruction
|
// ceci pour éviter que les handles n'informent les entités inutilement lors de leur destruction
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// 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 NAZARA_OBJECTHANDLER_HPP
|
||||||
|
#define NAZARA_OBJECTHANDLER_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Core/Bitset.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template<typename T> class ObjectHandle;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class HandledObject
|
||||||
|
{
|
||||||
|
friend ObjectHandle<T>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HandledObject() = default;
|
||||||
|
HandledObject(const HandledObject& object);
|
||||||
|
HandledObject(HandledObject&& object);
|
||||||
|
~HandledObject();
|
||||||
|
|
||||||
|
ObjectHandle<T> CreateHandle();
|
||||||
|
|
||||||
|
HandledObject& operator=(const HandledObject& object);
|
||||||
|
HandledObject& operator=(HandledObject&& object);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void UnregisterAllHandles();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RegisterHandle(ObjectHandle<T>* handle);
|
||||||
|
void UnregisterHandle(ObjectHandle<T>* handle);
|
||||||
|
|
||||||
|
std::vector<ObjectHandle<T>*> m_handles;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Core/HandledObject.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_OBJECTHANDLER_HPP
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Core/ObjectHandle.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
HandledObject<T>::HandledObject(const HandledObject& object)
|
||||||
|
{
|
||||||
|
// Don't copy anything, we're a copy of the object, we have no handle right now
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
HandledObject<T>::HandledObject(HandledObject&& object) :
|
||||||
|
m_handles(std::move(object.m_handles))
|
||||||
|
{
|
||||||
|
for (ObjectHandle<T>* handle : m_handles)
|
||||||
|
handle->OnObjectMoved(static_cast<T*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
HandledObject<T>::~HandledObject()
|
||||||
|
{
|
||||||
|
UnregisterAllHandles();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T> HandledObject<T>::CreateHandle()
|
||||||
|
{
|
||||||
|
return ObjectHandle<T>(static_cast<T*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object)
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object)
|
||||||
|
{
|
||||||
|
m_handles = std::move(object.m_handles);
|
||||||
|
for (ObjectHandle<T>* handle : m_handles)
|
||||||
|
handle->OnObjectMoved(static_cast<T*>(this));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle)
|
||||||
|
{
|
||||||
|
///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois
|
||||||
|
m_handles.push_back(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void HandledObject<T>::UnregisterAllHandles()
|
||||||
|
{
|
||||||
|
// Tell every handle we got destroyed, to null them
|
||||||
|
for (ObjectHandle<T>* handle : m_handles)
|
||||||
|
handle->OnObjectDestroyed();
|
||||||
|
|
||||||
|
m_handles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle)
|
||||||
|
{
|
||||||
|
///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash
|
||||||
|
auto it = std::find(m_handles.begin(), m_handles.end(), handle);
|
||||||
|
NazaraAssert(it != m_handles.end(), "Handle not registred");
|
||||||
|
|
||||||
|
// On échange cet élément avec le dernier, et on diminue la taille du vector de 1
|
||||||
|
std::swap(*it, m_handles.back());
|
||||||
|
m_handles.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
// Copyright (C) 2015 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_OBJECTHANDLE_HPP
|
||||||
|
#define NAZARA_OBJECTHANDLE_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template<typename T> class HandledObject;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class ObjectHandle
|
||||||
|
{
|
||||||
|
friend HandledObject<T>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ObjectHandle();
|
||||||
|
explicit ObjectHandle(T* object);
|
||||||
|
ObjectHandle(const ObjectHandle& handle);
|
||||||
|
~ObjectHandle();
|
||||||
|
|
||||||
|
T* GetObject() const;
|
||||||
|
|
||||||
|
bool IsValid() const;
|
||||||
|
|
||||||
|
void Reset(T* object = nullptr);
|
||||||
|
void Reset(const ObjectHandle& handle);
|
||||||
|
|
||||||
|
ObjectHandle& Swap(ObjectHandle& handle);
|
||||||
|
|
||||||
|
Nz::String ToString() const;
|
||||||
|
|
||||||
|
operator bool() const;
|
||||||
|
operator T*() const;
|
||||||
|
T* operator->() const;
|
||||||
|
|
||||||
|
ObjectHandle& operator=(T* object);
|
||||||
|
ObjectHandle& operator=(const ObjectHandle& handle);
|
||||||
|
|
||||||
|
static const ObjectHandle InvalidHandle;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnObjectDestroyed();
|
||||||
|
void OnObjectMoved(T* newObject);
|
||||||
|
|
||||||
|
T* m_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle);
|
||||||
|
|
||||||
|
template<typename T> bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator==(const T& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator==(const ObjectHandle<T>& lhs, const T& rhs);
|
||||||
|
|
||||||
|
template<typename T> bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator!=(const T& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator!=(const ObjectHandle<T>& lhs, const T& rhs);
|
||||||
|
|
||||||
|
template<typename T> bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator<(const T& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator<(const ObjectHandle<T>& lhs, const T& rhs);
|
||||||
|
|
||||||
|
template<typename T> bool operator<=(const ObjectHandle<T>, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator<=(const T& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator<=(const ObjectHandle<T>& lhs, const T& rhs);
|
||||||
|
|
||||||
|
template<typename T> bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator>(const T& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator>(const ObjectHandle<T>& lhs, const T& rhs);
|
||||||
|
|
||||||
|
template<typename T> bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator>=(const T& lhs, const ObjectHandle<T>& rhs);
|
||||||
|
template<typename T> bool operator>=(const ObjectHandle<T>& lhs, const T& rhs);
|
||||||
|
|
||||||
|
template<typename T> struct PointedType<ObjectHandle<T>> { typedef T type; };
|
||||||
|
template<typename T> struct PointedType<const ObjectHandle<T>> { typedef T type; };
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Core/ObjectHandle.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_OBJECTHANDLE_HPP
|
||||||
|
|
@ -0,0 +1,280 @@
|
||||||
|
// Copyright (C) 2015 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Core/ObjectHandle.hpp>
|
||||||
|
#include <Nazara/Core/StringStream.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>::ObjectHandle() :
|
||||||
|
m_object(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>::ObjectHandle(T* object) :
|
||||||
|
ObjectHandle()
|
||||||
|
{
|
||||||
|
Reset(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>::ObjectHandle(const ObjectHandle<T>& handle) :
|
||||||
|
ObjectHandle()
|
||||||
|
{
|
||||||
|
Reset(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>::~ObjectHandle()
|
||||||
|
{
|
||||||
|
Reset(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* ObjectHandle<T>::GetObject() const
|
||||||
|
{
|
||||||
|
return m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool ObjectHandle<T>::IsValid() const
|
||||||
|
{
|
||||||
|
return m_object != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ObjectHandle<T>::Reset(T* object)
|
||||||
|
{
|
||||||
|
// Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle
|
||||||
|
if (m_object)
|
||||||
|
m_object->UnregisterHandle(this);
|
||||||
|
|
||||||
|
m_object = object;
|
||||||
|
if (m_object)
|
||||||
|
// On informe la nouvelle entité que nous pointons sur elle
|
||||||
|
m_object->RegisterHandle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ObjectHandle<T>::Reset(const ObjectHandle<T>& handle)
|
||||||
|
{
|
||||||
|
Reset(handle.GetObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle)
|
||||||
|
{
|
||||||
|
// Comme nous inversons les handles, nous devons prévenir les entités
|
||||||
|
// La version par défaut de swap (à base de move) aurait fonctionné,
|
||||||
|
// mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire).
|
||||||
|
if (m_object)
|
||||||
|
{
|
||||||
|
m_object->UnregisterHandle(this);
|
||||||
|
m_object->RegisterHandle(&handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle.m_object)
|
||||||
|
{
|
||||||
|
handle.m_object->UnregisterHandle(&handle);
|
||||||
|
handle.m_object->RegisterHandle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On effectue l'échange
|
||||||
|
std::swap(m_object, handle.m_object);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Nz::String ObjectHandle<T>::ToString() const
|
||||||
|
{
|
||||||
|
Nz::StringStream ss;
|
||||||
|
ss << "ObjectHandle(";
|
||||||
|
if (IsValid())
|
||||||
|
ss << m_object->ToString();
|
||||||
|
else
|
||||||
|
ss << "Null";
|
||||||
|
|
||||||
|
ss << ')';
|
||||||
|
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>::operator bool() const
|
||||||
|
{
|
||||||
|
return IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>::operator T*() const
|
||||||
|
{
|
||||||
|
return m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* ObjectHandle<T>::operator->() const
|
||||||
|
{
|
||||||
|
return m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity)
|
||||||
|
{
|
||||||
|
Reset(entity);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle<T>& handle)
|
||||||
|
{
|
||||||
|
Reset(handle);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ObjectHandle<T>::OnObjectDestroyed()
|
||||||
|
{
|
||||||
|
// Shortcut
|
||||||
|
m_object = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ObjectHandle<T>::OnObjectMoved(T* newObject)
|
||||||
|
{
|
||||||
|
// The object has been moved, update our pointer
|
||||||
|
m_object = newObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle)
|
||||||
|
{
|
||||||
|
return handle.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return lhs.GetObject() == rhs.GetObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return &lhs == rhs.GetObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
|
{
|
||||||
|
return lhs.GetObject() == &rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator!=(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator!=(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_object < rhs.m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator<(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return &lhs < rhs.m_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator<(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_object < &rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs > rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator<=(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs > rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator<=(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs > rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator>(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator>(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator>=(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator>=(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
const ObjectHandle<T> ObjectHandle<T>::InvalidHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs)
|
||||||
|
{
|
||||||
|
lhs.Swap(rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue