H3LLB0Y

FunctionMapping

Sep 26th, 2021 (edited)
779
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <cassert>
  2. #include <iostream>
  3. #include <map>
  4. #include <tuple>
  5. #include <variant>
  6. #include <any>
  7.  
  8. class MpMapper {
  9. public:
  10.     void slot_setRoomSize(std::variant<int, bool> param) {
  11.         assert(std::holds_alternative<int>(param));
  12.         slot_setRoomSize(std::get<int>(param));
  13.     }
  14.  
  15.     void slot_setExitSize(std::variant<int, bool> param) {
  16.         assert(std::holds_alternative<int>(param));
  17.         slot_setExitSize(std::get<int>(param));
  18.     }
  19.  
  20.     void slot_toggleRoundRooms(std::variant<int, bool> param) {
  21.         assert(std::holds_alternative<bool>(param));
  22.         slot_toggleRoundRooms(std::get<bool>(param));
  23.     }
  24.  
  25.     void slot_setShowRoomIds(std::variant<int, bool> param) {
  26.         assert(std::holds_alternative<bool>(param));
  27.         slot_setShowRoomIds(std::get<bool>(param));
  28.     }
  29.  
  30.     void slot_setRoomSize(int param) {
  31.         std::cout << __func__ << " " << param << std::endl;
  32.     }
  33.  
  34.     void slot_setExitSize(int param) {
  35.         std::cout << __func__ << " " << param << std::endl;
  36.     }
  37.  
  38.     void slot_toggleRoundRooms(bool param) {
  39.         std::cout << __func__ << " " << param << std::endl;
  40.     }
  41.  
  42.     void slot_setShowRoomIds(bool param) {
  43.         std::cout << __func__ << " " << param << std::endl;
  44.     }
  45. };
  46.  
  47. class MpMap {
  48. public:
  49.     MpMapper *mpMapper = new MpMapper();
  50. };
  51.  
  52. class Host {
  53. public:
  54.     MpMap *mpMap = new MpMap();
  55. };
  56.  
  57. class Lua {
  58. private:
  59.     Host host;
  60. public:
  61.     Host &getHost() {
  62.         return host;
  63.     }
  64. };
  65.  
  66. auto lua_pushboolean(Lua lua, bool value) {
  67. }
  68.  
  69. Host &getHostFromLua(Lua lua) {
  70.     return lua.getHost();
  71. }
  72.  
  73. std::variant<int, bool> getVerifiedVariantInt(Lua lua, const char func[], int num, const std::string &value) {
  74.     std::cout << "Int: " << &lua << " " << func << " " << num << " " << value << std::endl;
  75.     return 0;
  76. }
  77.  
  78. std::variant<int, bool> getVerifiedVariantBool(Lua lua, const char func[], int num, const std::string &value) {
  79.     std::cout << "Bool: " << &lua << " " << func << " " << num << " " << value << std::endl;
  80.     return false;
  81. }
  82.  
  83. int getVerifiedInt(Lua lua, const char func[], int num, const std::string &value) {
  84.     std::cout << "Int: " << &lua << " " << func << " " << num << " " << value << std::endl;
  85.     return 0;
  86. }
  87.  
  88. bool getVerifiedBool(Lua lua, const char func[], int num, const std::string &value) {
  89.     std::cout << "Bool: " << &lua << " " << func << " " << num << " " << value << std::endl;
  90.     return false;
  91. }
  92.  
  93. typedef void(MpMapper::*f1_int)(int);
  94.  
  95. typedef void(MpMapper::*f1_bool)(bool);
  96.  
  97. typedef int(*f2_int)(Lua, const char[], int, const std::string &);
  98.  
  99. typedef bool(*f2_bool)(Lua, const char[], int, const std::string &);
  100.  
  101. typedef void(MpMapper::*f1)(std::variant<int, bool>);
  102.  
  103. typedef std::variant<int, bool>(*f2)(Lua, const char[], int, const std::string &);
  104.  
  105. class Mapping {
  106. public:
  107.     enum {
  108.         INT, BOOL
  109.     } mapping_type;
  110.  
  111.     union func1 {
  112.         f1_int int_func;
  113.         f1_bool bool_func;
  114.  
  115.         explicit func1(f1_int func) : int_func(func) {}
  116.  
  117.         explicit func1(f1_bool func) : bool_func(func) {}
  118.     };
  119.  
  120.     func1 fn1;
  121.  
  122.     union func2 {
  123.         f2_int int_func;
  124.         f2_bool bool_func;
  125.  
  126.         explicit func2(f2_int func) : int_func(func) {}
  127.  
  128.         explicit func2(f2_bool func) : bool_func(func) {}
  129.     };
  130.  
  131.     func2 fn2;
  132.  
  133.     Mapping() = delete;
  134.  
  135.     Mapping(f1_int fn1, f2_int fn2) : mapping_type(INT), fn1(fn1), fn2(fn2) {}
  136.  
  137.     Mapping(f1_bool fn1, f2_bool fn2) : mapping_type(BOOL), fn1(fn1), fn2(fn2) {}
  138.  
  139.     void call(MpMapper *mpMapper, Lua lua, const char func[], int num, const std::string &value) const {
  140.         switch (mapping_type) {
  141.             case INT:
  142.                 (mpMapper->*fn1.int_func)(fn2.int_func(lua, func, num, value));
  143.                 break;
  144.             case BOOL:
  145.                 (mpMapper->*fn1.bool_func)(fn2.bool_func(lua, func, num, value));
  146.                 break;
  147.         }
  148.     }
  149. };
  150.  
  151. enum WhichWay {
  152.     KEY_TO_TUPLE,
  153.     MAPPING_CLASS,
  154.     TEMPLATED_MAPPING,
  155.     OLD_SCHOOL,
  156.     NO_WAY,
  157. };
  158.  
  159. template<typename T>
  160. concept IsIntOrBool = std::is_same< T, bool >::value || std::is_same< T, int >::value;
  161.  
  162. template<IsIntOrBool T>
  163. class TemplatedMapping {
  164. public:
  165.     typedef void(MpMapper::*QT_SlotFunction)(T);
  166.  
  167.     typedef T(*Lua_GetVerifiedFunction)(Lua, const char[], int, const std::string &);
  168.  
  169.     QT_SlotFunction slotFunction;
  170.  
  171.     Lua_GetVerifiedFunction getVerified;
  172.  
  173.     TemplatedMapping() = delete;
  174.  
  175.     TemplatedMapping(QT_SlotFunction fn1, Lua_GetVerifiedFunction fn2) : slotFunction(fn1), getVerified(fn2) {}
  176.  
  177.     void call(MpMapper *mpMapper, Lua lua, const char func[], int num, const std::string &value) const {
  178.         (mpMapper->*slotFunction)(getVerified(lua, func, num, value));
  179.     }
  180. };
  181.  
  182. typedef std::variant<TemplatedMapping<int>, TemplatedMapping<bool>> TemplatedMappings;
  183.  
  184. template<typename... Ts, typename F>
  185. constexpr void for_types(F &&f) {
  186.     (f.template operator()<Ts>(), ...);
  187. }
  188.  
  189. static void call(TemplatedMappings mapping, MpMapper *mpMapper, Lua lua, const char func[], int num, const std::string &value) {
  190.     for_types<int, bool>([&]<typename Type>() {
  191.         if (std::holds_alternative<TemplatedMapping<Type>>(mapping)) {
  192.             std::get<TemplatedMapping<Type>>(mapping).call(mpMapper, lua, func, num, value);
  193.         }
  194.     });
  195. }
  196.  
  197. auto function(WhichWay which_way, Lua L, const std::string &key) {
  198.     auto success = [&]() {
  199.         lua_pushboolean(L, true);
  200.         return 1;
  201.     };
  202.  
  203.     std::map<std::string, std::tuple<f1, f2>> key_to_tuple_mapping{
  204.             {"mapperRoomSize",    {&MpMapper::slot_setRoomSize,      getVerifiedVariantInt}},
  205.             {"mapperExitSize",    {&MpMapper::slot_setExitSize,      getVerifiedVariantInt}},
  206.             {"mapperRoundRooms",  {&MpMapper::slot_toggleRoundRooms, getVerifiedVariantBool}},
  207.             {"mapperShowRoomIds", {&MpMapper::slot_setShowRoomIds,   getVerifiedVariantBool}},
  208.     };
  209.  
  210.     std::map<std::string, Mapping> function_mapping{
  211.             {"mapperRoomSize",    Mapping(&MpMapper::slot_setRoomSize, getVerifiedInt)},
  212.             {"mapperExitSize",    Mapping(&MpMapper::slot_setExitSize, getVerifiedInt)},
  213.             {"mapperRoundRooms",  Mapping(&MpMapper::slot_toggleRoundRooms, getVerifiedBool)},
  214.             {"mapperShowRoomIds", Mapping(&MpMapper::slot_setShowRoomIds, getVerifiedBool)},
  215.     };
  216.  
  217.     std::map<std::string, TemplatedMappings> templated_mapping{
  218.             {"mapperRoomSize",    TemplatedMapping<int>(&MpMapper::slot_setRoomSize, getVerifiedInt)},
  219.             {"mapperExitSize",    TemplatedMapping<int>(&MpMapper::slot_setExitSize, getVerifiedInt)},
  220.             {"mapperRoundRooms",  TemplatedMapping<bool>(&MpMapper::slot_toggleRoundRooms, getVerifiedBool)},
  221.             {"mapperShowRoomIds", TemplatedMapping<bool>(&MpMapper::slot_setShowRoomIds, getVerifiedBool)},
  222.     };
  223.  
  224.     Host &host = getHostFromLua(L);
  225.     if (host.mpMap && host.mpMap->mpMapper) {
  226.         switch (which_way) {
  227.             case KEY_TO_TUPLE:
  228.                 try {
  229.                     auto[slot_function, getVerifiedValue] = key_to_tuple_mapping.at(key);
  230.                     (host.mpMap->mpMapper->*slot_function)(getVerifiedValue(L, __func__, 2, "value"));
  231.                     return success();
  232.                 } catch (const std::out_of_range &out_of_range) {
  233.                     std::cerr << out_of_range.what() << std::endl;
  234.                 }
  235.                 break;
  236.             case MAPPING_CLASS:
  237.                 try {
  238.                     auto mapping = function_mapping.at(key);
  239.                     mapping.call(host.mpMap->mpMapper, L, __func__, 2, "value");
  240.                     return success();
  241.                 } catch (const std::out_of_range &out_of_range) {
  242.                     std::cerr << out_of_range.what() << std::endl;
  243.                 }
  244.                 break;
  245.             case TEMPLATED_MAPPING:
  246.                 try {
  247.                     auto mapping = templated_mapping.at(key);
  248.                     call(mapping, host.mpMap->mpMapper, L, __func__, 2, "value");
  249.                     return success();
  250.                 } catch (const std::out_of_range &out_of_range) {
  251.                     std::cerr << out_of_range.what() << std::endl;
  252.                 }
  253.                 break;
  254.             case OLD_SCHOOL:
  255.                 if (key == "mapperRoomSize") {
  256.                     host.mpMap->mpMapper->slot_setRoomSize(getVerifiedInt(L, __func__, 2, "value"));
  257.                     return success();
  258.                 }
  259.                 if (key == "mapperExitSize") {
  260.                     host.mpMap->mpMapper->slot_setExitSize(getVerifiedInt(L, __func__, 2, "value"));
  261.                     return success();
  262.                 }
  263.                 if (key == "mapperRoundRooms") {
  264.                     host.mpMap->mpMapper->slot_toggleRoundRooms(getVerifiedBool(L, __func__, 2, "value"));
  265.                     return success();
  266.                 }
  267.                 if (key == "mapperShowRoomIds") {
  268.                     host.mpMap->mpMapper->slot_setShowRoomIds(getVerifiedBool(L, __func__, 2, "value"));
  269.                     return success();
  270.                 }
  271.                 break;
  272.             case NO_WAY:
  273.                 std::cout << "Um, this isn't doing anything :shrug:" << std::endl;
  274.                 break;
  275.         }
  276.     }
  277.     return 0;
  278. }
  279.  
  280. int main() {
  281.     Lua lua{};
  282.     for (int way = KEY_TO_TUPLE; way != NO_WAY; ++way) {
  283.         auto which_way = static_cast< WhichWay >(way);
  284.         std::cout << "mapperRoomSize=>" << std::endl << function(which_way, lua, "mapperRoomSize") << std::endl;
  285.         std::cout << "mapperExitSize=>" << std::endl << function(which_way, lua, "mapperExitSize") << std::endl;
  286.         std::cout << "mapperRoundRooms=>" << std::endl << function(which_way, lua, "mapperRoundRooms") << std::endl;
  287.         std::cout << "mapperShowRoomIds=>" << std::endl << function(which_way, lua, "mapperShowRoomIds") << std::endl;
  288.     }
  289.     return 0;
  290. }
  291.  
RAW Paste Data