forked from enlightenment/efl
eolian-cxx: Initial version of complex types / callbacks / events implementation.
This commit is contained in:
parent
88f1293527
commit
78e396ac19
|
@ -16,6 +16,7 @@ bindings/eo_cxx/eo_inherit.hh \
|
||||||
bindings/eo_cxx/eo_ops.hh \
|
bindings/eo_cxx/eo_ops.hh \
|
||||||
bindings/eo_cxx/eo_private.hh \
|
bindings/eo_cxx/eo_private.hh \
|
||||||
bindings/eo_cxx/eo_inherit_bindings.hh \
|
bindings/eo_cxx/eo_inherit_bindings.hh \
|
||||||
bindings/eo_cxx/Eo.hh
|
bindings/eo_cxx/Eo.hh \
|
||||||
|
bindings/eo_cxx/eo_cxx_interop.hh
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -22,6 +22,7 @@ lib/eolian_cxx/grammar/eo_class_generator.hh \
|
||||||
lib/eolian_cxx/grammar/eo_header_generator.hh \
|
lib/eolian_cxx/grammar/eo_header_generator.hh \
|
||||||
lib/eolian_cxx/grammar/inheritance_base_generator.hh \
|
lib/eolian_cxx/grammar/inheritance_base_generator.hh \
|
||||||
lib/eolian_cxx/grammar/parameters_generator.hh \
|
lib/eolian_cxx/grammar/parameters_generator.hh \
|
||||||
|
lib/eolian_cxx/grammar/type_generator.hh \
|
||||||
lib/eolian_cxx/grammar/tab.hh
|
lib/eolian_cxx/grammar/tab.hh
|
||||||
|
|
||||||
### Binary
|
### Binary
|
||||||
|
@ -35,7 +36,8 @@ bin_eolian_cxx_eolian_cxx_SOURCES = \
|
||||||
bin/eolian_cxx/convert.hh \
|
bin/eolian_cxx/convert.hh \
|
||||||
bin/eolian_cxx/eolian_wrappers.hh \
|
bin/eolian_cxx/eolian_wrappers.hh \
|
||||||
bin/eolian_cxx/safe_strings.hh \
|
bin/eolian_cxx/safe_strings.hh \
|
||||||
bin/eolian_cxx/type_lookup.hh \
|
bin/eolian_cxx/type_lookup.hh \
|
||||||
|
bin/eolian_cxx/type_lookup_table.cc \
|
||||||
bin/eolian_cxx/eolian_cxx.cc
|
bin/eolian_cxx/eolian_cxx.cc
|
||||||
|
|
||||||
bin_eolian_cxx_eolian_cxx_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
|
bin_eolian_cxx_eolian_cxx_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||||
|
@ -82,11 +84,4 @@ tests_eolian_cxx_eolian_cxx_suite_DEPENDENCIES = @USE_EOLIAN_INTERNAL_LIBS@
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DIST += \
|
|
||||||
tests/eolian_cxx/data/base.eo \
|
|
||||||
tests/eolian_cxx/data/class_simple.eo \
|
|
||||||
tests/eolian_cxx/data/scope.eo \
|
|
||||||
tests/eolian_cxx/data/ctor_dtor.eo \
|
|
||||||
tests/eolian_cxx/data/complex_type.eo
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -116,7 +116,7 @@ convert_eolian_property_to_functions(Eolian_Class const& klass)
|
||||||
{
|
{
|
||||||
efl::eolian::eolian_type getter_param_type =
|
efl::eolian::eolian_type getter_param_type =
|
||||||
type_to_native(param.type);
|
type_to_native(param.type);
|
||||||
getter_param_type/*.native*/ += "*"; // XXX implement complex types
|
getter_param_type.native += "*";
|
||||||
return efl::eolian::eo_parameter
|
return efl::eolian::eo_parameter
|
||||||
{ { getter_param_type }, param.name };
|
{ { getter_param_type }, param.name };
|
||||||
});
|
});
|
||||||
|
|
|
@ -180,8 +180,7 @@ function_type(Eolian_Function const& func)
|
||||||
inline efl::eolian::eolian_type_instance
|
inline efl::eolian::eolian_type_instance
|
||||||
function_return_type(Eolian_Function const& func, Eolian_Function_Type func_type = method_t::value)
|
function_return_type(Eolian_Function const& func, Eolian_Function_Type func_type = method_t::value)
|
||||||
{
|
{
|
||||||
return type_lookup
|
return type_lookup(::eolian_function_return_type_get(&func, func_type));
|
||||||
(::eolian_function_return_type_get(&func, func_type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline efl::eolian::eolian_type_instance
|
inline efl::eolian::eolian_type_instance
|
||||||
|
@ -286,11 +285,17 @@ parameter_type(Eolian_Function_Parameter const& parameter,
|
||||||
efl::eolian::eolian_type_instance type
|
efl::eolian::eolian_type_instance type
|
||||||
(type_lookup(::eolian_parameter_type_get(¶meter)));
|
(type_lookup(::eolian_parameter_type_get(¶meter)));
|
||||||
assert(!type.empty());
|
assert(!type.empty());
|
||||||
// XXX implement complex types.
|
|
||||||
if (parameter_is_out(parameter))
|
if (parameter_is_out(parameter))
|
||||||
type = { type_to_native(type) + "*" };
|
{
|
||||||
|
type = { efl::eolian::type_to_native(type) };
|
||||||
|
type.front().native += "*";
|
||||||
|
}
|
||||||
if (parameter_is_const(parameter, func_type))
|
if (parameter_is_const(parameter, func_type))
|
||||||
type.insert(0, "const ");
|
{
|
||||||
|
type[0].native.insert(0, "const ");
|
||||||
|
if (!type[0].binding.empty())
|
||||||
|
type[0].binding.insert(0, "const ");
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +316,9 @@ event_create(Eolian_Class const& klass, const Eolian_Event *event_)
|
||||||
{
|
{
|
||||||
efl::eolian::eo_event event;
|
efl::eolian::eo_event event;
|
||||||
const char *name, *comment;
|
const char *name, *comment;
|
||||||
if(::eolian_class_event_information_get(event_, &name, NULL, &comment))
|
const Eolian_Type *type;
|
||||||
|
static_cast<void>(type); // XXX
|
||||||
|
if(::eolian_class_event_information_get(event_, &name, &type, &comment))
|
||||||
{
|
{
|
||||||
std::string name_ = safe_str(name);
|
std::string name_ = safe_str(name);
|
||||||
std::transform(name_.begin(), name_.end(), name_.begin(),
|
std::transform(name_.begin(), name_.end(), name_.begin(),
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include <Eolian.h>
|
#include <Eolian.h>
|
||||||
|
#include <eolian_database.h>
|
||||||
|
|
||||||
#include <Eina.hh>
|
#include <Eina.hh>
|
||||||
|
|
||||||
#include "eo_types.hh"
|
#include "eo_types.hh"
|
||||||
|
@ -19,18 +21,46 @@
|
||||||
|
|
||||||
namespace eolian_cxx {
|
namespace eolian_cxx {
|
||||||
|
|
||||||
inline std::string
|
typedef std::vector<efl::eolian::eolian_type> lookup_table_type;
|
||||||
type_lookup(const Eolian_Type *type)
|
extern const lookup_table_type type_lookup_table;
|
||||||
|
|
||||||
|
inline efl::eolian::eolian_type
|
||||||
|
type_from_eolian(Eolian_Type const& type)
|
||||||
{
|
{
|
||||||
if (type == NULL)
|
efl::eolian::eolian_type x;
|
||||||
return "void";
|
x.native = normalize_spaces(safe_str(type.name));
|
||||||
// XXX add complex types implementation.
|
x.is_own = type.is_own;
|
||||||
const char *tps = eolian_type_c_type_get(type);
|
return x;
|
||||||
std::string ret = safe_str(tps);
|
|
||||||
::eina_stringshare_del(tps);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
inline const efl::eolian::eolian_type&
|
||||||
|
type_find(Iterator first, Iterator last, efl::eolian::eolian_type const& type)
|
||||||
|
{
|
||||||
|
auto res = std::find_if
|
||||||
|
(first, last,
|
||||||
|
[&type] (efl::eolian::eolian_type const& x)
|
||||||
|
{
|
||||||
|
return (x.native == type.native && x.is_own == type.is_own);
|
||||||
|
});
|
||||||
|
return (res != last) ? *res : type;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline efl::eolian::eolian_type_instance
|
||||||
|
type_lookup(const Eolian_Type* type,
|
||||||
|
lookup_table_type const& lut = type_lookup_table)
|
||||||
|
{
|
||||||
|
if (type == NULL) return { efl::eolian::void_type };
|
||||||
|
size_t n = ::eina_list_count(type->subtypes) + 1;
|
||||||
|
assert(n > 0);
|
||||||
|
efl::eolian::eolian_type_instance v(n);
|
||||||
|
for (size_t i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
v[i] = type_find(lut.begin(), lut.end(), type_from_eolian(*type));
|
||||||
|
assert (i == n-1 || type_is_complex(v[i]));
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace eolian_cxx {
|
} // namespace eolian_cxx {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "type_lookup.hh"
|
||||||
|
|
||||||
|
namespace eolian_cxx {
|
||||||
|
|
||||||
|
using efl::eolian::eolian_type;
|
||||||
|
|
||||||
|
// Keep the table sorted!
|
||||||
|
// This can help: cat type_lookup_table | LC_ALL=C sort
|
||||||
|
const lookup_table_type
|
||||||
|
type_lookup_table
|
||||||
|
{
|
||||||
|
{"Ecore_Cb", eolian_type::callback_, {"Ecore.h"}},
|
||||||
|
{"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}},
|
||||||
|
{"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}},
|
||||||
|
{"Eina_Accessor *", eolian_type::complex_, false, "efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
|
||||||
|
{"Eina_Bool", eolian_type::simple_, false, "bool", {}},
|
||||||
|
{"Eina_Inlist *", eolian_type::complex_, false, "efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
|
||||||
|
{"Eina_Inlist *", eolian_type::complex_, true, "efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
|
||||||
|
{"Eina_Iterator *", eolian_type::complex_, false, "efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
|
||||||
|
{"Eina_List *", eolian_type::complex_, false, "efl::eina::range_ptr_list", {"eina-cxx/eina_ptrlist.hh"}},
|
||||||
|
{"Eina_List *", eolian_type::complex_, true, "efl::eina::ptr_list", {"eina-cxx/eina_ptrlist.hh"}},
|
||||||
|
//{"Eina_List *", eolian_type::complex_, false, "efl::eina::ptr_list", {"eina-cxx/eina_ptrlist.hh"}},
|
||||||
|
{"Eo *", eolian_type::simple_, true, "efl::eo::base", {"eo_base.hh"}},
|
||||||
|
{"Evas_Object *", eolian_type::simple_, false, "evas_object", {"canvas/evas_object.eo.hh"}},
|
||||||
|
{"char *", eolian_type::simple_, true, "std::unique_ptr<char*>", {"memory"}},
|
||||||
|
{"const Eina_Inlist *", eolian_type::complex_, false, "efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
|
||||||
|
{"const Eina_List *", eolian_type::complex_, false, "efl::eina::range_ptr_list", {"eina-cxx/eina_ptrlist.hh"}},
|
||||||
|
{"const char *", eolian_type::simple_, false, "std::string", {"string"}}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
#include <eina_optional.hh>
|
#include <eina_optional.hh>
|
||||||
|
|
||||||
#include "eo_ops.hh"
|
#include "eo_ops.hh"
|
||||||
|
#include "eo_event.hh"
|
||||||
|
|
||||||
|
|
||||||
namespace efl { namespace eo {
|
namespace efl { namespace eo {
|
||||||
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
|
||||||
|
#ifndef EFL_EOLIAN_INTEROP_HH
|
||||||
|
#define EFL_EOLIAN_INTEROP_HH
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <Eina.hh>
|
||||||
|
#include <Eo.hh>
|
||||||
|
|
||||||
|
namespace efl { namespace eolian {
|
||||||
|
|
||||||
|
//// From C++ to C
|
||||||
|
|
||||||
|
inline Eo*
|
||||||
|
to_c(efl::eo::base const& x)
|
||||||
|
{
|
||||||
|
return ::eo_ref(x._eo_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char*
|
||||||
|
to_c(std::string const& x)
|
||||||
|
{
|
||||||
|
return x.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char*
|
||||||
|
to_c(efl::eina::stringshare const& x)
|
||||||
|
{
|
||||||
|
return x.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Eina_Bool
|
||||||
|
to_c(bool x)
|
||||||
|
{
|
||||||
|
return x ? EINA_TRUE : EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// From C to C++
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct tag {};
|
||||||
|
|
||||||
|
template <typename T, typename U, typename O>
|
||||||
|
T to_cxx(U object, O o);
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
inline void*
|
||||||
|
to_cxx(void *x, std::tuple<std::false_type>, tag<void*>)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
inline const void*
|
||||||
|
to_cxx(const void *x, std::tuple<std::false_type>, tag<const void*>)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T
|
||||||
|
to_cxx(Eo* x, std::tuple<std::true_type>, tag<T>)
|
||||||
|
{
|
||||||
|
return T(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T
|
||||||
|
to_cxx(Eo* x, std::tuple<std::false_type>, tag<T>)
|
||||||
|
{
|
||||||
|
return T(::eo_ref(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _EVAS_H
|
||||||
|
template <typename T>
|
||||||
|
Evas_Object_Textblock_Node_Format *
|
||||||
|
to_cxx(Evas_Object_Textblock_Node_Format* x, std::tuple<std::false_type>, tag<T>)
|
||||||
|
{
|
||||||
|
return x; // XXX
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
to_cxx(Eina_Bool x, std::tuple<std::false_type>, tag<bool>)
|
||||||
|
{
|
||||||
|
return !!x;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string
|
||||||
|
to_cxx(const char* x, std::tuple<std::false_type>, tag<std::string>)
|
||||||
|
{
|
||||||
|
return std::string(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct traits
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct traits
|
||||||
|
<T, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value>::type>
|
||||||
|
{
|
||||||
|
typedef Eo* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct traits
|
||||||
|
<T, typename std::enable_if<std::is_base_of<std::basic_string<char>, T>::value>::type>
|
||||||
|
{
|
||||||
|
typedef const char* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
inline efl::eina::range_ptr_list<T>
|
||||||
|
to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_ptr_list<T> >)
|
||||||
|
{
|
||||||
|
efl::eina::ptr_list<T> list;
|
||||||
|
const Eina_List *l;
|
||||||
|
void *val;
|
||||||
|
EINA_LIST_FOREACH(x, l, val)
|
||||||
|
{
|
||||||
|
typedef typename traits<T>::type type;
|
||||||
|
list.push_back(new T (to_cxx(static_cast<type>(val), std::tuple<Args...>()
|
||||||
|
, tag<T>())));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
inline efl::eina::range_ptr_list<T>
|
||||||
|
to_cxx(Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_ptr_list<T> >)
|
||||||
|
{
|
||||||
|
efl::eina::ptr_list<T> list;
|
||||||
|
Eina_List *l;
|
||||||
|
void *val;
|
||||||
|
EINA_LIST_FOREACH(x, l, val)
|
||||||
|
{
|
||||||
|
typedef typename traits<T>::type type;
|
||||||
|
list.push_back(new T (to_cxx(static_cast<type>(val), std::tuple<Args...>()
|
||||||
|
, tag<T>())));
|
||||||
|
}
|
||||||
|
eina_list_free(x);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
inline efl::eina::ptr_list<T>
|
||||||
|
to_cxx(Eina_List* x, std::tuple<std::true_type, Args...>, tag< efl::eina::ptr_list<T> >)
|
||||||
|
{
|
||||||
|
efl::eina::ptr_list<T> list;
|
||||||
|
Eina_List *l;
|
||||||
|
void *val;
|
||||||
|
EINA_LIST_FOREACH(x, l, val)
|
||||||
|
{
|
||||||
|
typedef typename traits<T>::type type;
|
||||||
|
list.push_back(new T (to_cxx(static_cast<type>(val), std::tuple<Args...>()
|
||||||
|
, tag<T>())));
|
||||||
|
}
|
||||||
|
eina_list_free(x);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline eina::stringshare
|
||||||
|
to_cxx(Eina_Stringshare const* x, const std::false_type, tag<eina::stringshare>)
|
||||||
|
{
|
||||||
|
return ::eina_stringshare_ref(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
inline efl::eina::accessor<T>
|
||||||
|
to_cxx(Eina_Accessor* x, std::tuple<std::false_type, Args...>, tag< efl::eina::accessor<T> >)
|
||||||
|
{
|
||||||
|
return efl::eina::accessor<T>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
inline efl::eina::iterator<T>
|
||||||
|
to_cxx(Eina_Iterator* x, std::tuple<std::false_type, Args...>, tag< efl::eina::iterator<T> >)
|
||||||
|
{
|
||||||
|
return efl::eina::iterator<T>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, typename O>
|
||||||
|
T to_cxx(U object, O o)
|
||||||
|
{
|
||||||
|
return to_cxx(object, o, tag<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
//// Callbacks
|
||||||
|
|
||||||
|
template <typename F, typename R, typename V, typename... Args>
|
||||||
|
R funcall(V* data, Args... args)
|
||||||
|
{
|
||||||
|
F const* f = static_cast<F const*>(data);
|
||||||
|
return (*f)(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct callback_result_type;
|
||||||
|
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
struct callback_result_type<R(*)(Args...)>
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
struct callback_args_type;
|
||||||
|
|
||||||
|
template <typename R, typename... Args>
|
||||||
|
struct callback_args_type<R(*)(Args...)>
|
||||||
|
{
|
||||||
|
typedef std::tuple<Args...> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename C, typename F, typename R, typename V, typename... Args>
|
||||||
|
C get_callback_impl(tag<std::tuple<V*, Args...> >)
|
||||||
|
{
|
||||||
|
static_assert(std::is_same<void, typename std::remove_cv<V>::type>::value,
|
||||||
|
"First argument of callback should be void* or const void*");
|
||||||
|
return static_cast<C>(&eolian::funcall<F, R, V, Args...>);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename C, typename F>
|
||||||
|
C get_callback()
|
||||||
|
{
|
||||||
|
return get_callback_impl<C, F, typename callback_result_type<C>::type>
|
||||||
|
(tag<typename callback_args_type<C>::type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
} } // namespace efl { namespace eolian {
|
||||||
|
|
||||||
|
#endif // EFL_EOLIAN_INTEROP_HH
|
|
@ -0,0 +1,130 @@
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @file eo_event.hh
|
||||||
|
///
|
||||||
|
|
||||||
|
#ifndef EFL_CXX_EO_EVENT_HH
|
||||||
|
#define EFL_CXX_EO_EVENT_HH
|
||||||
|
|
||||||
|
#include <Eo.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace efl { namespace eo {
|
||||||
|
|
||||||
|
typedef ::Eo_Callback_Priority callback_priority;
|
||||||
|
namespace callback_priorities
|
||||||
|
{
|
||||||
|
static const callback_priority before = -100;
|
||||||
|
static const callback_priority default_ = 0;
|
||||||
|
static const callback_priority after = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct signal_connection
|
||||||
|
{
|
||||||
|
signal_connection(std::function<void()> deleter)
|
||||||
|
: _deleter(deleter) {}
|
||||||
|
void disconnect()
|
||||||
|
{
|
||||||
|
if(_deleter)
|
||||||
|
{
|
||||||
|
_deleter();
|
||||||
|
_deleter = std::function<void()>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::function<void()> _deleter;
|
||||||
|
friend struct scoped_signal_connection;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scoped_signal_connection
|
||||||
|
{
|
||||||
|
scoped_signal_connection(signal_connection const& other)
|
||||||
|
: _deleter(other._deleter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~scoped_signal_connection()
|
||||||
|
{
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
void disconnect()
|
||||||
|
{
|
||||||
|
if(_deleter)
|
||||||
|
{
|
||||||
|
_deleter();
|
||||||
|
_deleter = std::function<void()>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scoped_signal_connection(scoped_signal_connection&& other)
|
||||||
|
: _deleter(other._deleter)
|
||||||
|
{
|
||||||
|
other._deleter = std::function<void()>();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::function<void()> _deleter;
|
||||||
|
|
||||||
|
scoped_signal_connection& operator=(scoped_signal_connection const&) = delete;
|
||||||
|
scoped_signal_connection(scoped_signal_connection const&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
struct _event_deleter
|
||||||
|
{
|
||||||
|
_event_deleter(F* data, Eo* eo, ::Eo_Event_Cb cb, Eo_Event_Description const* description)
|
||||||
|
: _data(data), _eo( ::eo_ref(eo)), _cb(cb), _description(description)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~_event_deleter()
|
||||||
|
{
|
||||||
|
::eo_unref(_eo);
|
||||||
|
}
|
||||||
|
_event_deleter(_event_deleter const& other)
|
||||||
|
: _data(other._data), _eo( ::eo_ref(other._eo)), _cb(other._cb), _description(other._description)
|
||||||
|
{}
|
||||||
|
_event_deleter& operator=(_event_deleter const& other)
|
||||||
|
{
|
||||||
|
::eo_unref( _eo);
|
||||||
|
_data = other._data;
|
||||||
|
_eo = ::eo_ref(other._eo);
|
||||||
|
_cb = other._cb;
|
||||||
|
_description = other._description;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
eo_do(_eo, ::eo_event_callback_del(_description, _cb, _data));
|
||||||
|
delete _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
F* _data;
|
||||||
|
Eo* _eo;
|
||||||
|
::Eo_Event_Cb _cb;
|
||||||
|
Eo_Event_Description const* _description;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
signal_connection make_signal_connection(std::unique_ptr<F>& data, Eo* eo, ::Eo_Event_Cb cb, Eo_Event_Description const* description)
|
||||||
|
{
|
||||||
|
signal_connection c(_event_deleter<F>(data.get(), eo, cb, description));
|
||||||
|
data.release();
|
||||||
|
return std::move(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace _detail {
|
||||||
|
|
||||||
|
template <typename T, typename F>
|
||||||
|
Eina_Bool
|
||||||
|
event_callback(void *data, Eo *obj, Eo_Event_Description const* desc, void *info)
|
||||||
|
{
|
||||||
|
T wrapper(::eo_ref(obj));
|
||||||
|
F *f = static_cast<F*>(data);
|
||||||
|
return (*f)(wrapper, *desc, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,6 +21,142 @@ typedef std::vector<eo_function> functions_container_type;
|
||||||
typedef std::vector<eo_parameter> parameters_container_type;
|
typedef std::vector<eo_parameter> parameters_container_type;
|
||||||
typedef std::vector<eo_event> events_container_type;
|
typedef std::vector<eo_event> events_container_type;
|
||||||
|
|
||||||
|
struct eolian_type
|
||||||
|
{
|
||||||
|
enum category_type
|
||||||
|
{
|
||||||
|
unknown_, simple_, complex_, callback_
|
||||||
|
};
|
||||||
|
|
||||||
|
eolian_type()
|
||||||
|
: native("")
|
||||||
|
, category(unknown_)
|
||||||
|
, is_own(false)
|
||||||
|
, binding()
|
||||||
|
, includes()
|
||||||
|
{}
|
||||||
|
|
||||||
|
eolian_type(std::string native_,
|
||||||
|
category_type category_,
|
||||||
|
bool is_own_,
|
||||||
|
std::string binding_,
|
||||||
|
includes_container_type includes_)
|
||||||
|
: native(native_)
|
||||||
|
, category(category_)
|
||||||
|
, is_own(is_own_)
|
||||||
|
, binding(binding_)
|
||||||
|
, includes(includes_)
|
||||||
|
{
|
||||||
|
assert(!native.empty());
|
||||||
|
assert(category != unknown_);
|
||||||
|
}
|
||||||
|
|
||||||
|
eolian_type(std::string native_,
|
||||||
|
category_type category_,
|
||||||
|
includes_container_type const& includes_)
|
||||||
|
: eolian_type(native_, category_, false, "", includes_)
|
||||||
|
{
|
||||||
|
assert(category == callback_);
|
||||||
|
}
|
||||||
|
|
||||||
|
~eolian_type() {}
|
||||||
|
|
||||||
|
eolian_type(eolian_type const& other)
|
||||||
|
: native(other.native)
|
||||||
|
, category(other.category)
|
||||||
|
, is_own(other.is_own)
|
||||||
|
, binding(other.binding)
|
||||||
|
, includes(other.includes)
|
||||||
|
{}
|
||||||
|
|
||||||
|
eolian_type&
|
||||||
|
operator=(eolian_type const& rhs)
|
||||||
|
{
|
||||||
|
native = rhs.native;
|
||||||
|
category = rhs.category;
|
||||||
|
is_own = rhs.is_own;
|
||||||
|
binding = rhs.binding;
|
||||||
|
includes = rhs.includes;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string native;
|
||||||
|
category_type category;
|
||||||
|
bool is_own;
|
||||||
|
std::string binding;
|
||||||
|
includes_container_type includes;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<eolian_type> eolian_type_instance;
|
||||||
|
|
||||||
|
const efl::eolian::eolian_type
|
||||||
|
void_type { "void", efl::eolian::eolian_type::simple_, false, "", {} };
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
type_is_void(eolian_type_instance const& type)
|
||||||
|
{
|
||||||
|
return type.empty() || type[0].native.compare("void") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
type_is_binding(eolian_type const& type)
|
||||||
|
{
|
||||||
|
return !type.binding.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
type_is_binding(eolian_type_instance const& type)
|
||||||
|
{
|
||||||
|
assert(!type.empty());
|
||||||
|
return type_is_binding(type.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline eolian_type
|
||||||
|
type_to_native(eolian_type const& type)
|
||||||
|
{
|
||||||
|
eolian_type native = type;
|
||||||
|
native.binding.clear();
|
||||||
|
native.category = eolian_type::simple_;
|
||||||
|
return native;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline eolian_type
|
||||||
|
type_to_native(eolian_type_instance const& type_ins)
|
||||||
|
{
|
||||||
|
assert(!type_ins.empty());
|
||||||
|
return type_to_native(type_ins.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string
|
||||||
|
type_to_native_str(eolian_type_instance const& type_ins)
|
||||||
|
{
|
||||||
|
return type_to_native(type_ins).native;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
type_is_complex(eolian_type const& type)
|
||||||
|
{
|
||||||
|
return type.category == eolian_type::complex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool
|
||||||
|
type_is_callback(T const&);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline bool
|
||||||
|
type_is_callback(eolian_type const& type)
|
||||||
|
{
|
||||||
|
return type.category == eolian_type::callback_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline bool
|
||||||
|
type_is_callback(eolian_type_instance const& type_ins)
|
||||||
|
{
|
||||||
|
return type_is_callback(type_ins.front());
|
||||||
|
}
|
||||||
|
|
||||||
struct eo_generator_options
|
struct eo_generator_options
|
||||||
{
|
{
|
||||||
includes_container_type cxx_headers;
|
includes_container_type cxx_headers;
|
||||||
|
@ -48,7 +184,7 @@ struct eo_class
|
||||||
|
|
||||||
struct eo_parameter
|
struct eo_parameter
|
||||||
{
|
{
|
||||||
std::string type;
|
eolian_type_instance type;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,15 +204,24 @@ struct eo_function
|
||||||
eo_function_type type;
|
eo_function_type type;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string impl;
|
std::string impl;
|
||||||
std::string ret;
|
eolian_type_instance ret;
|
||||||
parameters_container_type params;
|
parameters_container_type params;
|
||||||
std::string comment;
|
std::string comment;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct eo_event
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::string eo_name;
|
||||||
|
//parameters_container_type params; // XXX desirable.
|
||||||
|
std::string comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
function_is_void(eo_function const& func)
|
function_is_void(eo_function const& func)
|
||||||
{
|
{
|
||||||
return func.ret.empty() || func.ret.compare("void") == 0;
|
return func.ret.empty() || func.ret[0].native.compare("void") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
@ -85,31 +230,28 @@ function_is_static(eo_function const& func)
|
||||||
return func.type == eo_function::class_;
|
return func.type == eo_function::class_;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct eo_event
|
inline unsigned int
|
||||||
|
parameters_count_callbacks(parameters_container_type const& parameters)
|
||||||
{
|
{
|
||||||
std::string name;
|
unsigned int r = 0u;
|
||||||
std::string eo_name;
|
for (eo_parameter const& param : parameters)
|
||||||
std::string comment;
|
if(type_is_callback(param.type))
|
||||||
};
|
++r;
|
||||||
|
return r;
|
||||||
|
|
||||||
// XXX mocked implementation. waiting for complex types...
|
|
||||||
typedef std::string eolian_type_instance;
|
|
||||||
typedef std::string eolian_type;
|
|
||||||
inline bool
|
|
||||||
type_is_void(eolian_type_instance const& type)
|
|
||||||
{
|
|
||||||
return type.empty() || type.compare("void") == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} }
|
inline parameters_container_type::const_iterator
|
||||||
|
parameters_find_callback(parameters_container_type const& parameters)
|
||||||
namespace eolian_cxx {
|
|
||||||
inline efl::eolian::eolian_type
|
|
||||||
type_to_native(efl::eolian::eolian_type const& type)
|
|
||||||
{
|
{
|
||||||
return type;
|
for (auto it = parameters.cbegin(), last = parameters.cend();
|
||||||
|
it != last; ++it)
|
||||||
|
{
|
||||||
|
if (type_is_callback((*it).type))
|
||||||
|
return it;
|
||||||
}
|
}
|
||||||
|
return parameters.cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} } // namespace efl { namespace eolian {
|
||||||
|
|
||||||
#endif // EFL_EOLIAN_CXX_EO_TYPES_HH
|
#endif // EFL_EOLIAN_CXX_EO_TYPES_HH
|
||||||
|
|
|
@ -16,6 +16,39 @@ _is_valid(std::string const& value)
|
||||||
return !value.empty() and isalpha(value[0]);
|
return !value.empty() and isalpha(value[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
_is_valid(eolian_type_instance const& type)
|
||||||
|
{
|
||||||
|
if (type.empty() || (*type.rbegin()).category == eolian_type::complex_)
|
||||||
|
return false;
|
||||||
|
for (auto rit = ++type.rbegin(), last = type.rend(); rit != last; ++rit)
|
||||||
|
{
|
||||||
|
if ((*rit).binding.empty() || (*rit).category != eolian_type::complex_)
|
||||||
|
return false;
|
||||||
|
else if (rit != type.rbegin() && (*rit).category != eolian_type::complex_)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
_is_valid(parameters_container_type const& parameters)
|
||||||
|
{
|
||||||
|
unsigned int n_callbacks = parameters_count_callbacks(parameters);
|
||||||
|
return n_callbacks == 0 || n_callbacks == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
_is_valid(events_container_type const& events)
|
||||||
|
{
|
||||||
|
for (eo_event event : events)
|
||||||
|
{
|
||||||
|
if (event.name.empty() || event.eo_name.empty())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void
|
inline void
|
||||||
_validate(T val, const eo_class& cls)
|
_validate(T val, const eo_class& cls)
|
||||||
|
@ -44,6 +77,7 @@ eo_class_validate(const eo_class& cls)
|
||||||
it != last; ++it)
|
it != last; ++it)
|
||||||
{
|
{
|
||||||
_validate((*it).name, cls);
|
_validate((*it).name, cls);
|
||||||
|
_validate((*it).params, cls);
|
||||||
// parameters
|
// parameters
|
||||||
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||||
it_p != last_p; ++it_p)
|
it_p != last_p; ++it_p)
|
||||||
|
@ -59,6 +93,7 @@ eo_class_validate(const eo_class& cls)
|
||||||
_validate((*it).name, cls);
|
_validate((*it).name, cls);
|
||||||
_validate((*it).impl, cls);
|
_validate((*it).impl, cls);
|
||||||
_validate((*it).ret, cls);
|
_validate((*it).ret, cls);
|
||||||
|
_validate((*it).params, cls);
|
||||||
// parameters
|
// parameters
|
||||||
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||||
it_p != last_p; ++it_p)
|
it_p != last_p; ++it_p)
|
||||||
|
@ -67,6 +102,8 @@ eo_class_validate(const eo_class& cls)
|
||||||
_validate((*it_p).type, cls);
|
_validate((*it_p).type, cls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// events
|
||||||
|
_validate(cls.events, cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
} } // namespace efl { namespace eolian {
|
} } // namespace efl { namespace eolian {
|
||||||
|
|
|
@ -114,14 +114,16 @@ operator<<(std::ostream& out, constructors const& x)
|
||||||
for (it = first; it != last; ++it)
|
for (it = first; it != last; ++it)
|
||||||
{
|
{
|
||||||
eo_constructor const& ctor = *it;
|
eo_constructor const& ctor = *it;
|
||||||
out << comment(ctor.comment, 1)
|
out << comment(ctor.comment, 1);
|
||||||
<< tab(1)
|
if (parameters_count_callbacks(ctor.params))
|
||||||
|
out << tab(1) << "template <typename F>" << endl;
|
||||||
|
out << tab(1)
|
||||||
<< x._cls.name
|
<< x._cls.name
|
||||||
<< '(' << parameters_declaration(ctor.params)
|
<< '(' << parameters_declaration(ctor.params)
|
||||||
<< (ctor.params.size() > 0 ? ", " : "")
|
<< (ctor.params.size() > 0 ? ", " : "")
|
||||||
<< "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
|
<< "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
|
||||||
<< tab(2) << ": " << class_name(x._cls.name)
|
<< tab(2) << ": " << class_name(x._cls.name)
|
||||||
<< "(_c" << (it - first) << "(" << parameters_list(ctor.params)
|
<< "(_c" << (it - first) << "(" << parameters_cxx_list(ctor.params)
|
||||||
<< (ctor.params.size() > 0 ? ", " : "")
|
<< (ctor.params.size() > 0 ? ", " : "")
|
||||||
<< "_p))" << endl
|
<< "_p))" << endl
|
||||||
<< tab(1) << "{}" << endl << endl;
|
<< tab(1) << "{}" << endl << endl;
|
||||||
|
@ -180,14 +182,26 @@ operator<<(std::ostream& out, eo_class_constructors const& x)
|
||||||
last = x._cls.constructors.end();
|
last = x._cls.constructors.end();
|
||||||
for (it = first; it != last; ++it)
|
for (it = first; it != last; ++it)
|
||||||
{
|
{
|
||||||
|
if (parameters_count_callbacks((*it).params))
|
||||||
|
out << tab(1) << "template <typename F>" << endl;
|
||||||
out << tab(1)
|
out << tab(1)
|
||||||
<< "static Eo* _c" << (it - first) << "("
|
<< "static Eo* _c" << (it - first) << "("
|
||||||
<< parameters_declaration((*it).params)
|
<< parameters_declaration((*it).params)
|
||||||
<< ((*it).params.size() > 0 ? ", " : "")
|
<< ((*it).params.size() > 0 ? ", " : "")
|
||||||
<< "efl::eo::parent_type _p"
|
<< "efl::eo::parent_type _p"
|
||||||
<< ')' << endl
|
<< ')' << endl
|
||||||
<< tab(1) << "{" << endl
|
<< tab(1) << "{" << endl;
|
||||||
<< tab(2) << "return eo_add_custom("
|
|
||||||
|
parameters_container_type::const_iterator callback_iter =
|
||||||
|
parameters_find_callback((*it).params);
|
||||||
|
if (callback_iter != (*it).params.cend())
|
||||||
|
{
|
||||||
|
out << tab(2)
|
||||||
|
<< "F* _tmp_f = new F(std::move("
|
||||||
|
<< (*callback_iter).name << "));"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
out << tab(2) << "return eo_add_custom("
|
||||||
<< x._cls.eo_name << ", _p._eo_raw, " << (*it).name
|
<< x._cls.eo_name << ", _p._eo_raw, " << (*it).name
|
||||||
<< "(" << parameters_list((*it).params) << "));" << endl
|
<< "(" << parameters_list((*it).params) << "));" << endl
|
||||||
<< tab(1) << "}" << endl << endl;
|
<< tab(1) << "}" << endl << endl;
|
||||||
|
|
|
@ -4,88 +4,76 @@
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
#include <algorithm> // std::transform()
|
|
||||||
#include <ctype.h> // ::toupper()
|
|
||||||
|
|
||||||
#include "eo_types.hh"
|
#include "eo_types.hh"
|
||||||
#include "tab.hh"
|
#include "tab.hh"
|
||||||
#include "comment.hh"
|
#include "comment.hh"
|
||||||
#include "parameters_generator.hh"
|
|
||||||
|
|
||||||
namespace efl { namespace eolian { namespace grammar {
|
namespace efl { namespace eolian { namespace grammar {
|
||||||
|
|
||||||
struct event_callback_add
|
struct event_callback_add
|
||||||
{
|
{
|
||||||
eo_event const& _event;
|
eo_event const& _event;
|
||||||
std::string const& _ev_name;
|
eo_class const& _cls;
|
||||||
event_callback_add(eo_event const& event, std::string const& ev_name)
|
event_callback_add(eo_event const& event, eo_class const& cls)
|
||||||
: _event(event),
|
: _event(event), _cls(cls)
|
||||||
_ev_name(ev_name)
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
operator<<(std::ostream& out, event_callback_add const& x)
|
operator<<(std::ostream& out, event_callback_add const& x)
|
||||||
{
|
{
|
||||||
// TODO implement
|
out << tab(1) << "template <typename F>" << endl
|
||||||
return out;
|
<< tab(1) << "::efl::eo::signal_connection" << endl
|
||||||
}
|
<< tab(1) << "event_" << x._event.name << "_callback_add(F && callback_," << endl
|
||||||
|
<< tab(11) << "::efl::eo::callback_priority priority_ =" << endl
|
||||||
struct event_callback_del
|
<< tab(11) << "::efl::eo::callback_priorities::default_)" << endl
|
||||||
{
|
<< tab(1) << "{" << endl
|
||||||
eo_event const& _event;
|
<< tab(2) << "::std::unique_ptr<F> f ( new F(std::move(callback_)) );" << endl
|
||||||
std::string const& _ev_name;
|
<< tab(2) << "eo_do(_eo_ptr()," << endl
|
||||||
event_callback_del(eo_event const& event, std::string const& ev_name)
|
<< tab(4) << "eo_event_callback_priority_add" << endl
|
||||||
: _event(event),
|
<< tab(4) << "(" << x._event.eo_name << ", priority_," << endl
|
||||||
_ev_name(ev_name)
|
<< tab(4) << "&efl::eo::_detail::event_callback<" << x._cls.name << ", F>, f.get()));" << endl
|
||||||
{}
|
<< tab(2) << "return ::efl::eo::make_signal_connection" << endl
|
||||||
};
|
<< tab(3) << "(f, this->_eo_ptr(), &efl::eo::_detail::event_callback<" << x._cls.name << ", F>," << endl
|
||||||
|
<< tab(3) << x._event.eo_name << " );" << endl
|
||||||
inline std::ostream&
|
<< tab(1) << "}" << endl;
|
||||||
operator<<(std::ostream& out, event_callback_del const& x)
|
|
||||||
{
|
|
||||||
// TODO: implement
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct event_callback_call
|
struct event_callback_call
|
||||||
{
|
{
|
||||||
eo_event const& _event;
|
eo_event const& _event;
|
||||||
std::string const& _ev_name;
|
event_callback_call(eo_event const& event)
|
||||||
event_callback_call(eo_event const& event, std::string const& ev_name)
|
: _event(event)
|
||||||
: _event(event),
|
|
||||||
_ev_name(ev_name)
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
operator<<(std::ostream& out, event_callback_call const& x)
|
operator<<(std::ostream& out, event_callback_call const& x)
|
||||||
{
|
{
|
||||||
// TODO implement
|
out << tab(1) << "template <typename T>" << endl
|
||||||
|
<< tab(1) << "void" << endl
|
||||||
|
<< tab(1) << "event_" << x._event.name << "_callback_call(T* info)" << endl
|
||||||
|
<< tab(1) << "{" << endl
|
||||||
|
<< tab(2) << "eo_do(_eo_ptr(), eo_event_callback_call" << endl
|
||||||
|
<< tab(4) << "(" << x._event.eo_name << ", info));" << endl
|
||||||
|
<< tab(1) << "}" << endl;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct events
|
struct events
|
||||||
{
|
{
|
||||||
events_container_type const& _events;
|
eo_class const& _cls;
|
||||||
events(events_container_type const& events) : _events(events) {}
|
events(eo_class const& cls) : _cls(cls) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
operator<<(std::ostream& out, events const& x)
|
operator<<(std::ostream& out, events const& x)
|
||||||
{
|
{
|
||||||
std::string prefix = x._cls.name + "_EVENT_";
|
for (eo_event const& e : x._cls.events)
|
||||||
std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper());
|
|
||||||
events_container_type::const_iterator it,
|
|
||||||
first = x._events.begin(),
|
|
||||||
last = x._events.end();
|
|
||||||
for (it = first; it != last; ++it)
|
|
||||||
{
|
{
|
||||||
std::string ev_name = (*it).name;
|
out << event_callback_add(e, x._cls) << endl
|
||||||
std::transform(ev_name.begin(), ev_name.end(), ev_name.begin(), ::toupper());
|
<< event_callback_call(e);
|
||||||
out << event_callback_add((*it), prefix+ev_name)
|
|
||||||
<< event_callback_del((*it), prefix+ev_name)
|
|
||||||
<< event_callback_call((*it), prefix+ev_name);
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "tab.hh"
|
#include "tab.hh"
|
||||||
#include "comment.hh"
|
#include "comment.hh"
|
||||||
#include "parameters_generator.hh"
|
#include "parameters_generator.hh"
|
||||||
|
#include "type_generator.hh"
|
||||||
|
|
||||||
namespace efl { namespace eolian { namespace grammar {
|
namespace efl { namespace eolian { namespace grammar {
|
||||||
|
|
||||||
|
@ -21,10 +22,9 @@ inline std::ostream&
|
||||||
operator<<(std::ostream& out, function_call const& x)
|
operator<<(std::ostream& out, function_call const& x)
|
||||||
{
|
{
|
||||||
bool is_void = function_is_void(x._func);
|
bool is_void = function_is_void(x._func);
|
||||||
out << (!is_void ? "_tmp_ret = " : "")
|
return out << (!is_void ? "_tmp_ret = " : "")
|
||||||
<< "::" << x._func.impl
|
<< "::" << x._func.impl
|
||||||
<< "(" << parameters_list(x._func.params) << ")";
|
<< "(" << parameters_list(x._func.params) << ")";
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct function
|
struct function
|
||||||
|
@ -37,25 +37,30 @@ inline std::ostream&
|
||||||
operator<<(std::ostream& out, function const& x)
|
operator<<(std::ostream& out, function const& x)
|
||||||
{
|
{
|
||||||
eo_function const& func = x._func;
|
eo_function const& func = x._func;
|
||||||
bool is_void = function_is_void(func);
|
|
||||||
out << comment(x._func.comment, 1)
|
out << comment(x._func.comment, 1);
|
||||||
<< tab(1)
|
if (parameters_count_callbacks(x._func.params) == 1)
|
||||||
<< ( func.type == eo_function::class_ ? "static " : "" )
|
out << tab(1) << "template <typename F>" << endl;
|
||||||
<< func.ret << " " << func.name << "("
|
|
||||||
|
if (function_is_static(func))
|
||||||
|
out << tab(1) << "static ";
|
||||||
|
|
||||||
|
out << tab(1)
|
||||||
|
<< reinterpret_type(func.ret) << " " << func.name << "("
|
||||||
<< parameters_declaration(func.params)
|
<< parameters_declaration(func.params)
|
||||||
<< ") const" << endl
|
<< ") const" << endl
|
||||||
<< tab(1) << "{" << endl;
|
<< tab(1) << "{" << endl;
|
||||||
if (!is_void)
|
|
||||||
{
|
if (!function_is_void(func))
|
||||||
out << tab(2) << func.ret << " _tmp_ret;" << endl;
|
out << tab(2)
|
||||||
}
|
<< func.ret.front().native << " _tmp_ret;" << endl;
|
||||||
out << tab(2) << "eo_do(_eo_ptr(), "
|
|
||||||
<< function_call(x._func)
|
out << tab(2)
|
||||||
<< ");" << endl;
|
<< "eo_do(_eo_ptr(), " << function_call(x._func) << ");" << endl;
|
||||||
if (!is_void)
|
|
||||||
{
|
if (!function_is_void(func))
|
||||||
out << tab(2) << "return _tmp_ret;" << endl;
|
out << tab(2) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
|
||||||
}
|
|
||||||
out << tab(1) << "}" << endl;
|
out << tab(1) << "}" << endl;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "comment.hh"
|
#include "comment.hh"
|
||||||
#include "eo_class_constructors_generator.hh"
|
#include "eo_class_constructors_generator.hh"
|
||||||
#include "eo_class_functions_generator.hh"
|
#include "eo_class_functions_generator.hh"
|
||||||
|
#include "eo_class_events_generator.hh"
|
||||||
|
|
||||||
namespace efl { namespace eolian { namespace grammar {
|
namespace efl { namespace eolian { namespace grammar {
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
|
||||||
<< copy_constructor(cls)
|
<< copy_constructor(cls)
|
||||||
<< destructor(cls)
|
<< destructor(cls)
|
||||||
<< functions(cls.functions)
|
<< functions(cls.functions)
|
||||||
|
<< events(cls)
|
||||||
<< eo_class_getter(cls)
|
<< eo_class_getter(cls)
|
||||||
<< "private:" << endl
|
<< "private:" << endl
|
||||||
<< eo_class_constructors(cls)
|
<< eo_class_constructors(cls)
|
||||||
|
|
|
@ -38,6 +38,42 @@ _onceguard_key(efl::eolian::eo_class const& cls)
|
||||||
|
|
||||||
namespace efl { namespace eolian { namespace grammar {
|
namespace efl { namespace eolian { namespace grammar {
|
||||||
|
|
||||||
|
struct include_dependencies
|
||||||
|
{
|
||||||
|
eo_class const& _cls;
|
||||||
|
include_dependencies(eo_class const& cls)
|
||||||
|
: _cls(cls)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream&
|
||||||
|
operator<<(std::ostream& out, include_dependencies const& x)
|
||||||
|
{
|
||||||
|
std::set<std::string> headers;
|
||||||
|
eo_class const& cls = x._cls;
|
||||||
|
|
||||||
|
for (auto it = cls.constructors.cbegin(), last = cls.constructors.cend();
|
||||||
|
it != last; ++it)
|
||||||
|
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||||
|
it_p != last_p; ++it_p)
|
||||||
|
for (eolian_type const& subtype : (*it_p).type)
|
||||||
|
for (std::string header : subtype.includes)
|
||||||
|
headers.insert(header);
|
||||||
|
|
||||||
|
for (auto it = cls.functions.begin(), last = cls.functions.end();
|
||||||
|
it != last; ++it)
|
||||||
|
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||||
|
it_p != last_p; ++it_p)
|
||||||
|
for (eolian_type const& subtype : (*it_p).type)
|
||||||
|
for (std::string header : subtype.includes)
|
||||||
|
headers.insert(header);
|
||||||
|
|
||||||
|
for (std::string header : headers)
|
||||||
|
out << "#include <" << header << ">" << endl;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
onceguard_head(std::ostream& out, eo_class const& cls)
|
onceguard_head(std::ostream& out, eo_class const& cls)
|
||||||
{
|
{
|
||||||
|
@ -91,6 +127,7 @@ include_headers(std::ostream& out,
|
||||||
eo_generator_options const& opts)
|
eo_generator_options const& opts)
|
||||||
{
|
{
|
||||||
out << "#include <Eo.hh>" << endl << endl
|
out << "#include <Eo.hh>" << endl << endl
|
||||||
|
<< "#include <eo_cxx_interop.hh>" << endl << endl
|
||||||
<< "extern \"C\"" << endl
|
<< "extern \"C\"" << endl
|
||||||
<< "{" << endl;
|
<< "{" << endl;
|
||||||
for (auto c_header : opts.c_headers)
|
for (auto c_header : opts.c_headers)
|
||||||
|
@ -102,6 +139,7 @@ include_headers(std::ostream& out,
|
||||||
{
|
{
|
||||||
out << "#include \"" << cxx_header << "\"" << endl;
|
out << "#include \"" << cxx_header << "\"" << endl;
|
||||||
}
|
}
|
||||||
|
out << include_dependencies(cls) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
|
|
@ -96,7 +96,7 @@ inline std::ostream&
|
||||||
operator<<(std::ostream& out, inheritance_wrapper const& x)
|
operator<<(std::ostream& out, inheritance_wrapper const& x)
|
||||||
{
|
{
|
||||||
out << "template <typename T>" << endl
|
out << "template <typename T>" << endl
|
||||||
<< x._func.ret << " "
|
<< reinterpret_type(x._func.ret) << " "
|
||||||
<< _ns_as_prefix(x._cls) << "_"
|
<< _ns_as_prefix(x._cls) << "_"
|
||||||
<< x._cls.name << "_" << x._func.name
|
<< x._cls.name << "_" << x._func.name
|
||||||
<< "_wrapper(Eo* objid EINA_UNUSED, "
|
<< "_wrapper(Eo* objid EINA_UNUSED, "
|
||||||
|
@ -130,7 +130,7 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
|
||||||
{
|
{
|
||||||
eo_function const& func = *it;
|
eo_function const& func = *it;
|
||||||
out << "template <typename T>" << endl
|
out << "template <typename T>" << endl
|
||||||
<< func.ret << " "
|
<< reinterpret_type(func.ret) << " "
|
||||||
<< _ns_as_prefix(x._cls) << "_"
|
<< _ns_as_prefix(x._cls) << "_"
|
||||||
<< x._cls.name << "_" << func.name
|
<< x._cls.name << "_" << func.name
|
||||||
<< "_wrapper(Eo* objid EINA_UNUSED, "
|
<< "_wrapper(Eo* objid EINA_UNUSED, "
|
||||||
|
@ -186,13 +186,13 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
|
||||||
eo_function const& func = x._func;
|
eo_function const& func = x._func;
|
||||||
bool is_void = function_is_void(func);
|
bool is_void = function_is_void(func);
|
||||||
|
|
||||||
out << tab(2) << "virtual " << func.ret << " "
|
out << tab(2) << "virtual " << reinterpret_type(func.ret) << " "
|
||||||
<< func.name << "("
|
<< func.name << "("
|
||||||
<< parameters_declaration(func.params) << ")" << endl
|
<< parameters_declaration(func.params) << ")" << endl
|
||||||
<< tab(2) << "{" << endl;
|
<< tab(2) << "{" << endl;
|
||||||
if (!is_void)
|
if (!is_void)
|
||||||
{
|
{
|
||||||
out << tab(3) << func.ret << " _tmp_ret = {};" << endl;
|
out << tab(3) << reinterpret_type(func.ret) << " _tmp_ret = {};" << endl;
|
||||||
}
|
}
|
||||||
out << tab(3)
|
out << tab(3)
|
||||||
<< "eo_do_super(static_cast<T*>(this)->_eo_ptr()" << endl
|
<< "eo_do_super(static_cast<T*>(this)->_eo_ptr()" << endl
|
||||||
|
@ -301,7 +301,7 @@ operator<<(std::ostream& out, inheritance_extension_function const& x)
|
||||||
{
|
{
|
||||||
bool is_void = function_is_void(x._func);
|
bool is_void = function_is_void(x._func);
|
||||||
out << tab(2)
|
out << tab(2)
|
||||||
<< x._func.ret << " "
|
<< reinterpret_type(x._func.ret) << " "
|
||||||
<< x._func.name << "("
|
<< x._func.name << "("
|
||||||
<< parameters_declaration(x._func.params)
|
<< parameters_declaration(x._func.params)
|
||||||
<< ")" << endl
|
<< ")" << endl
|
||||||
|
@ -309,7 +309,7 @@ operator<<(std::ostream& out, inheritance_extension_function const& x)
|
||||||
|
|
||||||
if (!is_void)
|
if (!is_void)
|
||||||
{
|
{
|
||||||
out << tab(3) << x._func.ret << " _tmp_ret = {};" << endl;
|
out << tab(3) << reinterpret_type(x._func.ret) << " _tmp_ret = {};" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << tab(3) << "eo_do(static_cast<T*>(this)->_eo_ptr(), "
|
out << tab(3) << "eo_do(static_cast<T*>(this)->_eo_ptr(), "
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "tab.hh"
|
#include "tab.hh"
|
||||||
#include "eo_types.hh"
|
#include "eo_types.hh"
|
||||||
|
#include "type_generator.hh"
|
||||||
|
|
||||||
namespace efl { namespace eolian { namespace grammar {
|
namespace efl { namespace eolian { namespace grammar {
|
||||||
|
|
||||||
|
@ -21,12 +22,20 @@ parameters_declaration
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
operator<<(std::ostream& out, parameters_declaration const& x)
|
operator<<(std::ostream& out, parameters_declaration const& x)
|
||||||
{
|
{
|
||||||
parameters_container_type::const_iterator it, first = x._params.cbegin();
|
auto first = x._params.cbegin(),
|
||||||
parameters_container_type::const_iterator last = x._params.cend();
|
last = x._params.cend();
|
||||||
for (it = first; it != last; ++it)
|
for (auto it = first; it != last; ++it)
|
||||||
{
|
{
|
||||||
if (it != first) out << ", ";
|
if (it != first)
|
||||||
out << (*it).type << " " << (*it).name;
|
out << ", ";
|
||||||
|
if (type_is_callback((*it).type))
|
||||||
|
{
|
||||||
|
out << "F && " << (*it).name;
|
||||||
|
assert(it+1 != last);
|
||||||
|
++it; // skip next.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out << reinterpret_type((*it).type) << " " << (*it).name;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +58,7 @@ operator<<(std::ostream& out, parameters_types const& x)
|
||||||
for (it = first; it != last; ++it)
|
for (it = first; it != last; ++it)
|
||||||
{
|
{
|
||||||
if(it != first) out << ", ";
|
if(it != first) out << ", ";
|
||||||
out << (*it).type;
|
out << reinterpret_type((*it).type);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -66,16 +75,52 @@ parameters_list
|
||||||
inline std::ostream&
|
inline std::ostream&
|
||||||
operator<<(std::ostream& out, parameters_list const& x)
|
operator<<(std::ostream& out, parameters_list const& x)
|
||||||
{
|
{
|
||||||
parameters_container_type::const_iterator it, first = x._params.cbegin();
|
auto first = x._params.cbegin(), last = x._params.cend();
|
||||||
parameters_container_type::const_iterator last = x._params.cend();
|
for (auto it = first; it != last; ++it)
|
||||||
for (it = first; it != last; ++it)
|
|
||||||
{
|
{
|
||||||
if (it != first) out << ", ";
|
if (it != first)
|
||||||
out << (*it).name;
|
out << ", ";
|
||||||
|
out << to_c((*it).type, (*it).name);
|
||||||
|
if (type_is_callback((*it).type))
|
||||||
|
{
|
||||||
|
out << ", _tmp_f";
|
||||||
|
++it; // skip next
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct
|
||||||
|
parameters_cxx_list
|
||||||
|
{
|
||||||
|
parameters_container_type const& _params;
|
||||||
|
parameters_cxx_list(parameters_container_type const& params)
|
||||||
|
: _params(params)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream&
|
||||||
|
operator<<(std::ostream& out, parameters_cxx_list const& x)
|
||||||
|
{
|
||||||
|
auto first = x._params.cbegin(),
|
||||||
|
last = x._params.cend();
|
||||||
|
for (auto it = first; it != last; ++it)
|
||||||
|
{
|
||||||
|
if (it != first)
|
||||||
|
out << ", ";
|
||||||
|
if (type_is_callback((*it).type))
|
||||||
|
{
|
||||||
|
out << "std::move(" << (*it).name << ")";
|
||||||
|
assert(it+1 != last);
|
||||||
|
++it; // skip next.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out << (*it).name;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
|
||||||
|
#ifndef EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH
|
||||||
|
#define EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#include "eo_types.hh"
|
||||||
|
|
||||||
|
namespace efl { namespace eolian { namespace grammar {
|
||||||
|
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
struct reinterpret_type
|
||||||
|
{
|
||||||
|
eolian_type_instance const& _list;
|
||||||
|
reinterpret_type(eolian_type_instance const& list)
|
||||||
|
: _list(list)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream&
|
||||||
|
operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
|
||||||
|
{
|
||||||
|
assert(x._list.size() > 0);
|
||||||
|
std::string res;
|
||||||
|
for (auto rit = x._list.rbegin(), last = x._list.rend(); rit != last; ++rit)
|
||||||
|
{
|
||||||
|
if (type_is_complex(*rit))
|
||||||
|
res = (*rit).binding + "< " + res + " >";
|
||||||
|
else
|
||||||
|
res = type_is_binding(*rit) ? (*rit).binding : (*rit).native;
|
||||||
|
}
|
||||||
|
assert(!res.empty());
|
||||||
|
return out << res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct type_ownership
|
||||||
|
{
|
||||||
|
eolian_type_instance const& _type;
|
||||||
|
type_ownership(eolian_type_instance const& type)
|
||||||
|
: _type(type)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream&
|
||||||
|
operator<<(std::ostream& out, type_ownership const& x)
|
||||||
|
{
|
||||||
|
out << "std::tuple<";
|
||||||
|
for (auto it=x._type.begin(), last=x._type.end(); it != last; ++it)
|
||||||
|
{
|
||||||
|
if (it != x._type.begin())
|
||||||
|
out << ", ";
|
||||||
|
out << ((*it).is_own ? "std::true_type" : "std::false_type");
|
||||||
|
}
|
||||||
|
return out << ">()";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct to_cxx
|
||||||
|
{
|
||||||
|
eolian_type_instance const& _type;
|
||||||
|
std::string const& _varname;
|
||||||
|
to_cxx(eolian_type_instance const& type, std::string const& varname)
|
||||||
|
: _type(type), _varname(varname)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream&
|
||||||
|
operator<<(std::ostream& out, to_cxx const& x)
|
||||||
|
{
|
||||||
|
if (type_is_binding(x._type))
|
||||||
|
{
|
||||||
|
out << "efl::eolian::to_cxx<"
|
||||||
|
<< reinterpret_type(x._type)
|
||||||
|
<< ">(" << x._varname
|
||||||
|
<< ", " << type_ownership(x._type) << ");";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out << "_ret";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct to_c
|
||||||
|
{
|
||||||
|
eolian_type_instance const& _type;
|
||||||
|
std::string const& _varname;
|
||||||
|
to_c(eolian_type_instance const& type, std::string const& varname)
|
||||||
|
: _type(type), _varname(varname)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream&
|
||||||
|
operator<<(std::ostream& out, to_c const& x)
|
||||||
|
{
|
||||||
|
if (type_is_callback(x._type))
|
||||||
|
out << "efl::eolian::get_callback<" << type_to_native_str(x._type) << ", F>()";
|
||||||
|
else if (type_is_binding(x._type))
|
||||||
|
out << "efl::eolian::to_c(" << x._varname << ")";
|
||||||
|
else
|
||||||
|
out << x._varname;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#endif // EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH
|
Loading…
Reference in New Issue