UnknownComponent.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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. #include "../Precompiled.h"
  23. #include "../Core/Context.h"
  24. #include "../IO/Deserializer.h"
  25. #include "../IO/Log.h"
  26. #include "../IO/Serializer.h"
  27. #include "../Resource/XMLElement.h"
  28. #include "../Resource/JSONValue.h"
  29. #include "../Scene/UnknownComponent.h"
  30. #include "../DebugNew.h"
  31. namespace Atomic
  32. {
  33. static HashMap<StringHash, String> unknownTypeToName;
  34. static String letters("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
  35. static String GenerateNameFromType(StringHash typeHash)
  36. {
  37. if (unknownTypeToName.Contains(typeHash))
  38. return unknownTypeToName[typeHash];
  39. String test;
  40. // Begin brute-force search
  41. unsigned numLetters = letters.Length();
  42. unsigned combinations = numLetters;
  43. bool found = false;
  44. for (unsigned i = 1; i < 6; ++i)
  45. {
  46. test.Resize(i);
  47. for (unsigned j = 0; j < combinations; ++j)
  48. {
  49. unsigned current = j;
  50. for (unsigned k = 0; k < i; ++k)
  51. {
  52. test[k] = letters[current % numLetters];
  53. current /= numLetters;
  54. }
  55. if (StringHash(test) == typeHash)
  56. {
  57. found = true;
  58. break;
  59. }
  60. }
  61. if (found)
  62. break;
  63. combinations *= numLetters;
  64. }
  65. unknownTypeToName[typeHash] = test;
  66. return test;
  67. }
  68. UnknownComponent::UnknownComponent(Context* context) :
  69. Component(context),
  70. useXML_(false)
  71. {
  72. }
  73. void UnknownComponent::RegisterObject(Context* context)
  74. {
  75. context->RegisterFactory<UnknownComponent>();
  76. }
  77. bool UnknownComponent::Load(Deserializer& source, bool setInstanceDefault)
  78. {
  79. useXML_ = false;
  80. xmlAttributes_.Clear();
  81. xmlAttributeInfos_.Clear();
  82. // Assume we are reading from a component data buffer, and the type has already been read
  83. unsigned dataSize = source.GetSize() - source.GetPosition();
  84. binaryAttributes_.Resize(dataSize);
  85. return dataSize ? source.Read(&binaryAttributes_[0], dataSize) == dataSize : true;
  86. }
  87. bool UnknownComponent::LoadXML(const XMLElement& source, bool setInstanceDefault)
  88. {
  89. useXML_ = true;
  90. xmlAttributes_.Clear();
  91. xmlAttributeInfos_.Clear();
  92. binaryAttributes_.Clear();
  93. XMLElement attrElem = source.GetChild("attribute");
  94. while (attrElem)
  95. {
  96. AttributeInfo attr;
  97. attr.mode_ = AM_FILE;
  98. attr.name_ = attrElem.GetAttribute("name");
  99. attr.type_ = VAR_STRING;
  100. if (!attr.name_.Empty())
  101. {
  102. String attrValue = attrElem.GetAttribute("value");
  103. attr.defaultValue_ = String::EMPTY;
  104. xmlAttributeInfos_.Push(attr);
  105. xmlAttributes_.Push(attrValue);
  106. }
  107. attrElem = attrElem.GetNext("attribute");
  108. }
  109. // Fix up pointers to the attributes after all have been read
  110. for (unsigned i = 0; i < xmlAttributeInfos_.Size(); ++i)
  111. xmlAttributeInfos_[i].ptr_ = &xmlAttributes_[i];
  112. return true;
  113. }
  114. bool UnknownComponent::LoadJSON(const JSONValue& source, bool setInstanceDefault)
  115. {
  116. useXML_ = true;
  117. xmlAttributes_.Clear();
  118. xmlAttributeInfos_.Clear();
  119. binaryAttributes_.Clear();
  120. JSONArray attributesArray = source.Get("attributes").GetArray();
  121. for (unsigned i = 0; i < attributesArray.Size(); i++)
  122. {
  123. const JSONValue& attrVal = attributesArray.At(i);
  124. AttributeInfo attr;
  125. attr.mode_ = AM_FILE;
  126. attr.name_ = attrVal.Get("name").GetString();
  127. attr.type_ = VAR_STRING;
  128. if (!attr.name_.Empty())
  129. {
  130. String attrValue = attrVal.Get("value").GetString();
  131. attr.defaultValue_ = String::EMPTY;
  132. xmlAttributeInfos_.Push(attr);
  133. xmlAttributes_.Push(attrValue);
  134. }
  135. }
  136. // Fix up pointers to the attributes after all have been read
  137. for (unsigned i = 0; i < xmlAttributeInfos_.Size(); ++i)
  138. xmlAttributeInfos_[i].ptr_ = &xmlAttributes_[i];
  139. return true;
  140. }
  141. bool UnknownComponent::Save(Serializer& dest) const
  142. {
  143. if (useXML_)
  144. ATOMIC_LOGWARNING("UnknownComponent loaded in XML mode, attributes will be empty for binary save");
  145. // Write type and ID
  146. if (!dest.WriteStringHash(GetType()))
  147. return false;
  148. if (!dest.WriteUInt(id_))
  149. return false;
  150. if (!binaryAttributes_.Size())
  151. return true;
  152. else
  153. return dest.Write(&binaryAttributes_[0], binaryAttributes_.Size()) == binaryAttributes_.Size();
  154. }
  155. bool UnknownComponent::SaveXML(XMLElement& dest) const
  156. {
  157. if (dest.IsNull())
  158. {
  159. ATOMIC_LOGERROR("Could not save " + GetTypeName() + ", null destination element");
  160. return false;
  161. }
  162. if (!useXML_)
  163. ATOMIC_LOGWARNING("UnknownComponent loaded in binary or JSON mode, attributes will be empty for XML save");
  164. // Write type and ID
  165. if (!dest.SetString("type", GetTypeName()))
  166. return false;
  167. if (!dest.SetInt("id", id_))
  168. return false;
  169. for (unsigned i = 0; i < xmlAttributeInfos_.Size(); ++i)
  170. {
  171. XMLElement attrElem = dest.CreateChild("attribute");
  172. attrElem.SetAttribute("name", xmlAttributeInfos_[i].name_);
  173. attrElem.SetAttribute("value", xmlAttributes_[i]);
  174. }
  175. return true;
  176. }
  177. bool UnknownComponent::SaveJSON(JSONValue& dest) const
  178. {
  179. if (!useXML_)
  180. ATOMIC_LOGWARNING("UnknownComponent loaded in binary mode, attributes will be empty for JSON save");
  181. // Write type and ID
  182. dest.Set("type", GetTypeName());
  183. dest.Set("id", (int) id_);
  184. JSONArray attributesArray;
  185. attributesArray.Reserve(xmlAttributeInfos_.Size());
  186. for (unsigned i = 0; i < xmlAttributeInfos_.Size(); ++i)
  187. {
  188. JSONValue attrVal;
  189. attrVal.Set("name", xmlAttributeInfos_[i].name_);
  190. attrVal.Set("value", xmlAttributes_[i]);
  191. attributesArray.Push(attrVal);
  192. }
  193. dest.Set("attributes", attributesArray);
  194. return true;
  195. }
  196. void UnknownComponent::SetTypeName(const String& typeName)
  197. {
  198. typeName_ = typeName;
  199. typeHash_ = typeName;
  200. }
  201. void UnknownComponent::SetType(StringHash typeHash)
  202. {
  203. typeName_ = GenerateNameFromType(typeHash);
  204. typeHash_ = typeHash;
  205. }
  206. }