Fixed so calculating absolute positions, etc. works. Sets the field of all children to dirty if a transform field is altered. Will also set Position to dirty if Scale or Orientation is altered.

Moved some methods in ComponentWrapper to a .cpp.
This commit is contained in:
William Moberg
2016-03-12 17:51:03 +01:00
parent 24bb05ec67
commit 36b84f7cc3
7 changed files with 74 additions and 57 deletions
+3 -1
View File
@@ -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<char> m_Pool;
std::unordered_map<EntityID, char*> m_EntityToComponent;
DirtySet m_DirtySet;
World* m_World;
};
#endif
+8 -39
View File
@@ -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 <typename T>
T& Field(const std::string& name)
@@ -271,7 +240,7 @@ struct Field<glm::vec4> : FieldBase<glm::vec4>
struct SharedComponentWrapper : ComponentWrapper
{
SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data)
: ComponentWrapper(componentInfo, data.get(), nullptr)
: ComponentWrapper(componentInfo, data.get(), nullptr, nullptr)
, m_DataReference(data)
{ }
+3 -3
View File
@@ -11,7 +11,7 @@ ComponentWrapper ComponentPoolForwardIterator::operator*() const
{
char* data = &(*m_MemoryPoolIterator);
EntityID entity = *reinterpret_cast<EntityID*>(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)
+59
View File
@@ -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);
}
}
-12
View File
@@ -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;
}
}
+1 -1
View File
@@ -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);
}
}
-1
View File
@@ -178,7 +178,6 @@ void RenderSystem::fillSprites(std::list<std::shared_ptr<RenderJob>>& 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;