TypeRegistry.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #pragma once
  2. #include <cstdlib>
  3. #include <JSON.h>
  4. #include <typeinfo>
  5. #include "Dimension.h"
  6. #include "DimensionGenerator.h"
  7. #include "GeneratorRule.h"
  8. class TypeRegistry;
  9. /*
  10. * Used to convert an object of type T to a JSONValue and vice versa.
  11. * Can be registered at the TypeRegistry to be used by the JSON system
  12. */
  13. template<typename T> class TypeFactory : public Framework::ReferenceCounter
  14. {
  15. public:
  16. TypeFactory()
  17. : ReferenceCounter(){};
  18. virtual T* fromJson(Framework::JSON::JSONValue* zJson) const = 0;
  19. virtual Framework::JSON::JSONValue* toJSON(T* zObject) const = 0;
  20. virtual Framework::JSON::Validator::JSONValidator* getValidator() const = 0;
  21. };
  22. /*
  23. * Used to convert an object of type S witch inherits from type T to a JSONValue
  24. * and vice versa. Can be registered at the TypeRegistry to be used by the JSON
  25. */
  26. template<typename T,
  27. typename S,
  28. typename = std::enable_if<std::is_base_of<T, S>::value>>
  29. class SubTypeFactory : public Framework::ReferenceCounter
  30. {
  31. public:
  32. SubTypeFactory()
  33. : ReferenceCounter(){};
  34. virtual S* fromJson(Framework::JSON::JSONObject* zJson) const = 0;
  35. virtual Framework::JSON::JSONObject* toJSON(S* zObject) const = 0;
  36. virtual Framework::JSON::Validator::JSONValidator* getValidator(
  37. Framework::JSON::Validator::ObjectValidationBuilder<
  38. Framework::JSON::Validator::JSONValidator>* builder) const
  39. = 0;
  40. virtual Framework::Text getTypeToken() const = 0;
  41. };
  42. template<typename T> class SubTypeFactoryRef
  43. : public Framework::ReferenceCounter
  44. {
  45. private:
  46. Framework::Text typetoken;
  47. std::function<T*(Framework::JSON::JSONObject*)> fromJsonFunc;
  48. std::function<Framework::JSON::JSONObject*(T*)> toJsonFunc;
  49. std::function<Framework::JSON::Validator::JSONValidator*(
  50. Framework::JSON::Validator::ObjectValidationBuilder<
  51. Framework::JSON::Validator::JSONValidator>*)>
  52. getValidatorFunc;
  53. Framework::ReferenceCounter* factory;
  54. public:
  55. SubTypeFactoryRef(Framework::Text typetoken,
  56. std::function<T*(Framework::JSON::JSONObject*)> fromJsonFunc,
  57. std::function<Framework::JSON::JSONObject*(T*)> toJsonFunc,
  58. std::function<Framework::JSON::Validator::JSONValidator*(
  59. Framework::JSON::Validator::ObjectValidationBuilder<
  60. Framework::JSON::Validator::JSONValidator>*)> getValidatorFunc,
  61. Framework::ReferenceCounter* factory)
  62. : ReferenceCounter(),
  63. typetoken(typetoken),
  64. fromJsonFunc(fromJsonFunc),
  65. toJsonFunc(toJsonFunc),
  66. getValidatorFunc(getValidatorFunc),
  67. factory(factory)
  68. {}
  69. ~SubTypeFactoryRef()
  70. {
  71. factory->release();
  72. }
  73. T* fromJson(Framework::JSON::JSONObject* zJson) const
  74. {
  75. return fromJsonFunc(zJson);
  76. }
  77. Framework::JSON::JSONObject* toJSON(T* zObject) const
  78. {
  79. return toJsonFunc(zObject);
  80. }
  81. Framework::JSON::Validator::JSONValidator* getValidator(
  82. Framework::JSON::Validator::ObjectValidationBuilder<
  83. Framework::JSON::Validator::JSONValidator>* builder) const
  84. {
  85. return getValidatorFunc(builder);
  86. }
  87. const Framework::Text& getTypetoken() const
  88. {
  89. return typetoken;
  90. }
  91. };
  92. template<typename T> class PolymorphTypeFactory : public TypeFactory<T>
  93. {
  94. private:
  95. Framework::RCArray<SubTypeFactoryRef<T>> factories;
  96. public:
  97. PolymorphTypeFactory()
  98. : TypeFactory<T>()
  99. {}
  100. T* fromJson(Framework::JSON::JSONValue* zJson) const override
  101. {
  102. for (SubTypeFactoryRef<T>* factory : factories)
  103. {
  104. if (zJson->asObject()
  105. ->zValue("type")
  106. ->asString()
  107. ->getString()
  108. .istGleich(factory->getTypetoken()))
  109. {
  110. return factory->fromJson(zJson->asObject());
  111. }
  112. }
  113. return 0;
  114. }
  115. Framework::JSON::JSONValue* toJSON(T* zObject) const override
  116. {
  117. for (SubTypeFactoryRef<T>* factory : factories)
  118. {
  119. Framework::JSON::JSONObject* result = factory->toJSON(zObject);
  120. if (result)
  121. {
  122. result->addValue("type",
  123. new Framework::JSON::JSONString(factory->getTypetoken()));
  124. return result;
  125. }
  126. }
  127. return 0;
  128. }
  129. Framework::JSON::Validator::JSONValidator* getValidator() const override
  130. {
  131. auto validator
  132. = Framework::JSON::Validator::JSONValidator::buildForOneOf()
  133. ->typeSpecifiedByAttribute("type");
  134. for (SubTypeFactoryRef<T>* factory : factories)
  135. {
  136. validator = validator->addAcceptedType(factory->getValidator(
  137. Framework::JSON::Validator::JSONValidator::buildForObject()
  138. ->withRequiredString("type")
  139. ->withExactMatch(factory->getTypetoken())
  140. ->finishString()));
  141. }
  142. return validator->finishOneOf();
  143. }
  144. template<typename S,
  145. typename = std::enable_if<std::is_base_of<T, S>::value>>
  146. void addFactory(SubTypeFactory<T, S>* factory)
  147. {
  148. factories.add(new SubTypeFactoryRef<T>(
  149. factory->getTypeToken(),
  150. [factory](Framework::JSON::JSONObject* zJson) {
  151. S* value = factory->fromJson(zJson);
  152. if (value)
  153. {
  154. return dynamic_cast<T*>(factory->fromJson(zJson));
  155. }
  156. return (T*)0;
  157. },
  158. [factory](T* zObject) {
  159. S* value = dynamic_cast<S*>(zObject);
  160. if (value)
  161. {
  162. return factory->toJSON(value);
  163. }
  164. return (Framework::JSON::JSONObject*)0;
  165. },
  166. [factory](Framework::JSON::Validator::ObjectValidationBuilder<
  167. Framework::JSON::Validator::JSONValidator>* builder) {
  168. return factory->getValidator(builder);
  169. },
  170. dynamic_cast<Framework::ReferenceCounter*>(factory)));
  171. }
  172. };
  173. class TypeFatoryRef : public Framework::ReferenceCounter
  174. {
  175. private:
  176. std::function<void*(Framework::JSON::JSONValue*)> fromJsonFunc;
  177. std::function<Framework::JSON::JSONValue*(void*)> toJsonFunc;
  178. std::function<Framework::JSON::Validator::JSONValidator*()>
  179. getValidatorFunc;
  180. Framework::ReferenceCounter* factory;
  181. public:
  182. TypeFatoryRef(
  183. std::function<void*(Framework::JSON::JSONValue*)> fromJsonFunc,
  184. std::function<Framework::JSON::JSONValue*(void*)> toJsonFunc,
  185. std::function<Framework::JSON::Validator::JSONValidator*()>
  186. getValidatorFunc,
  187. Framework::ReferenceCounter* factory)
  188. : ReferenceCounter(),
  189. fromJsonFunc(fromJsonFunc),
  190. toJsonFunc(toJsonFunc),
  191. getValidatorFunc(getValidatorFunc),
  192. factory(factory)
  193. {}
  194. ~TypeFatoryRef()
  195. {
  196. factory->release();
  197. }
  198. void* fromJson(Framework::JSON::JSONValue* zJson) const
  199. {
  200. return fromJsonFunc(zJson);
  201. }
  202. Framework::JSON::JSONValue* toJSON(void* zObject) const
  203. {
  204. return toJsonFunc(zObject);
  205. }
  206. Framework::JSON::Validator::JSONValidator* getValidator() const
  207. {
  208. return getValidatorFunc();
  209. }
  210. template<typename T> TypeFactory<T>* zFactory() const
  211. {
  212. return (TypeFactory<T>*)(factory);
  213. }
  214. };
  215. class TypeRegistry : public Framework::ReferenceCounter
  216. {
  217. private:
  218. Framework::RCArray<GeneratorRuleFactory> generatorRules;
  219. Framework::RCArray<DimensionGeneratorFactory> dimensionGenerators;
  220. Framework::RCArray<DimensionFactory> dimensionFactories;
  221. Framework::RCTrie<TypeFatoryRef> parsableTypes;
  222. public:
  223. TypeRegistry();
  224. void registerGeneratorRuleFactory(GeneratorRuleFactory* factory);
  225. GeneratorRule* createGeneratorRule(
  226. Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
  227. Framework::JSON::Validator::JSONValidator* getGeneratorRuleValidator();
  228. void registerDimensionGeneratorFactory(DimensionGeneratorFactory* factory);
  229. DimensionGenerator* createDimensionGenerator(
  230. Framework::JSON::JSONValue* zConfig, int worldSeed);
  231. Framework::JSON::Validator::JSONValidator* getDimensionGeneratorValidator();
  232. const Framework::RCArray<DimensionGeneratorFactory>&
  233. getDimensionGeneratorFactories() const;
  234. void registerDimension(DimensionFactory* factory);
  235. Dimension* createDimension(int id);
  236. template<typename T,
  237. typename S,
  238. typename = std::enable_if<std::is_base_of<T, S>::value>>
  239. void registerSubType(SubTypeFactory<T, S>* factory)
  240. {
  241. Framework::Text typeId = typeid(T).name();
  242. TypeFatoryRef* typeFactoryRef
  243. = parsableTypes.z(typeId, typeId.getLength());
  244. if (!typeFactoryRef)
  245. {
  246. PolymorphTypeFactory<T>* polymorphFactory
  247. = new PolymorphTypeFactory<T>();
  248. registerType(polymorphFactory);
  249. typeFactoryRef = parsableTypes.z(typeId, typeId.getLength());
  250. }
  251. PolymorphTypeFactory<T>* polymorphFactory
  252. = dynamic_cast<PolymorphTypeFactory<T>*>(
  253. typeFactoryRef->zFactory<T>());
  254. if (!polymorphFactory)
  255. {
  256. throw Framework::Text("Type not registered as Polymorphic type: ")
  257. + typeId;
  258. }
  259. polymorphFactory->addFactory<S>(factory);
  260. }
  261. template<typename T> void registerType(TypeFactory<T>* factory)
  262. {
  263. Framework::Text typeId = typeid(T).name();
  264. TypeFatoryRef* typeFactoryRef
  265. = parsableTypes.z(typeId, typeId.getLength());
  266. if (typeFactoryRef)
  267. {
  268. throw Framework::Text("Type already registered: ") + typeId;
  269. }
  270. typeFactoryRef = new TypeFatoryRef(
  271. [factory](Framework::JSON::JSONValue* zJson) {
  272. return factory->fromJson(zJson);
  273. },
  274. [factory](void* zObject) { return factory->toJSON((T*)zObject); },
  275. [factory]() { return factory->getValidator(); },
  276. factory);
  277. parsableTypes.set(typeId, typeId.getLength(), typeFactoryRef);
  278. }
  279. template<typename T> T* fromJson(Framework::JSON::JSONValue* zJson) const
  280. {
  281. Framework::Text typeId = typeid(T).name();
  282. TypeFatoryRef* typeFactoryRef
  283. = parsableTypes.z(typeId, typeId.getLength());
  284. if (!typeFactoryRef)
  285. {
  286. throw Framework::Text("Type not registered: ") + typeId;
  287. }
  288. return (T*)(typeFactoryRef->fromJson(zJson));
  289. }
  290. template<typename T> Framework::JSON::JSONValue* toJSON(T* zObject) const
  291. {
  292. Framework::Text typeId = typeid(T).name();
  293. TypeFatoryRef* typeFactoryRef
  294. = parsableTypes.z(typeId, typeId.getLength());
  295. if (!typeFactoryRef)
  296. {
  297. throw Framework::Text("Type not registered: ") + typeId;
  298. }
  299. return typeFactoryRef->toJSON(zObject);
  300. }
  301. template<typename T>
  302. Framework::JSON::Validator::JSONValidator* getValidator() const
  303. {
  304. Framework::Text typeId = typeid(T).name();
  305. TypeFatoryRef* typeFactoryRef
  306. = parsableTypes.z(typeId, typeId.getLength());
  307. if (!typeFactoryRef)
  308. {
  309. throw Framework::Text("Type not registered: ") + typeId;
  310. }
  311. return typeFactoryRef->getValidator();
  312. }
  313. template<typename T> Framework::JSON::JSONValue* getValidParts(
  314. Framework::JSON::JSONValue* zJson) const
  315. {
  316. Framework::RCArray<Framework::JSON::Validator::JSONValidationResult>
  317. invalidParts;
  318. Framework::JSON::Validator::JSONValidator* validator
  319. = getValidator<T>();
  320. Framework::JSON::JSONValue* result
  321. = validator->getValidParts(zJson, &invalidParts);
  322. for (Framework::JSON::Validator::JSONValidationResult* invalidPart :
  323. invalidParts)
  324. {
  325. invalidPart->printInvalidInfo();
  326. }
  327. return result;
  328. }
  329. };