Added base work for dity bits in components

This commit is contained in:
2016-03-08 18:26:03 +01:00
parent 5d53fc74cb
commit b7d93058b1
10 changed files with 86 additions and 53 deletions
+38 -28
View File
@@ -6,42 +6,52 @@
#include "../Common.h"
#include "Entity.h"
#include "ComponentInfo.h"
#include "DirtySet.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
{
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField)
: Info(componentInfo)
, EntityID(*reinterpret_cast<::EntityID*>(data))
, Data(data + componentInfo.GetHeaderSize())
, DirtyBitField(dirtyBitField)
{ }
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);
}
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>
T& Field(const std::string& name)
{
@@ -96,32 +106,32 @@ struct ComponentWrapper
{
friend struct ComponentWrapper;
private:
SubscriptProxy(ComponentWrapper* component, std::string propertyName)
SubscriptProxy(ComponentWrapper* component, std::string fieldName)
: m_Component(component)
, m_PropertyName(propertyName)
, m_FieldName(fieldName)
{ }
ComponentWrapper* m_Component;
std::string m_PropertyName;
std::string m_FieldName;
public:
// 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); }
bool Dirty(DirtySet set) { return true; }
void SetDirty(bool dirty = true) { }
ComponentInfo::EnumType Enum(const char* enumKey) { return m_Component->Enum(m_FieldName.c_str(), enumKey); }
bool Dirty(DirtySetType type) { return m_Component->Dirty(type, m_FieldName); }
void SetDirty(DirtySetType type, bool dirty = true) { m_Component->SetDirty(type, m_FieldName, dirty); }
template <typename T>
operator T&() { return m_Component->Field<T>(m_PropertyName); }
operator T&() { return m_Component->Field<T>(m_FieldName); }
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?)
//template <typename T>
//void operator=(T& val) { m_Component->SetField<T>(m_PropertyName, val); }
// Specialization for string literals
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); }
};
@@ -130,7 +140,7 @@ struct ComponentWrapper
struct SharedComponentWrapper : ComponentWrapper
{
SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data)
: ComponentWrapper(componentInfo, data.get())
: ComponentWrapper(componentInfo, data.get(), nullptr)
, m_DataReference(data)
{ }