Conscience Core
CscCommandAutoParse.h
Go to the documentation of this file.
1 #ifndef CscCommandAutoParse_h
2 #define CscCommandAutoParse_h
3 
4 #include <memory>
5 #include "CscCommon.h"
6 #include "../FunctionCommandWrapper.h"
7 #include "CommandParseContext.h"
8 
10 
11 class CscCommand;
12 class CscCommandAutoParseMetadata;
13 
15 private:
16  CommandTypeId commandId;
17  function<ptr<CscCommand>(CscCommandParseContext &params)> createCommandFunction;
18  static map<CommandTypeId, const CscCommandAutoParseMetadata *> &commandAutoParseMetadataById();
19 
20  static map<string, const CscCommandAutoParseMetadata *> &commandAutoParseMetadataByFunctionName();
21 
22 public:
23  CscCommandAutoParseMetadata(const CommandTypeId &commandId, function<ptr<CscCommand>(CscCommandParseContext &params)> createCommandFunction);
24 
25  function<ptr<CscCommand>(CscCommandParseContext &params)> getCreateCommandFunction() const;
26 
30  static optional<const CscCommandAutoParseMetadata *> getForCommandId(const CommandTypeId &commandId);
31 
32  static vector<CommandTypeId> getSupportedCommandIds();
33 
34  static const CscCommandAutoParseMetadata *registerCommand(const CommandTypeId &commandId, const string &classPrefix, function<ptr<CscCommand>(CscCommandParseContext &params)> createCommandFunction);
35  static void unregisterCommand(const CommandTypeId &commandId);
36 
37  static vector<string> getCommandFunctionNames();
38 };
39 
40 typedef function<void *(const map<string, any> &paramsValues, const vector<string> &paramNames)> CommandTypeBuilder;
41 inline map<const std::type_info *, CommandTypeBuilder> &commandTypeBuilders() {
42  static map<const std::type_info *, CommandTypeBuilder> theMap;
43  return theMap;
44 }
45 
46 inline void registerCommandTypeBuilder(const std::type_info &type, const CommandTypeBuilder &builder) {
47  map<const std::type_info *, CommandTypeBuilder> &builders = commandTypeBuilders();
48  auto it = builders.find(&type);
49  if (it != builders.end()) {
50  auto autoParseLogger = CscLogger::getForCategory("CommandAutoParse");
51  autoParseLogger->debug("replace existing command data type builder: " + getClassName(type, true));
52  /* Note : no delete because class may have been unloaded */
53  builders.erase(it);
54  }
55  builders.emplace(&type, builder);
56 }
57 
58 inline optional<CommandTypeBuilder> getCommandTypeBuilder(const std::type_info &type) {
59  map<const std::type_info *, CommandTypeBuilder> &builders = commandTypeBuilders();
60  auto it = builders.find(&type);
61  if (it != builders.end()) {
62  return it->second;
63  }
64  LOG_WARN("no builder for command type " + getClassName(type, true));
65  return {};
66 }
67 
71 #define COMMAND_FUNCTION(COMMAND_FUNCTION_paramsClassPrefix, COMMAND_FUNCTION_commandId) \
72  \
73  COMMAND_FUNCTION_paramsClassPrefix##CommandResult cscCommand_##COMMAND_FUNCTION_paramsClassPrefix(ptr<COMMAND_FUNCTION_paramsClassPrefix##CommandParams> params, CscEnvironmentSimulator &environmentSimulator); \
74  \
75  static FunctionCommand get##COMMAND_FUNCTION_paramsClassPrefix##Command(ptr<COMMAND_FUNCTION_paramsClassPrefix##CommandParams> params) { \
76  \
77  return [params](CscEnvironmentSimulator &environmentSimulator) { \
78  auto result = cscCommand_##COMMAND_FUNCTION_paramsClassPrefix(params, environmentSimulator); \
79  return result.toRawResult(); \
80  }; \
81  } \
82  class CSC_DLL_IMPORTEXPORT __##COMMAND_FUNCTION_paramsClassPrefix##AutoParseMetadataInit { \
83  inline static const CscCommandAutoParseMetadata *__metadata = CscCommandAutoParseMetadata::registerCommand(COMMAND_FUNCTION_commandId, #COMMAND_FUNCTION_paramsClassPrefix, [](CscCommandParseContext &params) { \
84  string commandId = COMMAND_FUNCTION_commandId; \
85  ptr<COMMAND_FUNCTION_paramsClassPrefix##CommandParams> paramsObject = parseCommandParameters<COMMAND_FUNCTION_paramsClassPrefix##CommandParams>(commandId, params.arguments, params.knowledgeId); \
86  FunctionCommand functionCommand = get##COMMAND_FUNCTION_paramsClassPrefix##Command(paramsObject); \
87  ptr<CscEntityReflexion> entityReflexion = params.getEntityReflexionFromParameter(); \
88  return newptr<FunctionCommandWrapper>(entityReflexion, commandId, functionCommand, params.originalCommandString, params.arguments); \
89  }); \
90  };
91 
92 template <IsMap TMap>
93 TMap convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
94 
95 template <typename T>
96  requires(IsStarPointer<std::remove_cvref_t<T>>)
97 T convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
98 
99 template <typename T>
100  requires(IsSharedPointer<std::remove_cvref_t<T>>)
101 T convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
102 
103 template <IsOptional TOptional>
104 TOptional convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
105 
106 template <IsVector TVector>
107 TVector convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
108 
109 template <typename TArray>
110  requires(IsStdFixedArray<TArray>)
111 TArray convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
112 
113 template <IsEnum TEnum>
114 TEnum convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
115 
116 template <typename TTargetType>
117  requires(!IsStdFixedArray<TTargetType> && !IsOptional<TTargetType> && !IsEnum<TTargetType> && !IsVector<TTargetType> && !IsMap<TTargetType> && !IsSharedPointer<TTargetType> && !IsStarPointer<TTargetType>)
118 TTargetType convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex);
119 
120 template <IsEnum TEnum>
121 TEnum convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
122  return (TEnum)(convertMapValueToArg<unsigned long long>(anyValue, argName, argIndex));
123 }
124 
125 #define TRY_ANY_CAST(targetType, varName, outVarName, parentName) \
126  try { \
127  outVarName = std::any_cast<targetType>(varName); \
128  } catch (std::exception & e) { \
129  LOG_ERROR(string("cannot cast to ") + getClassName(typeid(targetType), false) + " name=" + parentName + " - " + string(e.what())); \
130  throw runtime_error(string("cannot cast to ") + getClassName(typeid(targetType), false) + " name=" + parentName); \
131  }
132 
133 template <IsOptional TOptional>
134 TOptional convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
135  using TElement = typename TOptional::value_type;
136  if (anyValue.type() == typeid(TOptional)) {
137  return any_cast<TOptional>(anyValue);
138  }
139  TOptional result;
140  if (anyValue.type() == typeid(optional<any>)) {
141  auto theOptional = any_cast<optional<any>>(anyValue);
142  if (theOptional.has_value()) {
143  result = convertMapValueToArg<TElement>(theOptional.value(), argName, argIndex);
144  }
145  } else if (anyValue.has_value()) {
146  result = convertMapValueToArg<TElement>(anyValue, argName, argIndex);
147  }
148 
149  return result;
150 }
151 
152 template <typename TNumber>
153 TNumber getNumberFromString(const string &strValue) {
154  const type_info &numberType = typeid(TNumber);
155  try {
156  if (numberType == typeid(char)) {
157  // Convert back to char
158  int temp = std::stoi(strValue);
159  return static_cast<char>(temp);
160  } else if (numberType == typeid(unsigned char)) {
161  // Convert back to unsigned char
162  unsigned int temp = std::stoul(strValue);
163  return static_cast<unsigned char>(temp);
164  } else if (numberType == typeid(short)) {
165  short temp = std::stoi(strValue);
166  return temp;
167  } else if (numberType == typeid(unsigned short)) {
168  unsigned short temp = static_cast<unsigned short>(std::stoul(strValue));
169  return temp;
170  } else if (numberType == typeid(int)) {
171  int temp = std::stoi(strValue);
172  return temp;
173  } else if (numberType == typeid(unsigned int)) {
174  unsigned int temp = std::stoul(strValue);
175  return temp;
176  } else if (numberType == typeid(long)) {
177  long temp = std::stol(strValue);
178  return temp;
179  } else if (numberType == typeid(unsigned long)) {
180  unsigned long temp = std::stoul(strValue);
181  return temp;
182  } else if (numberType == typeid(long long)) {
183  long long temp = std::stoll(strValue);
184  return temp;
185  } else if (numberType == typeid(unsigned long long)) {
186  unsigned long long temp = std::stoull(strValue);
187  return temp;
188  } else if (numberType == typeid(float)) {
189  float temp = std::stof(strValue);
190  return temp;
191  } else if (numberType == typeid(double)) {
192  double temp = std::stod(strValue);
193  return temp;
194  } else if (numberType == typeid(long double)) {
195  long double temp = std::stold(strValue);
196  return temp;
197  } else {
198  // This should not happen
199  throw std::logic_error("Unhandled numeric type during conversion.");
200  }
201  } catch (const std::exception &e) {
202  return 0;
203  }
204 }
205 
206 template <IsMap TMap>
207 TMap convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
208  using K = typename TMap::key_type;
209  using V = typename TMap::mapped_type;
210 
211  if (!anyValue.has_value()) {
212  return {};
213  }
214 
215  if (anyValue.type() == typeid(TMap)) {
216  TMap resMap;
217  TRY_ANY_CAST(TMap, anyValue, resMap, argName)
218  return resMap;
219  }
220 
221  // 2 map key types supported from json for now
222  TMap result;
223  unsigned mapValueIndex = 0;
224  if constexpr (std::is_arithmetic_v<K> || std::is_enum_v<K>) {
225  if (anyValue.type() == typeid(map<string, any>)) {
226  auto mapAny = any_cast<map<string, any>>(anyValue);
227  for (auto it : mapAny) {
228  if constexpr (std::is_enum_v<K>) {
229  result[(K)getNumberFromString<unsigned>(it.first)] = convertMapValueToArg<V>(it.second, "mapValues", mapValueIndex++);
230  } else {
231  result[getNumberFromString<K>(it.first)] = convertMapValueToArg<V>(it.second, "mapValues", mapValueIndex++);
232  }
233  }
234  } else {
235  using MapByInt = map<int, any>;
236  MapByInt mapAny;
237  TRY_ANY_CAST(MapByInt, anyValue, mapAny, argName)
238  for (auto it : mapAny) {
239  result[(K)it.first] = convertMapValueToArg<V>(it.second, "mapValues", mapValueIndex++);
240  }
241  }
242  } else {
243  using MapByString = map<string, any>;
244  MapByString mapAny;
245  TRY_ANY_CAST(MapByString, anyValue, mapAny, argName)
246  for (auto it : mapAny) {
247  result[it.first] = convertMapValueToArg<V>(it.second, "mapValues", mapValueIndex++);
248  }
249  }
250  return result;
251 }
252 
253 template <IsVector TVector>
254 TVector convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
255  using TElement = typename TVector::value_type;
256  if (anyValue.type() == typeid(TVector)) {
257  return any_cast<TVector>(anyValue);
258  }
259 
260  vector<any> vectorAny;
261  TRY_ANY_CAST(vector<any>, anyValue, vectorAny, argName)
262  TVector result;
263  unsigned elementIndex = 0;
264  for (auto it : vectorAny) {
265  result.push_back(convertMapValueToArg<TElement>(it, "elements", elementIndex++));
266  }
267  return result;
268 }
269 template <typename TArray>
270  requires(IsStdFixedArray<TArray>)
271 TArray convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
272  using TElement = typename TArray::value_type;
273  if (anyValue.type() == typeid(TArray)) {
274  return any_cast<TArray>(anyValue);
275  }
276  vector<any> vectorAny;
277  TRY_ANY_CAST(vector<any>, anyValue, vectorAny, argName)
278  TArray result;
279  for (size_t i = 0; i < result.size(); i++) {
280  if (i >= vectorAny.size()) {
281  LOG_WARN("not enough item in array " + argName + " expected " + to_string(result.size()) + " - got " + to_string(i));
282  break;
283  }
284  result[i] = convertMapValueToArg<TElement>(vectorAny.at(i), "elements", i);
285  }
286  return result;
287 }
288 
289 // Fonction pour extraire dynamiquement un tuple de paramètres
290 template <typename Tuple, typename Map, std::size_t... Is>
291 Tuple extractArgsHelper(const Map &paramMap, const std::vector<std::string> &paramNames, std::index_sequence<Is...>) {
292  return std::make_tuple(
293  convertMapValueToArg<std::tuple_element_t<Is, Tuple>>(
294  (Is >= paramNames.size() || paramMap.find(paramNames[Is]) == paramMap.end() ? any() : paramMap.at(paramNames[Is])),
295  Is >= paramNames.size() ? ("?param" + to_string(Is)) : paramNames[Is], Is)...);
296 }
297 
298 template <typename Tuple>
299 Tuple extractArgs(const std::map<std::string, std::any> &paramMap, const std::vector<std::string> &paramNames) {
300  return extractArgsHelper<Tuple>(paramMap, paramNames, std::make_index_sequence<std::tuple_size<Tuple>::value>{});
301 }
302 
303 // Fonction pour créer dynamiquement une instance d'une classe
304 template <typename T, typename... Params>
305 T *createInstance(const std::map<std::string, std::any> &paramMap, const std::vector<std::string> &paramNames) {
306  using ArgsTuple = std::tuple<std::decay_t<Params>...>;
307 
308  // Extraire les arguments
309  auto argsTuple = extractArgs<ArgsTuple>(paramMap, paramNames);
310 
311  // Appeler le constructeur avec les arguments unpackés
312  return std::apply(
313  [](auto &&...args) {
314  return new T(std::forward<decltype(args)>(args)...);
315  },
316  argsTuple);
317 }
318 
319 ptr<CscEntityReflexion> getEntityReflexionFromAny(std::any anyValue, const string &argName);
320 
321 template <typename T>
322 bool doesAnyContainStarPointer(const std::any &anyValue) {
323  return anyValue.type() == typeid(T *);
324 }
325 template <typename T>
326 bool doesAnyContainSharedPtr(const std::any &anyValue) {
327  return anyValue.type() == typeid(std::shared_ptr<T>);
328 }
329 
330 template <typename TObject>
331 constexpr bool isCommandBuiltinObjectType() {
332  using TObjectCleaned = std::remove_cvref_t<TObject>;
333  return std::is_same_v<TObjectCleaned, CscEntityReflexion> || std::is_same_v<TObjectCleaned, CscEntityModel> || std::is_same_v<TObjectCleaned, CscObjectModel> || std::is_same_v<TObjectCleaned, CscPlaceModel>;
334 }
335 
336 template <typename T>
337  requires(IsStarPointer<std::remove_cvref_t<T>>)
338 T convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
339  if (!anyValue.has_value()) {
340  return nullptr;
341  }
342  if (anyValue.type() == typeid(optional<any>)) {
343  optional<any> optionalValue = any_cast<optional<any>>(anyValue);
344  if (!optionalValue.has_value()) {
345  return nullptr;
346  }
347  return convertMapValueToArg<T>(optionalValue.value(), argName, argIndex);
348  }
349  // Récupérer le type de l'objet pointé
350  using CleanT = std::remove_cvref_t<T>;
351  using TPointee = std::remove_cvref_t<typename PointeeType<CleanT>::pointee_type>;
352 
353  if constexpr (std::is_arithmetic_v<TPointee> || std::is_same_v<TPointee, string> || std::is_same_v<TPointee, bool>) {
354  if (anyValue.type() == typeid(TPointee)) {
355  TPointee outValue;
356  TRY_ANY_CAST(TPointee, anyValue, outValue, argName)
357  return new TPointee(outValue);
358  }
359  }
360 
361  if (doesAnyContainStarPointer<TPointee>(anyValue)) {
362  TPointee *outValue = nullptr;
363  TRY_ANY_CAST(TPointee *, anyValue, outValue, argName)
364  return (T)outValue;
365  }
366  if (doesAnyContainStarPointer<const TPointee>(anyValue)) {
367  const TPointee *outValue = nullptr;
368  TRY_ANY_CAST(const TPointee *, anyValue, outValue, argName)
369  return (T)outValue;
370  }
371  if constexpr (IsMap<TPointee> || IsVector<TPointee> || IsOptional<TPointee>) {
372  return new TPointee(convertMapValueToArg<TPointee>(anyValue, argName, argIndex));
373  }
374 
375  if constexpr (!isCommandBuiltinObjectType<TPointee>()) {
376  const std::type_info &pointerTypeId = typeid(TPointee);
377 
378  string typeName = conscience_utils::getClassName(pointerTypeId, true);
379  LOG_TRACE(argName + " type is " + typeName + " *");
380  const CscCommandDataTypeMetadata *commandParamsInfo = getCommandTypeMetadataByName(typeName);
381  optional<CommandTypeBuilder> builder = {};
382  if (commandParamsInfo) {
383  using MapAnyType = map<string, any>;
384  MapAnyType commandParams;
385  TRY_ANY_CAST(MapAnyType, anyValue, commandParams, argName);
386  builder = getCommandTypeBuilder(typeid(TPointee));
387  if (builder) {
388  void *result = builder.value()(commandParams, commandParamsInfo->getParamNames());
389  return static_cast<TPointee *>(result);
390  }
391  }
392  if constexpr (std::is_default_constructible_v<TPointee>) {
393  // IMPORTANT : if you have an error here, provide a no-arg constructor for your type please
394  return new TPointee{};
395  }
396  LOG_WARN("cannot find metadata or builder for type: " + typeName + " hasMetadata=" + boolToString(commandParamsInfo) + " - hasBuilder=" + boolToString(builder.has_value()) + " - return NULL")
397  return nullptr;
398  }
399  return nullptr;
400 }
401 
402 template <typename T>
403  requires(IsSharedPointer<std::remove_cvref_t<T>>)
404 T convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
405  if (!anyValue.has_value()) {
406  return nullptr;
407  }
408  if (anyValue.type() == typeid(optional<any>)) {
409  optional<any> optionalValue = any_cast<optional<any>>(anyValue);
410  if (!optionalValue.has_value()) {
411  return nullptr;
412  }
413  return convertMapValueToArg<T>(optionalValue.value(), argName, argIndex);
414  }
415 
416  using CleanT = std::remove_cvref_t<T>;
417  using TPointeeOriginal = typename SharedPtrTraits<CleanT>::pointee_type;
418  using TPointee = std::remove_cvref_t<TPointeeOriginal>;
419 
420  if (doesAnyContainSharedPtr<TPointee>(anyValue)) {
421  ptr<TPointee> outValue = nullptr;
422  TRY_ANY_CAST(ptr<TPointee>, anyValue, outValue, argName)
423  return std::dynamic_pointer_cast<TPointeeOriginal>(outValue);
424  }
425  if (doesAnyContainSharedPtr<const TPointee>(anyValue)) {
426  ptr<const TPointee> outValue = nullptr;
427  TRY_ANY_CAST(ptr<const TPointee>, anyValue, outValue, argName)
428  return std::dynamic_pointer_cast<TPointeeOriginal>(std::const_pointer_cast<TPointee>(outValue));
429  }
430  if constexpr (std::is_arithmetic_v<TPointee> || std::is_same_v<TPointee, string> || std::is_same_v<TPointee, bool>) {
431  if (anyValue.type() == typeid(TPointee)) {
432  TPointee outValue;
433  TRY_ANY_CAST(TPointee, anyValue, outValue, argName)
434  return newptr<TPointee>(outValue);
435  }
436  }
437  if constexpr (IsMap<TPointee> || IsVector<TPointee> || IsOptional<TPointee>) {
438  return newptr<TPointee>(convertMapValueToArg<TPointee>(anyValue, argName, argIndex));
439  }
440  if constexpr (!isCommandBuiltinObjectType<TPointee>()) {
441  const std::type_info &pointerTypeId = typeid(std::remove_cv_t<std::remove_reference_t<TPointee>>);
442 
443  LOG_TRACE(argName + " type is ptr<" + conscience_utils::getClassName(pointerTypeId, true) + ">");
444  TPointee *obj = convertMapValueToArg<TPointee *>(anyValue, argName, argIndex);
445  if (obj == nullptr) {
446  return nullptr;
447  }
448  return T(obj);
449  }
450  return nullptr;
451 }
452 
453 template <typename TTargetType>
454  requires(!IsStdFixedArray<TTargetType> && !IsOptional<TTargetType> && !IsEnum<TTargetType> && !IsVector<TTargetType> && !IsMap<TTargetType> && !IsSharedPointer<TTargetType> && !IsStarPointer<TTargetType>)
455 TTargetType convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex) {
456  auto &x = typeid(TTargetType);
457  LOG_TRACE("convertMapValueToArg - i: " + to_string(argIndex) + " name:" + argName + " requested: " + x.name() + " in any: " + anyValue.type().name());
458 
459  using TTargetTypeCleaned = std::remove_cvref_t<TTargetType>;
460  try {
461  return std::any_cast<TTargetTypeCleaned>(anyValue);
462  } catch (std::exception &e) {
463  if constexpr (std::is_arithmetic_v<TTargetTypeCleaned>) {
464  if (anyValue.type() == typeid(unsigned long long)) {
465  return static_cast<TTargetTypeCleaned>(std::any_cast<unsigned long long>(anyValue));
466  }
467 
468  if (anyValue.type() == typeid(double)) {
469  return static_cast<TTargetTypeCleaned>(std::any_cast<double>(anyValue));
470  }
471  }
472  LOG_ERROR(string("cannot cast to ") + getClassName(typeid(TTargetTypeCleaned), false) + " name=" + argName + " - " + string(e.what()));
473  throw runtime_error(string("cannot cast to ") + getClassName(typeid(TTargetTypeCleaned), false) + " name=" + argName);
474  }
475 }
476 
477 #define COMMAND_REGISTER(COMMAND_REGISTER_className, ...) \
478  class CSC_DLL_IMPORTEXPORT __##COMMAND_REGISTER_className##AutoParseMetadataInit { \
479  inline static void *registerCommand() { \
480  string commandId = COMMAND_REGISTER_className::COMMAND_ID; \
481  auto builder = [commandId](const map<string, any> &commandParams, const vector<string> &paramNames) { \
482  return createInstance<COMMAND_REGISTER_className __VA_OPT__(, ) __VA_ARGS__>(commandParams, paramNames); \
483  }; \
484  registerCommandTypeBuilder(typeid(COMMAND_REGISTER_className), builder); \
485  CscCommandAutoParseMetadata::registerCommand(commandId, #COMMAND_REGISTER_className, [commandId, builder](CscCommandParseContext &params) { \
486  map<string, any> commandParams = parseCommandParametersAsMap(commandId, params.arguments, params.knowledgeId, /* sub objects are maps */ true); \
487  const CscCommandDataTypeMetadata *commandParamsInfo = CscCommandDataTypeMetadata::getCommandMetadata(commandId); \
488  return ptr<COMMAND_REGISTER_className>(builder(commandParams, commandParamsInfo->getParamNames())); \
489  }); \
490  /* we used to return instance but we should not keep any reference to command to allow shared lib hot reload (and not point of keeping __metadata instance) */ \
491  return nullptr; \
492  } \
493  inline static void *__metadata = registerCommand(); \
494  };
495 
496 #define USER_COMMAND_REGISTER(COMMAND_REGISTER_className, ...) \
497  class CSC_USER_DLL_EXPORT __##COMMAND_REGISTER_className##AutoParseMetadataInit { \
498  inline static void *registerCommand() { \
499  string commandId = COMMAND_REGISTER_className::COMMAND_ID; \
500  auto builder = [commandId](const map<string, any> &commandParams, const vector<string> &paramNames) { \
501  return createInstance<COMMAND_REGISTER_className __VA_OPT__(, ) __VA_ARGS__>(commandParams, paramNames); \
502  }; \
503  registerCommandTypeBuilder(typeid(COMMAND_REGISTER_className), builder); \
504  CscCommandAutoParseMetadata::registerCommand(commandId, #COMMAND_REGISTER_className, [commandId, builder](CscCommandParseContext &params) { \
505  map<string, any> commandParams = parseCommandParametersAsMap(commandId, params.arguments, params.knowledgeId, /* sub objects are maps */ true); \
506  const CscCommandDataTypeMetadata *commandParamsInfo = CscCommandDataTypeMetadata::getCommandMetadata(commandId); \
507  return ptr<COMMAND_REGISTER_className>(builder(commandParams, commandParamsInfo->getParamNames())); \
508  }); \
509  /* we used to return instance but we should not keep any reference to command to allow shared lib hot reload (and not point of keeping __metadata instance) */ \
510  return nullptr; \
511  } \
512  inline static void *__metadata = registerCommand(); \
513  };
514 
515 #define COMMAND_TYPE_BUILDER(PREFIX, COMMAND_REGISTER_className, ...) \
516  namespace { \
517  static bool __##PREFIX##__##COMMAND_REGISTER_className##initialized = ([]() { \
518  auto builder = [](const map<string, any> &commandParams, const vector<string> &paramNames) { \
519  return createInstance<COMMAND_REGISTER_className, __VA_ARGS__>(commandParams, paramNames); \
520  }; \
521  registerCommandTypeBuilder(typeid(COMMAND_REGISTER_className), builder); \
522  return true; \
523  })(); \
524  }
525 
526 }
527 
528 #endif
nlohmann::to_string
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:26470
conscience_core::bridging::commands::extractArgsHelper
Tuple extractArgsHelper(const Map &paramMap, const std::vector< std::string > &paramNames, std::index_sequence< Is... >)
Definition: CscCommandAutoParse.h:291
CSC_DLL_IMPORTEXPORT
#define CSC_DLL_IMPORTEXPORT
Definition: os.h:34
conscience_core::bridging::commands::doesAnyContainStarPointer
bool doesAnyContainStarPointer(const std::any &anyValue)
Definition: CscCommandAutoParse.h:322
conscience_core::bridging::commands::doesAnyContainSharedPtr
bool doesAnyContainSharedPtr(const std::any &anyValue)
Definition: CscCommandAutoParse.h:326
conscience_core::bridging::commands::CscCommandParseContext
Definition: CommandParseContext.h:57
conscience_core::bridging::commands::requires
requires(IsSharedPointer< std::remove_cvref_t< T >>) JsonSerializableData field_value_to_json_serializable(T value)
Definition: CommandParamsSpec.h:595
conscience_core::bridging::commands::CommandTypeBuilder
function< void *(const map< string, any > &paramsValues, const vector< string > &paramNames)> CommandTypeBuilder
Definition: CscCommandAutoParse.h:40
conscience_core::bridging::commands::createInstance
T * createInstance(const std::map< std::string, std::any > &paramMap, const std::vector< std::string > &paramNames)
Definition: CscCommandAutoParse.h:305
conscience_core::bridging::commands::CommandTypeId
string CommandTypeId
Definition: Command.h:29
conscience_utils::IsStdFixedArray
constexpr bool IsStdFixedArray
Definition: conscience_util.h:157
conscience_utils::boolToString
string boolToString(bool value)
Definition: conscience_util.cpp:99
conscience_utils::getClassName
string getClassName(const type_info &paramsClass, bool withNamespace)
Definition: conscience_util.cpp:593
conscience_core::bridging::commands
Definition: cartographyCommands.cpp:4
CommandParseContext.h
nlohmann::detail::make_index_sequence
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3275
conscience_utils::IsStarPointer
concept IsStarPointer
Definition: conscience_util.h:202
LOG_WARN
#define LOG_WARN(message)
Definition: conscience_log.h:193
conscience_utils::IsMap
concept IsMap
Definition: conscience_util.h:160
conscience_utils::IsEnum
concept IsEnum
Definition: conscience_util.h:163
CscCommon.h
jwt::json::type
type
Generic JSON types used in JWTs.
Definition: jwt.h:1794
conscience_core::bridging::commands::commandTypeBuilders
map< const std::type_info *, CommandTypeBuilder > & commandTypeBuilders()
Definition: CscCommandAutoParse.h:41
conscience_utils::SharedPtrTraits::pointee_type
void pointee_type
Definition: conscience_util.h:207
conscience_core::bridging::commands::isCommandBuiltinObjectType
constexpr bool isCommandBuiltinObjectType()
Definition: CscCommandAutoParse.h:331
conscience_core::bridging::commands::getCommandTypeMetadataByName
const CscCommandDataTypeMetadata * getCommandTypeMetadataByName(const string &qualifiedTypeName)
Definition: CommandParamsSpec.cpp:869
conscience_utils::IsSharedPointer
concept IsSharedPointer
Definition: conscience_util.h:218
std
Definition: json.hpp:4598
LOG_ERROR
#define LOG_ERROR(message)
Definition: conscience_log.h:194
conscience_core::bridging::commands::getEntityReflexionFromAny
ptr< CscEntityReflexion > getEntityReflexionFromAny(std::any anyValue, const string &argName)
Definition: CscCommandAutoParse.cpp:75
conscience_utils::IsVector
concept IsVector
Definition: conscience_util.h:147
conscience_core::bridging::commands::getCommandTypeBuilder
optional< CommandTypeBuilder > getCommandTypeBuilder(const std::type_info &type)
Definition: CscCommandAutoParse.h:58
conscience_core::bridging::commands::getNumberFromString
TNumber getNumberFromString(const string &strValue)
Definition: CscCommandAutoParse.h:153
conscience_core::bridging::commands::CscCommandAutoParseMetadata
Definition: CscCommandAutoParse.h:14
conscience_core::bridging::commands::extractArgs
Tuple extractArgs(const std::map< std::string, std::any > &paramMap, const std::vector< std::string > &paramNames)
Definition: CscCommandAutoParse.h:299
TRY_ANY_CAST
#define TRY_ANY_CAST(targetType, varName, outVarName, parentName)
Definition: CscCommandAutoParse.h:125
conscience_core::bridging::commands::registerCommandTypeBuilder
void registerCommandTypeBuilder(const std::type_info &type, const CommandTypeBuilder &builder)
Definition: CscCommandAutoParse.h:46
ptr
std::shared_ptr< T > ptr
Definition: CscCommon.h:29
LOG_TRACE
#define LOG_TRACE(message)
Definition: conscience_log.h:188
conscience_utils::IsOptional
concept IsOptional
Definition: conscience_util.h:144
conscience_core::bridging::commands::convertMapValueToArg
requires(!IsStdFixedArray< TTargetType > &&!IsOptional< TTargetType > &&!IsEnum< TTargetType > &&!IsVector< TTargetType > &&!IsMap< TTargetType > &&!IsSharedPointer< TTargetType > &&!IsStarPointer< TTargetType >) TTargetType convertMapValueToArg(const std TEnum convertMapValueToArg(const std::any &anyValue, const string &argName, size_t argIndex)
Definition: CscCommandAutoParse.h:121
i
int i
Definition: HybridAStar.cpp:191