2
0

BsManagedSerializableDictionary.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsScriptEnginePrerequisites.h"
  5. #include "Reflection/BsIReflectable.h"
  6. namespace bs
  7. {
  8. /** @addtogroup SBansheeEngine
  9. * @{
  10. */
  11. /** Contains key and value data used for serializing a managed dictionary. */
  12. struct BS_SCR_BE_EXPORT ManagedSerializableDictionaryKeyValue : public IReflectable
  13. {
  14. ManagedSerializableDictionaryKeyValue() {}
  15. ManagedSerializableDictionaryKeyValue(const SPtr<ManagedSerializableFieldData>& key,
  16. const SPtr<ManagedSerializableFieldData>& value);
  17. SPtr<ManagedSerializableFieldData> key;
  18. SPtr<ManagedSerializableFieldData> value;
  19. /************************************************************************/
  20. /* RTTI */
  21. /************************************************************************/
  22. public:
  23. friend class ManagedSerializableDictionaryKeyValueRTTI;
  24. static RTTITypeBase* getRTTIStatic();
  25. virtual RTTITypeBase* getRTTI() const override;
  26. };
  27. /**
  28. * Allows access to an underlying managed dictionary, or a cached version of that dictionary that can be
  29. * serialized/deserialized.
  30. *
  31. * @note
  32. * This class can be in two states:
  33. * - Linked - When the object has a link to a managed object. This is the default state when a new instance
  34. * of ManagedSerializableObject is created. Any operations during this state will operate directly
  35. * on the linked managed object.
  36. * - Serialized - When the object has no link to the managed object but instead just contains cached object
  37. * and field data that may be used for initializing a managed object. Any operations during
  38. * this state will operate only on the cached internal data.
  39. * You can transfer between these states by calling serialize(linked->serialized) & deserialize (serialized->linked).
  40. */
  41. class BS_SCR_BE_EXPORT ManagedSerializableDictionary : public IReflectable
  42. {
  43. private:
  44. struct ConstructPrivately {};
  45. /** Generates a hash value for field data. */
  46. struct BS_SCR_BE_EXPORT Hash
  47. {
  48. inline size_t operator()(const SPtr<ManagedSerializableFieldData>& x) const;
  49. };
  50. /** Compares two field data objects. */
  51. struct BS_SCR_BE_EXPORT Equals
  52. {
  53. inline bool operator()(const SPtr<ManagedSerializableFieldData>& a, const SPtr<ManagedSerializableFieldData>& b) const;
  54. };
  55. public:
  56. typedef UnorderedMap<SPtr<ManagedSerializableFieldData>, SPtr<ManagedSerializableFieldData>> CachedEntriesMap;
  57. /**
  58. * Helper class that enumerates over all entires in a managed dictionary. Operates on managed object if the parent
  59. * dictionary is in linked state, or on cached data otherwise.
  60. */
  61. class Enumerator
  62. {
  63. public:
  64. /**
  65. * Constructs a new enumerator for the provided managed object.
  66. *
  67. * @param[in] instance Managed instance of type System.Collections.Generic.Dictionary.
  68. * @param[in] parent Serializable parent of the managed instance.
  69. */
  70. Enumerator(MonoObject* instance, const ManagedSerializableDictionary* parent);
  71. /**
  72. * Returns the wrapped key data at the current enumerator position. Only valid to call this if enumerator is
  73. * valid (meaning last call to moveNext() returned true).
  74. */
  75. SPtr<ManagedSerializableFieldData> getKey() const;
  76. /**
  77. * Returns the wrapped value data at the current enumerator position. Only valid to call this if enumerator is
  78. * valid (meaning last call to moveNext() returned true).
  79. */
  80. SPtr<ManagedSerializableFieldData> getValue() const;
  81. /**
  82. * Moves the enumerator to the next position. Initially enumerator is at an invalid position and must be called
  83. * at least once before accesing its data.
  84. *
  85. * @return Returns if the enumerator is at valid position. When the enumerator returns false it means there are
  86. * no more elements to enumerate.
  87. */
  88. bool moveNext();
  89. private:
  90. MonoObject* mInstance;
  91. MonoObject* mCurrent;
  92. CachedEntriesMap::const_iterator mCachedIter;
  93. bool mIteratorInitialized;
  94. const ManagedSerializableDictionary* mParent;
  95. };
  96. public:
  97. ManagedSerializableDictionary(const ConstructPrivately& dummy, const SPtr<ManagedSerializableTypeInfoDictionary>& typeInfo, MonoObject* managedInstance);
  98. ManagedSerializableDictionary(const ConstructPrivately& dummy);
  99. /**
  100. * Returns the internal managed instance of the dictionary. This will return null if the object is in serialized
  101. * mode.
  102. */
  103. MonoObject* getManagedInstance() const { return mManagedInstance; }
  104. /** Returns the type information for the internal dictionary. */
  105. SPtr<ManagedSerializableTypeInfoDictionary> getTypeInfo() const { return mDictionaryTypeInfo; }
  106. /**
  107. * Returns the dictionary value at the specified key. If the key doesn't exist the default value for the type is
  108. * returned. Operates on managed object if in linked state, or on cached data otherwise.
  109. *
  110. * @param[in] key Wrapper around the key data at which to retrieve the value.
  111. * @return A wrapper around the value in the dictionary at the specified key.
  112. */
  113. SPtr<ManagedSerializableFieldData> getFieldData(const SPtr<ManagedSerializableFieldData>& key);
  114. /**
  115. * Sets the dictionary value at the specified key. Operates on managed object if in linked state, or on cached data
  116. * otherwise.
  117. *
  118. * @param[in] key Wrapper around the key data at which to set the value.
  119. * @param[in] val Wrapper around the value to set at the specified key.
  120. */
  121. void setFieldData(const SPtr<ManagedSerializableFieldData>& key, const SPtr<ManagedSerializableFieldData>& val);
  122. /**
  123. * Deletes the key/value pair at the specified key. If the key doesn't exist this operation does nothing. Operates
  124. * on managed object if in linked state, or on cached data otherwise.
  125. *
  126. * @param[in] key Wrapper around the key data at which to delete the value.
  127. */
  128. void removeFieldData(const SPtr<ManagedSerializableFieldData>& key);
  129. /**
  130. * Checks if the dictionary contains the specified key. Operates on managed object if in linked state, or on cached
  131. * data otherwise.
  132. *
  133. * @param[in] key Wrapper around the key data which to check.
  134. */
  135. bool contains(const SPtr<ManagedSerializableFieldData>& key) const;
  136. /** Returns an enumerator object that allows you to iterate over all key/value pairs in the dictionary. */
  137. Enumerator getEnumerator() const;
  138. /**
  139. * Serializes the internal managed object into a set of cached data that can be saved in memory/disk and can be
  140. * deserialized later. Does nothing if object is already is serialized mode. When in serialized mode the reference
  141. * to the managed instance will be lost.
  142. */
  143. void serialize();
  144. /**
  145. * Deserializes a set of cached data into a managed object. This action may fail in case the cached data contains a
  146. * type that no longer exists. You may check if it completely successfully if getManagedInstance() returns non-null
  147. * after.
  148. *
  149. * This action transfers the object into linked mode. All further operations will operate directly on the managed
  150. * instance and the cached data will be cleared. If you call this method on an already linked object the old object
  151. * will be replaced and initialized with empty data (since cached data does not exist).
  152. */
  153. void deserialize();
  154. /**
  155. * Creates a managed serializable dictionary that references an existing managed dictionary. Created object will be
  156. * in linked mode.
  157. *
  158. * @param[in] managedInstance Constructed managed instance of the dictionary to link with. Its type must
  159. * correspond with the provided type info.
  160. * @param[in] typeInfo Type information for the dictionary and its key/value pair.
  161. */
  162. static SPtr<ManagedSerializableDictionary> createFromExisting(MonoObject* managedInstance, const SPtr<ManagedSerializableTypeInfoDictionary>& typeInfo);
  163. /**
  164. * Creates a managed serializable dictionary that creates and references a brand new managed dictionary instance.
  165. *
  166. * @param[in] typeInfo Type of the dictionary to create.
  167. */
  168. static SPtr<ManagedSerializableDictionary> createNew(const SPtr<ManagedSerializableTypeInfoDictionary>& typeInfo);
  169. /**
  170. * Creates a managed dictionary instance.
  171. *
  172. * @param[in] typeInfo Type of the dictionary to create.
  173. */
  174. static MonoObject* createManagedInstance(const SPtr<ManagedSerializableTypeInfoDictionary>& typeInfo);
  175. protected:
  176. /**
  177. * Retrieves needed Mono types and methods. Should be called before performing any operations with the managed
  178. * object.
  179. */
  180. void initMonoObjects(MonoClass* dictionaryClass);
  181. MonoObject* mManagedInstance;
  182. MonoMethod* mAddMethod;
  183. MonoMethod* mRemoveMethod;
  184. MonoMethod* mTryGetValueMethod;
  185. MonoMethod* mContainsKeyMethod;
  186. MonoMethod* mGetEnumerator;
  187. MonoMethod* mEnumMoveNext;
  188. MonoProperty* mEnumCurrentProp;
  189. MonoProperty* mKeyProp;
  190. MonoProperty* mValueProp;
  191. SPtr<ManagedSerializableTypeInfoDictionary> mDictionaryTypeInfo;
  192. CachedEntriesMap mCachedEntries;
  193. /************************************************************************/
  194. /* RTTI */
  195. /************************************************************************/
  196. /** Creates an empty and uninitialized object used for serialization purposes. */
  197. static SPtr<ManagedSerializableDictionary> createEmpty();
  198. public:
  199. friend class ManagedSerializableDictionaryRTTI;
  200. static RTTITypeBase* getRTTIStatic();
  201. virtual RTTITypeBase* getRTTI() const override;
  202. };
  203. /** @} */
  204. }