Serializable.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include "Attribute.h"
  25. #include "Object.h"
  26. class Deserializer;
  27. class Serializer;
  28. class XMLElement;
  29. /// Base class for objects with automatic serialization through attributes
  30. class Serializable : public Object
  31. {
  32. OBJECT(Serializable);
  33. public:
  34. /// Construct
  35. Serializable(Context* context);
  36. /// Destruct
  37. virtual ~Serializable();
  38. /// Handle attribute write access. Default implementation writes to the variable at offset, or invokes the set accessor
  39. virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& value);
  40. /// Handle attribute read access. Default implementation reads the variable at offset, or invokes the get accessor
  41. virtual Variant OnGetAttribute(const AttributeInfo& attr);
  42. /// Load from binary data. Return true if successful
  43. virtual bool Load(Deserializer& source);
  44. /// Save as binary data. Return true if successful
  45. virtual bool Save(Serializer& dest);
  46. /// Load from XML data. Return true if successful
  47. virtual bool LoadXML(const XMLElement& source);
  48. /// Save as XML data. Return true if successful
  49. virtual bool SaveXML(XMLElement& dest);
  50. /// Perform post-load after the whole scene has been loaded
  51. virtual void PostLoad() {}
  52. /// Set attribute by index. Return true if successfully set
  53. bool SetAttribute(unsigned index, const Variant& value);
  54. /// Set attribute by name. Return true if successfully set
  55. bool SetAttribute(const std::string& name, const Variant& value);
  56. /// Return attribute value by index. Return empty if illegal index
  57. Variant GetAttribute(unsigned index);
  58. /// Return attribute value by name. Return empty if not found
  59. Variant GetAttribute(const std::string& name);
  60. /// Return number of attributes
  61. unsigned GetNumAttributes() const;
  62. /// Return attribute descriptions, or null if none defined
  63. const std::vector<AttributeInfo>* GetAttributes() const;
  64. protected:
  65. /// In serialization -flag
  66. bool inSerialization_;
  67. /// In network replication -flag
  68. bool inNetwork_;
  69. };
  70. /// Template implementation of the attribute accessor invoke helper class (stores function pointers of specific class)
  71. template <class T, class U> class AttributeAccessorImpl : public AttributeAccessor
  72. {
  73. public:
  74. typedef U (T::*GetFunctionPtr)() const;
  75. typedef void (T::*SetFunctionPtr)(U);
  76. /// Construct with function pointers
  77. AttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
  78. getFunction_(getFunction),
  79. setFunction_(setFunction)
  80. {
  81. }
  82. /// Invoke getter function
  83. virtual Variant Get(Serializable* ptr)
  84. {
  85. T* classPtr = static_cast<T*>(ptr);
  86. return Variant((classPtr->*getFunction_)());
  87. }
  88. /// Invoke setter function
  89. virtual void Set(Serializable* ptr, const Variant& value)
  90. {
  91. T* classPtr = static_cast<T*>(ptr);
  92. (classPtr->*setFunction_)(value.Get<U>());
  93. }
  94. /// Class-specific pointer to getter function
  95. GetFunctionPtr getFunction_;
  96. /// Class-specific pointer to setter function
  97. SetFunctionPtr setFunction_;
  98. };
  99. #define ATTRIBUTE(className, type, name, variable, defaultValue) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), defaultValue, AM_BOTH))
  100. #define ATTRIBUTE_MODE(className, type, name, variable, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), defaultValue, mode))
  101. #define ENUM_ATTRIBUTE(className, name, variable, enumNames, defaultValue) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, AM_BOTH))
  102. #define ENUM_ATTRIBUTE_MODE(className, name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, mode))
  103. #define ACCESSOR_ATTRIBUTE(className, type, name, getFunction, setFunction, typeName, defaultValue) context->RegisterAttribute<className>(AttributeInfo(type, name, new AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, AM_BOTH))
  104. #define ACCESSOR_ATTRIBUTE_MODE(className, type, name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, new AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, mode))