Changes from Version 1 of documentation/LuaManual/ProxyTables

Show
Ignore:
Author:
gambini (IP: 96.38.104.126)
Timestamp:
05/21/12 17:45:57 (5 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • documentation/LuaManual/ProxyTables

    v0 v1  
     1== Proxy Tables == 
     2== Problem to solve == 
     3The 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 
     5This 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 == 
     8All 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{{{ 
     10proxy_table =  
     11{  
     12GetTable = 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 
     17userdata:setmetatable(proxy_table)  
     18}}} 
     19It 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 
     23local item = userdata["name"] 
     24--or 
     25local item = userdata.name 
     26--or 
     27local item = userdata[3] 
     28--newindexes 
     29userdata["name"] = "apple" 
     30userdata.name = "orange" 
     31userdtata[2] = "banana" 
     32-- 
     33local item = userdata.name --would still trigger an __index metamethod, but still return 'orange' 
     34}}} 
     35Because ''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 == 
     38Getting 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 
     40Using 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. 
     41 
     42== Why == 
     43The 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. 
     44 
     45== List of proxy tables == 
     46This 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". 
     47 
     48{{{ 
     49Context.documents --read only, index by integer and string 
     50Element.attributes --read only, index by string 
     51Element.child_nodes --read only, index by integer 
     52Element.style --read & write, index by string 
     53Event.parameters --read only, index by string 
     54}}} 
     55A 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.