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