Chi-Tech
chi_console_fwrapper_call.cc
Go to the documentation of this file.
1#include "chi_console.h"
2
4#include "chi_lua.h"
5
6namespace chi
7{
8
9RegisterLuaFunction(Console::LuaWrapperCall, chi_console, LuaWrapperCall);
10
11/** This function expects at least 1 parameter. The first parameter must
12 * be a string indicating the registered name of the function wrapper to
13 * call. All other parameters will be forwarded to the function wrapper.*/
14int Console::LuaWrapperCall(lua_State* L)
15{
16 const int num_args = lua_gettop(L);
17 // We do not check for the required parameters here because we want
18 // to make this function call as fast as possible. Besides, via the
19 // static registration we should never run into an issue here.
20
21 auto& console = Console::GetInstance();
22
23 const auto& registry = console.function_wrapper_registry_;
24
25 const std::string fname = lua_tostring(L, 1);
26
27 ChiLogicalErrorIf(registry.count(fname) == 0,
28 std::string("Wrapper with name \"") + fname +
29 "\" not in console registry.");
30
31 const auto& reg_entry = registry.at(fname);
32
33 auto input_params = reg_entry.get_in_params_func();
34
35 ParameterBlock main_arguments_block;
36 for (int p = 2; p <= num_args; ++p)
37 {
38 const std::string arg_name = "arg" + std::to_string(p-2);
39
40 if (lua_isboolean(L, p))
41 main_arguments_block.AddParameter(arg_name, lua_toboolean(L, p));
42 else if (lua_isinteger(L, p))
43 main_arguments_block.AddParameter(arg_name, lua_tointeger(L, p));
44 else if (lua_isnumber(L, p))
45 main_arguments_block.AddParameter(arg_name, lua_tonumber(L, p));
46 else if (lua_isstring(L, p))
47 main_arguments_block.AddParameter(arg_name, lua_tostring(L, p));
48 else if (lua_istable(L, p))
49 {
50 auto block = chi_lua::TableParserAsParameterBlock::ParseTable(L, p);
51 block.SetBlockName(arg_name);
52 std::string scope = fname + ":";
53 scope.append(arg_name + " ");
54 block.SetErrorOriginScope(scope);
55 main_arguments_block.AddParameter(block);
56 }
57 else
58 ChiInvalidArgument("In call to \"" + fname +
59 "\": Unsupported argument "
60 "type \"" +
61 lua_typename(L, lua_type(L, p)) + "\" encountered.");
62 }
63 // Set input parameters here
64 input_params.SetErrorOriginScope(fname + "()");
65 input_params.AssignParameters(main_arguments_block);
66
67 auto output_params = reg_entry.call_func(input_params);
68
69 output_params.SetErrorOriginScope(fname + ":output:");
70 chi_lua::PushParameterBlock(L, output_params);
71
72 const int num_sub_params = static_cast<int>(output_params.NumParameters());
73
74 return output_params.IsScalar() ? 1 : num_sub_params;
75}
76
77} // namespace chi_objects
#define ChiLogicalErrorIf(condition, message)
#define ChiInvalidArgument(message)
static int LuaWrapperCall(lua_State *L)
Generic entry point for wrapper calls.
static Console & GetInstance() noexcept
void AddParameter(ParameterBlock block)
RegisterLuaFunction(Console::LuaWrapperCall, chi_console, LuaWrapperCall)