Code archives/Miscellaneous/lua_objectfromtable
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| There's not really a whole lot to say about this aside from how it determines how to set a value. Provided the key in the KV pair of the table is a string, the first thing the method will do is check for a field with the same name as the key. If no field is found, it checks for a setter method matching "set<key>". If no method is found, it checks for _key, where the key is prefixed with an underscore. If a field is found in either the first or the last case, the method checks to see if the value's type will work when assigning it to the field, and if it does the value of the field is set to that. If a method is found, the last case will not occur. The method (referring to lua_objectfromtable) will check to make sure the value will work with the first argument of the found method. If it does, the method is called and presumably something is set. When assigning a value to something that takes an object of any type (excluding arrays and strings) and the value is a table, the function will attempt to create an object from the table. If any value cannot be assigned because the type of the field and the value being assigned are incompatible, an exception will be thrown. If you attempt to create an array with the method, an exception will be thrown. If you do not provide a type for the object or the value at the index provided is not a table, Null is returned. No values are pushed onto the stack. | |||||
Strict
Import Brl.Reflection
Import LuGI.Core
Function lua_objectfromtable:Object(L@Ptr, index%, as:TTypeID)
Local reset% = lua_gettop(L)
If Not (lua_istable(L, index) And as) Then
Return Null
EndIf
Assert as._class <> ArrayTypeID._class Else "Cannot use lua_objectfromtable to create an array"
lua_pushvalue(L, index)
lua_pushnil(L)
Local obj:Object = as.NewObject()
' poor man's profiling
' Local findtime%=0
' Local fsettime%=0
' Local msettime%=0
' Local _t%, _t2%, _t3%
While lua_next(L, -2)
If lua_isstring(L, -2) Then
' _t=millisecs()
Local key$ = lua_tostring(L, -2)
Local f:TField = as.FindField(key)
If Not f Then
Local m:TMethod = as.FindMethod("set"+key)
If m Then
' _t2 = Millisecs()
Select m.ArgTypes()[0]
Case ByteTypeID, ShortTypeID, IntTypeID, LongTypeID
Assert lua_isnumber(L, -1) Else "Invalid value for integer setter argument"
m.Invoke(obj, [Object(String(lua_tointeger(L, -1)))])
Case FloatTypeID, DoubleTypeID
Assert lua_isnumber(L, -1) Else "Invalid value for float/double setter argument"
m.Invoke(obj, [Object(String(lua_tonumber(L, -1)))])
Case StringTypeID
Assert lua_isstring(L, -1) Else "Invalid value for string setter argument"
Default
If lua_istable(L, -1) And f.TypeID()._class <> ArrayTypeID._class Then
m.Invoke(obj, [lua_objectfromtable(L, -1, f.TypeID())])
Else
Assert lua_isbmaxobject(L, -1) Else "Invalid value for object setter argument"
m.Invoke(obj, [lua_tobmaxobject(L, -1)])
EndIf
End Select
' _t2 = Millisecs()-_t2
' msettime :+ _t2
' findtime :- _t2
Else
f = as.FindField("_"+key)
EndIf
EndIf
' findtime :+ Millisecs()-_t
If f Then
' _t = Millisecs()
Select f.TypeID()
Case ByteTypeID, ShortTypeID, IntTypeID
Assert lua_isnumber(L, -1) Else "Invalid value for integer field"
f.SetInt(obj, lua_tointeger(L, -1))
Case LongTypeID
Assert lua_isnumber(L, -1) Else "Invalid value for long field"
f.SetLong(obj, lua_tointeger(L, -1))
Case FloatTypeID
Assert lua_isnumber(L, -1) Else "Invalid value for float field"
f.SetFloat(obj, lua_tonumber(L, -1))
Case DoubleTypeID
Assert lua_isnumber(L, -1) Else "Invalid value for double field"
f.SetDouble(obj, lua_tonumber(L, -1))
Case StringTypeID
Assert lua_isstring(L, -1) Else "Invalid value for string field"
f.Set(obj, lua_tostring(L, -1))
Default
If lua_istable(L, -1) And f.TypeID()._class <> ArrayTypeID._class Then
f.Set(obj, lua_objectfromtable(L, -1, f.TypeID()))
Else
Assert lua_isbmaxobject(L, -1) Else "Invalid value for object field"
f.Set(obj, lua_tobmaxobject(L, -1))
EndIf
End Select
' fsettime :+ Millisecs()-_t
EndIf
EndIf
lua_pop(L, 1)
Wend
' DebugLog "find time: "+findtime+"ms"
' DebugLog "method set time: "+msettime+"ms"
' DebugLog "field set time: "+fsettime+"ms"
lua_settop(L, reset)
Return obj
End Function |
Comments
None.
Code Archives Forum