vinniefalco/LuaBridge

beginNamespace promblem

PyXiion opened this issue · 4 comments

Hello! I have a problem. I have registered several SFML classes, but it gives an error when running.
This error:
/home/pyxiion/lua/bridge2.6/LuaBridge/detail/Namespace.h:1034: luabridge::Namespace::Namespace(const char*, luabridge::Namespace&): Assertion lua_istable (L, -1)' failed.

I have a script class that looks like this:

// Script.h
class Script {
public:
	lua_State *L;

	Script();
	Script(std::string);
	~Script();

	void LoadFile(std::string);
	void Unload();

	void Start();
	void Update();
	void Draw();

	void CallFunction(std::string);
};

I register classes first, call LoadFile, and then call Start

// Script.cpp
Script::Script() {
	L = luaL_newstate();
}
void Script::LoadFile(std::string script) {
	luaL_dofile(L, script.c_str());
	luaL_openlibs(L);
}
void Script::Start() {
	CallFunction("start");
}
void Script::Update() {
	CallFunction("update");
}
void Script::Draw() {
	CallFunction("draw");
}

void Script::CallFunction(std::string string) {
	LuaRef func = getGlobal(L, string.c_str());
	if (!func.isNil()) func();
}
// Proxies
void LuaDefines::transformableSetPositionProxy(sf::Transformable* t, sf::Vector2f xy) {
	t->setPosition(xy);
}
void LuaDefines::transformableSetScaleProxy(sf::Transformable* t, sf::Vector2f xy) {
	t->setScale(xy);
}
void LuaDefines::transformableSetOriginProxy(sf::Transformable* t, sf::Vector2f xy) {
	t->setOrigin(xy);
}
template<class T>
void LuaDefines::drawProxy(T* drawable) {
	window->draw(*drawable);
}

// Code for registering classes
void LuaDefines::RegisterGraphics(lua_State* L) {
	getGlobalNamespace(L)
		.beginNamespace("sf")
			.beginClass<sf::Vector2f>("vec2f")
				.addConstructor<void (*) ()>()
				.addConstructor<void (*) (float x, float y)>()
				.addProperty("x", &sf::Vector2f::x)
				.addProperty("y", &sf::Vector2f::y)

				.addFunction("__add", std::function<sf::Vector2f (sf::Vector2f*, sf::Vector2f*)>(
						[] (sf::Vector2f* v1, sf::Vector2f* v2) { return *v1 + *v2; }))

				.addFunction("__sub", std::function<sf::Vector2f (sf::Vector2f*, sf::Vector2f*)>(
						[] (sf::Vector2f* v1, sf::Vector2f* v2) { return *v1 - *v2; }))

				.addFunction("__div", std::function<sf::Vector2f (sf::Vector2f*, float)>(
						[] (sf::Vector2f* v, float f) { return *v / f; }))

				.addFunction("__mul", std::function<sf::Vector2f (sf::Vector2f*, float)>(
						[] (sf::Vector2f* v, float f) { return *v * f; }))

				.addFunction("__eq", std::function<bool (sf::Vector2f*, sf::Vector2f*)>(
						[] (sf::Vector2f* v1, sf::Vector2f* v2) { return *v1 == *v2; }))
			.endClass()

			.beginClass<sf::Vector2u>("vec2u")
				.addConstructor<void (*) ()>()
				.addConstructor<void (*) (int x, int y)>()
				.addProperty("x", &sf::Vector2u::x)
				.addProperty("y", &sf::Vector2u::y)

				.addFunction("__add", std::function<sf::Vector2u (sf::Vector2u*, sf::Vector2u*)>(
						[] (sf::Vector2u* v1, sf::Vector2u* v2) { return *v1 + *v2; }))

				.addFunction("__sub", std::function<sf::Vector2u (sf::Vector2u*, sf::Vector2u*)>(
						[] (sf::Vector2u* v1, sf::Vector2u* v2) { return *v1 - *v2; }))

				.addFunction("__eq", std::function<bool (sf::Vector2u*, sf::Vector2u*)>(
						[] (sf::Vector2u* v1, sf::Vector2u* v2) { return *v1 == *v2; }))
			.endClass()

			.beginClass<sf::Transformable>("transformable")
				.addFunction("setPosition", &transformableSetPositionProxy)
				.addFunction("setRotation", &sf::Transformable::setRotation)
				.addFunction("setScale", &transformableSetScaleProxy)
				.addFunction("setOrigin", &transformableSetOriginProxy)
			.endClass()

			.deriveClass<sf::Text, sf::Transformable>("text")
				.addConstructor<void (*) (void)>()
				.addFunction("setString", &sf::Text::setString)
				.addFunction("setFont", &sf::Text::setFont)
				.addFunction("setCharasterSize", &sf::Text::setCharacterSize)
				.addFunction("setLineSpacing", &sf::Text::setLineSpacing)
				.addFunction("setLetterSpacing", &sf::Text::setLetterSpacing)
				.addFunction("setStyle", &sf::Text::setStyle)
				.addFunction("setFillColor", &sf::Text::setFillColor)
				.addFunction("setOutlineColor", &sf::Text::setOutlineColor)
				.addFunction("setOutlineThickness", &sf::Text::setOutlineThickness)

				.addConstructor<void (*) (void)>()
				.addFunction("getString", &sf::Text::getString)
				.addFunction("getFont", &sf::Text::getFont)
				.addFunction("getCharasterSize", &sf::Text::getCharacterSize)
				.addFunction("getLineSpacing", &sf::Text::getLineSpacing)
				.addFunction("getLetterSpacing", &sf::Text::getLetterSpacing)
				.addFunction("getStyle", &sf::Text::getStyle)
				.addFunction("getFillColor", &sf::Text::getFillColor)
				.addFunction("getOutlineColor", &sf::Text::getOutlineColor)
				.addFunction("getOutlineThickness", &sf::Text::getOutlineThickness)

				.addFunction("draw", &drawProxy<sf::Text>)

			.endClass()
		.endNamespace()
	;
}

