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.
Bookmarks