Hi al

I have been creating an update to my LuaClasses routines. Now I have made it easier to also add LuaRecords to scripts read/write fields :-)

Example Vector3f addition to Lua

Code:
Function Vector3f_Read(L: lua_State): Integer; CDecl; Forward;
Function Vector3f_Write(L: lua_State): Integer; CDecl; Forward;
Function Vector3f_Add(L: lua_State): Integer; CDecl; Forward;
Function Vector3f_Sub(L: lua_State): Integer; CDecl; Forward;
Function Vector3f_GC(L: lua_State): Integer; CDecl; Forward;
{.......................................................}

{.......................................................}
Function LuaVector3fCheck(L: lua_State; Idx: Integer): PVector3f;
Var
    v3f : PVector3f;
Begin
    Result := Nil;

    If (Not lua_istable(L,Idx)) Then
    Begin
        LuaDoError(L,'Vector3f expected, found "'+lua_typename(L,lua_type(L,Idx))+'"');
        Exit;
    End;

    lua_getmetatable(L,Idx);

    lua_pushstring(L,'_Vector3f');
    lua_gettable(L,-2);

    If (Not lua_isuserdata(L,-1)) Then
    Begin
        LuaDoError(L,'Vector3f expected, found "'+lua_typename(L,lua_type(L,Idx))+'"');
        Exit;
    End;

    Result := lua_touserdata(L,-1);
End;
{.......................................................}

{.......................................................}
Procedure Vector3f_PushOntoLuaStack(L: lua_State; V3f: PVector3f);
Var
    Table : Integer;
    MT    : Integer;
Begin
    lua_newtable(L);

    Table := lua_gettop(L);

    //  create a meta table
    lua_newtable(L);

    MT := lua_gettop(L);

    lua_pushstring(L,'__index');
    lua_pushcfunction(L,Vector3f_Read);
    lua_settable(L,MT);

    lua_pushstring(L,'__newindex');
    lua_pushcfunction(L,Vector3f_Write);
    lua_settable(L,MT);

    lua_pushstring(L,'__add');
    lua_pushcfunction(L,Vector3f_Add);
    lua_settable(L,MT);

    lua_pushstring(L,'__sub');
    lua_pushcfunction(L,Vector3f_Sub);
    lua_settable(L,MT);

    lua_pushstring(L,'__gc');
    lua_pushcfunction(L,Vector3f_GC);
    lua_settable(L,MT);

    lua_pushstring(L,'_Vector3f');
    lua_pushlightuserdata(L,V3f);
    lua_settable(L,MT);

    lua_setmetatable(L,Table);
End;
{.......................................................}

{.......................................................}
Function Vector3f_New(L: lua_State): Integer; CDecl;
Var
    V3f   : PVector3f;
Begin
    New(V3f);
    
    V3f^.x := luaL_checknumber(L,1);
    V3f^.y := luaL_checknumber(L,2);
    V3f^.z := luaL_checknumber(L,3);

    Vector3f_PushOntoLuaStack(L,V3f);

    Result := 1;
End;
{.......................................................}

{.......................................................}
Function Vector3f_Read(L: lua_State): Integer; CDecl;
Var
    V3f   : PVector3f;
    Key   : AnsiString;
Begin
    Result := 0;

    V3f := LuaVector3fCheck(L,1);

    If (V3f = Nil) Then
        Exit;

    Key := luaL_checkstring(L,2);

    If (Key = 'x') Then
        lua_pushnumber(L,V3f^.x)
    Else
    If (Key = 'y') Then
        lua_pushnumber(L,V3f^.y)
    Else
    If (Key = 'z') Then
        lua_pushnumber(L,V3f^.z)
    Else
    Begin
        LuaDoError(L,'Vector3f: unknown field "' + Key + '"');
    End;

    Result := 1;
End;
{.......................................................}

{.......................................................}
Function Vector3f_Write(L: lua_State): Integer; CDecl;
Var
    V3f   : PVector3f;
    Key   : AnsiString;
Begin
    Result := 0;

    V3f := LuaVector3fCheck(L,1);

    If (V3f = Nil) Then
        Exit;

    Key := luaL_checkstring(L,2);

    If (Key = 'x') Then
        V3f^.x := luaL_checknumber(L,3)
    Else
    If (Key = 'y') Then
        V3f^.y := luaL_checknumber(L,3)
    Else
    If (Key = 'z') Then
        V3f^.z := luaL_checknumber(L,3)
    Else
    Begin
        LuaDoError(L,'Vector3f: unknown field "' + Key + '"');
    End;

    Result := 0;
