Plasma Engine  2.0
Loading...
Searching...
No Matches
ObjectMetaData_inl.h
1#pragma once
2
3template <typename KEY, typename VALUE>
5{
6 m_DefaultValue = VALUE();
7
8 auto pStorage = PL_DEFAULT_NEW(Storage);
9 pStorage->m_AcessingKey = KEY();
10 pStorage->m_AccessMode = Storage::AccessMode::Nothing;
11 SwapStorage(pStorage);
12}
13
14template <typename KEY, typename VALUE>
15const VALUE* plObjectMetaData<KEY, VALUE>::BeginReadMetaData(const KEY objectKey) const
16{
17 m_pMetaStorage->m_Mutex.Lock();
18 PL_ASSERT_DEV(m_pMetaStorage->m_AccessMode == Storage::AccessMode::Nothing, "Already accessing some data");
19 m_pMetaStorage->m_AccessMode = Storage::AccessMode::Read;
20 m_pMetaStorage->m_AcessingKey = objectKey;
21
22 const VALUE* pRes = nullptr;
23 if (m_pMetaStorage->m_MetaData.TryGetValue(objectKey, pRes)) // TryGetValue is not const correct with the second parameter
24 return pRes;
25
26 return &m_DefaultValue;
27}
28
29template <typename KEY, typename VALUE>
30void plObjectMetaData<KEY, VALUE>::ClearMetaData(const KEY objectKey)
31{
32 PL_LOCK(m_pMetaStorage->m_Mutex);
33 PL_ASSERT_DEV(m_pMetaStorage->m_AccessMode == Storage::AccessMode::Nothing, "Already accessing some data");
34
35 if (HasMetaData(objectKey))
36 {
37 m_pMetaStorage->m_MetaData.Remove(objectKey);
38
39 EventData e;
40 e.m_ObjectKey = objectKey;
41 e.m_pValue = &m_DefaultValue;
42
43 m_pMetaStorage->m_DataModifiedEvent.Broadcast(e);
44 }
45}
46
47template <typename KEY, typename VALUE>
48bool plObjectMetaData<KEY, VALUE>::HasMetaData(const KEY objectKey) const
49{
50 PL_LOCK(m_pMetaStorage->m_Mutex);
51 const VALUE* pValue = nullptr;
52 return m_pMetaStorage->m_MetaData.TryGetValue(objectKey, pValue);
53}
54
55template <typename KEY, typename VALUE>
57{
58 m_pMetaStorage->m_Mutex.Lock();
59 PL_ASSERT_DEV(m_pMetaStorage->m_AccessMode == Storage::AccessMode::Nothing, "Already accessing some data");
60 m_pMetaStorage->m_AccessMode = Storage::AccessMode::Write;
61 m_pMetaStorage->m_AcessingKey = objectKey;
62
63 return &m_pMetaStorage->m_MetaData[objectKey];
65
66template <typename KEY, typename VALUE>
68{
69 PL_ASSERT_DEV(m_pMetaStorage->m_AccessMode == Storage::AccessMode::Read, "Not accessing data at the moment");
70
71 m_pMetaStorage->m_AccessMode = Storage::AccessMode::Nothing;
72 m_pMetaStorage->m_Mutex.Unlock();
73}
74
75
76template <typename KEY, typename VALUE>
77void plObjectMetaData<KEY, VALUE>::EndModifyMetaData(plUInt32 uiModifiedFlags /*= 0xFFFFFFFF*/)
78{
79 PL_ASSERT_DEV(m_pMetaStorage->m_AccessMode == Storage::AccessMode::Write, "Not accessing data at the moment");
80 m_pMetaStorage->m_AccessMode = Storage::AccessMode::Nothing;
81
82 if (uiModifiedFlags != 0)
83 {
84 EventData e;
85 e.m_ObjectKey = m_pMetaStorage->m_AcessingKey;
86 e.m_pValue = &m_pMetaStorage->m_MetaData[m_pMetaStorage->m_AcessingKey];
87 e.m_uiModifiedFlags = uiModifiedFlags;
88
89 m_pMetaStorage->m_DataModifiedEvent.Broadcast(e);
90 }
91
92 m_pMetaStorage->m_Mutex.Unlock();
93}
94
95
96template <typename KEY, typename VALUE>
98{
99 auto& AllNodes = inout_graph.GetAllNodes();
100
101 PL_LOCK(m_pMetaStorage->m_Mutex);
102
104
105 // store the default values in an easily accessible hash map, to be able to compare against them
106 {
107 DefaultValues.Reserve(m_DefaultValue.GetDynamicRTTI()->GetProperties().GetCount());
108
109 for (const auto& pProp : m_DefaultValue.GetDynamicRTTI()->GetProperties())
110 {
111 if (pProp->GetCategory() != plPropertyCategory::Member)
112 continue;
113
114 DefaultValues[pProp->GetPropertyName()] =
115 plReflectionUtils::GetMemberPropertyValue(static_cast<const plAbstractMemberProperty*>(pProp), &m_DefaultValue);
116 }
117 }
118
119 // now serialize all properties that differ from the default value
120 {
121 plVariant value;
122
123 for (auto it = AllNodes.GetIterator(); it.IsValid(); ++it)
124 {
125 auto* pNode = it.Value();
126 const plUuid& guid = pNode->GetGuid();
127
128 const VALUE* pMeta = nullptr;
129 if (!m_pMetaStorage->m_MetaData.TryGetValue(guid, pMeta)) // TryGetValue is not const correct with the second parameter
130 continue; // it is the default object, so all values are default -> skip
131
132 for (const auto& pProp : pMeta->GetDynamicRTTI()->GetProperties())
133 {
134 if (pProp->GetCategory() != plPropertyCategory::Member)
135 continue;
136
137 value = plReflectionUtils::GetMemberPropertyValue(static_cast<const plAbstractMemberProperty*>(pProp), pMeta);
138
139 if (value.IsValid() && DefaultValues[pProp->GetPropertyName()] != value)
140 {
141 pNode->AddProperty(pProp->GetPropertyName(), value);
142 }
143 }
144 }
145 }
146}
147
148
149template <typename KEY, typename VALUE>
151{
152 PL_LOCK(m_pMetaStorage->m_Mutex);
153
154 plHybridArray<plString, 16> PropertyNames;
155
156 // find all properties (names) that we want to read
157 {
158 for (const auto& pProp : m_DefaultValue.GetDynamicRTTI()->GetProperties())
159 {
160 if (pProp->GetCategory() != plPropertyCategory::Member)
161 continue;
162
163 PropertyNames.PushBack(pProp->GetPropertyName());
164 }
165 }
166
167 auto& AllNodes = graph.GetAllNodes();
168
169 for (auto it = AllNodes.GetIterator(); it.IsValid(); ++it)
170 {
171 auto* pNode = it.Value();
172 const plUuid& guid = pNode->GetGuid();
173
174 for (const auto& name : PropertyNames)
175 {
176 if (const auto* pProp = pNode->FindProperty(name))
177 {
178 VALUE* pValue = &m_pMetaStorage->m_MetaData[guid];
179
180 plReflectionUtils::SetMemberPropertyValue(
181 static_cast<const plAbstractMemberProperty*>(pValue->GetDynamicRTTI()->FindPropertyByName(name)), pValue, pProp->m_Value);
182 }
183 }
184 }
185}
186
187template <typename KEY, typename VALUE>
189{
190 PL_ASSERT_ALWAYS(pNewStorage != nullptr, "Need a valid history storage object");
191
192 auto retVal = m_pMetaStorage;
193
194 m_EventsUnsubscriber.Unsubscribe();
195
196 m_pMetaStorage = pNewStorage;
197
198 m_pMetaStorage->m_DataModifiedEvent.AddEventHandler([this](const EventData& e) { m_DataModifiedEvent.Broadcast(e); }, m_EventsUnsubscriber);
199
200 return retVal;
201}
This is the base class for all properties that are members of a class. It provides more information a...
Definition AbstractProperty.h:237
Definition AbstractObjectGraph.h:115
void PushBack(const T &value)
Pushes value at the end of the array.
Definition ArrayBase_inl.h:333
void Reserve(plUInt32 uiCapacity)
Expands the hashtable by over-allocating the internal storage so that the load factor is lower or equ...
Definition HashTable_inl.h:307
Definition HashTable.h:333
A hybrid array uses in-place storage to handle the first few elements without any allocation....
Definition HybridArray.h:12
Definition ObjectMetaData.h:30
Stores meta data for document objects that is not part of the object itself. E.g. editor-only states ...
Definition ObjectMetaData.h:16
void AttachMetaDataToAbstractGraph(plAbstractObjectGraph &inout_graph) const
Uses reflection information from VALUE to store all properties that differ from the default value as ...
Definition ObjectMetaData_inl.h:97
void RestoreMetaDataFromAbstractGraph(const plAbstractObjectGraph &graph)
Uses reflection information from VALUE to restore all meta data properties from the graph.
Definition ObjectMetaData_inl.h:150
const VALUE * BeginReadMetaData(const KEY objectKey) const
Will always return a non-null result. May be a default object.
Definition ObjectMetaData_inl.h:15
A Shared ptr manages a shared object and destroys that object when no one references it anymore....
Definition SharedPtr.h:10
This data type is the abstraction for 128-bit Uuid (also known as GUID) instances.
Definition Uuid.h:11
plVariant is a class that can store different types of variables, which is useful in situations where...
Definition Variant.h:44
bool IsValid() const
Returns whether this variant stores any other type than 'Invalid'.
Definition Variant_inl.h:274
@ Member
The property is a 'member property', i.e. it represents some accessible value. Cast to plAbstractMemb...
Definition AbstractProperty.h:138