Eolian: WIP
This commit is contained in:
parent
a795ec8c10
commit
2ba244d263
|
@ -34,6 +34,7 @@ from efl.c_eo cimport Eo as cEo, eo_init, eo_shutdown, eo_del, eo_do, \
|
|||
cimport efl.eo.enums as enums
|
||||
|
||||
from efl.utils.logger cimport add_logger
|
||||
from efl.utils.conversions cimport _ctouni
|
||||
|
||||
# Set this to public and export it in pxd if you need it in another module
|
||||
cdef int PY_EFL_EO_LOG_DOMAIN = add_logger(__name__).eina_log_domain
|
||||
|
@ -196,30 +197,76 @@ cdef Eina_Bool _eo_event_del_cb(void *data, cEo *obj,
|
|||
return enums.EO_CALLBACK_STOP
|
||||
|
||||
cdef Eina_Bool _py_efl_eo_event_cb(
|
||||
void *data, cEo *obj, const Eo_Event_Description *desc, void *event_info):
|
||||
void *data, cEo *obj,
|
||||
const Eo_Event_Description *desc,
|
||||
void *event_info
|
||||
) with gil:
|
||||
|
||||
cdef:
|
||||
void* tmp
|
||||
void *tmp1
|
||||
void *tmp2
|
||||
bint ret
|
||||
Eo o
|
||||
EventDesc py_ev_desc
|
||||
#EventInfo py_ev_info_obj
|
||||
|
||||
func = <object>data
|
||||
o = object_from_instance(obj)
|
||||
|
||||
# create event description python object
|
||||
py_ev_desc = EventDesc.__new__(EventDesc)
|
||||
py_ev_desc.desc = desc
|
||||
|
||||
tmp = eina_hash_find(o.event_conv_mapping, desc)
|
||||
if tmp == NULL:
|
||||
py_ev_info_obj = None
|
||||
else:
|
||||
py_ev_info_cls = <object>tmp
|
||||
#tmp1 = eina_hash_find(o.event_conv_to_py_mapping, desc)
|
||||
#tmp2 = eina_hash_find(o.event_conv_to_c_mapping, desc)
|
||||
#if tmp1 == NULL:
|
||||
# py_ev_info_obj = None
|
||||
#else:
|
||||
#py_ev_info_cls = <object>tmp
|
||||
# use a generic class and set some conv func??
|
||||
#py_ev_info_obj = py_ev_info_cls.__new__(py_ev_info_cls)
|
||||
#py_ev_info_obj = EventInfo.__new__(EventInfo)
|
||||
#py_ev_info_obj.event_info = event_info
|
||||
#py_ev_info_obj.conv_to_python = tmp1
|
||||
#py_ev_info_obj.conv_to_c = tmp2
|
||||
|
||||
#ret = func(py_ev_desc, py_ev_info_obj) # o as first param?
|
||||
#return ret
|
||||
|
||||
|
||||
cdef class EventDesc(object):
|
||||
|
||||
cdef Eo_Event_Description *desc
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
property name:
|
||||
def __get__(self):
|
||||
return _ctouni(self.desc.name)
|
||||
|
||||
property doc:
|
||||
def __get__(self):
|
||||
return _ctouni(self.desc.doc)
|
||||
|
||||
property unfreezable:
|
||||
def __get__(self):
|
||||
return bool(self.desc.unfreezable)
|
||||
|
||||
|
||||
#cdef class EventStruct(object):
|
||||
|
||||
# cdef:
|
||||
# void *event_info
|
||||
|
||||
|
||||
# property value:
|
||||
# def __get__(self):
|
||||
# return self.conv_to_python(self.event_info)
|
||||
|
||||
# def __set__(self, val):
|
||||
# self.event_info = self.conv_to_c(val)
|
||||
|
||||
|
||||
cdef class Eo(object):
|
||||
"""
|
||||
|
||||
|
|
|
@ -201,51 +201,71 @@ cdef object void_ptr_to_python_obj(void *data, type cls):
|
|||
|
||||
|
||||
cdef Class eolian_class_to_python_obj(const Eolian_Class *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Class ret = Class.__new__(Class)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef Function eolian_func_to_python_obj(const Eolian_Function *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Function ret = Function.__new__(Function)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef FunctionParameter eolian_func_param_to_python_obj(const Eolian_Function_Parameter *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef FunctionParameter ret = FunctionParameter.__new__(FunctionParameter)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef Type eolian_type_to_python_obj(const Eolian_Type *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Type ret = Type.__new__(Type)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef TypeStructField eolian_type_struct_field_to_python_obj(const Eolian_Struct_Type_Field *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef TypeStructField ret = TypeStructField.__new__(TypeStructField)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef TypeEnumField eolian_type_enum_field_to_python_obj(const Eolian_Enum_Type_Field *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef TypeEnumField ret = TypeEnumField.__new__(TypeEnumField)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef Implement eolian_implement_to_python_obj(const Eolian_Implement *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Implement ret = Implement.__new__(Implement)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef Constructor eolian_constructor_to_python_obj(const Eolian_Constructor *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Constructor ret = Constructor.__new__(Constructor)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef Event eolian_event_to_python_obj(const Eolian_Event *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Event ret = Event.__new__(Event)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
||||
cdef Expression eolian_expression_to_python_obj(const Eolian_Expression *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Expression ret = Expression.__new__(Expression)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
@ -256,6 +276,8 @@ cdef Value eolian_value_to_python_obj(Eolian_Value o):
|
|||
return ret
|
||||
|
||||
cdef Variable eolian_variable_to_python_obj(const Eolian_Variable *o):
|
||||
if o == NULL:
|
||||
return None
|
||||
cdef Variable ret = Variable.__new__(Variable)
|
||||
ret._set_obj(o)
|
||||
return ret
|
||||
|
@ -642,6 +664,8 @@ cdef class Class(object):
|
|||
cdef const Eolian_Class *klass
|
||||
|
||||
cdef _set_obj(self, const Eolian_Class *obj):
|
||||
if obj == NULL:
|
||||
raise ValueError("obj is NULL!")
|
||||
self.klass = obj
|
||||
|
||||
def __init__(self):
|
||||
|
@ -895,6 +919,8 @@ cdef class Function(object):
|
|||
cdef const Eolian_Function *function_id
|
||||
|
||||
cdef _set_obj(self, const Eolian_Function *obj):
|
||||
if obj == NULL:
|
||||
raise ValueError("obj is NULL!")
|
||||
self.function_id = obj
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1152,6 +1178,8 @@ cdef class FunctionParameter(object):
|
|||
cdef const Eolian_Function_Parameter *param
|
||||
|
||||
cdef _set_obj(self, const Eolian_Function_Parameter *obj):
|
||||
if obj == NULL:
|
||||
raise ValueError("obj is NULL!")
|
||||
self.param = obj
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1240,6 +1268,8 @@ cdef class Implement(object):
|
|||
cdef const Eolian_Implement *impl
|
||||
|
||||
cdef _set_obj(self, const Eolian_Implement *obj):
|
||||
if obj == NULL:
|
||||
raise ValueError("obj is NULL!")
|
||||
self.impl = obj
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1334,6 +1364,8 @@ cdef class Constructor(object):
|
|||
cdef const Eolian_Constructor *ctor
|
||||
|
||||
cdef _set_obj(self, const Eolian_Constructor *obj):
|
||||
if obj == NULL:
|
||||
raise ValueError("obj is NULL")
|
||||
self.ctor = obj
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1378,6 +1410,8 @@ cdef class Event(object):
|
|||
cdef const Eolian_Event *event
|
||||
|
||||
cdef _set_obj(self, const Eolian_Event *obj):
|
||||
if obj == NULL:
|
||||
raise ValueError("obj is NULL!")
|
||||
self.event = obj
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1449,6 +1483,8 @@ cdef class Type(object):
|
|||
cdef const Eolian_Type *tp
|
||||
|
||||
cdef _set_obj(self, const Eolian_Type *obj):
|
||||
if obj == NULL:
|
||||
raise ValueError("obj is NULL!")
|
||||
self.tp = obj
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1468,9 +1504,14 @@ cdef class Type(object):
|
|||
:return: the alias type or None
|
||||
|
||||
"""
|
||||
cdef Type ret = cls.__new__(cls)
|
||||
cdef:
|
||||
Type ret = cls.__new__(cls)
|
||||
Eolian_Type *obj
|
||||
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
||||
ret._set_obj(eolian_type_alias_get_by_name(name))
|
||||
obj = eolian_type_alias_get_by_name(name)
|
||||
if obj == NULL:
|
||||
return None
|
||||
ret._set_obj(obj)
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
|
@ -1481,9 +1522,14 @@ cdef class Type(object):
|
|||
:return: the struct or None
|
||||
|
||||
"""
|
||||
cdef Type ret = cls.__new__(cls)
|
||||
cdef:
|
||||
Type ret = cls.__new__(cls)
|
||||
Eolian_Type *obj
|
||||
if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
|
||||
ret._set_obj(eolian_type_struct_get_by_name(name))
|
||||
obj = eolian_type_struct_get_by_name(name)
|
||||
if obj == NULL:
|
||||
return None
|
||||
ret._set_obj(obj)
|
||||
return ret
|
||||
|
||||
property type:
|
||||
|
|
|
@ -197,5 +197,32 @@ def conv_type_ret(tp):
|
|||
return py_ret_type, c_type
|
||||
|
||||
def event_conversion_get(tp):
|
||||
if tp.type != eolian.TypeType.UNKNOWN:
|
||||
return "Eo_Event_%s" % tp.name
|
||||
if not tp:
|
||||
return
|
||||
if tp.type == eolian.TypeType.UNKNOWN:
|
||||
return
|
||||
if tp.type == eolian.TypeType.POINTER:
|
||||
tp = tp.base_type
|
||||
if tp.type == eolian.TypeType.STRUCT:
|
||||
#return "EventInfo%s" % tp.name
|
||||
return "return <dict><%s>" % tp.c_type
|
||||
elif tp.type == eolian.TypeType.REGULAR:
|
||||
def get_alias(tp1):
|
||||
#print(tp1.name, tp1.type)
|
||||
alias = eolian.Type.alias_get_by_name(tp1.full_name)
|
||||
if not alias:
|
||||
log.error("Unhandled event %s type %s" % (tp.c_type, tp.type))
|
||||
return
|
||||
tp2 = alias.base_type
|
||||
if tp2.type == eolian.TypeType.UNKNOWN:
|
||||
log.error("UGH")
|
||||
elif tp2.type == eolian.TypeType.STRUCT:
|
||||
#print(tp2.name, tp2.c_type)
|
||||
ret = "<dict>tmp"
|
||||
return ret
|
||||
else:
|
||||
return get_alias(tp2)
|
||||
return get_alias(tp)
|
||||
else:
|
||||
log.error("Unhandled event type %s" % (tp.type))
|
||||
return
|
||||
|
|
|
@ -40,6 +40,10 @@ from converters import convert_in_param, convert_out_param, conv_type_ret, \
|
|||
conv_cls_name, EolianTypeError, event_conversion_get
|
||||
|
||||
|
||||
PY_EFL_TOP_LEVEL_PACKAGE = "efl"
|
||||
generated_pxis = {}
|
||||
|
||||
|
||||
class EolianSkip(Exception):
|
||||
pass
|
||||
|
||||
|
@ -209,7 +213,7 @@ class Function(object):
|
|||
for p in func.parameters:
|
||||
self.c_params.append((p.type.c_type, p.name))
|
||||
|
||||
self.c_ret_type = ret_type.c_type if ret_type.type != eolian.TypeType.UNKNOWN else "void"
|
||||
self.c_ret_type = ret_type.c_type if ret_type else "void"
|
||||
|
||||
def cdef_generate(self, gen):
|
||||
func = self.func
|
||||
|
@ -323,7 +327,7 @@ class Function(object):
|
|||
|
||||
gen.out_cdefs_write(out_cdefs)
|
||||
|
||||
if ret_type.type != eolian.TypeType.UNKNOWN:
|
||||
if ret_type:
|
||||
ret_type2 = ret_type.c_type
|
||||
else:
|
||||
ret_type2 = None
|
||||
|
@ -336,12 +340,12 @@ class Function(object):
|
|||
py_ret_type, c_ret_type = conv_type_ret(t)
|
||||
rparams.append((c_ret_type, n))
|
||||
gen.write("return %s" % (", ".join([r[1] for r in rparams])))
|
||||
elif ret_type.type != eolian.TypeType.UNKNOWN:
|
||||
elif ret_type:
|
||||
ret = self.RET_PARAM
|
||||
try:
|
||||
ret_type = convert_out_param(ret_type, ret)
|
||||
except EolianTypeError:
|
||||
gen.write("# FIXME: Unknown return type")
|
||||
gen.write("# FIXME: Unknown return type %s" % ret_type.c_type)
|
||||
gen.dedent()
|
||||
raise
|
||||
gen.write("return %s" % (ret))
|
||||
|
@ -486,6 +490,7 @@ class Class(object):
|
|||
class_counter[cls.name] += 1
|
||||
|
||||
self.c_name = cls.name
|
||||
self.full_c_name = cls.full_name
|
||||
self.lib_name, self.name = conv_cls_name(cls)
|
||||
|
||||
header_path = cls.filename
|
||||
|
@ -592,17 +597,27 @@ class Class(object):
|
|||
gen.write("cdef class _%s(%s):" % (self.name, inherits))
|
||||
gen.indent()
|
||||
|
||||
gen.write("def __cinit__(self):")
|
||||
gen.indent()
|
||||
for o in self.events:
|
||||
try:
|
||||
o.generate(gen)
|
||||
except EolianTypeError:
|
||||
log.info("Skipping %r because of unknown type", o)
|
||||
except Exception:
|
||||
log.exception("Error while generating %r", o)
|
||||
gen.dedent()
|
||||
gen.write()
|
||||
if self.events:
|
||||
gen.write("def __cinit__(self):")
|
||||
gen.indent()
|
||||
for o in self.events[:]:
|
||||
try:
|
||||
o.generate_name_mapping(gen)
|
||||
o.generate_conversion_mapping(gen)
|
||||
except EolianTypeError:
|
||||
log.info("Skipping %r because of unknown type", o)
|
||||
except Exception:
|
||||
log.exception("Error while generating %r", o)
|
||||
gen.dedent()
|
||||
gen.write()
|
||||
|
||||
for o in self.events[:]:
|
||||
try:
|
||||
o.generate_conversion_function(gen)
|
||||
except EolianTypeError:
|
||||
log.info("Skipping %r because of unknown type", o)
|
||||
except Exception:
|
||||
log.exception("Error while generating %r", o)
|
||||
|
||||
if not self.ctor and not self.props and not self.methods:
|
||||
gen.write("pass")
|
||||
|
@ -634,7 +649,7 @@ class Class(object):
|
|||
gen.dedent()
|
||||
gen.write()
|
||||
|
||||
def py_generate(self, gen):
|
||||
#def py_generate(self, gen):
|
||||
inherits = ["_" + self.name]
|
||||
imports = [(self.lib_name, "_" + self.name)]
|
||||
for i in self.inherits:
|
||||
|
@ -654,7 +669,7 @@ class Class(object):
|
|||
imports.append((lib_name, "_" + name))
|
||||
|
||||
for l, n in imports:
|
||||
l = l.lower()
|
||||
l = PY_EFL_TOP_LEVEL_PACKAGE + "." + l.lower()
|
||||
gen.write("from %s import %s" % (l, n))
|
||||
|
||||
gen.write()
|
||||
|
@ -674,7 +689,7 @@ class Class(object):
|
|||
gen.dedent()
|
||||
gen.dedent()
|
||||
gen.write()
|
||||
gen.write('_object_mapping_register("%s", %s)' % (self.c_name, self.name))
|
||||
gen.write('_object_mapping_register("%s", %s)' % (self.full_c_name.replace(".", "_"), self.name))
|
||||
gen.write()
|
||||
|
||||
|
||||
|
@ -701,8 +716,10 @@ class File(object):
|
|||
if base.type == eolian.TypeType.REGULAR:
|
||||
gen.write("ctypedef %s %s" % (i.name, base.name))
|
||||
elif base.type == eolian.TypeType.FUNCTION:
|
||||
ret = base.return_type.c_type
|
||||
if ret is None:
|
||||
ret_type = base.return_type
|
||||
if ret_type:
|
||||
ret = ret_type.c_type
|
||||
else:
|
||||
ret = "void"
|
||||
gen.write("ctypedef %s (*%s)(%s)" % (
|
||||
ret,
|
||||
|
@ -752,12 +769,14 @@ class File(object):
|
|||
|
||||
self.pyxgen.printout(filepath=pxi_path)
|
||||
|
||||
def py_generate(self):
|
||||
py_path = os.path.join(args.output, "__init__" + ".py")
|
||||
generated_pxis.setdefault(namespace, []).append(pxi_path)
|
||||
|
||||
self.gencls.py_generate(self.pygen)
|
||||
# def py_generate(self):
|
||||
# py_path = os.path.join(args.output, "__init__" + ".py")
|
||||
|
||||
self.pygen.printout(filepath=py_path, append=True)
|
||||
# self.gencls.py_generate(self.pygen)
|
||||
|
||||
# self.pygen.printout(filepath=py_path, append=True)
|
||||
|
||||
|
||||
class Event(object):
|
||||
|
@ -767,19 +786,37 @@ class Event(object):
|
|||
def cdef_generate(self, gen):
|
||||
gen.write("enum: %s" % (self.event.c_name))
|
||||
|
||||
def generate(self, gen):
|
||||
def generate_name_mapping(self, gen):
|
||||
gen.write(
|
||||
'eina_hash_set(self.event_desc_mapping, "%s", %s)' % (
|
||||
self.event.name, self.event.c_name
|
||||
)
|
||||
)
|
||||
|
||||
def generate_conversion_mapping(self, gen):
|
||||
conv = event_conversion_get(self.event.type)
|
||||
if conv:
|
||||
gen.write(
|
||||
'eina_hash_set(self.event_conv_mapping, %s, %s)' % (
|
||||
self.event.c_name, conv
|
||||
'eina_hash_set(self.event_conv_mapping, %s, self._event_conv_%s_to_python)' % (
|
||||
self.event.c_name, self.event.name.replace(",", "_")
|
||||
)
|
||||
)
|
||||
else:
|
||||
pass #print("{0} - {1}".format(self.event.name, self.event.type.c_type))
|
||||
|
||||
def generate_conversion_function(self, gen):
|
||||
conv = event_conversion_get(self.event.type)
|
||||
if conv:
|
||||
gen.write(
|
||||
'cdef object _event_conv_%s_to_python(self, void *evi):' % (
|
||||
self.event.name.replace(",", "_")
|
||||
)
|
||||
)
|
||||
gen.indent()
|
||||
gen.write('cdef {0} tmp = <{0}>evi'.format(self.event.type.c_type))
|
||||
gen.write('return ' + conv)
|
||||
gen.dedent()
|
||||
gen.write()
|
||||
|
||||
|
||||
class_counter = Counter()
|
||||
|
@ -821,11 +858,21 @@ for path in args.paths:
|
|||
log.exception("Exception while generating pyx for %s" % (filename))
|
||||
continue
|
||||
|
||||
try:
|
||||
eolf.py_generate()
|
||||
except Exception:
|
||||
log.exception("Exception while generating py for %s" % (filename))
|
||||
continue
|
||||
# try:
|
||||
# eolf.py_generate()
|
||||
# except Exception:
|
||||
# log.exception("Exception while generating py for %s" % (filename))
|
||||
# continue
|
||||
|
||||
|
||||
for ns, pxis in generated_pxis.items():
|
||||
filename = os.path.join(args.output, "generated_" + ns + ".pxi")
|
||||
if os.path.exists(filename):
|
||||
log.error("File %s exists, removing" % (filename))
|
||||
with open(filename, "a") as f:
|
||||
for pxi in pxis:
|
||||
line = 'include "%s"\n' % (pxi)
|
||||
f.write(line)
|
||||
|
||||
|
||||
def report():
|
||||
|
|
Loading…
Reference in New Issue