elua: property support in object system, lualian progress, initial (incomplete) eo bindings

This commit is contained in:
Daniel Kolesa 2014-04-16 11:42:18 +01:00 committed by Daniel Kolesa
parent 2ba2b1f6bf
commit b930c9c432
3 changed files with 345 additions and 9 deletions

View File

@ -6,13 +6,51 @@ local M = {}
local getmetatable, setmetatable = getmetatable, setmetatable
local gen_field = function(self, fname)
local t = rawget(self, fname)
if not t then
t = {}
rawset(self, fname, t)
return false, t
end
return true, t
end
local init_getters = function(self)
local has_gtrs, gtrs = gen_field(self, "__getters")
if not has_gtrs then
local oidx = self.__index
if type(oidx) == "table" then
local ooidx = oidx
oidx = function(self, n) return ooidx[n] end
end
self.__index = function(self, n)
local f = gtrs[n]
if f then return f(self) end
local v = rawget(self, n)
if v == nil then return oidx(self, n) end
return v
end
end
return gtrs
end
local init_setters = function(self)
local has_strs, strs = gen_field(self, "__setters")
if not has_strs then
local onindex = self.__newindex or rawset
self.__newindex = function(self, n, v)
local f = strs[n]
if f then return f(self, v) end
onindex(self, n, v)
end
end
return strs
end
M.Object = {
__call = function(self, ...)
local r = {
__index = self, __proto = self, __call = self.__call,
__tostring = self.__tostring
}
setmetatable(r, r)
local r = self:clone()
if self.__ctor then self.__ctor(r, ...) end
return r
end,
@ -38,6 +76,27 @@ M.Object = {
return is
end,
define_property = function(self, propname, get, set)
if get then
init_getters(self)[propname] = get
end
if set then
init_setters(self)[propname] = set
end
end,
define_property_key = function(self, propname, get, set)
local proxy = setmetatable({}, {
__index = function(proxy, key)
if get then return get(self, key) end
end,
__newindex = function(proxy, key, val)
if set then return set(self, key, val) end
end
})
init_getters(self)[propname] = function(self, n) return proxy end
end,
__tostring = function(self)
return ("Object: %s"):format(self.name or "unnamed")
end

View File

@ -32,9 +32,19 @@ local Node = util.Object:clone {
}
local Method = Node:clone {
__ctor = function(self, meth)
self.method = meth
end
}
local Property = Node:clone {
__ctor = function(self, prop)
self.property = prop
end,
generate = function(self, s)
end
}
local Constructor = Node:clone {
@ -72,7 +82,7 @@ local Class = Node:clone {
generate = function(self, s)
dom:log(log.level.INFO, " Generating for class: " .. self.cname)
s:write(([[
local Parent = eo_get("%s")
local Parent = eo.class_get("%s")
M.%s = Parent:clone {
]]):format(self.parent, self.cname))
@ -81,7 +91,7 @@ M.%s = Parent:clone {
s:write("\n}\n")
for i, v in ipairs(self.mixins) do
s:write("\nM.%s:mixin(eo_get(\"%s\"))\n", self.cname, v)
s:write("\nM.%s:mixin(eo.class_get(\"%s\"))\n", self.cname, v)
end
end
}
@ -100,6 +110,8 @@ local File = Node:clone {
-- EFL LuaJIT bindings: %s (class %s)
-- For use with Elua; automatically generated, do not modify
local eo = require("eo")
local M = {}
]]):format(self.fname, self.cname))
@ -114,7 +126,19 @@ return M
}
local gen_contents = function(classn)
return {}
local cnt = {}
local ft = eolian.function_type
-- first try properties
local props = eolian.class_functions_list_get(classn, ft.PROPERTY)
for i, v in ipairs(props) do
cnt[#cnt + 1] = Property(v)
end
-- then methods
local meths = eolian.class_functions_list_get(classn, ft.METHOD)
for i, v in ipairs(meths) do
cnt[#cnt + 1] = Method(v)
end
return cnt
end
local gen_mixin = function(classn)
@ -128,7 +152,7 @@ local gen_class = function(classn)
local ct = eolian.class_type
for i, v in ipairs(inherits) do
local tp = eolian.class_type_get(v)
if tp == ct.REGULAR or tp == ct.ABSTRACT then
if tp == ct.REGULAR or tp == ct.ABSTRACT or v == "Eo_Base" then
if parent then
error(classn .. ": more than 1 parent!")
end

253
src/bindings/luajit/eo.lua Normal file
View File

@ -0,0 +1,253 @@
-- EFL LuaJIT bindings: Eo
-- For use with Elua
local ffi = require("ffi")
ffi.cdef [[
typedef unsigned char Eina_Bool;
typedef struct _Eo_Opaque Eo;
typedef Eo Eo_Class;
Eina_Bool eo_init(void);
Eina_Bool eo_shutdown(void);
void eo_constructor(void);
void eo_destructor(void);
Eo *_eo_add_internal_start(const char *file, int line,
const Eo_Class *klass_id, Eo *parent);
Eo *_eo_add_internal_end (const char *file, int line, const Eo *obj);
Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass,
Eina_Bool is_super, const char *file, const char *func, int line);
void _eo_do_end (const Eo **ojb);
void eo_parent_set(Eo *parent);
Eo *eo_parent_get(void);
void eo_event_freeze(void);
void eo_event_thaw(void);
int eo_event_freeze_get(void);
void eo_event_global_freeze(void);
void eo_event_global_thaw(void);
int eo_event_global_freeze_get(void);
]]
local cutil = require("cutil")
local util = require("util")
local M = {}
local eo
local init = function()
eo = util.lib_load("eo")
eo.eo_init()
end
local shutdown = function()
eo.eo_shutdown()
util.lib_unload("eo")
end
cutil.init_module(init, shutdown)
local getinfo = debug.getinfo
local getfuncname = function(info)
return info.name or "<" .. tostring(info.func) .. ">"
end
M.Eo_Base = util.Object:clone {
__ctor = function(self, klass, parent, ctor, loff, ...)
local info = getinfo(2 + (loff or 0), "nlSf")
local source = info.source
local func = getfuncname(info)
local line = info.currentline
local tmp_obj = eo._eo_add_internal_start(source, line, klass,
parent.__obj)
if eo._eo_do_start(tmp_obj, nil, false, source, func, line) ~= 0 then
if ctor then
ctor(...)
else
eo.eo_constructor()
end
tmp_obj = eo._eo_add_internal_end(source, line, tmp_obj)
eo._eo_do_end(nil)
end
self.__obj = tmp_obj
self.__parent = parent
end,
__do_start = function(self)
local info = getinfo(3, "nlSf")
return eo._eo_do_start(self.__obj, nil, false, info.source,
getfuncname(info), info.currentline) ~= 0
end,
__do_end = function(self)
eo._eo_do_end(nil) -- the parameter is unused and originally there
-- only for cleanup (dtor)
end,
parent_get = function(self)
return self.__parent
end,
parent_set = function(self, parent)
self:__do_start()
self.__parent = parent
eo.eo_parent_set(parent.__obj)
self:__do_end()
end,
event_global_freeze_get = function(self)
self:__do_start()
local v = eo.eo_event_global_freeze_get()
self:__do_end()
return v
end,
event_freeze_get = function(self)
self:__do_start()
local v = eo.eo_event_freeze_get()
self:__do_end()
return v
end
}
--[[
methods {
event_callback_forwarder_del {
/*@ Remove an event callback forwarder for an event and an object. */
params {
@in const Eo_Event_Description* desc; /*@ The description of the event to listen to */
@in Eo* new_obj; /*@ The object to emit events from */
}
}
event_thaw {
/*@ thaw events of object.
Lets event callbacks be called for the object. */
}
event_freeze {
/*@ freeze events of object.
Prevents event callbacks from being called for the object. */
}
event_global_freeze {
/*@ freeze events of object.
Prevents event callbacks from being called for the object. */
}
event_callback_array_del {
/*@ Del a callback array with a specific data associated to it for an event. */
params {
@in const Eo_Callback_Array_Item* array; /*@ an #Eo_Callback_Array_Item of events to listen to */
@in const void* user_data; /*@ The data to compare */
}
}
wref_del {
/*@ Delete the weak reference passed. */
params {
@inout Eo** wref;
}
}
destructor {
/*@ Call the object's destructor.
Should not be used with #eo_do. Only use it with #eo_do_super. */
}
key_data_set {
/*@ Set generic data to object. */
params {
@in const char* key; /*@ the key associated with the data */
@in const void* data; /*@ the data to set */
@in eo_key_data_free_func free_func; /*@ the func to free data with (NULL means */
}
}
key_data_get {
/*@ Get generic data from object. */
params {
@in const char* key; /*@ the key associated with the data */
}
return void *; /* the data for the key */
}
event_callback_del {
/*@ Del a callback with a specific data associated to it for an event. */
params {
@in const Eo_Event_Description* desc; /*@ The description of the event to listen to */
@in Eo_Event_Cb func; /*@ the callback to delete */
@in const void* user_data; /*@ The data to compare */
}
}
event_global_thaw {
/*@ thaw events of object.
Lets event callbacks be called for the object. */
}
key_data_del {
/*@ Del generic data from object. */
params {
@in const char* key; /*@ the key associated with the data */
}
}
event_callback_array_priority_add {
/*@ Add a callback array for an event with a specific priority.
callbacks of the same priority are called in reverse order of creation. */
params {
@in const Eo_Callback_Array_Item* array; /*@ an #Eo_Callback_Array_Item of events to listen to */
@in Eo_Callback_Priority priority; /*@ The priority of the callback */
@in const void* data; /*@ additional data to pass to the callback */
}
}
wref_add {
/*@ Add a new weak reference to obj.
This function registers the object handle pointed by wref to obj so when obj is deleted it'll be updated to NULL. This functions should be used when you want to keep track of an object in a safe way, but you don't want to prevent it from being freed. */
params {
@inout Eo** wref;
}
}
dbg_info_get {
/*@ Get dbg information from the object. */
params {
@in Eo_Dbg_Info* root_node; /*@ node of the tree */
}
}
event_callback_forwarder_add {
/*@ Add an event callback forwarder for an event and an object. */
params {
@in const Eo_Event_Description* desc; /*@ The description of the event to listen to */
@in Eo* new_obj; /*@ The object to emit events from */
}
}
event_callback_call {
/*@ Call the callbacks for an event of an object. */
params {
@in const Eo_Event_Description* desc; /*@ The description of the event to call */
@in const void* event_info; /*@ Extra event info to pass to the callbacks */
}
return Eina_Bool; /* @c EINA_TRUE if one of the callbacks aborted the call, @c EINA_FALSE otherwise */
}
event_callback_priority_add {
/*@ Add a callback for an event with a specific priority.
callbacks of the same priority are called in reverse order of creation. */
params {
@in const Eo_Event_Description* desc; /*@ The description of the event to listen to */
@in Eo_Callback_Priority priority; /*@ The priority of the callback */
@in Eo_Event_Cb cb; /*@ the callback to call */
@in const void* data; /*@ additional data to pass to the callback */
}
}
children_iterator_new {
/*@ Get an iterator on all childrens */
params {
@inout Eina_Iterator** it;
}
}
}
events {
callback,add; /*@ A callback was added. */
callback,del; /*@ A callback was deleted. */
del; /*@ Obj is being deleted. */
}
}
]]
return M