Serializable.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  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. #pragma once
  23. #include "../Core/Attribute.h"
  24. #include "../Core/Object.h"
  25. #include <cstddef>
  26. namespace Atomic
  27. {
  28. class Connection;
  29. class Deserializer;
  30. class Serializer;
  31. class XMLElement;
  32. class JSONValue;
  33. struct DirtyBits;
  34. struct NetworkState;
  35. struct ReplicationState;
  36. /// Base class for objects with automatic serialization through attributes.
  37. class ATOMIC_API Serializable : public Object
  38. {
  39. ATOMIC_OBJECT(Serializable, Object);
  40. public:
  41. /// Construct.
  42. Serializable(Context* context);
  43. /// Destruct.
  44. virtual ~Serializable();
  45. /// Handle attribute write access. Default implementation writes to the variable at offset, or invokes the set accessor.
  46. virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
  47. /// Handle attribute read access. Default implementation reads the variable at offset, or invokes the get accessor.
  48. virtual void OnGetAttribute(const AttributeInfo& attr, Variant& dest) const;
  49. /// Return attribute descriptions, or null if none defined.
  50. virtual const Vector<AttributeInfo>* GetAttributes() const;
  51. /// Return network replication attribute descriptions, or null if none defined.
  52. virtual const Vector<AttributeInfo>* GetNetworkAttributes() const;
  53. /// 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.
  54. virtual bool Load(Deserializer& source, bool setInstanceDefault = false);
  55. /// Save as binary data. Return true if successful.
  56. virtual bool Save(Serializer& dest) const;
  57. /// 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.
  58. virtual bool LoadXML(const XMLElement& source, bool setInstanceDefault = false);
  59. /// Save as XML data. Return true if successful.
  60. virtual bool SaveXML(XMLElement& dest) const;
  61. /// 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.
  62. virtual bool LoadJSON(const JSONValue& source, bool setInstanceDefault = false);
  63. /// Save as JSON data. Return true if successful.
  64. virtual bool SaveJSON(JSONValue& dest) const;
  65. /// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
  66. virtual void ApplyAttributes() { }
  67. /// Return whether should save default-valued attributes into XML. Default false.
  68. virtual bool SaveDefaultAttributes() const { return false; }
  69. /// Mark for attribute check on the next network update.
  70. virtual void MarkNetworkUpdate() { }
  71. /// Set attribute by index. Return true if successfully set.
  72. bool SetAttribute(unsigned index, const Variant& value);
  73. /// Set attribute by name. Return true if successfully set.
  74. bool SetAttribute(const String& name, const Variant& value);
  75. /// Reset all editable attributes to their default values.
  76. void ResetToDefault();
  77. /// Remove instance's default values if they are set previously.
  78. void RemoveInstanceDefault();
  79. /// Set temporary flag. Temporary objects will not be saved.
  80. void SetTemporary(bool enable);
  81. /// 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.
  82. void SetInterceptNetworkUpdate(const String& attributeName, bool enable);
  83. /// Allocate network attribute state.
  84. void AllocateNetworkState();
  85. /// Write initial delta network update.
  86. void WriteInitialDeltaUpdate(Serializer& dest, unsigned char timeStamp);
  87. /// Write a delta network update according to dirty attribute bits.
  88. void WriteDeltaUpdate(Serializer& dest, const DirtyBits& attributeBits, unsigned char timeStamp);
  89. /// Write a latest data network update.
  90. void WriteLatestDataUpdate(Serializer& dest, unsigned char timeStamp);
  91. /// Read and apply a network delta update. Return true if attributes were changed.
  92. bool ReadDeltaUpdate(Deserializer& source);
  93. /// Read and apply a network latest data update. Return true if attributes were changed.
  94. bool ReadLatestDataUpdate(Deserializer& source);
  95. /// Return attribute value by index. Return empty if illegal index.
  96. Variant GetAttribute(unsigned index) const;
  97. /// Return attribute value by name. Return empty if not found.
  98. Variant GetAttribute(const String& name) const;
  99. /// Return attribute default value by index. Return empty if illegal index.
  100. Variant GetAttributeDefault(unsigned index) const;
  101. /// Return attribute default value by name. Return empty if not found.
  102. Variant GetAttributeDefault(const String& name) const;
  103. /// Return number of attributes.
  104. unsigned GetNumAttributes() const;
  105. /// Return number of network replication attributes.
  106. unsigned GetNumNetworkAttributes() const;
  107. /// Return whether is temporary.
  108. bool IsTemporary() const { return temporary_; }
  109. /// Return whether an attribute's network updates are being intercepted.
  110. bool GetInterceptNetworkUpdate(const String& attributeName) const;
  111. /// Return the network attribute state, if allocated.
  112. NetworkState* GetNetworkState() const { return networkState_.Get(); }
  113. protected:
  114. /// Network attribute state.
  115. UniquePtr<NetworkState> networkState_;
  116. private:
  117. /// Set instance-level default value. Allocate the internal data structure as necessary.
  118. void SetInstanceDefault(const String& name, const Variant& defaultValue);
  119. /// Get instance-level default value.
  120. Variant GetInstanceDefault(const String& name) const;
  121. /// Attribute default value at each instance level.
  122. UniquePtr<VariantMap> instanceDefaultValues_;
  123. /// Temporary flag.
  124. bool temporary_;
  125. };
  126. /// Template implementation of the enum attribute accessor invoke helper class.
  127. template <typename T, typename U> class EnumAttributeAccessorImpl : public AttributeAccessor
  128. {
  129. public:
  130. typedef U (T::*GetFunctionPtr)() const;
  131. typedef void (T::*SetFunctionPtr)(U);
  132. /// Construct with function pointers.
  133. EnumAttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
  134. getFunction_(getFunction),
  135. setFunction_(setFunction)
  136. {
  137. assert(getFunction_);
  138. assert(setFunction_);
  139. }
  140. /// Invoke getter function.
  141. virtual void Get(const Serializable* ptr, Variant& dest) const
  142. {
  143. assert(ptr);
  144. const T* classPtr = static_cast<const T*>(ptr);
  145. dest = (int)(classPtr->*getFunction_)();
  146. }
  147. /// Invoke setter function.
  148. virtual void Set(Serializable* ptr, const Variant& value)
  149. {
  150. assert(ptr);
  151. T* classPtr = static_cast<T*>(ptr);
  152. (classPtr->*setFunction_)((U)value.GetInt());
  153. }
  154. /// Class-specific pointer to getter function.
  155. GetFunctionPtr getFunction_;
  156. /// Class-specific pointer to setter function.
  157. SetFunctionPtr setFunction_;
  158. };
  159. /// Template implementation of the enum attribute accessor that uses free functions invoke helper class.
  160. template <typename T, typename U> class EnumAttributeAccessorFreeImpl : public AttributeAccessor
  161. {
  162. public:
  163. typedef U(*GetFunctionPtr)(const T*);
  164. typedef void(*SetFunctionPtr)(T*, U);
  165. /// Construct with function pointers.
  166. EnumAttributeAccessorFreeImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
  167. getFunction_(getFunction),
  168. setFunction_(setFunction)
  169. {
  170. assert(getFunction_);
  171. assert(setFunction_);
  172. }
  173. /// Invoke getter function.
  174. virtual void Get(const Serializable* ptr, Variant& dest) const
  175. {
  176. assert(ptr);
  177. const T* classPtr = static_cast<const T*>(ptr);
  178. dest = (*getFunction_)(classPtr);
  179. }
  180. /// Invoke setter function.
  181. virtual void Set(Serializable* ptr, const Variant& value)
  182. {
  183. assert(ptr);
  184. T* classPtr = static_cast<T*>(ptr);
  185. (*setFunction_)(classPtr, (U)value.GetInt());
  186. }
  187. /// Class-specific pointer to getter function.
  188. GetFunctionPtr getFunction_;
  189. /// Class-specific pointer to setter function.
  190. SetFunctionPtr setFunction_;
  191. };
  192. /// Attribute trait (default use const reference for object type).
  193. template <typename T> struct AttributeTrait
  194. {
  195. /// Get function return type.
  196. typedef const T& ReturnType;
  197. /// Set function parameter type.
  198. typedef const T& ParameterType;
  199. };
  200. /// Int attribute trait.
  201. template <> struct AttributeTrait<int>
  202. {
  203. typedef int ReturnType;
  204. typedef int ParameterType;
  205. };
  206. /// unsigned attribute trait.
  207. template <> struct AttributeTrait<unsigned>
  208. {
  209. typedef unsigned ReturnType;
  210. typedef unsigned ParameterType;
  211. };
  212. /// Bool attribute trait.
  213. template <> struct AttributeTrait<bool>
  214. {
  215. typedef bool ReturnType;
  216. typedef bool ParameterType;
  217. };
  218. /// Float attribute trait.
  219. template <> struct AttributeTrait<float>
  220. {
  221. typedef float ReturnType;
  222. typedef float ParameterType;
  223. };
  224. /// Mixed attribute trait (use const reference for set function only).
  225. template <typename T> struct MixedAttributeTrait
  226. {
  227. typedef T ReturnType;
  228. typedef const T& ParameterType;
  229. };
  230. /// Template implementation of the attribute accessor invoke helper class.
  231. template <typename T, typename U, typename Trait> class AttributeAccessorImpl : public AttributeAccessor
  232. {
  233. public:
  234. typedef typename Trait::ReturnType (T::*GetFunctionPtr)() const;
  235. typedef void (T::*SetFunctionPtr)(typename Trait::ParameterType);
  236. /// Construct with function pointers.
  237. AttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
  238. getFunction_(getFunction),
  239. setFunction_(setFunction)
  240. {
  241. assert(getFunction_);
  242. assert(setFunction_);
  243. }
  244. /// Invoke getter function.
  245. virtual void Get(const Serializable* ptr, Variant& dest) const
  246. {
  247. assert(ptr);
  248. const T* classPtr = static_cast<const T*>(ptr);
  249. dest = (classPtr->*getFunction_)();
  250. }
  251. /// Invoke setter function.
  252. virtual void Set(Serializable* ptr, const Variant& value)
  253. {
  254. assert(ptr);
  255. T* classPtr = static_cast<T*>(ptr);
  256. (classPtr->*setFunction_)(value.Get<U>());
  257. }
  258. /// Class-specific pointer to getter function.
  259. GetFunctionPtr getFunction_;
  260. /// Class-specific pointer to setter function.
  261. SetFunctionPtr setFunction_;
  262. };
  263. /// Template implementation of the attribute accessor that uses free functions invoke helper class.
  264. template <typename T, typename U, typename Trait> class AttributeAccessorFreeImpl : public AttributeAccessor
  265. {
  266. public:
  267. typedef typename Trait::ReturnType(*GetFunctionPtr)(const T*);
  268. typedef void(*SetFunctionPtr)(T*, typename Trait::ParameterType);
  269. /// Construct with function pointers.
  270. AttributeAccessorFreeImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
  271. getFunction_(getFunction),
  272. setFunction_(setFunction)
  273. {
  274. assert(getFunction_);
  275. assert(setFunction_);
  276. }
  277. /// Invoke getter function.
  278. virtual void Get(const Serializable* ptr, Variant& dest) const
  279. {
  280. assert(ptr);
  281. const T* classPtr = static_cast<const T*>(ptr);
  282. dest = (*getFunction_)(classPtr);
  283. }
  284. /// Invoke setter function.
  285. virtual void Set(Serializable* ptr, const Variant& value)
  286. {
  287. assert(ptr);
  288. T* classPtr = static_cast<T*>(ptr);
  289. (*setFunction_)(classPtr, value.Get<U>());
  290. }
  291. /// Class-specific pointer to getter function.
  292. GetFunctionPtr getFunction_;
  293. /// Class-specific pointer to setter function.
  294. SetFunctionPtr setFunction_;
  295. };
  296. // The following macros need to be used within a class member function such as ClassName::RegisterObject().
  297. // A variable called "context" needs to exist in the current scope and point to a valid Context object.
  298. /// Copy attributes from a base class.
  299. #define ATOMIC_COPY_BASE_ATTRIBUTES(sourceClassName) context->CopyBaseAttributes<sourceClassName, ClassName>()
  300. /// Remove attribute by name.
  301. #define ATOMIC_REMOVE_ATTRIBUTE(name) context->RemoveAttribute<ClassName>(name)
  302. /// Define an attribute that points to a memory offset in the object.
  303. #define ATOMIC_ATTRIBUTE(name, typeName, variable, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(Atomic::GetVariantType<typeName >(), name, offsetof(ClassName, variable), defaultValue, mode))
  304. /// 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.
  305. #define ATOMIC_ENUM_ATTRIBUTE(name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(name, offsetof(ClassName, variable), enumNames, defaultValue, mode))
  306. /// Define an attribute that uses get and set functions.
  307. #define ATOMIC_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(Atomic::GetVariantType<typeName >(), name, new Atomic::AttributeAccessorImpl<ClassName, typeName, Atomic::AttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, mode))
  308. /// Define an attribute that uses get and set free functions.
  309. #define ATOMIC_ACCESSOR_ATTRIBUTE_FREE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(Atomic::GetVariantType<typeName >(), name, new Atomic::AttributeAccessorFreeImpl<ClassName, typeName, Atomic::AttributeTrait<typeName > >(getFunction, setFunction), defaultValue, mode))
  310. /// 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.
  311. #define ATOMIC_ENUM_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(name, new Atomic::EnumAttributeAccessorImpl<ClassName, typeName >(&ClassName::getFunction, &ClassName::setFunction), enumNames, defaultValue, mode))
  312. /// 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.
  313. #define ATOMIC_ENUM_ACCESSOR_ATTRIBUTE_FREE(name, getFunction, setFunction, typeName, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(name, new Atomic::EnumAttributeAccessorFreeImpl<ClassName, typeName >(getFunction, setFunction), enumNames, defaultValue, mode))
  314. /// Define an attribute that uses get and set functions, where the get function returns by value, but the set function uses a reference.
  315. #define ATOMIC_MIXED_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(Atomic::GetVariantType<typeName >(), name, new Atomic::AttributeAccessorImpl<ClassName, typeName, Atomic::MixedAttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, mode))
  316. /// Define an attribute that uses get and set free functions, where the get function returns by value, but the set function uses a reference.
  317. #define ATOMIC_MIXED_ACCESSOR_ATTRIBUTE_FREE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(Atomic::GetVariantType<typeName >(), name, new Atomic::AttributeAccessorFreeImpl<ClassName, typeName, Atomic::MixedAttributeTrait<typeName > >(getFunction, setFunction), defaultValue, mode))
  318. /// Update the default value of an already registered attribute.
  319. #define ATOMIC_UPDATE_ATTRIBUTE_DEFAULT_VALUE(name, defaultValue) context->UpdateAttributeDefaultValue<ClassName>(name, defaultValue)
  320. /// Define a variant structure attribute that uses get and set functions.
  321. #define ATOMIC_ACCESSOR_VARIANT_VECTOR_STRUCTURE_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, variantStructureElementNames, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(Atomic::GetVariantType<typeName >(), name, new Atomic::AttributeAccessorImpl<ClassName, typeName, Atomic::AttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, variantStructureElementNames, mode))
  322. /// 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.
  323. #define ATOMIC_MIXED_ACCESSOR_VARIANT_VECTOR_STRUCTURE_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, variantStructureElementNames, mode) context->RegisterAttribute<ClassName>(Atomic::AttributeInfo(Atomic::GetVariantType<typeName >(), name, new Atomic::AttributeAccessorImpl<ClassName, typeName, Atomic::MixedAttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, variantStructureElementNames, mode))
  324. }