Добавьте ссылку на переменную c ++ в Lua (C ++ luawrapper) - PullRequest
0 голосов
/ 23 марта 2020

Я использую оболочку C ++ вокруг библиотеки libluajit-5.1-dev Здесь

Мои данные существуют как экземпляр структуры C ++. Я не могу изменить этот дизайн. Эти данные постоянно меняются

Я хочу выполнить некоторые предикатные проверки этих данных, которые можно добавить с помощью языка сценариев Lua.

Я понимаю, как добавлять и выполнять функции в Lua, но я сталкиваюсь с битой, ссылающейся на данные C ++ из Lua, а не просто копирую данные C ++ в Lua.

Например:

struct MyData {
    int a = 1;
    int b = 2;
}

MyData data;

ctx.writeVariable("a", data.a);
std::cout << ctx.readVariable<int>("a") << std::endl; // prints 1

data.a = 3;
std::cout << ctx.readVariable<int>("a") << std::endl; // still prints 1 (obviously). I want this to print 3

Один из способов заставить это работать - хранить указатели C ++ в стеке Lua, например,

LuaContext ctx;
MyData foo;

ctx.writeVariable("a",&foo.a);

std::cout << *ctx.readVariable<int*>("a") << std::endl; //prints 1
foo.a = 42;
std::cout << *ctx.readVariable<int*>("a") << std::endl; //prints 42. Yay

Но теперь я не могу использовать переменные Lua в функциях Lua (в качестве значения) , поскольку в Lua.

отсутствует понятие «разыменование». Одно из решений, которое я нашел, - написать функцию, которая определяет новый Lua Тип обтекания std::reffrence_wrapper<T>, а затем использовать список захвата лямбды, переданный зарегистрированной функции «getter». Это лучше объясняется в комментариях к приведенному ниже коду:

template<typename T>
void registerRefferenceType(LuaContext& ctx, std::string name, const std::reference_wrapper<T>& refference) {
    ctx.registerMember<T(std::reference_wrapper<T>::*)>(
                "value", //adds a member item (called value) to the Lua type std::reference_wrapper<T>

                //This is called when lua code wants to read the variable
                [&refference](const std::reference_wrapper<T>&) -> T { return refference.get(); },

                //This is called when lua code wants to write the variable
                [](std::reference_wrapper<T>&, int) {});

    //Push the std::reference_wrapper<T> onto the lua stack, with name <name>. The value of this reffernce can be retrieved with <name>.value
    ctx.writeVariable(name,refference);
}

Теперь, если я это сделаю:

LuaContext ctx;

int a = 9;
auto ref = std::reference_wrapper(a);

registerRefferenceType(ctx, "a", ref);
std::cout << ctx.executeCode<int>("return a.value") << std::endl; //prints 9

a = 10;

std::cout << ctx.executeCode<int>("return a.value") << std::endl; //prints 10

Это работает так, как я хочу. Но это кажется немного хакерским. Есть ли лучший способ или "стандартный" способ ссылки на переменные C ++ из Lua?

Спасибо

edit: одна проблема с моим решением заключается в том, что если переменная C ++ выходит из области видимости, он все еще будет существовать в Lua и будет просто давать значения мусора. Я думаю, что это должно быть хорошо, но если есть лучший способ, я хотел бы знать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...