1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Core/Attribute.h"
26 #include "../Core/Object.h"
27 
28 #include <cstddef>
29 
30 namespace Urho3D
31 {
32 
33 class Connection;
34 class Deserializer;
35 class Serializer;
36 class XMLElement;
37 class JSONValue;
38 
39 struct DirtyBits;
40 struct NetworkState;
41 struct ReplicationState;
42 
43 /// Base class for objects with automatic serialization through attributes.
44 class URHO3D_API Serializable : public Object
45 {
46     URHO3D_OBJECT(Serializable, Object);
47 
48 public:
49     /// Construct.
50     Serializable(Context* context);
51     /// Destruct.
52     virtual ~Serializable();
53 
54     /// Handle attribute write access. Default implementation writes to the variable at offset, or invokes the set accessor.
55     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
56     /// Handle attribute read access. Default implementation reads the variable at offset, or invokes the get accessor.
57     virtual void OnGetAttribute(const AttributeInfo& attr, Variant& dest) const;
58     /// Return attribute descriptions, or null if none defined.
59     virtual const Vector<AttributeInfo>* GetAttributes() const;
60     /// Return network replication attribute descriptions, or null if none defined.
61     virtual const Vector<AttributeInfo>* GetNetworkAttributes() const;
62     /// Load from binary data. When setInstanceDefault is set to true, after setting the attribute value, store the value as instance's default value. Return true if successful.
63     virtual bool Load(Deserializer& source, bool setInstanceDefault = false);
64     /// Save as binary data. Return true if successful.
65     virtual bool Save(Serializer& dest) const;
66     /// Load from XML data. When setInstanceDefault is set to true, after setting the attribute value, store the value as instance's default value. Return true if successful.
67     virtual bool LoadXML(const XMLElement& source, bool setInstanceDefault = false);
68     /// Save as XML data. Return true if successful.
69     virtual bool SaveXML(XMLElement& dest) const;
70     /// Load from JSON data. When setInstanceDefault is set to true, after setting the attribute value, store the value as instance's default value. Return true if successful.
71     virtual bool LoadJSON(const JSONValue& source, bool setInstanceDefault = false);
72     /// Save as JSON data. Return true if successful.
73     virtual bool SaveJSON(JSONValue& dest) const;
74 
75     /// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
ApplyAttributes()76     virtual void ApplyAttributes() { }
77 
78     /// Return whether should save default-valued attributes into XML. Default false.
SaveDefaultAttributes()79     virtual bool SaveDefaultAttributes() const { return false; }
80 
81     /// Mark for attribute check on the next network update.
MarkNetworkUpdate()82     virtual void MarkNetworkUpdate() { }
83 
84     /// Set attribute by index. Return true if successfully set.
85     bool SetAttribute(unsigned index, const Variant& value);
86     /// Set attribute by name. Return true if successfully set.
87     bool SetAttribute(const String& name, const Variant& value);
88     /// Reset all editable attributes to their default values.
89     void ResetToDefault();
90     /// Remove instance's default values if they are set previously.
91     void RemoveInstanceDefault();
92     /// Set temporary flag. Temporary objects will not be saved.
93     void SetTemporary(bool enable);
94     /// Enable interception of an attribute from network updates. Intercepted attributes are sent as events instead of applying directly. This can be used to implement client side prediction.
95     void SetInterceptNetworkUpdate(const String& attributeName, bool enable);
96     /// Allocate network attribute state.
97     void AllocateNetworkState();
98     /// Write initial delta network update.
99     void WriteInitialDeltaUpdate(Serializer& dest, unsigned char timeStamp);
100     /// Write a delta network update according to dirty attribute bits.
101     void WriteDeltaUpdate(Serializer& dest, const DirtyBits& attributeBits, unsigned char timeStamp);
102     /// Write a latest data network update.
103     void WriteLatestDataUpdate(Serializer& dest, unsigned char timeStamp);
104     /// Read and apply a network delta update. Return true if attributes were changed.
105     bool ReadDeltaUpdate(Deserializer& source);
106     /// Read and apply a network latest data update. Return true if attributes were changed.
107     bool ReadLatestDataUpdate(Deserializer& source);
108 
109     /// Return attribute value by index. Return empty if illegal index.
110     Variant GetAttribute(unsigned index) const;
111     /// Return attribute value by name. Return empty if not found.
112     Variant GetAttribute(const String& name) const;
113     /// Return attribute default value by index. Return empty if illegal index.
114     Variant GetAttributeDefault(unsigned index) const;
115     /// Return attribute default value by name. Return empty if not found.
116     Variant GetAttributeDefault(const String& name) const;
117     /// Return number of attributes.
118     unsigned GetNumAttributes() const;
119     /// Return number of network replication attributes.
120     unsigned GetNumNetworkAttributes() const;
121 
122     /// Return whether is temporary.
IsTemporary()123     bool IsTemporary() const { return temporary_; }
124 
125     /// Return whether an attribute's network updates are being intercepted.
126     bool GetInterceptNetworkUpdate(const String& attributeName) const;
127 
128     /// Return the network attribute state, if allocated.
GetNetworkState()129     NetworkState* GetNetworkState() const { return networkState_.Get(); }
130 
131 protected:
132     /// Network attribute state.
133     UniquePtr<NetworkState> networkState_;
134 
135 private:
136     /// Set instance-level default value. Allocate the internal data structure as necessary.
137     void SetInstanceDefault(const String& name, const Variant& defaultValue);
138     /// Get instance-level default value.
139     Variant GetInstanceDefault(const String& name) const;
140 
141     /// Attribute default value at each instance level.
142     UniquePtr<VariantMap> instanceDefaultValues_;
143     /// Temporary flag.
144     bool temporary_;
145 };
146 
147 /// Template implementation of the enum attribute accessor invoke helper class.
148 template <typename T, typename U> class EnumAttributeAccessorImpl : public AttributeAccessor
149 {
150 public:
151     typedef U (T::*GetFunctionPtr)() const;
152     typedef void (T::*SetFunctionPtr)(U);
153 
154     /// Construct with function pointers.
EnumAttributeAccessorImpl(GetFunctionPtr getFunction,SetFunctionPtr setFunction)155     EnumAttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
156         getFunction_(getFunction),
157         setFunction_(setFunction)
158     {
159         assert(getFunction_);
160         assert(setFunction_);
161     }
162 
163     /// Invoke getter function.
Get(const Serializable * ptr,Variant & dest)164     virtual void Get(const Serializable* ptr, Variant& dest) const
165     {
166         assert(ptr);
167         const T* classPtr = static_cast<const T*>(ptr);
168         dest = (int)(classPtr->*getFunction_)();
169     }
170 
171     /// Invoke setter function.
Set(Serializable * ptr,const Variant & value)172     virtual void Set(Serializable* ptr, const Variant& value)
173     {
174         assert(ptr);
175         T* classPtr = static_cast<T*>(ptr);
176         (classPtr->*setFunction_)((U)value.GetInt());
177     }
178 
179     /// Class-specific pointer to getter function.
180     GetFunctionPtr getFunction_;
181     /// Class-specific pointer to setter function.
182     SetFunctionPtr setFunction_;
183 };
184 
185 /// Template implementation of the enum attribute accessor that uses free functions invoke helper class.
186 template <typename T, typename U> class EnumAttributeAccessorFreeImpl : public AttributeAccessor
187 {
188 public:
189     typedef U(*GetFunctionPtr)(const T*);
190     typedef void(*SetFunctionPtr)(T*, U);
191 
192     /// Construct with function pointers.
EnumAttributeAccessorFreeImpl(GetFunctionPtr getFunction,SetFunctionPtr setFunction)193     EnumAttributeAccessorFreeImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
194         getFunction_(getFunction),
195         setFunction_(setFunction)
196     {
197         assert(getFunction_);
198         assert(setFunction_);
199     }
200 
201     /// Invoke getter function.
Get(const Serializable * ptr,Variant & dest)202     virtual void Get(const Serializable* ptr, Variant& dest) const
203     {
204         assert(ptr);
205         const T* classPtr = static_cast<const T*>(ptr);
206         dest = (*getFunction_)(classPtr);
207     }
208 
209     /// Invoke setter function.
Set(Serializable * ptr,const Variant & value)210     virtual void Set(Serializable* ptr, const Variant& value)
211     {
212         assert(ptr);
213         T* classPtr = static_cast<T*>(ptr);
214         (*setFunction_)(classPtr, (U)value.GetInt());
215     }
216 
217     /// Class-specific pointer to getter function.
218     GetFunctionPtr getFunction_;
219     /// Class-specific pointer to setter function.
220     SetFunctionPtr setFunction_;
221 };
222 
223 /// Attribute trait (default use const reference for object type).
224 template <typename T> struct AttributeTrait
225 {
226     /// Get function return type.
227     typedef const T& ReturnType;
228     /// Set function parameter type.
229     typedef const T& ParameterType;
230 };
231 
232 /// Int attribute trait.
233 template <> struct AttributeTrait<int>
234 {
235     typedef int ReturnType;
236     typedef int ParameterType;
237 };
238 
239 /// unsigned attribute trait.
240 template <> struct AttributeTrait<unsigned>
241 {
242     typedef unsigned ReturnType;
243     typedef unsigned ParameterType;
244 };
245 
246 /// Bool attribute trait.
247 template <> struct AttributeTrait<bool>
248 {
249     typedef bool ReturnType;
250     typedef bool ParameterType;
251 };
252 
253 /// Float attribute trait.
254 template <> struct AttributeTrait<float>
255 {
256     typedef float ReturnType;
257     typedef float ParameterType;
258 };
259 
260 /// Mixed attribute trait (use const reference for set function only).
261 template <typename T> struct MixedAttributeTrait
262 {
263     typedef T ReturnType;
264     typedef const T& ParameterType;
265 };
266 
267 /// Template implementation of the attribute accessor invoke helper class.
268 template <typename T, typename U, typename Trait> class AttributeAccessorImpl : public AttributeAccessor
269 {
270 public:
271     typedef typename Trait::ReturnType (T::*GetFunctionPtr)() const;
272     typedef void (T::*SetFunctionPtr)(typename Trait::ParameterType);
273 
274     /// Construct with function pointers.
275     AttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
276         getFunction_(getFunction),
277         setFunction_(setFunction)
278     {
279         assert(getFunction_);
280         assert(setFunction_);
281     }
282 
283     /// Invoke getter function.
284     virtual void Get(const Serializable* ptr, Variant& dest) const
285     {
286         assert(ptr);
287         const T* classPtr = static_cast<const T*>(ptr);
288         dest = (classPtr->*getFunction_)();
289     }
290 
291     /// Invoke setter function.
292     virtual void Set(Serializable* ptr, const Variant& value)
293     {
294         assert(ptr);
295         T* classPtr = static_cast<T*>(ptr);
296         (classPtr->*setFunction_)(value.Get<U>());
297     }
298 
299     /// Class-specific pointer to getter function.
300     GetFunctionPtr getFunction_;
301     /// Class-specific pointer to setter function.
302     SetFunctionPtr setFunction_;
303 };
304 
305 /// Template implementation of the attribute accessor that uses free functions invoke helper class.
306 template <typename T, typename U, typename Trait> class AttributeAccessorFreeImpl : public AttributeAccessor
307 {
308 public:
309     typedef typename Trait::ReturnType(*GetFunctionPtr)(const T*);
310     typedef void(*SetFunctionPtr)(T*, typename Trait::ParameterType);
311 
312     /// Construct with function pointers.
313     AttributeAccessorFreeImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
314         getFunction_(getFunction),
315         setFunction_(setFunction)
316     {
317         assert(getFunction_);
318         assert(setFunction_);
319     }
320 
321     /// Invoke getter function.
322     virtual void Get(const Serializable* ptr, Variant& dest) const
323     {
324         assert(ptr);
325         const T* classPtr = static_cast<const T*>(ptr);
326         dest = (*getFunction_)(classPtr);
327     }
328 
329     /// Invoke setter function.
330     virtual void Set(Serializable* ptr, const Variant& value)
331     {
332         assert(ptr);
333         T* classPtr = static_cast<T*>(ptr);
334         (*setFunction_)(classPtr, value.Get<U>());
335     }
336 
337     /// Class-specific pointer to getter function.
338     GetFunctionPtr getFunction_;
339     /// Class-specific pointer to setter function.
340     SetFunctionPtr setFunction_;
341 };
342 
343 // The following macros need to be used within a class member function such as ClassName::RegisterObject().
344 // A variable called "context" needs to exist in the current scope and point to a valid Context object.
345 
346 /// Copy attributes from a base class.
347 #define URHO3D_COPY_BASE_ATTRIBUTES(sourceClassName) context->CopyBaseAttributes<sourceClassName, ClassName>()
348 /// Remove attribute by name.
349 #define URHO3D_REMOVE_ATTRIBUTE(name) context->RemoveAttribute<ClassName>(name)
350 /// Define an attribute that points to a memory offset in the object.
351 #define URHO3D_ATTRIBUTE(name, typeName, variable, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(Urho3D::GetVariantType<typeName >(), name, offsetof(ClassName, variable), defaultValue, mode))
352 /// Define an attribute that points to a memory offset in the object, and uses zero-based enum values, which are mapped to names through an array of C string pointers.
353 #define URHO3D_ENUM_ATTRIBUTE(name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(name, offsetof(ClassName, variable), enumNames, defaultValue, mode))
354 /// Define an attribute that uses get and set functions.
355 #define URHO3D_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(Urho3D::GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorImpl<ClassName, typeName, Urho3D::AttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, mode))
356 /// Define an attribute that uses get and set free functions.
357 #define URHO3D_ACCESSOR_ATTRIBUTE_FREE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(Urho3D::GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorFreeImpl<ClassName, typeName, Urho3D::AttributeTrait<typeName > >(getFunction, setFunction), defaultValue, mode))
358 /// Define an attribute that uses get and set functions, and uses zero-based enum values, which are mapped to names through an array of C string pointers.
359 #define URHO3D_ENUM_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(name, new Urho3D::EnumAttributeAccessorImpl<ClassName, typeName >(&ClassName::getFunction, &ClassName::setFunction), enumNames, defaultValue, mode))
360 /// Define an attribute that uses get and set free functions, and uses zero-based enum values, which are mapped to names through an array of C string pointers.
361 #define URHO3D_ENUM_ACCESSOR_ATTRIBUTE_FREE(name, getFunction, setFunction, typeName, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(name, new Urho3D::EnumAttributeAccessorFreeImpl<ClassName, typeName >(getFunction, setFunction), enumNames, defaultValue, mode))
362 /// Define an attribute that uses get and set functions, where the get function returns by value, but the set function uses a reference.
363 #define URHO3D_MIXED_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(Urho3D::GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorImpl<ClassName, typeName, Urho3D::MixedAttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, mode))
364 /// Define an attribute that uses get and set free functions, where the get function returns by value, but the set function uses a reference.
365 #define URHO3D_MIXED_ACCESSOR_ATTRIBUTE_FREE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(Urho3D::GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorFreeImpl<ClassName, typeName, Urho3D::MixedAttributeTrait<typeName > >(getFunction, setFunction), defaultValue, mode))
366 /// Update the default value of an already registered attribute.
367 #define URHO3D_UPDATE_ATTRIBUTE_DEFAULT_VALUE(name, defaultValue) context->UpdateAttributeDefaultValue<ClassName>(name, defaultValue)
368 /// Define a variant structure attribute that uses get and set functions.
369 #define URHO3D_ACCESSOR_VARIANT_VECTOR_STRUCTURE_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, variantStructureElementNames, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(Urho3D::GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorImpl<ClassName, typeName, Urho3D::AttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, variantStructureElementNames, mode))
370 /// Define a variant structure attribute that uses get and set functions, where the get function returns by value, but the set function uses a reference.
371 #define URHO3D_MIXED_ACCESSOR_VARIANT_VECTOR_STRUCTURE_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, variantStructureElementNames, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(Urho3D::GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorImpl<ClassName, typeName, Urho3D::MixedAttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, variantStructureElementNames, mode))
372 
373 }
374