1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
-- 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 == nil then return nil end
return v
end,
container_get = function(self)
local v = eina.eina_accessor_container_get(self)
if v == nil 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 == nil 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
|