Implemented ComponentPool and initial tests for it

This commit is contained in:
sippeangelo
2015-12-02 15:07:48 +01:00
parent 8aa72735e7
commit b3e68c6c34
8 changed files with 212 additions and 21 deletions
+8 -1
View File
@@ -1,3 +1,6 @@
#ifndef ComponentInfo_h__
#define ComponentInfo_h__
#include "../Common.h" #include "../Common.h"
struct ComponentInfo struct ComponentInfo
@@ -5,11 +8,15 @@ struct ComponentInfo
struct Meta_t struct Meta_t
{ {
std::string Annotation; std::string Annotation;
int Allocation = 0; unsigned int Allocation = 0;
unsigned int Stride = 0;
}; };
std::string Name; std::string Name;
std::unordered_map<std::string, std::string> FieldTypes; std::unordered_map<std::string, std::string> FieldTypes;
std::unordered_map<std::string, unsigned int> FieldOffsets; std::unordered_map<std::string, unsigned int> FieldOffsets;
Meta_t Meta; Meta_t Meta;
std::shared_ptr<char*> Defaults = nullptr;
}; };
#endif
+119 -1
View File
@@ -1,7 +1,125 @@
#ifndef ComponentPool_h__
#define ComponentPool_h__
#include "MemoryPool.h"
#include "ComponentInfo.h"
#include "ComponentWrapper.h"
class ComponentPoolForwardIterator
: public std::iterator<std::forward_iterator_tag, ComponentWrapper>
{
public:
ComponentPoolForwardIterator(const ComponentInfo& componentInfo, const MemoryPool<char>::iterator begin, const MemoryPool<char>::iterator end)
: m_ComponentInfo(componentInfo)
, m_MemoryPoolIterator(begin)
, m_MemoryPoolEnd(end)
{ }
ComponentPoolForwardIterator(const ComponentPoolForwardIterator& other) = default;
ComponentPoolForwardIterator(ComponentPoolForwardIterator&& other) = default;
~ComponentPoolForwardIterator() = default;
ComponentPoolForwardIterator& operator= (const ComponentPoolForwardIterator& other) = default;
ComponentPoolForwardIterator& operator++()
{
++m_MemoryPoolIterator;
return *this;
}
ComponentPoolForwardIterator& operator++(int)
{
ComponentPoolForwardIterator copyIter(*this);
operator++();
return copyIter;
}
bool operator!= (const ComponentPoolForwardIterator& other) const
{
return m_MemoryPoolIterator != other.m_MemoryPoolIterator;
}
bool operator== (const ComponentPoolForwardIterator& other) const
{
return m_MemoryPoolIterator == other.m_MemoryPoolIterator;
}
ComponentWrapper operator* () const
{
char* data = &(*m_MemoryPoolIterator);
ComponentWrapper wrapper(m_ComponentInfo, data);
return wrapper;
}
//ComponentWrapper* operator-> () const
//{
// return &(*m_MemoryPoolIterator);
//}
private:
const ComponentInfo& m_ComponentInfo;
MemoryPool<char>::iterator m_MemoryPoolIterator;
const MemoryPool<char>::iterator m_MemoryPoolEnd;
};
class ComponentPool class ComponentPool
{ {
public: public:
ComponentPool() { } typedef ComponentPoolForwardIterator iterator;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef ComponentWrapper value_type;
typedef ComponentWrapper* pointer;
typedef ComponentWrapper& reference;
ComponentPool(const ComponentInfo& ci)
: m_ComponentInfo(ci)
, m_Pool(ci.Meta.Allocation, ci.Meta.Stride)
{ }
ComponentPool(const ComponentPool& other) = delete;
ComponentPool(const ComponentPool&& other) = delete;
ComponentWrapper New()
{
char* data = m_Pool.Allocate();
return ComponentWrapper(m_ComponentInfo, data);
}
void Delete(ComponentWrapper& component)
{
m_Pool.Free(component.Data);
}
iterator begin() const
{
return iterator(m_ComponentInfo, m_Pool.begin(), m_Pool.end());
}
iterator end() const
{
return iterator(m_ComponentInfo, m_Pool.end(), m_Pool.end());
}
//Dumps information about what the pool memory looks like right now
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
//Interpret the data in the memory as InterpretType.
template <typename InterpretType = char, typename OutStream>
void Dump(OutStream& out) const
{
m_Pool.Dump<InterpretType>(out);
}
//Dumps information about what the pool memory looks like right now
//into std::cout. Interpret the data in the memory as InterpretType.
template <typename InterpretType = char>
void Dump() const
{
m_Pool.Dump<InterpretType>();
}
private:
const ComponentInfo m_ComponentInfo;
MemoryPool<char> m_Pool;
}; };
#endif
@@ -2,24 +2,25 @@
#define Component_h__ #define Component_h__
#include "../Common.h" #include "../Common.h"
#include "Entity.h"
#include "ComponentInfo.h" #include "ComponentInfo.h"
struct Component struct ComponentWrapper
{ {
Component(const unsigned int entityID, const ComponentInfo* componentInfo, char* data) ComponentWrapper(const ComponentInfo& componentInfo, char* data)
: EntityID(entityID) : EntityID(*reinterpret_cast<::EntityID*>(data))
, Info(componentInfo) , Info(componentInfo)
, Data(data) , Data(data)
{ } { }
const unsigned int EntityID; ::EntityID& EntityID;
const ComponentInfo* Info; const ComponentInfo& Info;
char* Data; char* Data;
template <typename T> template <typename T>
T& Property(std::string name) T& Property(std::string name)
{ {
unsigned int offset=Info->FieldOffsets.at(name); unsigned int offset = Info.FieldOffsets.at(name);
return *reinterpret_cast<T*>(&Data[offset]); return *reinterpret_cast<T*>(&Data[offset]);
} }
@@ -34,14 +35,14 @@ struct Component
struct SubscriptProxy struct SubscriptProxy
{ {
friend struct Component; friend struct ComponentWrapper;
private: private:
SubscriptProxy(Component* component, std::string& propertyName) SubscriptProxy(ComponentWrapper* component, std::string& propertyName)
: m_Component(component) : m_Component(component)
, m_PropertyName(propertyName) , m_PropertyName(propertyName)
{ } { }
Component* m_Component; ComponentWrapper* m_Component;
std::string& m_PropertyName; std::string& m_PropertyName;
public: public:
@@ -28,7 +28,7 @@
#include <xercesc/framework/XMLValidator.hpp> #include <xercesc/framework/XMLValidator.hpp>
#include "Entity.h" #include "Entity.h"
#include "Component.h" #include "ComponentWrapper.h"
class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler
{ {
@@ -111,17 +111,17 @@ struct ComponentPool
char* Data = nullptr; char* Data = nullptr;
// TODO: Iterators // TODO: Iterators
Component at(unsigned int index) ComponentWrapper at(unsigned int index)
{ {
// TODO: EntityID // TODO: EntityID
return Component(0, &Info, Data + (index*Stride)); return ComponentWrapper(0, &Info, Data + (index*Stride));
} }
}; };
class EntityParser class EntityFactory
{ {
public: public:
EntityParser(std::string entityFile) EntityFactory(std::string entityFile)
: m_EntityFile(entityFile) : m_EntityFile(entityFile)
{ {
using namespace xercesc; using namespace xercesc;
@@ -147,7 +147,7 @@ public:
m_DOMParser->cacheGrammarFromParse(true); m_DOMParser->cacheGrammarFromParse(true);
} }
~EntityParser() ~EntityFactory()
{ {
using namespace xercesc; using namespace xercesc;
@@ -344,6 +344,7 @@ private:
fieldOffset += getTypeStride(type); fieldOffset += getTypeStride(type);
} }
compInfo.Meta.Stride = fieldOffset;
m_ComponentInfo[compInfo.Name] = compInfo; m_ComponentInfo[compInfo.Name] = compInfo;
} }
} }
@@ -476,4 +477,4 @@ private:
} }
}; };
unsigned int EntityParser::InstanceCount = 0; unsigned int EntityFactory::InstanceCount = 0;
+12
View File
@@ -0,0 +1,12 @@
#include "ResourceManager.h"
class EntityFile : public Resource
{
friend class ResourceManager;
private:
EntityFile(std::string path);
public:
};
+1
View File
@@ -32,6 +32,7 @@ public:
typedef T value_type; typedef T value_type;
typedef T* pointer; typedef T* pointer;
typedef T& reference; typedef T& reference;
MemoryPool() MemoryPool()
: m_StartAddress(nullptr) : m_StartAddress(nullptr)
, m_SlotIsAllocated() , m_SlotIsAllocated()
+22
View File
@@ -1,3 +1,9 @@
#ifndef World_h__
#define World_h__
#include "../Common.h"
#include "Entity.h"
#include "ComponentPool.h"
class World class World
{ {
@@ -7,5 +13,21 @@ public:
} }
~World()
{
// foreach (m_ComponentPools...
}
void AllocateComponentPool(ComponentInfo& ci)
{
auto pool = new ComponentPool(ci);
m_ComponentPools[ci.Name] = pool;
}
void AddComponent(EntityID entity, std::string componentType);
private: private:
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
}; };
#endif
+29
View File
@@ -0,0 +1,29 @@
#include <boost/test/unit_test.hpp>
#include "Core/ComponentPool.h"
BOOST_AUTO_TEST_CASE(ComponentPoolTest)
{
ComponentInfo ci;
ci.Name = "Test";
ci.FieldTypes["Field"] = "int";
ci.FieldOffsets["Field"] = sizeof(EntityID);
ci.Meta.Allocation = 4;
ci.Meta.Stride = sizeof(EntityID) + sizeof(int);
ComponentPool pool(ci);
for (int i = 0; i < 3; i++) {
ComponentWrapper c = pool.New();
c.EntityID = i;
unsigned int offset = c.Info.FieldOffsets.at("Field");
memcpy(&c.Data[offset], &i, sizeof(int));
}
int i = 0;
for (auto& c : pool) {
BOOST_CHECK(c.EntityID == i);
int field = c.Property<int>("Field");
BOOST_CHECK(field == i);
i++;
}
}