TypeRegistry.h 13 KB

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