"Meta-table"
The keys in the meta-table are events (event), which are called meta-Methods (Metamethod).
The meta table of the table is replaced by the function setmetatable by querying the getmetatable of any value through the function.
Setmetatable (for table only) and getmetatable (for any object)
Syntax: setmetatable (table, metatable), setting metatable for the specified table "__metatable will fail if there are setmetatable key values in the Meta table (metatable)"
Syntax: Tmeta = getmetatable (tab), returns the object's meta-table (metatable) "If the __metatable key value exists in the Meta table (metatable) when the value of __metatable is returned"
"Meta-method"
A meta-table can control the behavior of an object's mathematical operations, sequential comparisons, joins, takes long, and index operations.
When Lua performs one of the operations on a value, check whether the value contains a meta-table and the corresponding event. If so, the value associated with the key (the Meta method) controls how Lua completes the operation.
The key for each operation is a string whose name is prefixed by two underscores "__"; for example, the key of the action "add" is the string "__add".
Specifically, to get the meta-method for a given object, we use an expression
MetaTable (obj) [Event]
It should be interpreted as
Rawget (getmetatable (obj) or {}, event)
That is, accessing a meta-method does not invoke other meta-methods, and accessing objects without a meta-table does not fail (only nil).
"Add": + operation.
The following Getbinhandler function defines how LUA chooses handlers for the two-dollar operation. First try the first operand, and if its type does not define a handler for the operation, try the second operand.
function Getbinhandler (OP1, OP2, event)
Return metatable (OP1) [Event] or metatable (OP2) [Event]
End
Event:
Add
Sub
Mul
Div
MoD
Pow
UNM unary operation-
Concat Connection operation:
Len take long Action #
EQ same operation = =
Lt is less than operation <
Le
index Access Table[key], parameter Table,key
NewIndex index Assignment Table[key] = value, parameter table, key, value
Call LUA calls
__index Meta-method:
According to the previous argument, if A's meta-table is B, then if a member that does not exist in a is accessed, it will be accessed if there is no such member in Find B. This is generally the case, but it is not quite so, in fact, even if A's meta-table is set to B, and B does have this member, the return result will still be nil, because the __index meta-method of B is not assigned a value. As I understand it, the __index method is used to determine how a table looks when it is used as a meta-table.
"User data and Meta methods"
Userdata:
A UserData offers a row memory area, with no predefined operations in Lua, which we can use to store anything (allocates a specified amount of memory on the stack Data is stored in a user-defined structure)
Lua_newuserdata ()--allocates a block of memory with the given size, pushes the corresponding userdatum on the stack, and Returns the Block address
MetaTable:
The usual method to distinguish one type of userdata from other userdata are to create a unique metatable for that type.
Lua code cannot changes the metatable of a userdatum, it cannot fake our code (Lua cannot change userdata inside metatable, so UserData meta Table can be used as a unique identifier to identify UserData, where metatable to determine if the correct UserData parameters are passed in.
Inheritance
Inheritance in the COCOS2DX:
function class (classname, ...) Local CLS = {__cname = classname} Local supers = {...} For _, Super in Ipairs (supers) do local supertype = Type (Super) assert (supertype = = "nil" or supertype = = "T Able "or supertype = =" function ", String.Format (" Class ()-Create class \ "%s\" with invalid super class type \ " %s\ "", ClassName, supertype)) if supertype = = "function" then assert (cls.__create = = Nil, String.Format ("Class ()-Create class \"%s\ "with more than one creating function", CLA Ssname)); --If super is function, set it to __create cls.__create = Super ElseIf supertype = = "Table" Then If super[". IsClass"] then – super is native class assert (cls.__create = = Nil, String.Format ("Class ()-Create class \"%s\ "with more than one creating function or native class", classname)); Cls.__create = function () return super:create () end else--super is pure LUA class Cls.__supers = Cls.__supers or {} cls.__supers[#cls. __supers + 1] = Super If no T Cls.super then--set first Super Pure Lua class as class.super Cls.super = Super End END Else Error (String.Format ("Class ()-Create class \"%s\ "with invalid S Uper type ", classname), 0) end End cls.__index = CLS if not cls.__supers or #cls. __ Supers = = 1 then setmetatable (CLS, {__index = cls.super}) Else Setmetatable (CLS, {__index = function (_, K EY) Local supers = Cls.__supers for i = 1, #supers do local super = Supers[i] If Super[key] then return Super[key] end end END}) End If not Cls.ctor then--add Default constructor Cls.ctor = function () end End cls.new = function (...) Local instance if Cls.__create then instance = cls.__create (...) else instance = {} End Setmetatableindex (instance, CLS) Instance.class = CLS Instan Ce:ctor (...) Return instance End cls.create = function (_, ...) Return Cls.new (...) End return Clsend
The principle is not to elaborate, modify the __index, so that when accessing its members can traverse all the Supers parent class to find the member (similar to the JS prototype chain, but that is a chain, where Lua is free to play).
His first argument is the class name, the following argument can be the parent table or function, the function can only have one, is used as the creation function of the __create, will be called at. New.
How to use:
Local uiscene = Class ("Uiscene") Uiscene.__index = uiscenefunction uiscene.extend (target) local t = Tolua.getpeer ( Target) if not t then t = {} tolua.setpeer (target, T) end setmetatable (T, Uiscene) return Targetendfunction uiscene.create () local scene = cc. Scene:create () Local layer = Uiscene.extend (CC. Layer:create ()) layer:init () scene:addchild (layer) return scene end
Getpeer/setpeer I do not quite understand, from the Internet to find instructions to keep digestion:
Those is Tolua functions. The Tolua manual (for example here) have explanations for Them.tolua.setpeer (object, peer_table) (LUA 5.1 only) sets the TA ble as the object ' s peer table (can be nil). The peer table is where all the custom LUA fields for the object are stored. When compiled with Lua 5.1, tolua++ stores the peer as the object ' s environment table, and uses uses lua_gettable/settable (instead of Lua_rawget/set for LUA 5.0) to retrieve and store in it. This allows us to implement we own object system on our table (using Metatables), and use it as a-a-to-inherit from the UserData object. Consider an alternative to the previous example:--a ' luawidget ' classluawidget = {}luawidget.__index = luawidgetfunction Luawidget:add_button (Caption)--Add a button to our widgets here. ' Self ' 'll be being the userdata widgetendlocal w = Widget () Local t = {}setmetatable (t, luawidget)--make ' t ' an instance of L Uawidgettolua.setpeer (W, t)--make ' t ' the peer Table of ' W ' set_parent (w)-- We use ' W ' as the object Noww:show ()--a method from ' Widget ' W:add_button ("Quit")--a method from Luawidget (but we STI ll use ' W ' to call it] when indexing our object, the peer table (if present) would be consulted first, so we don ' t need to I Mplement our own __index Metamethod to call the C + + Functions.tolua.getpeer (object) (LUA 5.1 only) retrieves the peer Tabl E from the object (can is nil).
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
lua--meta-table, meta-method, inheritance