introduction to loc
DESCRIPTION
Loc (Lua to Objective-C) is a bridge of type conversion between Lua and Objective-C. This presentation shows the design idea of Loc.TRANSCRIPT
![Page 1: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/1.jpg)
Introduction to Loc A bridge between Lua and Objective-C
![Page 2: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/2.jpg)
Data Type Mapping
Lua Type Objective-C Type
LUA_TNIL nil
LUA_TBOOLEAN BOOL (? NSNumber)
LUA_TLIGHTUSERDATA
LUA_TNUMBER NSNumber
LUA_TSTRING NSString
LUA_TTABLE NS(Mutable)Dictionary (? NSArray)
LUA_TFUNCTION C Function Pointer (Lua Function)
LUA_TUSERDATA
(?) NSObject
![Page 3: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/3.jpg)
Table Lua Table type implements associative arrays.
It can be used as Array with numeric index:
local array = {0,1, "string3", true};
or Dictionary with string key:
local dict = {"hello"="world", 8="storm"};!
Pound(#) operator would return the length of table if table is Array, but it does not count string key/value pairs.
print(#array); 4
![Page 4: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/4.jpg)
Metatable
Metatable is still a table.
It is attached to other Lua type to:
Ø Identify a value as a “Class”
Ø Provide default behaviors by Metamethods
![Page 5: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/5.jpg)
Set/Get Metatable
• Lua API
getmetatable (object)!
setmetatable (table, metatable)!
!(In Lua, only able to set metatable on table)!
• C API
int lua_setmetatable (lua_State *L, int objindex)!
int lua_getmetatable (lua_State *L, int objindex)
![Page 6: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/6.jpg)
Metamethod
Simple explain: they are a set of special keys in metatable.
The values assigned with those keys will automatically trigger in certain situation.
Technical explain: they are Operator Overloading
__add, __sub, __mul, __div, __mod, __pow, __unm, __concat, __len, __eq, __lt, __le, __index, __newindex, __call
![Page 7: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/7.jpg)
__index
Trigger
• Try to get value from key which does not exist in original table
Metametahod Value
• A function • A Table
Effect
• Call __index(table, key) • Return __index[key]
![Page 8: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/8.jpg)
__newindex
Trigger
• Try to set value to key which does not exist in original table
Metametahod Value
• A function • A Table
Effect
• Call __newindex(table, key, value) • __newindex[key] = value;
![Page 9: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/9.jpg)
__call
Trigger • Use table as function, and call with ()
Metametahod Value
• A function
Effect • Call __call(table, …); … are arguments
![Page 10: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/10.jpg)
Colon(:) vs Dot(.)
Lua is not Class based Object oriented language, this or self is not reserved keyword. When call a method on object(table), inside method it don’t know which object it is using. Programmer has to manually pass it to method:
obj.count(obj);!
When define the method, we also need to reserve a argument for it, and we could define the argument name as this or self.
function count(self) {!
return #self;!
}!
![Page 11: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/11.jpg)
Colon(:) vs Dot(.)
Lua provide a syntax sugar, we could use colon(:) to call method, and it will automatically pass the caller as first argument.
obj:count();
However, when define the method, we still need to reserve first position of argument for caller.
![Page 12: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/12.jpg)
Userdata
The userdata type allows arbitrary C data to be stored in Lua variables.
void *lua_newuserdata (lua_State *L, size_t size)
It allocate memory with given size, and return pointer to that memory address.
It’s very similar to C void *malloc(size_t); except with above API, the memory is allocated in Lua, hence Lua GC will automatically free it, if there is no reference on it.
![Page 13: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/13.jpg)
Metatable on Userdata
Lua has not predefined any operations for Userdata, except assignment and equality test.
Userdata does not contain any key, hence any get/set of key would always trigger metamethod. Developer could define a custom metatable and set to userdata to provide certain functionalities.
E.g.: when set value on key, with __newindex we could redirect to set value on relative property; when compare two user data, with __eq we could compare not only the address but also the content.
![Page 14: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/14.jpg)
Light Userdata
A light userdata is a value that represents a C pointer (i.e. a void * value).
void lua_pushlightuserdata (lua_State *L, void *p)
Lua only hold the pointer to a memory, the program out of Lua should handle the memory manager of that data.
![Page 15: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/15.jpg)
Light Userdata vs Userdata
All the light userdata share the same metatable. Push A to Lua as light userdata;
Set MTX on A as metatable;
Push B to Lua as light userdata;
Get metatable of B, you will get MTX, not nil;
Set MTY on B as metatable;
Metatable of A will also change to MTY
Userdata has it’s own metatable, and programmer need to set metatable on each new created userdata
![Page 16: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/16.jpg)
Loc Design
1. Create metatable, bind C functions to metamethods
2. Create userdata, set the address of object to it
3. Set metatable on userdata
4. Push userdata to lua
Whenever we need to push objective-C object to Lua, we do step 2-4
![Page 17: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/17.jpg)
Use Light Userdata
" pushid
lua_pushlightuserdata(L, self);!
luaL_getmetatable(L, name);
lua_setmetatable(L, -2);
" toid
return (id)lua_touserdata(L, idx);
![Page 18: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/18.jpg)
Use Userdata
" pushid
id *ud = (id*)lua_newuserdata(L, sizeof(id));!
*ud = self;!
luaL_getmetatable(L, name);
lua_setmetatable(L, -2);
" toid
return *((id*)lua_touserdata(L, idx));
![Page 19: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/19.jpg)
Loc Trigger on Setter
Lua statement
• object.propertyName = value;
Trigger __newIndex
• __newindex(object, propertyName, value);
Call to bond C Function
• Retrieve userdata back to Object, get other info
Call Objective-C
• [object setValue:value forKey:propertyName];
![Page 20: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/20.jpg)
Loc Trigger on Getter
Object has data members, and method members.
When using Lua syntax to request member with name, inside __index method, only the name is provided, we don’t know the result should be a value, or a function which would accept more arguments. Because we don’t know if there are parenthesis after the name or not.
So in __index, Loc always return a function (use table with __call metamethod to implement a functor). Later call on that function, if there is no argument, we treat as property.
![Page 21: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/21.jpg)
Loc Trigger on Method Call
Lua statement
• value = object:propertyName(); • result = object:methodName(arguments);
Trigger __newIndex
• Create new table; save Name in table; set metatable
Trigger __call • Retrieve object; get name from table; parse arugments
Trigger __call
• [object valueForKey:propertyName]; • Use NSInvocaton to reflect the method call
![Page 22: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/22.jpg)
Loc Function Call Process
object:methodName(arguments);!
__index(object, methodName)!
functor = { _key = methodName };!
setMetatable(functor)!
return functor;!
![Page 23: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/23.jpg)
Loc Function Call Process
object:functor(arguments);!
functor(object, arguments)!
__call(functor, object, arguments)!
methodName = functor[_key];!
selector = convert(methodName);!
invocation = NSInvocatoin(...);!
invocation.invoke();!
return invocation.result;!
![Page 24: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/24.jpg)
NSDictionary & NSArray
NSDictionary and NSArray are well-defined system class. The functionalities required are more clear than user defined classes. So we don’t need to use reflection for them.
Loc define C functions to directly map to relative instance methods.
This is done by setting table, which contains a set of C Functions, on __index of metatable, and called by colon(:) syntax.
![Page 25: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/25.jpg)
LocDictionary
Selector Functions __index
Table
get(k) objectForKey:
set(k,v) setObject:forKey:
count() count
… …
Some methods may would allowed for NSMutableDictionary
![Page 26: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/26.jpg)
LocArray
Selector Functions __index
Table
get(i) objectAtIndex:
add(o) addObject:
count() count
… …
Some methods may would allowed for NSMutableArray The index is 1-based, it will convert to 0-based in methods
![Page 27: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/27.jpg)
LocLuaLib " It is a set of utility methods as Lua Library.
" It register as global table loc.
Method Library loc
loc
toclass(str) NSClassFromString()
todictionary(t) loc_todictionary()
toarray(t) loc_toarray()
![Page 28: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/28.jpg)
Q & A
![Page 29: Introduction to Loc](https://reader033.vdocument.in/reader033/viewer/2022042602/559929601a28ab45298b4735/html5/thumbnails/29.jpg)
You may also like to know
Registry: http://www.lua.org/pil/27.3.1.html Special place to share global data between C functions
Privacy: http://www.lua.org/pil/15.2.html Use local table as key for other table
Metatable protection: http://www.lua.org/pil/13.3.html __metatable
C Library: http://www.lua.org/pil/26.2.html Register a set of C Functions as Lua Library