I do not know, maybe I should update LuaBridge.
Even when I register only the namespace, it throws this error.

void LuaDefines::RegisterGraphics(lua_State* L) {
	getGlobalNamespace(L)
		.beginNamespace("sf")

		.endNamespace()
	;
}
// /home/pyxiion/lua/bridge2.6/LuaBridge/detail/Namespace.h:1034: luabridge::Namespace::Namespace(const char*, luabridge::Namespace&): Assertion `lua_istable (L, -1)' failed.

I have debugged this code and I am sure that the error is happening right here.

Script script;
LuaDefines::RegisterGraphics(script.L);
script.LoadFile("data/scripts/debugInfo.lua"); // Error here
script.Start();
-- data/scripts/debugInfo.lua
text = sf.text()
text:setString("Test text")

draw = function ()
    text:draw()
end

I will try to update LuaBridge. (It didn't help)

I'm having the same problem, Did you solve it?

Hi! I solved it, for some reason it works when I use in another class. It only gives the error in my Script class, I'm not sure why it happens but it seems to be that

Next time please provide a minimal working example if you want to get a quick response.

In you case such example is:

extern "C" {
#include <lua5.2/lauxlib.h>
#include <lua5.2/lua.h>
#include <lua5.2/lualib.h>
}

#include <LuaBridge/LuaBridge.h>

#include <Windows.h>

int WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpCmdLine,
            int nCmdShow)
{
    lua_State* L = luaL_newstate();
    luabridge::getGlobalNamespace(L).beginNamespace("sf");
}

The beginNamespace() is failed because the _G value is nil.
For me it starts working once I initialize the Lua state with the luaL_openlibs():

    lua_State* L = luaL_newstate();
    luaL_openlibs(L);

BTW this can be useful for debugging:

#include <LuaBridge/detail/dump.h>
#include <sstream>
...
    lua_State* L = luaL_newstate();
    auto global = luabridge::getGlobalNamespace(L);
    std::ostringstream stream; // There's no console in the app
    luabridge::debug::dumpState(L, stream);
    // Now can see the stream contents in the debugger. The stack has a single nil value