section of the Eo files.
Reviewers: woohyun, segfaultxavi, bu5hm4n, felipealmeida
Reviewed By: segfaultxavi
Subscribers: cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D7789
return name;
}
+ static std::string function_conversion(attributes::function_def const& func)
+ {
+ attributes::klass_def klass(get_klass(func.klass, func.unit), func.unit);
+ std::string name = name_helpers::klass_full_concrete_or_interface_name(klass);
+ switch (func.type)
+ {
+ // managed_method_name takes care of reordering the function name so the get/set goes first
+ // for properties
+ case attributes::function_type::method:
+ case attributes::function_type::prop_set:
+ case attributes::function_type::prop_get:
+ if (blacklist::is_function_blacklisted(func.c_name))return "";
+ name += ".";
+ name += name_helpers::managed_method_name(klass.eolian_name, func.name);
+ break;
+ default:
+ // No need to deal with property as function_defs are converted to get/set when building a given klass_def.
+ break;
+ }
+
+ return name;
+ }
+
// Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag
static std::string ref_conversion(const ::Eolian_Doc_Token *token, const Eolian_State *state, std::string name_tail)
{
{
return generate_tag_summary(sink, doc.full_text, context);
}
+
+ template<typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::constructor_def const& ctor, Context const& context) const
+ {
+ // Not sure if this is the best way to generate a reference outside the full doc generator.
+ auto unit = (const Eolian_Unit*) context_find_tag<eolian_state_context>(context).state;
+ auto func = ctor.function;
+ auto eolian_klass = get_klass(func.klass, unit);
+ attributes::klass_def klass(eolian_klass, unit);
+ std::string summary;
+
+ if (func.type == attributes::function_type::prop_set)
+ summary = func.property_documentation.summary;
+ else
+ summary = func.documentation.summary;
+
+ for (auto &¶m : ctor.function.parameters)
+ {
+ if (!as_generator(
+ scope_tab << "///<param name=\"" << constructor_parameter_name(ctor) << "\">" << summary << " See <see cref=\"" << function_conversion(func) << "\"/></param>\n"
+ ).generate(sink, param, context))
+ return false;
+ }
+ return true;
+ }
};
struct documentation_terminal
});
}
+inline std::vector<attributes::constructor_def> reorder_constructors(std::vector<attributes::constructor_def> constructors)
+{
+ auto is_required = [](attributes::constructor_def const& ctr) { return !ctr.is_optional; };
+ std::stable_partition(constructors.begin(), constructors.end(), is_required);
+ return constructors;
+}
} // namespace helpers
if (!generate_fields(sink, cls, concrete_cxt))
return false;
+ bool root = !helpers::has_regular_ancestor(cls);
if (!as_generator
(
scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
<< ")] internal static extern System.IntPtr\n"
<< scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
- << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
- << scope_tab << "public " << concrete_name << "(System.IntPtr raw)\n"
+ << scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
+ << scope_tab << "public " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
<< scope_tab << "{\n"
- << scope_tab << scope_tab << "handle = raw;\n"
+ << scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
<< scope_tab << scope_tab << "register_event_proxies();\n"
<< scope_tab << "}\n"
)
).generate(sink, attributes::unused, context))
return false;
+ auto constructors = helpers::reorder_constructors(cls.get_all_constructors());
- if (!root)
- {
- return as_generator(
+ // Public (API) constructors
+ if (!as_generator(
scope_tab << "///<summary>Creates a new instance.</summary>\n"
<< scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
- << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
- << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : "
- "base(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
+ << *(documentation)
+ // For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters.
+ << scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n"
+ << scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") :\n"
+ << scope_tab << scope_tab << (root ? "this" : "base") << "(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
<< scope_tab << "{\n"
- << scope_tab << scope_tab << "if (init_cb != null) {\n"
- << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
- << scope_tab << scope_tab << "}\n"
+ << *(scope_tab << scope_tab << constructor_invocation << "\n" )
<< scope_tab << scope_tab << "FinishInstantiation();\n"
<< scope_tab << "}\n"
-
- << scope_tab << "///<summary>Internal constructor to forward the wrapper initialization to the root class.</summary>\n"
- << scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent) : base(klass_name, base_klass, managed_type, parent) {}\n"
-
- << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
+ << scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
<< scope_tab << "public " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
<< scope_tab << scope_tab << "register_event_proxies();\n"
<< scope_tab << "}\n"
+ ).generate(sink, std::make_tuple(constructors, constructors, constructors), context))
+ return false;
+
+ // Internal constructors
+ if (!root)
+ {
+ return as_generator(
+ scope_tab << "///<summary>Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.</summary>\n"
+ << scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent) : base(klass_name, base_klass, managed_type, parent) {}\n"
).generate(sink, attributes::unused, context);
- }
+
+ }
// Detailed constructors go only in root classes.
return as_generator(
- scope_tab << "///<summary>Creates a new instance.</summary>\n"
- << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
- << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
- << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : this(\"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "if (init_cb != null) {\n"
- << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
- << scope_tab << scope_tab << "}\n"
- << scope_tab << scope_tab << "FinishInstantiation();\n"
- << scope_tab << "}\n"
-
- << scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n"
+ /// Actual root costructor that creates class and instantiates
+ scope_tab << "protected " << inherit_name << "(String klass_name, IntPtr base_klass, System.Type managed_type, Efl.Object parent)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "inherited = ((object)this).GetType() != managed_type;\n"
<< scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n"
<< scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n"
<< scope_tab << "}\n"
- << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
- << scope_tab << "public " << inherit_name << "(System.IntPtr raw)\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "handle = raw;\n"
- << scope_tab << scope_tab << "register_event_proxies();\n"
- << scope_tab << "}\n"
).generate(sink, attributes::unused, context);
}
return candidate;
}
+inline std::string managed_name(std::string const& name, char separator='_')
+{
+ auto tokens = utils::split(name, separator);
+ return utils::to_pascal_case(tokens);
+}
+
inline std::string managed_method_name(attributes::function_def const& f)
{
return managed_method_name(f.klass.eolian_name, f.name);
return as_generator(close_namespace).generate(sink, namespaces, context);
}
+std::string constructor_managed_name(std::string full_name)
+{
+ auto tokens = utils::split(full_name, '.');
+ return managed_name(tokens.at(tokens.size()-1));
+}
} // namespace name_helpers
#include "grammar/generator.hpp"
#include "grammar/klass_def.hpp"
+#include "grammar/attribute_reorder.hpp"
#include "grammar/case.hpp"
#include "helpers.hh"
#include "marshall_type.hh"
struct native_convert_return_variable_generator;
struct convert_function_pointer_generator;
struct native_convert_function_pointer_generator;
+ struct constructor_param_generator;
+ struct constructor_invocation_generator;
+ struct constructor_parameter_name_generator;
+ struct constructor_parameter_name_paremeterized;
}
namespace efl { namespace eolian { namespace grammar {
struct attributes_needed< ::eolian_mono::native_convert_function_pointer_generator> : std::integral_constant<int, 1> {};
}
+template <>
+struct is_eager_generator< ::eolian_mono::constructor_param_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::constructor_param_generator> : std::true_type {};
+
+namespace type_traits {
+template <>
+struct attributes_needed< ::eolian_mono::constructor_param_generator> : std::integral_constant<int, 1> {};
+}
+
+template <>
+struct is_eager_generator< ::eolian_mono::constructor_invocation_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::constructor_invocation_generator> : std::true_type {};
+
+namespace type_traits {
+template <>
+struct attributes_needed< ::eolian_mono::constructor_invocation_generator> : std::integral_constant<int, 1> {};
+}
+
+template <>
+struct is_eager_generator< ::eolian_mono::constructor_parameter_name_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::constructor_parameter_name_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::constructor_parameter_name_paremeterized> : std::true_type {};
+
+namespace type_traits {
+template <>
+struct attributes_needed< ::eolian_mono::constructor_parameter_name_generator> : std::integral_constant<int, 1> {};
+}
+
} } }
namespace eolian_mono {
} const native_convert_function_pointer {};
+struct constructor_parameter_name_generator
+{
+
+ template <typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
+ {
+ auto target_name = name_helpers::constructor_managed_name(ctor.name);
+
+ // Only multi-valued constructing methods get their actual parameter names
+ if (ctor.function.parameters.size() > 1)
+ target_name += '_' + param.param_name;
+
+ auto name = name_helpers::managed_name(target_name);
+ name[0] = std::tolower(name[0]);
+
+ return as_generator(string).generate(sink, name, context);
+ }
+
+ attributes::constructor_def const& ctor;
+};
+
+struct constructor_parameter_name_parameterized
+{
+ constructor_parameter_name_generator const operator()(attributes::constructor_def const& ctor) const
+ {
+ return {ctor};
+ }
+} const constructor_parameter_name;
+
+// Generates the parameters for the given constructor
+// If the constructor receives multiple parameters, they get the name
+// of the constructor plus the name of the parameter (e.g. DefineParentData, DefineIndex)
+struct constructor_param_generator
+{
+ template<typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::constructor_def const& ctor, Context context) const
+ {
+ auto params = ctor.function.parameters;
+
+ if (!as_generator(
+ efl::eolian::grammar::attribute_reorder<1, -1>
+ (type(false, ctor.is_optional) << " " << constructor_parameter_name(ctor) << (ctor.is_optional ? " = null" : "")) % ","
+ ).generate(sink, params, context))
+ return false;
+ // }
+ return true;
+ }
+
+} const constructor_param;
+
+// Generates the invocation of the given parameter
+struct constructor_invocation_generator
+{
+ template<typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::constructor_def const& ctor, Context context) const
+ {
+ auto params = ctor.function.parameters;
+ if (!as_generator(
+ "if (" <<
+ (efl::eolian::grammar::attribute_reorder<-1>
+ ("Efl.Eo.Globals.ParamHelperCheck(" << constructor_parameter_name(ctor) << ")") % "||") << ")\n"
+ << scope_tab << scope_tab << scope_tab << name_helpers::managed_method_name(ctor.function) << "("
+ ).generate(sink, params, context))
+ return false;
+
+ size_t idx = 0;
+
+ for (auto&& param : params)
+ {
+ idx++;
+ if (!as_generator(
+ "Efl.Eo.Globals.GetParamHelper(" << constructor_parameter_name(ctor) << ")" << ((idx < params.size()) ? ", " : "")
+ ).generate(sink, param, context))
+ return false;
+ }
+
+ if (!as_generator(");").generate(sink, attributes::unused, context))
+ return false;
+ return true;
+ }
+
+} const constructor_invocation;
+
}
#endif
struct type_generator
{
- type_generator(bool is_return = false)
- : is_return(is_return) {}
+ type_generator(bool is_return = false, bool is_optional = false)
+ : is_return(is_return), is_optional(is_optional) {}
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
{
- return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
+ return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr, is_optional});
}
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
- , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr});
+ , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr, is_optional});
}
- bool is_return;
+ bool is_return, is_optional;
};
struct type_terminal
{
- type_generator const operator()(bool is_return) const
+ type_generator const operator()(bool is_return, bool is_optional = false) const
{
- return type_generator(is_return);
+ return type_generator(is_return, is_optional);
}
} const type = {};
}
}
+template <typename T>
+attributes::regular_type_def replace_base_opt_integer(attributes::regular_type_def v)
+{
+ bool s = std::is_signed<T>::value;
+ switch (sizeof(T))
+ {
+ case 1: return s ? replace_base_type(v, " sbyte?") : replace_base_type(v, " byte?");
+ case 2: return s ? replace_base_type(v, " short?") : replace_base_type(v, " ushort?");
+ case 4: return s ? replace_base_type(v, " int?") : replace_base_type(v, " uint?");
+ case 8: return s ? replace_base_type(v, " long?") : replace_base_type(v, " ulong?");
+ default: return v;
+ }
+}
+
inline
attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular)
{
bool is_out;
bool is_return;
bool is_ptr;
+ mutable bool is_optional;
typedef visitor_generate<OutputIterator, Context> visitor_type;
typedef bool result_type;
eina::optional<bool> has_own;
std::function<attributes::type_def::variant_type()> function;
}
+ const optional_match_table[] =
+ {
+ // signed primitives
+ {"byte", nullptr, [&] { return replace_base_type(regular, " sbyte?"); }}
+ , {"float", nullptr, [&] { return replace_base_type(regular, " float?"); }}
+ , {"double", nullptr, [&] { return replace_base_type(regular, " double?"); }}
+ , {"bool", nullptr, [&] { return replace_base_type(regular, " bool?"); }}
+ , {"short", nullptr, [&] { return replace_base_opt_integer<short>(regular); }}
+ , {"int", nullptr, [&] { return replace_base_opt_integer<int>(regular); }}
+ , {"long", nullptr, [&] { return replace_base_opt_integer<long>(regular); }}
+ , {"llong", nullptr, [&] { return replace_base_opt_integer<long long>(regular); }}
+ , {"int8", nullptr, [&] { return replace_base_type(regular, " sbyte?"); }}
+ , {"int16", nullptr, [&] { return replace_base_type(regular, " short?"); }}
+ , {"int32", nullptr, [&] { return replace_base_type(regular, " int?"); }}
+ , {"int64", nullptr, [&] { return replace_base_type(regular, " long?"); }}
+ , {"ssize", nullptr, [&] { return replace_base_opt_integer<ssize_t>(regular); }}
+ // unsigned primitives
+ , {"ubyte", nullptr, [&] { return replace_base_type(regular, " byte?"); }}
+ , {"ushort", nullptr, [&] { return replace_base_opt_integer<unsigned short>(regular); }}
+ , {"uint", nullptr, [&] { return replace_base_opt_integer<unsigned int>(regular); }}
+ , {"ulong", nullptr, [&] { return replace_base_opt_integer<unsigned long>(regular); }}
+ , {"ullong", nullptr, [&] { return replace_base_opt_integer<unsigned long long>(regular); }}
+ , {"uint8", nullptr, [&] { return replace_base_type(regular, " byte?"); }}
+ , {"uint16", nullptr, [&] { return replace_base_type(regular, " ushort?"); }}
+ , {"uint32", nullptr, [&] { return replace_base_type(regular, " uint?"); }}
+ , {"uint64", nullptr, [&] { return replace_base_type(regular, " ulong?"); }}
+ , {"size", nullptr, [&] { return replace_base_opt_integer<size_t>(regular); }}
+
+ , {"ptrdiff", nullptr, [&] { return replace_base_opt_integer<ptrdiff_t>(regular); }}
+ , {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr?"); }}
+ , {"uintptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr?"); }}
+ , {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr?"); }}
+ };
+ struct match
const match_table[] =
{
// signed primitives
};
std::string full_type_name = name_helpers::type_full_eolian_name(regular);
if(eina::optional<bool> b = call_match
+ (optional_match_table
+ , [&] (match const& m)
+ {
+ return is_optional
+ && (!m.name || *m.name == regular.base_type || *m.name == full_type_name)
+ && (!m.has_own || *m.has_own == (bool)(regular.base_qualifier & qualifier_info::is_own))
+ ;
+ }
+ , [&] (attributes::type_def::variant_type const& v)
+ {
+ return v.visit(*this); // we want to keep is_out info
+ }))
+ {
+ return *b;
+ }
+ else if (is_optional && (regular.is_struct() || regular.is_enum() || regular.is_struct_opaque()))
+ {
+ attributes::regular_type_def r = regular;
+ r.base_type.push_back('?');
+ is_optional = false;
+ return (*this)(r);
+ }
+ else if(eina::optional<bool> b = call_match
(match_table
, [&] (match const& m)
{
public delegate byte class_initializer(IntPtr klass);
+ public static T GetParamHelper<T>(Nullable<T> v) where T : struct
+ {
+ return v.Value;
+ }
+ public static U GetParamHelper<U>(U v)
+ {
+ return v;
+ }
+ public static bool ParamHelperCheck<T>(Nullable<T> v) where T : struct
+ {
+ return v.HasValue;
+ }
+ public static bool ParamHelperCheck<U>(U v)
+ {
+ return v != null;
+ }
+
public static IntPtr register_class(String class_name, IntPtr base_klass, System.Type type)
{
ClassDescription description;
}
}
-class TestEoConstructingMethods
-{
- public static void constructing_method()
- {
- bool called = false;
- string name = "Test object";
- var obj = new Dummy.TestObject(null, (Dummy.TestObject a) => {
- called = true;
- Console.WriteLine("callback: obj NativeHandle: {0:x}", a.NativeHandle);
- a.SetName(name);
- });
-
- Test.Assert(called);
- Test.AssertEquals(name, obj.GetName());
- }
-
- private class Derived : Dummy.TestObject
- {
- public Derived(Dummy.TestObject parent = null,
- Dummy.TestObject.ConstructingMethod cb = null) : base(parent, cb) {
- }
- }
-
- public static void constructing_method_inherit()
- {
- bool called = false;
- string name = "Another test object";
- Derived obj = new Derived(null, (Dummy.TestObject a) => {
- called = true;
- a.SetComment(name);
- });
-
- Test.Assert(called);
- Test.AssertEquals(name, obj.GetComment());
- }
-}
-
class TestEoParent
{
public static void basic_parent()
public sealed class GrandChild : Dummy.Child
{
+
+ public GrandChild() : base(null, "", 0.0) { }
+
public int receivedValue = 0;
public override Efl.Object FinalizeAdd()
{
}
}
+class TestConstructors
+{
+ public static void test_simple_constructor()
+ {
+ int iface_prop = 42;
+ string a = "LFE";
+ double b = 3.14;
+ var obj = new Dummy.Child(null, a, b, iface_prop);
+ Test.AssertEquals(iface_prop, obj.IfaceProp);
+
+ obj = new Dummy.Child(parent: null, ifaceProp : iface_prop, doubleParamsA : a, doubleParamsB : b);
+ Test.AssertEquals(iface_prop, obj.IfaceProp);
+ }
+
+ public static void test_optional_constructor()
+ {
+ string a = "LFE";
+ double b = 3.14;
+ var obj = new Dummy.Child(null, a, b);
+ Test.Assert(!obj.GetIfaceWasSet());
+ }
+}
+
}
{
int received = 0;
int sent = 42;
- var obj = new Dummy.TestObject(null, (Dummy.TestObject t) => {
- t.EvtWithIntEvt += (object sender, Dummy.TestObjectEvtWithIntEvt_Args e) => {
- received = e.arg;
- };
- });
+ var obj = new Dummy.TestObject();
+ obj.EvtWithIntEvt += (object sender, Dummy.TestObjectEvtWithIntEvt_Args e) => {
+ received = e.arg;
+ };
obj.EmitEventWithInt(sent);
class Dummy.Child extends Dummy.Test_Object {
+ methods {
+ double_params {
+ params {
+ @in a: string;
+ @in b: double;
+ }
+ }
+
+ @property iface_was_set {
+ get {}
+ values {
+ data: bool;
+ }
+ }
+ }
+ constructors {
+ Dummy.Test_Iface.iface_prop @optional;
+ .double_params;
+ }
implements {
+ Dummy.Test_Iface.iface_prop { get; set; }
class.constructor;
class.destructor;
+ Efl.Object.constructor;
}
}
typedef struct Dummy_Child_Data
{
+ int iface_prop;
+ const char* a;
+ double b;
+ Eina_Bool iface_was_set;
} Dummy_Child_Data;
typedef struct Dummy_Inherit_Helper_Data
}
/// Dummy.Child
+
+static Efl_Object *
+_dummy_child_efl_object_constructor(Eo *obj, Dummy_Child_Data *pd)
+{
+ efl_constructor(efl_super(obj, DUMMY_CHILD_CLASS));
+
+ pd->iface_prop = 1984;
+ pd->iface_was_set = EINA_FALSE;
+ return obj;
+}
+
+void _dummy_child_dummy_test_iface_iface_prop_set(EINA_UNUSED Eo *obj, Dummy_Child_Data *pd, int value)
+{
+ pd->iface_prop = value;
+ pd->iface_was_set = EINA_TRUE;
+}
+
+int _dummy_child_dummy_test_iface_iface_prop_get(EINA_UNUSED const Eo *obj, Dummy_Child_Data *pd)
+{
+ return pd->iface_prop;
+}
+
+void _dummy_child_double_params(EINA_UNUSED Eo* obj, Dummy_Child_Data *pd, const char* a, double b)
+{
+ if (pd->a)
+ free((void*)pd->a);
+ pd->a = malloc(sizeof(char)*(strlen(a) + 1));
+ strcpy((char*)pd->a, a);
+
+ pd->b = b;
+}
+
+Eina_Bool _dummy_child_iface_was_set_get(EINA_UNUSED const Eo* obj, Dummy_Child_Data *pd)
+{
+ return pd->iface_was_set;
+}
EOLIAN static void
_dummy_child_class_constructor(Efl_Class *klass)
{