transform_utility.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #ifndef SOPHIAR2_TRANSFORM_UTILITY_HPP
  2. #define SOPHIAR2_TRANSFORM_UTILITY_HPP
  3. #include "core/basic_obj_types.hpp"
  4. #include "utility/coro_signal_group.hpp"
  5. #include "utility/coro_worker.hpp"
  6. #include "utility/simple_tristate_obj.hpp"
  7. #include "utility/global_obj_helper.hpp"
  8. #include <cassert>
  9. namespace sophiar {
  10. inline coro_worker::pointer make_transform_inverter_func(const nlohmann::json &config) {
  11. assert(config.contains("input_obj_name"));
  12. assert(config.contains("output_obj_name"));
  13. assert(config["input_obj_name"].is_string());
  14. assert(config["output_obj_name"].is_string());
  15. auto input_obj_name = config["input_obj_name"].get<std::string>();
  16. auto output_obj_name = config["output_obj_name"].get<std::string>();
  17. auto input_obj_index = REGISTER_GLOBAL_OBJ(transform_obj, input_obj_name);
  18. auto output_obj_index = REGISTER_GLOBAL_OBJ(transform_obj, output_obj_name);
  19. auto worker = make_infinite_coro_worker(global_context, [=,
  20. input_helper = GLOBAL_OBJ_AUTO_DELEGATE(transform_obj, input_obj_index)]() mutable
  21. -> boost::asio::awaitable<bool> {
  22. co_await input_helper.coro_wait_update(false);
  23. auto ts = GLOBAL_OBJ_UPDATE_TS(input_obj_index);
  24. if (input_helper.empty()) [[unlikely]] {
  25. UPDATE_GLOBAL_OBJ_TS(transform_obj, output_obj_index, nullptr, ts);
  26. } else [[likely]] {
  27. auto new_trans = transform_obj::new_instance();
  28. new_trans->value = input_helper->value.inverse();
  29. UPDATE_GLOBAL_OBJ_TS(transform_obj, output_obj_index, new_trans, ts);
  30. }
  31. co_return true;
  32. });
  33. return std::move(worker);
  34. }
  35. scalarxyz_obj::value_type get_scalarxyz_from_json_list(const nlohmann::json &config) {
  36. assert(config.is_array());
  37. assert(config.size() == 3);
  38. double val[3];
  39. for (int i = 0; i < 3; ++i) {
  40. assert(config[i].is_number());
  41. val[i] = config[i].get<double>();
  42. }
  43. return {val[0], val[1], val[2]};
  44. }
  45. template<bool IsVector>
  46. inline coro_worker::pointer make_fixed_scalarxyz_transformer(const nlohmann::json &config) {
  47. assert(config["transform_type"] == "point");
  48. auto fixed_value = get_scalarxyz_from_json_list(config["fixed_value"]);
  49. auto trans_obj_name = config["transform_obj_name"].get<std::string>();
  50. auto output_obj_name = config["output_obj_name"].get<std::string>();
  51. auto trans_obj_index = REGISTER_GLOBAL_OBJ(transform_obj, trans_obj_name);
  52. auto output_obj_index = REGISTER_GLOBAL_OBJ(scalarxyz_obj, output_obj_name);
  53. auto worker = make_infinite_coro_worker(global_context, [=,
  54. trans_helper = GLOBAL_OBJ_AUTO_DELEGATE(transform_obj, trans_obj_index)]() mutable
  55. -> boost::asio::awaitable<bool> {
  56. co_await trans_helper.coro_wait_update(false);
  57. auto ts = GLOBAL_OBJ_UPDATE_TS(trans_obj_index);
  58. if (trans_helper.empty()) [[unlikely]] {
  59. UPDATE_GLOBAL_OBJ_TS(scalarxyz_obj, output_obj_index, nullptr, ts);
  60. } else [[likely]] {
  61. auto new_value = scalarxyz_obj::new_instance();
  62. if constexpr (IsVector) {
  63. new_value->value = trans_helper->value.linear() * fixed_value;
  64. } else {
  65. new_value->value = trans_helper->value * fixed_value;
  66. }
  67. UPDATE_GLOBAL_OBJ_TS(scalarxyz_obj, output_obj_index, new_value, ts);
  68. }
  69. co_return true;
  70. });
  71. return std::move(worker);
  72. }
  73. inline coro_worker::pointer make_scalarxyz_transformer(const nlohmann::json &config) {
  74. assert(config.contains("transform_obj_name"));
  75. assert(config.contains("output_obj_name"));
  76. assert(config["transform_obj_name"].is_string());
  77. assert(config["output_obj_name"].is_string());
  78. assert(config.contains("transform_type"));
  79. assert(config["transform_type"].is_string());
  80. auto trans_type = config["transform_type"].get<std::string>();
  81. if (config.contains("fixed_value")) {
  82. if (trans_type == "vector") {
  83. return make_fixed_scalarxyz_transformer<true>(config);
  84. } else {
  85. assert(trans_type == "point");
  86. return make_fixed_scalarxyz_transformer<false>(config);
  87. }
  88. } else {
  89. assert(config.contains("input_obj_name"));
  90. assert(config["input_obj_name"].is_string());
  91. // TODO 实现 dynamic_scalaxyz_transformer
  92. assert(false);
  93. return nullptr;
  94. }
  95. assert(false);
  96. return nullptr;
  97. }
  98. using transform_inverter = simple_tristate_obj_wrapper<make_transform_inverter_func>;
  99. using scalarxyz_transformer = simple_tristate_obj_wrapper<make_scalarxyz_transformer>;
  100. }
  101. #endif //SOPHIAR2_TRANSFORM_UTILITY_HPP