-- EFL LuaJIT bindings: Eina (accessor module) -- For use with Elua local ffi = require("ffi") local C = ffi.C ffi.cdef [[ typedef struct _Eina_Accessor Eina_Accessor; typedef unsigned char Eina_Bool; void eina_accessor_free (Eina_Accessor *accessor); Eina_Bool eina_accessor_data_get (Eina_Accessor *accessor, unsigned int position, void **data); Eina_Bool eina_accessor_lock (Eina_Accessor *accessor); Eina_Bool eina_accessor_unlock (Eina_Accessor *accessor); Eina_Accessor *eina_accessor_clone (Eina_Accessor *accessor); void *eina_accessor_container_get(Eina_Accessor *accessor); ]] local cutil = require("cutil") local util = require("util") local M = {} local eina local init = function() eina = util.lib_load("eina") end local shutdown = function() util.lib_unload("eina") end ffi.metatype("Eina_Accessor", { __index = { free = function(self) eina.eina_accessor_free(ffi.gc(self, nil)) end, data_get = function(self, position) local data = ffi.new("void*[1]") local r = eina.eina_accessor_data_get(self, position - 1, data) if r == 0 then return nil end return data[0] end, lock = function(self) return eina.eina_accessor_lock (self) ~= 0 end, unlock = function(self) return eina.eina_accessor_unlock(self) ~= 0 end, clone = function(self) local v = eina.eina_accessor_clone(self) if v == ffi.nullptr then return nil end return v end, container_get = function(self) local v = eina.eina_accessor_container_get(self) if v == ffi.nullptr then return nil end return v end } }) cutil.init_module(init, shutdown) local dgetmt = debug.getmetatable M.Accessor = util.Readonly_Object:clone { __ctor = function(self, selfmt, acc) -- prevent null stuff if acc == ffi.nullptr then acc = nil end if acc then ffi.gc(acc, acc.free) end selfmt.__eq = function(self, other) return selfmt.__accessor == dgetmt(other).__accessor end selfmt.__call = function(self) return self:next() end local oi = selfmt.__index selfmt.__index = function(self, name) if type(name) == "number" then return self:data_get(name) end return oi[name] end selfmt.__accessor = acc end, free = function(self) self = dgetmt(self) if not self.__accessor then return end self.__accessor:free() self.__accessor = nil end, lock = function(self) self = dgetmt(self) if not self.__accessor then return false end return self.__accessor:lock() end, unlock = function(self) self = dgetmt(self) if not self.__accessor then return false end return self.__accessor:unlock() end, clone = function(self) self = dgetmt(self) if not self.__accessor then return nil end return self.__protos[1](self.__accessor:clone()) end, data_get = function(self, pos) self = dgetmt(self) if not self.__accessor then return nil end return self.__accessor:data_get(pos) end, container_get = function(self) self = dgetmt(self) if not self.__accessor then return end return self.__accessor:container_get() end, each = function(self) local acc = dgetmt(self).__accessor if not acc then return nil end local cnt = 0 return function() cnt = cnt + 1 local v = self:data_get(cnt) if v then return cnt, v end end end } return M