q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=9e770c06bef783289dcf4a579d5487b7df930188

commit 9e770c06bef783289dcf4a579d5487b7df930188
Author: Daniel Kolesa <[email protected]>
Date:   Fri Oct 17 15:54:07 2014 +0100

    elua: complete property handling in eo bindings (getters, setters, keys, 
vals)
---
 src/bindings/luajit/eo.lua | 72 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 70 insertions(+), 2 deletions(-)

diff --git a/src/bindings/luajit/eo.lua b/src/bindings/luajit/eo.lua
index 6db2d1c..88bec9e 100644
--- a/src/bindings/luajit/eo.lua
+++ b/src/bindings/luajit/eo.lua
@@ -242,11 +242,79 @@ local get_obj_mt = function(obj)
     return classes[eo_class_addr_get(cl)]
 end
 
+local prop_proxy_meta = {
+    __index = function(self, key)
+        if self.nkeys > 1 and type(key) == "table" then
+            if self.nvals > 1 then
+                return { self(unpack(key)) }
+            else
+                return self(unpack(key))
+            end
+        else
+            if self.nvals > 1 then
+                return { self(key) }
+            else
+                return self(key)
+            end
+        end
+    end,
+
+    __newindex = function(self, key, val)
+        local nkeys = self.nkeys
+        if nkeys > 1 then
+            -- ultra slow path, q66 failed optimizing this
+            local atbl
+            if type(key) == "table" then
+                atbl = { unpack(key) }
+            else
+                atbl = { key }
+            end
+            if self.nvals > 1 and type(val) == "table" then
+                for i, v in ipairs(val) do atbl[nkeys + i] = v end
+            else
+                atbl[nkeys + 1] = val
+            end
+            self.mt[self.key .. "_set"](self.obj, unpack(atbl))
+        else
+            if self.nvals > 1 and type(val) == "table" then
+                -- somewhat less slow but still slow path
+                self.mt[self.key .. "_set"](self.obj, key, unpack(val))
+            else
+                -- least slow, no unpacks, no temporaries, just proxy
+                self.mt[self.key .. "_set"](self.obj, key, val)
+            end
+        end
+    end,
+
+    -- provides alt syntax for getters with keys
+    __call = function(self, ...)
+        return self.mt[self.key .. "_get"](self.obj, ...)
+    end
+}
+
 ffi.metatype("Eo", {
     __index = function(self, key)
         local mt = get_obj_mt(self)
         if mt == nil then return nil end
-        return mt[key]
+        local pt = mt.__properties
+        local pp = pt[key]
+        if not pp then
+            return mt[key]
+        end
+        if not pp[3] then
+            error("property '" .. key .. "' is not gettable", 2)
+        end
+        local nkeys, nvals = pp[1], pp[2]
+        if nkeys ~= 0 then
+            -- proxy - slow path... TODO: find a better way
+            return setmetatable({ nkeys = nkeys, nvals = nvals,
+                obj = self, key = key, mt = mt }, prop_proxy_meta)
+        end
+        if nvals > 1 then
+            return { mt[key .. "_get"](self) }
+        else
+            return mt[key .. "_get"](self)
+        end
     end,
 
     __newindex = function(self, key, val)
@@ -258,7 +326,7 @@ ffi.metatype("Eo", {
             error("no such property '" .. key .. "'", 2)
         end
         if not pp[4] then
-            error("property '" .. key .. "' is not settable")
+            error("property '" .. key .. "' is not settable", 2)
         end
         if pp[1] ~= 0 then
             error("property '" .. key .. "' requires " .. pp[1] .. " keys", 2)

-- 


Reply via email to