Alexandre A.
Alexandre A.

Reputation: 1779

Is there a way to bind Lua member variable as a call to C/C++ function with the name of that variable

I'm totally new to Lua. From what I understand it is possible to bind Lua variables and methods to ones on the C/C++ side.

But is it possible to bind a user type variable to the call of the C/C++ function which may look like properties on the Lua side ?

Example:

// C++
struct player {
  int get_value(const std::string& property) const {
    auto it = values.find(name);

    if (it != values.end()) {
      return it->second;
    }

    return -1;
  }

  std::map<std::string, int> values;
};

And on the Lua side:

-- Lua
p = player.new()
print(p.score)

So when I call p.score in Lua, it gets translated to the call to the player::get_value function on C++ side with the value of property "score" ?

SOLUTION

Thanks to @Vlad for the directions!

I came up using sol2 which is in my opinion a very nice C++ library binding to Lua!

Here is how it can be done with sol2:

struct Player {
  sol::object get(const std::string& key, sol::this_state state) {
    const auto& it = values.find(key);

    if (it != values.cend()) {
      return sol::make_object(state, it->second);
    }

    return sol::lua_nil;
  }

  std::map<std::string, int> values;
};

int main() {
  Player player;

  player.values.emplace("score", 123);

  sol::state lua;

  lua.open_libraries(sol::lib::base);
  lua.new_usertype<Player>("Player", sol::meta_function::index, &Player::get);
  lua.set("player", &player);

  lua.script(R"(
    print("Player score: ", player.score)
  )");
  return 0;
}

Console output

Player score:   123

Upvotes: 3

Views: 1905

Answers (1)

Vlad
Vlad

Reputation: 5857

The object player should have metatable set with fields __index/__newindex set to C function that will be called when Lua is trying to read or write the field that doesn't exist in the Lua object.

Normally the Lua object representing the native object (player in your case) will be a userdata, either storing the pointer to the C++ object, or hosting it within its storage.

The metamethods __index/__newindex will receive in arguments the reference to the object being queried, the key value (e.g. your score field), and the value to store in case of __newindex metamethod. So you can find your native object and desired property easily.

Some people prefer using existing binding solutions - tolua++/sol/luabind/etc, but it's very simple to implement required functionality yourself.

Upvotes: 1

Related Questions