lua-users home
lua-l archive

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


Am Freitag 09 Dezember 2005 02:06 schrieb John Klimek:
> Thanks for the reply!
>
> So basically you're saying to have C++ (or Delphi in my case) call my
> lua script several times... I like that idea!

> I'm a little confused on the private object part though.  Are you
> saying I should have C++/Delphi call my lua script function and pass
> in an object?  Would that be a userdata object?  (I'm still confused

Perhaps a table would do... but first, you have to choose what you want
to do:

1) For every NPC create/load a new function, which means that for 20
   NPC's of the same type you'll need much memory. On the other side,
   as every NPC has its own function and this way has its own (local)
   variables available.

2) Share the same function for as much NPC's as you want. Here you need
   an identifier, perhaps a unique number for which NPC the function has
   been called. Perhaps the NPC's variables could be stored in the NPC
   object?

> Also, do you have any class diagrams or any kind of layout plan for
> the classes in your program?  I'd like to see some kind of outline of
> the object managers you have and how everything works... (without

I don't have a 'object manager' as i'm not writing a MUD game ;)
I'm currently working on a lua scripting 'engine' for an ircbot.
Here every script runs in its own VM. I program in C not C++ so the
'class' i use is a simple struct:

enum
{
    HOOK_TICKER_ONE_SECOND  ,    /* called every second */
    HOOK_TICKER_TEN_SECONDS ,    /* called every 10 seconds */
    HOOK_TICKER_ONE_MINUTE  ,    /* called once per minute */
    HOOK_TICKER_TEN_MINUTES ,    /* called every 10 minutes */
    HOOK_TICKER_ONE_HOUR    ,    /* called once every hour */
    ... other hooks
    HOOKSIZE                     /* Size of hook list */
} HookTable;

typedef struct aLuaScriptInfo
{
    struct aLuaScriptInfo *next;
    char    *ScriptName;    /* UNIQUE name of the script */
    lua_State *L;           /* The lua_State for the script */
    int     Debug;          /* flag / mode for script debugging */
    char    *HookList[HOOKSIZE]; /* hook's function names if used */
} aLuaScriptInfo;

Thats the basic C struct. Now, for example when i load a script,
i allocate a new 'aLuaScriptInfo'-object and link it to the list
of currently loaded scripts. Then i load the script and, if no error
occured, run it:

LSI->Debug = TRUE;   /* catch parameter errors */
if ((i = luaL_loadfile(LSI->L, buffer)) == 0)
    i = lua_pcall(LSI->L, 0, 0, 0); /* run the script once */
if (i)
{
    error = (char*)lua_tostring(LSI->L, -1);
    ... here i unload the LSI object, free its memory and print
    the error message from the script...
}

However, as the script gets run via lua_pcall, it registers its
own hooks, for example

     Bot.RegisterHook("Ticker.OneHour", "timer_1h");

would register the lua-function 'timer_1h' to the named hook. In
C i copy the string "timer_1h" and store its pointer in the array
'HookList[HOOK_TICKER_ONE_HOUR]'. Then, in C, once per hour i call
every script who registered a function to this hook:

script_CallHook_noparms(HOOK_TICKER_ONE_HOUR);

... no error/return value handling here in the example code ...

void script_CallHook_noparms(int Hook)
{
    aLuaScriptInfo  *LSI;
    for(LSI = current->LSIbase; LSI; LSI = LSI->next)
    {
        if (LSI->HookList[Hook])
        {
            lua_getglobal(LSI->L, LSI->HookList[Hook]);
            lua_pcall(LSI->L, 0, 0, 0);
        }
    }
}

Basically i can call every 'hook' from where i want with
script_CallHook_... - i also have routines who takes one
or more arguments which depends on the hook itself...
And of course, a hook function in lua can re-register
another function to a hook.

I dont know if this helps you (or Bob) ;-) but thats
the way i do it and it works very good atm.

HTH,
   Torsten