diff --git a/include/Engine/Core/ComponentPool.h b/include/Engine/Core/ComponentPool.h index b294f44a..44709c60 100644 --- a/include/Engine/Core/ComponentPool.h +++ b/include/Engine/Core/ComponentPool.h @@ -43,9 +43,10 @@ public: typedef ComponentWrapper* pointer; typedef ComponentWrapper& reference; - ComponentPool(const ::ComponentInfo& ci) + ComponentPool(const ::ComponentInfo& ci, World* world) : m_ComponentInfo(ci) , m_Pool(ci.Meta->Allocation, ci.GetHeaderSize() + ci.Stride) + , m_World(world) { } ~ComponentPool(); ComponentPool(const ComponentPool& other); @@ -82,6 +83,7 @@ private: MemoryPool m_Pool; std::unordered_map m_EntityToComponent; DirtySet m_DirtySet; + World* m_World; }; #endif \ No newline at end of file diff --git a/include/Engine/Core/ComponentWrapper.h b/include/Engine/Core/ComponentWrapper.h index 170cdddf..0b3075e7 100644 --- a/include/Engine/Core/ComponentWrapper.h +++ b/include/Engine/Core/ComponentWrapper.h @@ -10,56 +10,25 @@ #include "DirtySet.h" #include "Util/Any.h" +class World; struct ComponentWrapper { - ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField) - : Info(componentInfo) - , EntityID(*reinterpret_cast<::EntityID*>(data)) - , Data(data + componentInfo.GetHeaderSize()) - , DirtyBitField(dirtyBitField) - { } + ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField, World* world); + World* m_World; const ComponentInfo& Info; const ::EntityID EntityID; char* Data; ::DirtyBitField* DirtyBitField = nullptr; - ComponentInfo::EnumType Enum(const char* fieldName, const char* enumKey) - { - return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey); - } + ComponentInfo::EnumType Enum(const char* fieldName, const char* 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; - } - } + bool Dirty(DirtySetType type, const std::string& fieldName); - void SetDirty(DirtySetType type, const std::string& fieldName, bool dirty = true) - { - if (DirtyBitField == nullptr) { - return; - } + void SetDirty(DirtySetType type, const std::string& fieldName, bool dirty = true); - auto& field = Info.Fields.at(fieldName); - if (dirty) { - DirtyBitField->operator[](type).insert(field.Index); - } else { - DirtyBitField->operator[](type).erase(field.Index); - } - } - - void SetAllDirty(const std::string& fieldName, bool dirty = true) - { - for (auto& kv : *DirtyBitField) { - SetDirty(kv.first, fieldName); - } - } + void SetAllDirty(const std::string& fieldName, bool dirty = true); template T& Field(const std::string& name) @@ -271,7 +240,7 @@ struct Field : FieldBase struct SharedComponentWrapper : ComponentWrapper { SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array data) - : ComponentWrapper(componentInfo, data.get(), nullptr) + : ComponentWrapper(componentInfo, data.get(), nullptr, nullptr) , m_DataReference(data) { } diff --git a/src/Engine/Core/ComponentPool.cpp b/src/Engine/Core/ComponentPool.cpp index 1a763bfe..49b06fb1 100644 --- a/src/Engine/Core/ComponentPool.cpp +++ b/src/Engine/Core/ComponentPool.cpp @@ -11,7 +11,7 @@ ComponentWrapper ComponentPoolForwardIterator::operator*() const { char* data = &(*m_MemoryPoolIterator); EntityID entity = *reinterpret_cast(data); - ComponentWrapper wrapper(m_ComponentInfo, data, &m_ComponentPool->m_DirtySet[entity]); + ComponentWrapper wrapper(m_ComponentInfo, data, &m_ComponentPool->m_DirtySet[entity], m_ComponentPool->m_World); return wrapper; } @@ -79,7 +79,7 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity) memcpy(data, &entity, sizeof(EntityID)); m_EntityToComponent[entity] = data; - ComponentWrapper component(m_ComponentInfo, data, &m_DirtySet[entity]); + ComponentWrapper component(m_ComponentInfo, data, &m_DirtySet[entity], m_World); // Copy defaults memcpy(component.Data, m_ComponentInfo.Defaults.get(), m_ComponentInfo.Stride); @@ -92,7 +92,7 @@ ComponentWrapper ComponentPool::GetByEntity(EntityID ent) { auto data = m_EntityToComponent.at(ent); auto bitField = &m_DirtySet[ent]; - return ComponentWrapper(m_ComponentInfo, data, bitField); + return ComponentWrapper(m_ComponentInfo, data, bitField, m_World); } bool ComponentPool::KnowsEntity(EntityID ent) diff --git a/src/Engine/Core/ComponentWrapper.cpp b/src/Engine/Core/ComponentWrapper.cpp new file mode 100644 index 00000000..e4d7cde4 --- /dev/null +++ b/src/Engine/Core/ComponentWrapper.cpp @@ -0,0 +1,59 @@ +#include "Core/World.h" +#include "Core/ComponentWrapper.h" + +ComponentWrapper::ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField, World* world) + : Info(componentInfo) + , EntityID(*reinterpret_cast<::EntityID*>(data)) + , Data(data + componentInfo.GetHeaderSize()) + , DirtyBitField(dirtyBitField) + , m_World(world) +{} + +ComponentInfo::EnumType ComponentWrapper::Enum(const char* fieldName, const char* enumKey) +{ + return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey); +} + +bool ComponentWrapper::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 ComponentWrapper::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); + // Because parents affects children when altered, we also need to flag all children as dirty. + if (type == DirtySetType::Transform && m_World != nullptr) { + auto children = m_World->GetDirectChildren(EntityID); + for (auto kv = children.first; kv != children.second; ++kv) { + const auto& child = kv->second; + if (m_World->HasComponent(child, Info.Name)) { + m_World->GetComponent(child, Info.Name).SetDirty(DirtySetType::Transform, fieldName, true); + if (fieldName == "Orientation" || fieldName == "Scale") { + m_World->GetComponent(child, Info.Name).SetDirty(DirtySetType::Transform, "Position", true); + } + } + } + } + } else { + DirtyBitField->operator[](type).erase(field.Index); + } +} + +void ComponentWrapper::SetAllDirty(const std::string& fieldName, bool dirty /* = true */) +{ + for (auto& kv : *DirtyBitField) { + SetDirty(kv.first, fieldName); + } +} \ No newline at end of file diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index 4aed1c18..4f8bcf60 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -51,10 +51,6 @@ glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) RecalculatedPositions++; // Unset dirty flag cTransformPosition.SetDirty(DirtySetType::Transform, false); - // Flag children as dirty - for (auto& child : entity.ChildrenWithComponent("Transform")) { - child["Transform"]["Position"].SetDirty(DirtySetType::Transform, true); - } return position; } } @@ -97,10 +93,6 @@ glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) RecalculatedOrientations++; // Unset dirty flag cTransformOrientation.SetDirty(DirtySetType::Transform, false); - // Flag children as dirty - for (auto& child : entity.ChildrenWithComponent("Transform")) { - child["Transform"]["Orientation"].SetDirty(DirtySetType::Transform, true); - } return orientation; } } @@ -130,10 +122,6 @@ glm::vec3 Transform::AbsoluteScale(EntityWrapper entity) RecalculatedPositions++; // Unset dirty flag cTransformScale.SetDirty(DirtySetType::Transform, false); - // Flag children as dirty - for (auto& child : entity.ChildrenWithComponent("Transform")) { - child["Transform"]["Scale"].SetDirty(DirtySetType::Transform, true); - } return scale; } } diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index b8af4b62..62ad7a4c 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -48,7 +48,7 @@ bool World::ValidEntity(EntityID entity) const void World::RegisterComponent(const ComponentInfo& ci) { if (m_ComponentPools.find(ci.Name) == m_ComponentPools.end()) { - m_ComponentPools[ci.Name] = new ComponentPool(ci); + m_ComponentPools[ci.Name] = new ComponentPool(ci, this); } } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 3aaf2291..16633255 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -178,7 +178,6 @@ void RenderSystem::fillSprites(std::list>& jobs, Worl bool RenderSystem::isEntityVisible(EntityWrapper& entity) { - return true; // Only render children of a camera if that camera is currently active if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { return false;