Compare commits

...

1 Commits

Author SHA1 Message Date
Jace 36477abc63 WTF? 2016-03-08 18:26:03 +01:00
10 changed files with 87 additions and 53 deletions
-6
View File
@@ -5,12 +5,6 @@
#include "Entity.h" #include "Entity.h"
#include <boost/shared_array.hpp> #include <boost/shared_array.hpp>
enum class DirtySet
{
Transform,
Network
};
struct ComponentInfo struct ComponentInfo
{ {
typedef int EnumType; typedef int EnumType;
+10 -7
View File
@@ -5,16 +5,15 @@
#include "MemoryPool.h" #include "MemoryPool.h"
#include "ComponentInfo.h" #include "ComponentInfo.h"
#include "ComponentWrapper.h" #include "ComponentWrapper.h"
#include "DirtySet.h"
class ComponentPool;
class ComponentPoolForwardIterator class ComponentPoolForwardIterator
: public std::iterator<std::forward_iterator_tag, ComponentWrapper> : public std::iterator<std::forward_iterator_tag, ComponentWrapper>
{ {
public: public:
ComponentPoolForwardIterator(const ComponentInfo& componentInfo, const MemoryPool<char>::iterator begin, const MemoryPool<char>::iterator end) ComponentPoolForwardIterator(ComponentPool* pool);
: m_ComponentInfo(componentInfo)
, m_MemoryPoolIterator(begin)
, m_MemoryPoolEnd(end)
{ }
ComponentPoolForwardIterator(const ComponentPoolForwardIterator& other) = default; ComponentPoolForwardIterator(const ComponentPoolForwardIterator& other) = default;
ComponentPoolForwardIterator(ComponentPoolForwardIterator&& other) = default; ComponentPoolForwardIterator(ComponentPoolForwardIterator&& other) = default;
@@ -27,6 +26,7 @@ public:
ComponentWrapper operator*() const; ComponentWrapper operator*() const;
private: private:
ComponentPool* m_ComponentPool;
const ComponentInfo& m_ComponentInfo; const ComponentInfo& m_ComponentInfo;
MemoryPool<char>::iterator m_MemoryPoolIterator; MemoryPool<char>::iterator m_MemoryPoolIterator;
const MemoryPool<char>::iterator m_MemoryPoolEnd; const MemoryPool<char>::iterator m_MemoryPoolEnd;
@@ -34,6 +34,7 @@ private:
class ComponentPool class ComponentPool
{ {
friend class ComponentPoolForwardIterator;
public: public:
typedef ComponentPoolForwardIterator iterator; typedef ComponentPoolForwardIterator iterator;
typedef ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
@@ -41,6 +42,7 @@ public:
typedef ComponentWrapper value_type; typedef ComponentWrapper value_type;
typedef ComponentWrapper* pointer; typedef ComponentWrapper* pointer;
typedef ComponentWrapper& reference; typedef ComponentWrapper& reference;
typedef std::unordered_map<EntityID, std::set<decltype(ComponentInfo::Field_t::Index)>> DirtySet_t;
ComponentPool(const ::ComponentInfo& ci) ComponentPool(const ::ComponentInfo& ci)
: m_ComponentInfo(ci) : m_ComponentInfo(ci)
@@ -61,8 +63,8 @@ public:
// Delete a component and free its memory // Delete a component and free its memory
void Delete(ComponentWrapper& wrapper); void Delete(ComponentWrapper& wrapper);
iterator begin() const; iterator begin();
iterator end() const; iterator end();
size_t size() const; size_t size() const;
//Dumps information about what the pool memory looks like right now //Dumps information about what the pool memory looks like right now
@@ -80,6 +82,7 @@ private:
::ComponentInfo m_ComponentInfo; ::ComponentInfo m_ComponentInfo;
MemoryPool<char> m_Pool; MemoryPool<char> m_Pool;
std::unordered_map<EntityID, char*> m_EntityToComponent; std::unordered_map<EntityID, char*> m_EntityToComponent;
DirtySet m_DirtySet;
}; };
#endif #endif
+38 -28
View File
@@ -6,42 +6,52 @@
#include "../Common.h" #include "../Common.h"
#include "Entity.h" #include "Entity.h"
#include "ComponentInfo.h" #include "ComponentInfo.h"
#include "DirtySet.h"
#include "Util/Any.h" #include "Util/Any.h"
template <typename T, typename Enable = void>
struct ComponentField { };
template <typename T>
struct ComponentField<T, typename std::enable_if<std::is_trivially_copyable<T>::value>::type>
{
static T& Get(const ComponentInfo::Field_t& info, char* data) { return *reinterpret_cast<T*>(data); }
static void Set(const ComponentInfo::Field_t& info, char* data, const T& value) { Get(data) = value; }
};
template <>
struct ComponentField<std::string, void>
{
static std::string& Get(const ComponentInfo::Field_t& info, char* data) { return **reinterpret_cast<std::string**>(data); }
static void Set(const ComponentInfo::Field_t& info, char* data, const std::string& value) { Get(info, data) = value; }
};
struct ComponentWrapper struct ComponentWrapper
{ {
ComponentWrapper(const ComponentInfo& componentInfo, char* data) ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField)
: Info(componentInfo) : Info(componentInfo)
, EntityID(*reinterpret_cast<::EntityID*>(data)) , EntityID(*reinterpret_cast<::EntityID*>(data))
, Data(data + componentInfo.GetHeaderSize()) , Data(data + componentInfo.GetHeaderSize())
, DirtyBitField(dirtyBitField)
{ } { }
const ComponentInfo& Info; const ComponentInfo& Info;
const ::EntityID EntityID; const ::EntityID EntityID;
char* Data; char* Data;
::DirtyBitField* DirtyBitField = nullptr;
ComponentInfo::EnumType Enum(const char* fieldName, const char* enumKey) ComponentInfo::EnumType Enum(const char* fieldName, const char* enumKey)
{ {
return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey); return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey);
} }
bool Dirty(DirtySetType type, const std::string& fieldName)
{
if (DirtyBitField == nullptr) {
return true;
} else {
auto& field = Info.Fields.at(fieldName);
return DirtyBitField->operator[](type).count(field.Index) == 1;
}
}
void SetDirty(DirtySetType type, const std::string& fieldName, bool dirty = true)
{
if (DirtyBitField == nullptr) {
return;
}
auto& field = Info.Fields.at(fieldName);
if (dirty) {
DirtyBitField->operator[](type).insert(field.Index);
} else {
DirtyBitField->operator[](type).erase(field.Index);
}
}
template <typename T> template <typename T>
T& Field(const std::string& name) T& Field(const std::string& name)
{ {
@@ -96,32 +106,32 @@ struct ComponentWrapper
{ {
friend struct ComponentWrapper; friend struct ComponentWrapper;
private: private:
SubscriptProxy(ComponentWrapper* component, std::string propertyName) SubscriptProxy(ComponentWrapper* component, std::string fieldName)
: m_Component(component) : m_Component(component)
, m_PropertyName(propertyName) , m_FieldName(fieldName)
{ } { }
ComponentWrapper* m_Component; ComponentWrapper* m_Component;
std::string m_PropertyName; std::string m_FieldName;
public: public:
// Return the integer value of an enum type key for this field // Return the integer value of an enum type key for this field
ComponentInfo::EnumType Enum(const char* enumKey) { return m_Component->Enum(m_PropertyName.c_str(), enumKey); } ComponentInfo::EnumType Enum(const char* enumKey) { return m_Component->Enum(m_FieldName.c_str(), enumKey); }
bool Dirty(DirtySet set) { return true; } bool Dirty(DirtySetType type) { return m_Component->Dirty(type, m_FieldName); }
void SetDirty(bool dirty = true) { } void SetDirty(DirtySetType type, bool dirty = true) { m_Component->SetDirty(type, m_FieldName, dirty); }
template <typename T> template <typename T>
operator T&() { return m_Component->Field<T>(m_PropertyName); } operator T&() { return m_Component->Field<T>(m_FieldName); }
template <typename T> template <typename T>
void operator=(const T val) { m_Component->SetField<T>(m_PropertyName, val); } void operator=(const T val) { m_Component->SetField<T>(m_FieldName, val); }
// TODO: Pass by reference and rvalue (universal reference?) // TODO: Pass by reference and rvalue (universal reference?)
//template <typename T> //template <typename T>
//void operator=(T& val) { m_Component->SetField<T>(m_PropertyName, val); } //void operator=(T& val) { m_Component->SetField<T>(m_PropertyName, val); }
// Specialization for string literals // Specialization for string literals
template <std::size_t N> template <std::size_t N>
void operator=(const char(&val)[N]) { m_Component->SetField<N>(m_PropertyName, val); } void operator=(const char(&val)[N]) { m_Component->SetField<N>(m_FieldName, val); }
}; };
SubscriptProxy operator[](const std::string& propertyName) { return SubscriptProxy(this, propertyName); } SubscriptProxy operator[](const std::string& propertyName) { return SubscriptProxy(this, propertyName); }
}; };
@@ -130,7 +140,7 @@ struct ComponentWrapper
struct SharedComponentWrapper : ComponentWrapper struct SharedComponentWrapper : ComponentWrapper
{ {
SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data) SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data)
: ComponentWrapper(componentInfo, data.get()) : ComponentWrapper(componentInfo, data.get(), nullptr)
, m_DataReference(data) , m_DataReference(data)
{ } { }
+16
View File
@@ -0,0 +1,16 @@
#ifndef DirtySet_h__
#define DirtySet_h__
#include <set>
#include "ComponentInfo.h"
enum class DirtySetType
{
Transform,
Network
};
typedef std::unordered_map<DirtySetType, std::set<decltype(ComponentInfo::Field_t::Index)>> DirtyBitField;
typedef std::unordered_map<EntityID, DirtyBitField> DirtySet;
#endif
+1 -1
View File
@@ -81,7 +81,7 @@ public:
for (auto& pair : group.PureSystems) { for (auto& pair : group.PureSystems) {
const std::string& componentName = pair.first; const std::string& componentName = pair.first;
auto& systems = pair.second; auto& systems = pair.second;
const ComponentPool* pool = m_World->GetComponents(componentName); ComponentPool* pool = m_World->GetComponents(componentName);
if (pool == nullptr) { if (pool == nullptr) {
continue; continue;
} }
+1 -1
View File
@@ -35,7 +35,7 @@ public:
// Delete a component off an entity // Delete a component off an entity
void DeleteComponent(EntityID entity, const std::string& componentType); void DeleteComponent(EntityID entity, const std::string& componentType);
// Get all components of the specified type // Get all components of the specified type
const ComponentPool* GetComponents(const std::string& componentType); ComponentPool* GetComponents(const std::string& componentType);
// Get entity parent // Get entity parent
EntityID GetParent(EntityID entity); EntityID GetParent(EntityID entity);
// Change the parent of an entity // Change the parent of an entity
+18 -7
View File
@@ -1,9 +1,17 @@
#include "Core/ComponentPool.h" #include "Core/ComponentPool.h"
ComponentPoolForwardIterator::ComponentPoolForwardIterator(ComponentPool* pool)
: m_ComponentPool(pool)
, m_ComponentInfo(pool->m_ComponentInfo)
, m_MemoryPoolIterator(pool->m_Pool.begin())
, m_MemoryPoolEnd(pool->m_Pool.end())
{ }
ComponentWrapper ComponentPoolForwardIterator::operator*() const ComponentWrapper ComponentPoolForwardIterator::operator*() const
{ {
char* data = &(*m_MemoryPoolIterator); char* data = &(*m_MemoryPoolIterator);
ComponentWrapper wrapper(m_ComponentInfo, data); EntityID entity = *reinterpret_cast<EntityID*>(data);
ComponentWrapper wrapper(m_ComponentInfo, data, &m_ComponentPool->m_DirtySet[entity]);
return wrapper; return wrapper;
} }
@@ -71,7 +79,7 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity)
memcpy(data, &entity, sizeof(EntityID)); memcpy(data, &entity, sizeof(EntityID));
m_EntityToComponent[entity] = data; m_EntityToComponent[entity] = data;
ComponentWrapper component(m_ComponentInfo, data); ComponentWrapper component(m_ComponentInfo, data, &m_DirtySet[entity]);
// Copy defaults // Copy defaults
memcpy(component.Data, m_ComponentInfo.Defaults.get(), m_ComponentInfo.Stride); memcpy(component.Data, m_ComponentInfo.Defaults.get(), m_ComponentInfo.Stride);
@@ -82,7 +90,9 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity)
ComponentWrapper ComponentPool::GetByEntity(EntityID ent) ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
{ {
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent)); auto data = m_EntityToComponent.at(ent);
auto bitField = &m_DirtySet[ent];
return ComponentWrapper(m_ComponentInfo, data, bitField);
} }
bool ComponentPool::KnowsEntity(EntityID ent) bool ComponentPool::KnowsEntity(EntityID ent)
@@ -95,16 +105,17 @@ void ComponentPool::Delete(ComponentWrapper& wrapper)
ComponentWrapper::Destroy(wrapper.Info, wrapper.Data); ComponentWrapper::Destroy(wrapper.Info, wrapper.Data);
m_EntityToComponent.erase(wrapper.EntityID); m_EntityToComponent.erase(wrapper.EntityID);
m_Pool.Free(wrapper.Data - sizeof(EntityID)); m_Pool.Free(wrapper.Data - sizeof(EntityID));
m_DirtySet.erase(wrapper.EntityID);
} }
ComponentPool::iterator ComponentPool::begin() const ComponentPool::iterator ComponentPool::begin()
{ {
return iterator(m_ComponentInfo, m_Pool.begin(), m_Pool.end()); return iterator(this);
} }
ComponentPool::iterator ComponentPool::end() const ComponentPool::iterator ComponentPool::end()
{ {
return iterator(m_ComponentInfo, m_Pool.end(), m_Pool.end()); return iterator(this);
} }
size_t ComponentPool::size() const size_t ComponentPool::size() const
+1 -1
View File
@@ -95,7 +95,7 @@ void World::DeleteComponent(EntityID entity, const std::string& componentType)
} }
} }
const ComponentPool* World::GetComponents(const std::string& componentType) ComponentPool* World::GetComponents(const std::string& componentType)
{ {
auto it = m_ComponentPools.find(componentType); auto it = m_ComponentPools.find(componentType);
return (it != m_ComponentPools.end()) ? it->second : nullptr; return (it != m_ComponentPools.end()) ? it->second : nullptr;
+1 -1
View File
@@ -29,7 +29,7 @@ void PlayerMovementSystem::Update(double dt)
return; return;
} }
m_SprintEffectTimer = 0.f; m_SprintEffectTimer = 0.f;
const ComponentPool* pool = m_World->GetComponents("SprintAbility"); auto pool = m_World->GetComponents("SprintAbility");
if (pool == nullptr) { if (pool == nullptr) {
return; return;
} }
+1 -1
View File
@@ -86,7 +86,7 @@ bool SpawnerSystem::spawnedEntityIsColliding(EntityWrapper spawnedEntity, Entity
transformEntityToSpawnPoint(spawnedEntity, spawnPoint); transformEntityToSpawnPoint(spawnedEntity, spawnPoint);
//Check if the spawned entity collides with anything, and if so, continue to the next spawnpoint. //Check if the spawned entity collides with anything, and if so, continue to the next spawnpoint.
EntityAABB spawnedBox = *Collision::EntityAbsoluteAABB(spawnedEntity); EntityAABB spawnedBox = *Collision::EntityAbsoluteAABB(spawnedEntity);
const ComponentPool* otherSpawnedEntities = spawnPoint.World->GetComponents(dontCollideComponent); auto otherSpawnedEntities = spawnPoint.World->GetComponents(dontCollideComponent);
for (const auto& obj : *otherSpawnedEntities) { for (const auto& obj : *otherSpawnedEntities) {
if (spawnedEntity.ID == obj.EntityID) { if (spawnedEntity.ID == obj.EntityID) {
continue; continue;