Re: Opps...need help on how to manage c++ objects from Lua

voodooRod <[email protected]> Sat, 15 Jun 2013 17:01:41 -0700 (PDT)
Newsgroups gmane.comp.lang.lua.bind.user
Message-ID <[email protected]>
I solved my own problem. 

I needed to first bind my abstract class "IFoo." And, in my class Foo I
needed to bind the constructor with the derived IFoo. So now, all works. I
will post the working code below in case anyone else needs to know how to
do. 

All the samples online seem to show how to bind C++ to Lua and then
construct the objects from Lua. However, if you wish to do "declarative"
programming, creating and managing the objects on the C++ side and then
allowing Lua to manipulate those objects, I hadn't found any clear samples.
So, here's a sample...

// C++ CODE

template <typename T> 
void registrate(lua_State *pLuaState) { 
	T::registrate(pLuaState); 
}

class IFoo
{
public:
	virtual ~IFoo() {}
	virtual void sayName(void) = 0;
	virtual void doAwake(void) = 0;
	virtual void update(void) = 0;

	static void registrate(lua_State *pLuaState)
	{
		// export our class with LuaBind
		luabind::module(pLuaState) [
			luabind::class_<IFoo>("IFoo")
				.def("sayName", (void(IFoo::*) (void)) &IFoo::sayName)
		];
	}

};

class Foo : public IFoo
{
public:
	Foo() { m_sName = "Blank"; }
	Foo(std::string sName, lua_State* pLuaState) :
	  m_sName(sName), m_pLuaState(pLuaState) {}

	void sayName(void) { printf("FOO: the name is: %s\n", m_sName.c_str()); }
	void changeName(const std::string &sName) { m_sName = sName; } 
	void update(void){};
	void doAwake(void) 
	{
		// do the script
		if(luaL_dofile(m_pLuaState, "myscript1.lua"))
		{
			printf("Lua engine error: %s",lua_tostring(m_pLuaState, 1));
			return;
		}

		try {

			// call the lua function
			luabind::call_function<void>(m_pLuaState, "Awake"); 

		} catch (luabind::error& e)

		{
			std::string error = lua_tostring( e.state(), -1 );
			std::cout << error << "\n";
		}
	}

	static void registrate(lua_State *pLuaState)
	{
		// export our class with LuaBind
		luabind::module(pLuaState) [
			luabind::class_<Foo, IFoo>("Foo")
				.def(luabind::constructor<>())
				.def(luabind::constructor<std::string, lua_State*>())
				.def("sayName", (void(Foo::*) (void)) &Foo::sayName)
				.def("changeName", (void(Foo::*) (const std::string &))
&Foo::changeName)
		];
	}

private:
	std::string m_sName;
	lua_State *m_pLuaState;
};

class Foo2 : public Foo
{
public:
	Foo2() {}
	Foo2(std::string sName) :
		Foo(sName, NULL) { m_sName = sName; }

	void sayName(void) { printf("FOO2: the name is: %s\n", m_sName.c_str()); }
	void sayNothing(void) { printf("FOO2: saying nothing %s\n",
m_sName.c_str()); }
	void update(void) {}
	void doAwake(void) {}
	void sayFooName(void) { printf("FOO2: saying FOO's name = ");
Foo::sayName(); }

	static void registrate(lua_State *pLuaState)
	{
		luabind::module(pLuaState) [
			luabind::class_<Foo2, Foo>("Foo2")
				.def(luabind::constructor<std::string>())
				.def("sayName", (void(Foo2::*) (void)) &Foo2::sayName)
				.def("sayNothing", (void(Foo2::*) (void)) &Foo2::sayNothing)
		];
	}

private:
	std::string m_sName;
};

class FooManager
{
public:
	FooManager() {};
	~FooManager() {};

	void	addComponent(IFoo* pFoo) { m_iFooVector.push_back(pFoo); }
	IFoo*	getComponent(int nIndex) { return m_iFooVector[nIndex]; }

	static void registrate(lua_State *pLuaState)
	{
		luabind::module(pLuaState) [
			luabind::class_<FooManager>("FooManager")
				.def(luabind::constructor<>())
				.def("getComponent", (IFoo*(FooManager::*) (int))
&FooManager::getComponent)
		];
	}

private:
	std::vector<IFoo*> m_iFooVector;
};

int main() 
{
	lua_State *myLuaState = luaL_newstate();

	// Connect LuaBind to this lua state
	luabind::open(myLuaState);

	// open the lua libraries
	luaL_openlibs(myLuaState);

	// register the luaBind classes
	registrate<IFoo>(myLuaState);
	registrate<Foo>(myLuaState);
	registrate<Foo2>(myLuaState);
	registrate<FooManager>(myLuaState);

	// create all the objects
	Foo *pFoo = new Foo("Test: 1-2-3!", myLuaState);
	Foo2 *pFoo2 = new Foo2("Zimba");
	FooManager* pfooManager = new FooManager();

	pfooManager->addComponent(pFoo);
	pfooManager->addComponent(pFoo2);
	
	// set object manager global
	luabind::globals(myLuaState)["fooManager"] = boost::ref(pfooManager);

	pFoo->doAwake();

	lua_close(myLuaState);
 
	// clean up
	delete pFoo;
	delete pFoo2;

	return 0;
}


// LUA SCRIPT 

function Awake()

	print("In Awake!")

	local pFooObj = fooManager:getComponent(0)

	pFooObj:sayName();

end

Cheers!



--
View this message in context: http://lua.2524044.n2.nabble.com/Opps-need-help-on-how-to-manage-c-objects-from-Lua-tp7649956p7650002.html
Sent from the Lua C++ Bind mailing list archive at Nabble.com.

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev