(Lua C API в C++) создание функции уничтожения метатабличного объекта ⇐ C++
-
Anonymous
(Lua C API в C++) создание функции уничтожения метатабличного объекта
У меня есть способ создать объект-круг и поместить указатель в вектор, прежде чем передавать указатель в Lua. Я хочу иметь возможность вызывать функцию уничтожения, которая удалит указатель из вектора, а затем установит для объекта круга в lua нулевое значение перед удалением указателя.
вот как настраивается состояние Lua
lua_pushlightuserdata(luaState, this); lua_setglobal(luaState, "LUA_HOST"); lua_newtable (luaState); int CircleTblIdx = lua_gettop(luaState); lua_pushvalue (luaState, CircleTblIdx); lua_setglobal(luaState, «Круг»); lua_pushcfunction (luaState, Wrap_createCircle); lua_setfield(luaState, -2, «новый»); lua_pushcfunction (luaState, Wrap_setCircleRadius); lua_setfield(luaState, -2, «setRadius»); lua_pushcfunction (luaState, Wrap_destroyCircle); lua_setfield(luaState, -2, «уничтожить»); luaL_newmetatable(luaState, "CircleMetaTable"); lua_pushstring(luaState, "__index"); lua_pushvalue (luaState, CircleTblIdx); lua_settable (luaState, -3); вот функции
int Wrap_createCircle(lua_State* luaState){ if (lua_gettop(luaState) != 1) return -1; Радиус плавания = lua_tonumber(luaState, 1); CircleShape* круг = (CircleShape*)lua_newuserdata(luaState, sizeof(CircleShape)); новый (круг) CircleShape (радиус); luaL_getmetatable(luaState, "CircleMetaTable"); lua_setmetatable (luaState, -2); //помещаем круг в список объектов рисования lua_getglobal(luaState, «LUA_HOST»); Render* хост = static_cast(lua_touserdata(luaState, -1)); хост->drawObjects.push_back(круг); lua_pop (luaState, 1); возврат 1; } //это работает нормально, менять не нужно int Wrap_setCircleRadius(lua_State* luaState){ если (lua_gettop(luaState) != 2) вернуть -1; CircleShape* круг = static_cast(lua_touserdata(luaState, 1)); Радиус плавания = lua_tonumber (luaState, 2); круг->setRadius (радиус); вернуть 0; } int Wrap_destroyCircle(lua_State* luaState){ if (lua_gettop(luaState) != 1) return -1; CircleShape* круг = static_cast(lua_touserdata(luaState, 1)); // TODO: удалить указатель из Lua и превратить круг в нулевое значение // Это удаляет указатель из списка, это работает lua_getglobal(luaState, «LUA_HOST»); Render* хост = static_cast(lua_touserdata(luaState, -1)); for (int i=0; idrawObjects.size(); i++){ Drawable* obj = хост->drawObjects; if ( (void*)obj == (void*)circle ){ хост->drawObjects.erase(хост->drawObjects.begin() + я); перерыв; } } lua_pop (luaState, 1); //TODO: удалить указатель круга, в настоящее время удалить невозможно, так как я думаю, что происходит // Lua использует указатель, поэтому, когда я его удаляю, он вылетает //удаляем круг; вернуть 0; } вот код Lua
локальный круг = Circle.new(100) круг: setRadius (200) print(circle) — это напечатает указатель круга круг:destroy() -- уничтожить, здесь я хочу, чтобы круг был установлен на ноль print(круг) - должно быть напечатано ноль Я попытался установить для метатаблицы нулевое значение, но это просто превращает объект круга из типа CircleMetaTable в пользовательский тип данных, вызов удаления все равно приведет к сбою.
вот код, который я пробовал
int Wrap_destroyCircle(lua_State* luaState){ if (lua_gettop(luaState) != 1) return -1; CircleShape* круг = static_cast(lua_touserdata(luaState, 1)); lua_pushnil (luaState); lua_setmetatable (luaState, 1); // установка на ноль lua_getglobal(luaState, «LUA_HOST»); Render* хост = static_cast(lua_touserdata(luaState, -1)); for (int i=0; idrawObjects.size(); i++){ Drawable* obj = хост->drawObjects; if ( (void*)obj == (void*)circle ){ cout
У меня есть способ создать объект-круг и поместить указатель в вектор, прежде чем передавать указатель в Lua. Я хочу иметь возможность вызывать функцию уничтожения, которая удалит указатель из вектора, а затем установит для объекта круга в lua нулевое значение перед удалением указателя.
вот как настраивается состояние Lua
lua_pushlightuserdata(luaState, this); lua_setglobal(luaState, "LUA_HOST"); lua_newtable (luaState); int CircleTblIdx = lua_gettop(luaState); lua_pushvalue (luaState, CircleTblIdx); lua_setglobal(luaState, «Круг»); lua_pushcfunction (luaState, Wrap_createCircle); lua_setfield(luaState, -2, «новый»); lua_pushcfunction (luaState, Wrap_setCircleRadius); lua_setfield(luaState, -2, «setRadius»); lua_pushcfunction (luaState, Wrap_destroyCircle); lua_setfield(luaState, -2, «уничтожить»); luaL_newmetatable(luaState, "CircleMetaTable"); lua_pushstring(luaState, "__index"); lua_pushvalue (luaState, CircleTblIdx); lua_settable (luaState, -3); вот функции
int Wrap_createCircle(lua_State* luaState){ if (lua_gettop(luaState) != 1) return -1; Радиус плавания = lua_tonumber(luaState, 1); CircleShape* круг = (CircleShape*)lua_newuserdata(luaState, sizeof(CircleShape)); новый (круг) CircleShape (радиус); luaL_getmetatable(luaState, "CircleMetaTable"); lua_setmetatable (luaState, -2); //помещаем круг в список объектов рисования lua_getglobal(luaState, «LUA_HOST»); Render* хост = static_cast(lua_touserdata(luaState, -1)); хост->drawObjects.push_back(круг); lua_pop (luaState, 1); возврат 1; } //это работает нормально, менять не нужно int Wrap_setCircleRadius(lua_State* luaState){ если (lua_gettop(luaState) != 2) вернуть -1; CircleShape* круг = static_cast(lua_touserdata(luaState, 1)); Радиус плавания = lua_tonumber (luaState, 2); круг->setRadius (радиус); вернуть 0; } int Wrap_destroyCircle(lua_State* luaState){ if (lua_gettop(luaState) != 1) return -1; CircleShape* круг = static_cast(lua_touserdata(luaState, 1)); // TODO: удалить указатель из Lua и превратить круг в нулевое значение // Это удаляет указатель из списка, это работает lua_getglobal(luaState, «LUA_HOST»); Render* хост = static_cast(lua_touserdata(luaState, -1)); for (int i=0; idrawObjects.size(); i++){ Drawable* obj = хост->drawObjects; if ( (void*)obj == (void*)circle ){ хост->drawObjects.erase(хост->drawObjects.begin() + я); перерыв; } } lua_pop (luaState, 1); //TODO: удалить указатель круга, в настоящее время удалить невозможно, так как я думаю, что происходит // Lua использует указатель, поэтому, когда я его удаляю, он вылетает //удаляем круг; вернуть 0; } вот код Lua
локальный круг = Circle.new(100) круг: setRadius (200) print(circle) — это напечатает указатель круга круг:destroy() -- уничтожить, здесь я хочу, чтобы круг был установлен на ноль print(круг) - должно быть напечатано ноль Я попытался установить для метатаблицы нулевое значение, но это просто превращает объект круга из типа CircleMetaTable в пользовательский тип данных, вызов удаления все равно приведет к сбою.
вот код, который я пробовал
int Wrap_destroyCircle(lua_State* luaState){ if (lua_gettop(luaState) != 1) return -1; CircleShape* круг = static_cast(lua_touserdata(luaState, 1)); lua_pushnil (luaState); lua_setmetatable (luaState, 1); // установка на ноль lua_getglobal(luaState, «LUA_HOST»); Render* хост = static_cast(lua_touserdata(luaState, -1)); for (int i=0; idrawObjects.size(); i++){ Drawable* obj = хост->drawObjects; if ( (void*)obj == (void*)circle ){ cout
Мобильная версия