diff --git a/include/Engine/Core/ComponentInfo.h b/include/Engine/Core/ComponentInfo.h index 42ed7957..6453bf32 100644 --- a/include/Engine/Core/ComponentInfo.h +++ b/include/Engine/Core/ComponentInfo.h @@ -1,3 +1,6 @@ +#ifndef ComponentInfo_h__ +#define ComponentInfo_h__ + #include "../Common.h" struct ComponentInfo @@ -5,11 +8,15 @@ struct ComponentInfo struct Meta_t { std::string Annotation; - int Allocation = 0; + unsigned int Allocation = 0; + unsigned int Stride = 0; }; std::string Name; std::unordered_map FieldTypes; std::unordered_map FieldOffsets; Meta_t Meta; -}; \ No newline at end of file + std::shared_ptr Defaults = nullptr; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Core/ComponentPool.h b/include/Engine/Core/ComponentPool.h index d3f108dc..fe1c00db 100644 --- a/include/Engine/Core/ComponentPool.h +++ b/include/Engine/Core/ComponentPool.h @@ -1,7 +1,125 @@ +#ifndef ComponentPool_h__ +#define ComponentPool_h__ + +#include "MemoryPool.h" +#include "ComponentInfo.h" +#include "ComponentWrapper.h" + +class ComponentPoolForwardIterator + : public std::iterator +{ +public: + ComponentPoolForwardIterator(const ComponentInfo& componentInfo, const MemoryPool::iterator begin, const MemoryPool::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::iterator m_MemoryPoolIterator; + const MemoryPool::iterator m_MemoryPoolEnd; +}; + class ComponentPool { 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) + { } -}; \ No newline at end of file + 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 + void Dump(OutStream& out) const + { + m_Pool.Dump(out); + } + + //Dumps information about what the pool memory looks like right now + //into std::cout. Interpret the data in the memory as InterpretType. + template + void Dump() const + { + m_Pool.Dump(); + } + +private: + const ComponentInfo m_ComponentInfo; + MemoryPool m_Pool; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Core/Component.h b/include/Engine/Core/ComponentWrapper.h similarity index 77% rename from include/Engine/Core/Component.h rename to include/Engine/Core/ComponentWrapper.h index 3093f35f..3694336b 100644 --- a/include/Engine/Core/Component.h +++ b/include/Engine/Core/ComponentWrapper.h @@ -2,24 +2,25 @@ #define Component_h__ #include "../Common.h" +#include "Entity.h" #include "ComponentInfo.h" -struct Component +struct ComponentWrapper { - Component(const unsigned int entityID, const ComponentInfo* componentInfo, char* data) - : EntityID(entityID) + ComponentWrapper(const ComponentInfo& componentInfo, char* data) + : EntityID(*reinterpret_cast<::EntityID*>(data)) , Info(componentInfo) , Data(data) { } - const unsigned int EntityID; - const ComponentInfo* Info; + ::EntityID& EntityID; + const ComponentInfo& Info; char* Data; template T& Property(std::string name) { - unsigned int offset=Info->FieldOffsets.at(name); + unsigned int offset = Info.FieldOffsets.at(name); return *reinterpret_cast(&Data[offset]); } @@ -34,14 +35,14 @@ struct Component struct SubscriptProxy { - friend struct Component; + friend struct ComponentWrapper; private: - SubscriptProxy(Component* component, std::string& propertyName) + SubscriptProxy(ComponentWrapper* component, std::string& propertyName) : m_Component(component) , m_PropertyName(propertyName) { } - Component* m_Component; + ComponentWrapper* m_Component; std::string& m_PropertyName; public: diff --git a/include/Engine/Core/EntityParser.h b/include/Engine/Core/EntityFactory.h similarity index 98% rename from include/Engine/Core/EntityParser.h rename to include/Engine/Core/EntityFactory.h index cfce9bc9..39a9ab02 100644 --- a/include/Engine/Core/EntityParser.h +++ b/include/Engine/Core/EntityFactory.h @@ -28,7 +28,7 @@ #include #include "Entity.h" -#include "Component.h" +#include "ComponentWrapper.h" class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler { @@ -111,17 +111,17 @@ struct ComponentPool char* Data = nullptr; // TODO: Iterators - Component at(unsigned int index) + ComponentWrapper at(unsigned int index) { // TODO: EntityID - return Component(0, &Info, Data + (index*Stride)); + return ComponentWrapper(0, &Info, Data + (index*Stride)); } }; -class EntityParser +class EntityFactory { public: - EntityParser(std::string entityFile) + EntityFactory(std::string entityFile) : m_EntityFile(entityFile) { using namespace xercesc; @@ -147,7 +147,7 @@ public: m_DOMParser->cacheGrammarFromParse(true); } - ~EntityParser() + ~EntityFactory() { using namespace xercesc; @@ -344,6 +344,7 @@ private: fieldOffset += getTypeStride(type); } + compInfo.Meta.Stride = fieldOffset; m_ComponentInfo[compInfo.Name] = compInfo; } } @@ -476,4 +477,4 @@ private: } }; -unsigned int EntityParser::InstanceCount = 0; \ No newline at end of file +unsigned int EntityFactory::InstanceCount = 0; \ No newline at end of file diff --git a/include/Engine/Core/EntityFile.h b/include/Engine/Core/EntityFile.h new file mode 100644 index 00000000..7fa423d6 --- /dev/null +++ b/include/Engine/Core/EntityFile.h @@ -0,0 +1,12 @@ +#include "ResourceManager.h" + +class EntityFile : public Resource +{ + friend class ResourceManager; + +private: + EntityFile(std::string path); + +public: + +}; \ No newline at end of file diff --git a/include/Engine/Core/MemoryPool.h b/include/Engine/Core/MemoryPool.h index 8fba0845..f0579ded 100644 --- a/include/Engine/Core/MemoryPool.h +++ b/include/Engine/Core/MemoryPool.h @@ -32,6 +32,7 @@ public: typedef T value_type; typedef T* pointer; typedef T& reference; + MemoryPool() : m_StartAddress(nullptr) , m_SlotIsAllocated() diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index 7a349d24..0eac4550 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -1,3 +1,9 @@ +#ifndef World_h__ +#define World_h__ + +#include "../Common.h" +#include "Entity.h" +#include "ComponentPool.h" 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: -}; \ No newline at end of file + std::unordered_map m_ComponentPools; +}; + +#endif \ No newline at end of file diff --git a/src/Tests/ComponentPoolTest.cpp b/src/Tests/ComponentPoolTest.cpp new file mode 100644 index 00000000..b4fca331 --- /dev/null +++ b/src/Tests/ComponentPoolTest.cpp @@ -0,0 +1,29 @@ +#include + +#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("Field"); + BOOST_CHECK(field == i); + i++; + } +} \ No newline at end of file