25
25
struct MetaType {
26
26
27
27
MetaType () = default ;
28
- MetaType (MetaType&&) = default ;
29
- MetaType (const MetaType&) = default ;
30
- MetaType& operator =(MetaType&&) = default ;
31
- MetaType& operator =(const MetaType&) = default ;
28
+ MetaType (MetaType&& rhs):
29
+ id (rhs.id),
30
+ flags (rhs.flags)
31
+ {}
32
+ MetaType (const MetaType& rhs):
33
+ id (rhs.id),
34
+ flags (rhs.flags)
35
+ {}
36
+ MetaType& operator =(MetaType&& rhs) {
37
+ id=rhs.id ;
38
+ flags=rhs.flags ;
39
+ return *this ;
40
+ }
41
+ MetaType& operator =(const MetaType& rhs) {
42
+ id=rhs.id ;
43
+ flags=rhs.flags ;
44
+ return *this ;
45
+ }
32
46
33
47
template <class T >
34
48
MetaType (T val) {
@@ -113,16 +127,41 @@ struct MetaType {
113
127
114
128
struct MetaElement
115
129
{
130
+ MetaElement () = default ;
116
131
MetaElement (MetaType type, const std::string& key, boost::any&& value):
117
132
type (type),
118
133
key (key),
119
134
value (value)
120
135
{}
121
-
122
- MetaElement (const MetaElement& e) = default ;
123
- MetaElement (MetaElement&& e) = default ;
124
- MetaElement& operator =(const MetaElement& e) = default ;
125
-
136
+ MetaElement (const MetaElement& rhs):
137
+ type (rhs.type),
138
+ key (rhs.key),
139
+ value (rhs.value),
140
+ flags (rhs.flags)
141
+ {}
142
+ MetaElement (MetaElement&& rhs):
143
+ type (rhs.type),
144
+ key (rhs.key),
145
+ value (std::move(rhs.value)),
146
+ flags (rhs.flags)
147
+ {}
148
+ MetaElement& operator =(const MetaElement& rhs)
149
+ {
150
+ type = rhs.type ;
151
+ key = rhs.key ;
152
+ value = rhs.value ;
153
+ flags = rhs.flags ;
154
+ return *this ;
155
+ }
156
+ MetaElement& operator =(MetaElement&& rhs)
157
+ {
158
+ type = rhs.type ;
159
+ key = rhs.key ;
160
+ value = std::move (rhs.value );
161
+ flags = rhs.flags ;
162
+ return *this ;
163
+ }
164
+
126
165
template <class Mutex >
127
166
Json::Value serialize_json (unsigned flags = 0 ) const ;
128
167
@@ -134,7 +173,6 @@ struct MetaElement
134
173
std::runtime_error (" null pointer exception" )
135
174
{}
136
175
};
137
-
138
176
139
177
// template<class Mutex>
140
178
// void deserialize_json(const Json::Value&);
@@ -148,23 +186,18 @@ struct MetaElement
148
186
// {}
149
187
// type data (reflection)
150
188
151
- /*
152
- * Deduced type id
153
- */
154
- MetaType type; // null
155
-
156
189
void nullify () {
157
190
type.id = MetaType::ID::EMPTY;
158
191
value = boost::any ();
192
+ on_change.disconnect_all_slots ();
159
193
}
160
194
161
195
explicit operator bool () const {
162
196
return !value.empty ();
163
197
}
164
198
165
199
void trigger () {
166
- // if(change)
167
- // (*change)();
200
+ on_change ();
168
201
}
169
202
170
203
// may throw bad_any_cast
@@ -173,6 +206,12 @@ struct MetaElement
173
206
return boost::any_cast<T>(value);
174
207
}
175
208
209
+
210
+ /*
211
+ * Deduced type id
212
+ */
213
+ MetaType type; // null
214
+
176
215
/*
177
216
* Key (if any)
178
217
* Do not modify the key without modifying Meta's m_Key
@@ -192,7 +231,7 @@ struct MetaElement
192
231
unsigned flags = DEFAULT_FLAGS;
193
232
194
233
// value change listeners
195
- // std::shared_ptr< boost::signals2::signal<void()> > on_change;
234
+ boost::signals2::signal<void ()> on_change;
196
235
};
197
236
198
237
enum class MetaFormat : unsigned {
@@ -351,7 +390,9 @@ class MetaBase:
351
390
MetaBase (MetaFormat fmt, const std::string& data);
352
391
353
392
MetaBase (MetaBase&&)= delete ;
354
- MetaBase (const MetaBase&)= delete ;
393
+
394
+ MetaBase (const MetaBase&) = delete ;
395
+ explicit MetaBase (const std::shared_ptr<MetaBase<Mutex>>& rhs);
355
396
MetaBase& operator =(const MetaBase&) = delete ;
356
397
MetaBase& operator =(MetaBase&&) = delete ;
357
398
@@ -864,8 +905,19 @@ class MetaBase:
864
905
if ((itr = m_Keys.find (key)) != m_Keys.end ()) {
865
906
// TODO: if dynamic typing is off, check type compatibility
866
907
auto & e = m_Elements[itr->second ];
867
- e.type = MetaType (val); // overwrite type just in case
868
- e.value = val;
908
+ if (e.type .id != MetaType (val).id )
909
+ {
910
+ // type changed
911
+ e.type = MetaType (val);
912
+ e.value = val;
913
+ e.on_change .disconnect_all_slots ();
914
+ }
915
+ else
916
+ {
917
+ e.value = val;
918
+ e.trigger ();
919
+ }
920
+ //
869
921
// TODO: trigger change listener?... or maybe only for sync()?
870
922
return itr->second ;
871
923
}
@@ -916,15 +968,29 @@ class MetaBase:
916
968
T&& val
917
969
){
918
970
// Should really check type compatibility here...
971
+ auto l = this ->lock ();
919
972
920
973
try {
921
- m_Elements.at (offset).value = val;
974
+ auto & e = m_Elements.at (offset);
975
+ if (e.value != val) {
976
+ e.value = val;
977
+ e.trigger ();
978
+ }
922
979
}catch (...){
923
980
return false ;
924
981
}
925
982
return true ;
926
983
}
927
984
985
+ boost::signals2::connection on_change (
986
+ const std::string& key,
987
+ const boost::signals2::signal<void ()>::slot_type& slot
988
+ ){
989
+ auto l = this ->lock ();
990
+ auto & e = m_Elements.at (index (key));
991
+ return e.on_change .connect (slot);
992
+ }
993
+
928
994
/*
929
995
* Creates property with key and optional value (default is blank)
930
996
* Returns the id used to refer to the property
@@ -976,9 +1042,11 @@ class MetaBase:
976
1042
// }
977
1043
978
1044
void callbacks (bool enabled) {
1045
+ auto l = this ->lock ();
979
1046
m_bCallbacks = enabled;
980
1047
}
981
1048
bool callbacks () {
1049
+ auto l = this ->lock ();
982
1050
return m_bCallbacks;
983
1051
}
984
1052
0 commit comments