Extracting Wx Classes

lua-users home

This tutorial/sample is designed to help you understand how to extract a [wxLua] userdata object from the Lua stack in a lua_CFunction.

The basic procedure used here is to get what is called a class tag from the wxLuaState object of the wxWidgets class and use that tag to get the actual wxLua object in C++.

A class tag is an integer ID used to identify wxWidgets class types (wxDC, wxWindow, wxCheckBox, etc.) and are found in wxLuaBindClass structures. The tag is also stored in the metatable of all userdata objects that wxLua pushes into Lua to identify what the userdata is, see also "int wxlua_ttag(lua_State* L, int stack_idx)".

The wxLuaBindClass structure is a description of the C++ version of the wxWidget class that the wxLua binding uses to, well, bind the class to Lua.

struct wxLuaBindClass // defines a LUA C++ class interface
    const char      *name;          // name of the class
    wxLuaBindMethod *methods;       // pointer to methods for this class
    int              methods_n;     // number of methods
    wxClassInfo     *classInfo;     // pointer to the wxClassInfo associated with this class
    int             *class_tag;     // lua tag for user data allocated by ourselves
    const char      *baseclassName; // name of base class
    wxLuaBindClass  *baseclass;     // Pointer to the base class or NULL for none.
                                    // This member is set after all the bindings are
                                    // registered since the base class may be from
                                    // a different module (a library perhaps).
                                    // See wxLuaBinding::SetBaseClass

    wxLuaBindDefine* enums;         // Class member enums (if any)
    int              enums_n;       // number of enums
(You can find the definition of wxLuaBindClass in wxlbind.h)

The class_tag member is what you want. It is a pointer to a constant defined at start-up. (the structures are initialized in modules/wxbind/src/wxXXX_bind.cpp) Now how does one get the class description of a particular wxWidget class?

wxLuaBindClass* wxLuaState::GetLuaClass(const char* class_name)

This method returns a pointer to a wxLuaBindClass structure which will contain the class tag you can use to retrieve the actual object. class_name should specify the C++ name of the wxWidgets class, such as "wxPaintDC" or "wxFrame".

void* wxLuaState::GetUserDataType(int index, int tag)

index is the normal stack index that you would use to access any other element of the stack. tag is the value returned from wxLuaBindClass::class_tag (remember that this member is a pointer to an int) GetUserDataType will return the object that was requested.

There are many examples of how wxLua gets and pushes objects from and to Lua in the files modules/wxbind/src/*.cpp which are generated from the interface files in bindings/wxwidgets/*.i. These use the actual integer variable, which you can also use if you either include the header where they're declared or declare them yourself as an extern variable.


int Paint(lua_State* L)
	wxLuaState wxlState(L);
	wxPaintDC *dc;

	unsigned int tag;
	wxLuaBindClass* wxl_class;

	wxl_class = wxlState.GetLuaClass("wxPaintDC");     // get the WXLUACLASS
	tag = *wxl_class->class_tag;                       // remember to dereference the class_tag member!
	dc = (wxPaintDC*)wxlState.GetUserDataType(1, tag); // get the actual object

	  // ///////////////////////// //
	 //    Paint code goes here   //
	// ///////////////////////// //

	return 0;

notes: wxLuaBindClass: defined in modules/wxlua/include/wxlbind.h


I actually started researching this a while back when I was using wxLua to try and write a quick and dirty map editor and wanted to make sure I could optimize the paint handler. It took me a while to figure out and wanted to make sure that it was documented so somebody else looking to do the same thing didn't have to dive into and try and decipher the source code like I had to. --Nick

RecentChanges · preferences
edit · history
Last edited July 26, 2007 1:01 am GMT (diff)