End;
{.......................................................}

{.......................................................}
Function Vector3f_Add(L: lua_State): Integer; CDecl;
Var
    v1,v2,v3   : PVector3f;
    Key   : AnsiString;
Begin
    Result := 0;

    v1 := LuaVector3fCheck(L,1);
    v2 := LuaVector3fCheck(L,2);

    If (v1 = Nil) Or (v2 = Nil) Then
        Exit;

    New(v3);

    v3^.x := v1^.x + v2^.x;
    v3^.y := v1^.y + v2^.y;
    v3^.z := v1^.z + v2^.z;

    Vector3f_PushOntoLuaStack(L,v3);

    Result := 1;
End;
{.......................................................}

{.......................................................}
Function Vector3f_Sub(L: lua_State): Integer; CDecl;
Var
    v1,v2,v3   : PVector3f;
    Key   : AnsiString;
Begin
    Result := 0;

    v1 := LuaVector3fCheck(L,1);
    v2 := LuaVector3fCheck(L,2);

    If (v1 = Nil) Or (v2 = Nil) Then
        Exit;

    New(v3);

    v3^.x := v1^.x - v2^.x;
    v3^.y := v1^.y - v2^.y;
    v3^.z := v1^.z - v2^.z;

    Vector3f_PushOntoLuaStack(L,v3);

    Result := 1;
End;
{.......................................................}

{.......................................................}
Function Vector3f_GC(L: lua_State): Integer; CDecl;
Var
    V3f   : PVector3f;
Begin
    V3f := LuaVector3fCheck(L,1);

    If (V3f = Nil) Then
        Exit;

    Dispose(V3f);

    Result := 0;
End;
{.......................................................}

{.......................................................}
how to register the record with Lua
Code:
    //  register each record type
    RegisterLuaRecord('Vector3f',Vector3f_New);

    //  register all registered records to the lua state
    RegisterLuaRecordsWithLua(Script.State);
Lua script using the record

Code:
a = Vector3f(10,20,30)
b = Vector3f(4,5,6)

c = a + b

print(c.x,c.y,c.z)
LuaRecords unit code

Code:
Unit LuaRecords;
{.......................................................}
//  created by Paul Nicholls
//  Copyright 2006
//  Use for anything that you want, but
//  please email me with any improvements that you may make :)
//
//  Email:
//  paul_nicholls.hotmail.com
{.......................................................}

Interface

Uses
    Lua;

Procedure RegisterLuaRecordProcs(ARecordName: AnsiString;
                                 ANewRecordProc: lua_CFunction);
Procedure RegisterLuaRecordsWithLua(L: lua_State);

Implementation

Type
    TLuaRecord = Packed Record
        RecordName    : AnsiString;
        ANewRecordProc: lua_CFunction;
    End;

    TLuaRecordArray = Array Of TLuaRecord;

Var
    RegisteredLuaRecords: TLuaRecordArray;

{.......................................................}

{.......................................................}
Procedure RegisterLuaRecordProcs(ARecordName: AnsiString;
                                 ANewRecordProc: lua_CFunction);
Begin
    If (Not Assigned(ANewRecordProc)) Then
        Exit;

    SetLength(RegisteredLuaRecords,Length(RegisteredLuaRecords) + 1);

    RegisteredLuaRecords[High(RegisteredLuaRecords)].RecordName := ARecordName;
    RegisteredLuaRecords[High(RegisteredLuaRecords)].ANewRecordProc := ANewRecordProc;
End;
{.......................................................}

{.......................................................}
Procedure RegisterLuaRecordsWithLua(L: lua_State);
Var
    i         : Integer;
    LuaRecord : TLuaRecord;
Begin
    For i := 0 To High(RegisteredLuaRecords) Do
    Begin
        LuaRecord := RegisteredLuaRecords[i];

        lua_register(L,PChar(LuaRecord.RecordName),LuaRecord.ANewRecordProc);
    End;
End;
{.......................................................}

{.......................................................}
Initialization
    SetLength(RegisteredLuaRecords,0);
{.......................................................}

{.......................................................}
End.