elua: add Readonly_Object to util.lua (its instances are read only userdata, requires special care, but is not intended for the user), use it in List

This commit is contained in:
Daniel Kolesa 2014-04-11 17:02:01 +01:00 committed by Daniel Kolesa
parent 3ff1633180
commit 6c8fc0a87e
3 changed files with 36 additions and 9 deletions

View File

@ -4,6 +4,8 @@ local ffi = require("ffi")
local M = {}
local getmetatable, setmetatable = getmetatable, setmetatable
M.Object = {
__call = function(self, ...)
local r = {
@ -41,6 +43,20 @@ M.Object = {
end
}
local newproxy = newproxy
M.Readonly_Object = Object:clone {
__call = function(self, ...)
local r = newproxy(true)
local rmt = getmetatable(r)
rmt.__index = self
rmt.__tostring = self.__tostring
rmt.__metatable = false
if self.__ctor then self.__ctor(r, rmt, ...) end
return r
end
}
local loaded_libs = {}
local loaded_libc = {}

View File

@ -168,65 +168,76 @@ local List = ffi.metatype("Eina_List", {
}
})
local List_Base = util.Object:clone {
__ctor = function(self, list, freefunc)
local dgetmt = debug.getmetatable
local List_Base = util.Readonly_Object:clone {
__ctor = function(self, selfmt, list, freefunc)
if list and freefunc then
list = ffi.gc(list, freefunc)
self.__free = freefunc
selfmt.__free = freefunc
end
if list == nil then return end
self.__list = list
selfmt.__list = list
end,
free = function(self)
self = dgetmt(self)
local ffunc, l = self.__free, self.__list
if not ffunc or l == nil then return end
ffunc(ffi.gc(self.__list, nil))
end,
count = function(self)
self = dgetmt(self)
local l = self.__list
if l == nil then return 0 end
return #l
end,
nth = function(self, n)
self = dgetmt(self)
local l = self.__list
if l == nil then return nil end
return l:nth()
end,
nth_list = function(self, n)
self = dgetmt(self)
local l = self.__list
if l == nil then return nil end
return self.__index(l:nth_list())
end,
last = function(self, n)
self = dgetmt(self)
local l = self.__list
if l == nil then return nil end
return self.__index(l:last())
end,
next = function(self, n)
self = dgetmt(self)
local l = self.__list
if l == nil then return nil end
return self.__index(l:next())
end,
prev = function(self, n)
self = dgetmt(self)
local l = self.__list
if l == nil then return nil end
return self.__index(l:prev())
end,
data_get = function(self, ptr)
self = dgetmt(self)
local l = self.__list
if l == nil then return nil end
return l:data_get(ptr)
end,
to_array = function(self)
self = dgetmt(self)
local l = self.__list
if l == nil then return {}, 0 end
local n = 0
@ -246,7 +257,7 @@ M.List_Base = List_Base
M.String_List = List_Base:clone {
data_get = function(self, ptr)
ptr = List_Base:data_get(ptr)
ptr = List_Base.data_get(self, ptr)
return ffi.string(ptr)
end
}

View File

@ -183,7 +183,7 @@ local List_Base = list.List_Base
local Eolian_Functions_List = List_Base:clone {
data_get = function(self, ptr)
ptr = List_Base:data_get(ptr)
ptr = List_Base.data_get(self, ptr)
return ffi.cast("Eolian_Function", ptr)
end
}
@ -224,7 +224,7 @@ end
local Eolian_Parameters_List = List_Base:clone {
data_get = function(self, ptr)
ptr = List_Base:data_get(ptr)
ptr = List_Base.data_get(self, ptr)
return ffi.cast("Eolian_Function_Parameter", ptr)
end
}
@ -367,7 +367,7 @@ ffi.metatype("Eolian_Function_Parameter", {
local Eolian_Implements_List = List_Base:clone {
data_get = function(self, ptr)
ptr = List_Base:data_get(ptr)
ptr = List_Base.data_get(self, ptr)
return ffi.cast("Eolian_Implement", ptr)
end
}
@ -393,7 +393,7 @@ end
local Eolian_Events_List = List_Base:clone {
data_get = function(self, ptr)
ptr = List_Base:data_get(ptr)
ptr = List_Base.data_get(self, ptr)
return ffi.cast("Eolian_Event", ptr)
end
}