lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Thats exact the concept we have for our gui system. Our GUI consists of C++
classes for all the base gui stuff like windows and buttons and edits
fields. The components use a callback system like described in the article
below, the usage of these is a bit like delphi.

Now all these objects are available to the Lua state via toLua. Lua code is
able to receive such signals via these callbacks but are not able to send
signals (which when I think about it should also be perfectly possible *g*).

So how to persuade the C++ callback system to call Lua functions
transparently? A Lua call requires a state and the function name (and also
the parameters, but this will be taken care for later). These parameters are
not part of the callback storage, so I have to provide a proxy class for
this binding. Like this one:

template <class arg1>
class CScrCallbackProxy1 : public CScrCallbackProxyBase

    void Execute (arg1 _a1)
        pScript->PushObject (_a1);
        pScript->CallFunction (sFunction);

    CScrEnvironment *pScript;
    CUtlString sFunction;

Now when we bind the Lua function we create an instance of the proxy class,
store the state pointer (encapsuled in CScrEnvironment) and the function
name in this object, store the instance pointer in a global list for memory
management and create a C++ callback calling Execute with this special
instance object. Like this:

template <class arg1>
CUtlCallback1 <CScrCallbackProxy1 <arg1>, arg1> ScrMakeFunctor1
(CScrEnvironment *_pScript, const CUtlString &_sFunction)
    CScrCallbackProxy1 <arg1> *pProxy;

    pProxy = new CScrCallbackProxy1 <arg1> ();
    pProxy->pScript = _pScript;
    pProxy->sFunction = _sFunction;
    _pScript->RegisterProxy (pProxy);

    return UtlMakeFunctor1 (pProxy, CScrCallbackProxy1<arg1>::Execute);

All this template stuff is based on the base C++ callback paper, so don't be
worried, it is expained somewhere, but not here *g* But feel free to ask
offline for this, if you want further infos. I like this template magic and
callback stuff....

And for the params life is really easy. You've probably seen the PushObject
function pushing data on the Lua stack without caring for the type? Just a
few more template lines. This one will select based on the type a mapper
class and calls push on that:

template <class T> void PushObject (T What) { CScrTypeMapper<T>::Push
(What); }

And this are the mapper class definitions:

template <class T>
class CScrTypeMapper

        static void Push (T What) { lua_pushuserdata (What); };

template <>
class CScrTypeMapper <int>

        static void Push (int What) { lua_pushnumber (What); };

template <>
class CScrTypeMapper <double>

        static void Push (double What) { lua_pushnumber (What); };

template <>
class CScrTypeMapper <CUtlString>

        static void Push (CUtlString What) { lua_pushstring (const_cast
<char *> (What.CMbStr ())); };

Is rather long the explanation, but I hope you can understand this...


-----Ursprungliche Nachricht-----
[]Im Auftrag von James Hearn
Gesendet: Freitag, 12. Januar 2001 14:41
An: Multiple recipients of list
Betreff: Re: AW: tolua, c++, garbagecollection and memory management

Dirk Ringe wrote:
> QT signal/slot system does not only need a preprocessor, but also uses
> string message parsing, with causes a lot of overhead. Any decent template
> based C++ callback system should be able to outperform the signal/slot
> system and also provide more type safety (which is essentially for free on
> template system).
> For infos about C++ callbacks look at the following site:
> I did extend the system so that I am able to bind a Lua function to a
> callback, so that when the C++ object calls the callback it can jump
> seamless into Lua (without even knowing about Lua in the system).  Very
> feature, when you don't know beforehand, what parts of your code will be
> written in Lua and what in C++ (sometimes we got to switch from Lua to C++
> for performance reasons, etc.)
> Dirk

May I ask how you were able to bind lua to these callbacks? The game
windowing system I am modifying is a mini-Qt-alike system for the
Allegro game library. (No language extensions or string parsing, but it
does require gui objects to inherit from a base gui object class in
order to gain access to the signal and slot controlling methods.) My
goal is to be able to dynamically create/modify/save guis from a lua
console within a program. A big part of this would be using lua
functions transparently as signals/slots.

Many thanks,

James Hearn