Binding Lua

IUP - Portable User Interface

IupLua Advanced Guide

Exchanging "Ihandle*" between C and Lua

Each binding to a version of Lua uses different features of the language in order to implement IUP handles (Ihandle) in Lua. Therefore, functions have been created to help exchange references between Lua and C.

In C, to push an Ihandle in Lua's stack, use the function:

iuplua_pushihandle(Ihandle *ih);                 // for Lua3
iuplua_pushihandle(lua_State *L, Ihandle *ih);   // for Lua5

In C, to receive an Ihandle in a C function called from Lua, just use one of the following code:

Ihandle* ih = (Ihandle*)lua_getuserdata(object);    // for Lua 3
Ihandle* ih = *(Ihandle**)lua_touserdata(L, pos);   // for Lua 5

or using parameter checking:

Ihandle* iuplua_checkihandle(int pos);                 // for Lua 3
Ihandle* iuplua_checkihandle(lua_State *L, int pos);   // for Lua 5

In Lua, if the handle is a user data create with the above structure, but not mapped to a Lua object, use the function:

iup.RegisterHandle(handle, typename)

where "typename" is the string returned in IupGetType(handle)

In Lua, to access a handle created in C as a Lua object, alternatively use the function:

handle = iup.GetFromC(name)

where "name" is the name of the element previously defined with IupSetHandle.

Error Handling

In Lua 3 the _ALERT function is redefined to show the message in a dialog.

In Lua 5 there is no such function, so to improve the error report the following functions have been created to execute Lua code:

int iuplua_dofile(lua_State *L, char *filename);
int iuplua_dostring(lua_State *L, const char *string, const char *chunk_name);

These functions mimics the implementation in the standalone interpreter for Lua 5, that displays the error message followed by the stack.

If the these functions are used the errors will be reported through the _ERRORMESSAGE function. By default _ERRORMESSAGE is defined to show a dialog with the error message.

The Architecture Behind IupLua 3

The Lua API for the IUP system was based on object classes representing the different interface elements. A hierarchy was built among these classes, with the main purpose of reusing code. Code inheritance was implemented precisely as described in the Lua 3 user guide.

The root of this hierarchy is the WIDGET class. It contains the basic procedures for construction, parameter type verification, and allocation of structures for controlling IUP�s interface elements. This class also defines the basic parameters of all classes, such as handle (which stores the handle of the associated IUP element) and parent (used to implement the inheritance mechanism).

Even though almost all classes directly descend from the WIDGET class, some other classes serve as mediators in the tree. This is the case of the COMPOSITION class, located among the composition element classes: IUPHBOX, IUPVBOX and IUPZBOX.

Some classes use part of the code from other classes, when they are very similar. This happens to IUPITEM and IUPTOGGLE, which reuse the code related to the verification of parameter types and to the definition of the action callback in the IUPBUTTON class. Class IUPMULTILINE inherits several characteristics from IUPTEXT, such as the definition of the action callback and the verification of parameter types.

The complete class hierarchy for the standard controls can be represented as follows:

WIDGET
   IUPBUTTON
      IUPITEM
      IUPTOGGLE
   IUPCANVAS
   COMPOSITION
      IUPHBOX
      IUPVBOX
      IUPZBOX
   IUPDIALOG
   IUPFILL
   IUPFRAME
   IUPIMAGE
   IUPLABEL
   IUPLIST
   IUPMENU
   IUPRADIO
   IUPSEPARATOR
   IUPSUBMENU
   IUPTEXT
      IUPMULTILINE

The Architecture Behind IupLua 5

There are two important names in IupLua5: "iup handle" and "iup widget".

When you create an IUP element in Lua 5 it is created a table with a metatable called "iup widget". This metatable has its "__index" method redefined so when an index is not defined it looks for it in the "parent" table. The table it self represents the class of the control. And all the classes inherit the implementation of the base class WIDGET. Each control class must implement the "createElement" method of the class. The WIDGET class also a member called "handle" that contains the Ihandle* in Lua. The constructor of the WIDGET class returns the handle.

The Ihandle* is represented in Lua as a table with a metatable called "iup handle". This metable has its "__index", "__newindex" and "__eq" methods redefined. The index methods are used to implement the set and get attribute facility. The handle knows its class because it is stored in its "parent" member.

Since the controls creation is done by the "iup.<control>" function, the application does not use the WIDGET class directly. All the time the application only uses the handle.

So for example the IupLabel:

iup.label   calls    iup.LABEL:constructor
since   iup.LABEL.parent = iup.WIDGET    and     iup.LABEL:constructor is not implemented
it calls     iup.WIDGET:constructor  
then   iup.WIDGET:constructor    calls   iup.LABEL:createElement    
and finally returns the created    handle  

The complete class hierarchy for the standard controls can be represented as follows:

WIDGET
   BUTTON
   ITEM
   TOGGLE
   CANVAS
   BOX
      HBOX
      VBOX
      ZBOX
      MENU
   DIALOG
   FILL
   FRAME
   IMAGE
   LABEL
   LIST
   RADIO
   SEPARATOR
   SUBMENU
   TEXT
   MULTILINE