| 40 | |
| 41 | struct call_handler { |
| 42 | static int lookup_function(lua_State* L) { |
| 43 | sol::stack_object source(L, 1); |
| 44 | sol::stack_object key(L, 2); |
| 45 | if (!source.is<thing>()) { |
| 46 | return luaL_error(L, |
| 47 | "given an incorrect object for this " |
| 48 | "call"); |
| 49 | } |
| 50 | sol::optional<sol::string_view> maybe_svkey |
| 51 | = key.as<sol::optional<sol::string_view>>(); |
| 52 | if (maybe_svkey) { |
| 53 | { |
| 54 | // functions are different from |
| 55 | // variables functions, when obtain with |
| 56 | // the syntax obj.f, obj.f(), and |
| 57 | // obj:f() must return the function |
| 58 | // itself so we just push it realy into |
| 59 | // our target |
| 60 | auto it |
| 61 | = thing_function_associations.find( |
| 62 | *maybe_svkey); |
| 63 | if (it |
| 64 | != thing_function_associations |
| 65 | .cend()) { |
| 66 | return it->second.push(L); |
| 67 | } |
| 68 | } |
| 69 | { |
| 70 | // variables are different than funtions |
| 71 | // when someone does `obj.a`, they |
| 72 | // expect this __index call (this lookup |
| 73 | // function) to return to them the value |
| 74 | // itself they're seeing so we call out |
| 75 | // lua_CFunction that we serialized |
| 76 | // earlier |
| 77 | auto it |
| 78 | = thing_variable_associations.find( |
| 79 | *maybe_svkey); |
| 80 | if (it |
| 81 | != thing_variable_associations |
| 82 | .cend()) { |
| 83 | // note that calls generated by |
| 84 | // sol2 for member variables expect |
| 85 | // the stack ordering to be 2(, 3, |
| 86 | // ..., n) -- value(s) 1 -- source |
| 87 | // so we destroy the key on the |
| 88 | // stack |
| 89 | sol::stack::remove(L, 2, 1); |
| 90 | lua_CFunction cf |
| 91 | = it->second |
| 92 | .as<lua_CFunction>(); |
| 93 | return cf(L); |
| 94 | } |
| 95 | } |
| 96 | } |
| 97 | return sol::stack::push(L, sol::lua_nil); |
| 98 | } |
| 99 | |