Changes between Version 2 and Version 3 of documentation/LuaManual/ProxyTables

Show
Ignore:
Author:
gambini (IP: 96.38.104.126)
Timestamp:
05/29/12 17:27:07 (5 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • documentation/LuaManual/ProxyTables

    v2 v3  
    1 == Proxy Tables == 
    2 == Problem to solve == 
    3 The problem with Lua tables is that building them isn't an inexpensive operation when done once per frame, or even once per event if it is a large table. When a property or function in Lua calls in to C++ and that function would return a collection of items, proxy tables will forgo the table building unless explicitly told to do so. 
    4  
    5 This is one of the more noticeable areas where the Lua implementation varies from Python, and subsequently Javascript.[wiki:documentation/LuaManual/ProxyTables#Why Why?] 
    6  
    7 == How == 
    8 All proxy tables will override the usual ''!__index'' and/or ''!__newindex'' Lua metamethods. They hook in to the access and setting of tables when the items don't exist directly in the table. At all times, the table of a proxy table will be similar to 
    9 {{{ 
    10 proxy_table =  
    11 {  
    12 GetTable = function() call_c_function() end  
    13 __index = function() __index_function_in_c() end 
    14 __newindex = function() __newindex_function_in_c() end 
    15 
    16 --userdata has a reference to the C++ pointer object to retrieve the data from 
    17 userdata:setmetatable(proxy_table)  
    18 }}} 
    19 It is done all in C++, so that is not exactly how that happens, but it is an accurate enough representation for why the next example would trigger the ''!__index'' and ''!__newindex'' metamethods. 
    20 {{{ 
    21 --userdata is the same as the previous code block, with proxy_table 
    22 --as the metatable 
    23 local item = userdata["name"] 
    24 --or 
    25 local item = userdata.name 
    26 --or 
    27 local item = userdata[3] 
    28 --newindexes 
    29 userdata["name"] = "apple" 
    30 userdata.name = "orange" 
    31 userdtata[2] = "banana" 
    32 -- 
    33 local item = userdata.name --would still trigger an __index metamethod, but still return 'orange' 
    34 }}} 
    35 Because ''name'' and ''3'' doesn't exist on the actual table, it triggers the metamethods. The ''!__newindex'' does NOT actually add the item to the table, only adds the item to the C++ object using appropriate get/set methods available. 
    36  
    37 == I want the actual table == 
    38 Getting the actual table is no problem. Every single proxy table has a method named ''GetTable()''. This will build a table of key,value pairs. Depending on the needs, sometimes the tables are indexed by both integer keys and string keys. In this case, a table value is duplicated and set to both the integer and string indexes. 
    39  
    40 Using the ''GetTable()'' function is the only way to to be able to iterate over the table, but beware of the ones that are indexed by both integer keys and string keys. If using pairs(), then iteration will hit each value twice: once for its integer key and once for its string key. To hit each value only once, use ipairs() to iterate only over the integer keys. 
     1= Proxy Tables = 
     2When iterating over a table returned from a select few properties, you '''must''' use ''ipairs'' or ''pairs'' rather than ''foreach'', ''next'', or whatever else exists. The "tables" are actually userdata containing C++ pointers. 
    413 
    424== Why == 
    43 The Lua language is fairly simple. It does not have an iterator metamethod like it does for some other operations, and because of this, the ''GetTable()'' method exists for proxy tables. It is a tradeoff of performance for being a little less intuitive. However, accessing individual items is fast and intuitive, because the syntax is the same as if it were an actual value in the table
     5The Lua language is fairly simple. It does not have an iterator metamethod like it does for some other operations. Because of this, __pairs and __ipairs are pseudo-metamethods that exist for proxy tables. It is a tradeoff of performance for being a little less flexible. However, since Lua's ''foreach'' is being depreciated, there is almost no reason to not use ''ipairs'' or ''pairs''
    446 
    457== List of proxy tables == 
    46 This is an exhaustive list of functions and properties that return proxy tables. If you think that this is out of date or incorrect, then the file names in the source code will tell you if you are correct. If the file name ends with "Proxy.cpp", then it is proxy table, with the exception of "ElementStyle.cpp". 
     8This is an exhaustive list of everything that returns proxy tables. If you think that this is out of date or incorrect, then the file names in the source code will tell you if you are correct. If the file name ends with "Proxy.cpp", then it is proxy table, with the exception of "ElementStyle.cpp". 
    479 
    4810{{{ 
    49 Context.documents --read only, index by integer and string 
    50 Element.attributes --read only, index by string 
    51 Element.child_nodes --read only, index by integer 
     11Context.documents --read-only, index by integer and string 
     12Element.attributes --read-only, index by string 
     13Element.child_nodes --read-only, index by integer 
    5214Element.style --read & write, index by string 
    53 Event.parameters --read only, index by string 
     15Event.parameters --read-only, index by string 
    5416--From RocketControls 
    5517ElementFormControlSelect.options --[[read only, index by integer 
    5618      each index item is a table with two named values, {"element"=Element,"value"=string} ]] 
    5719}}} 
    58 A function that returns a table that is NOT a proxy table is ''rocket.contexts''. It is read only and indexed by both string and integer. 
     20 
     21If you try to use ''ipairs'' on a proxy table that is only indexed by string, then you will iterate over no items. If you use ''pairs'' on a proxy table that is only indexed by integer, then you will iterate over all of the items, just like you would expect.