efl/src/bin/eolian_mono/eolian/mono/parameter.hh

1442 lines
68 KiB
C++
Raw Normal View History

#ifndef EOLIAN_MONO_PARAMETER_HH
#define EOLIAN_MONO_PARAMETER_HH
#include "grammar/generator.hpp"
#include "grammar/klass_def.hpp"
#include "grammar/case.hpp"
#include "helpers.hh"
#include "marshall_type.hh"
#include "type.hh"
#include "using_decl.hh"
#include "name_helpers.hh"
using namespace eolian_mono::name_helpers;
namespace eolian_mono {
struct parameter_generator;
struct marshall_parameter_generator;
struct argument_generator;
struct argument_invocation_generator;
struct native_argument_invocation_generator;
struct native_convert_in_variable_generator;
struct convert_in_variable_generator;
struct native_convert_out_variable_generator;
struct convert_out_variable_generator;
struct convert_out_assign_generator;
struct native_convert_in_ptr_assign_generator;
struct convert_in_ptr_assign_generator;
struct native_convert_out_assign_parameterized;
struct native_convert_out_assign_generator;
struct convert_return_generator;
struct convert_return_variable_generator;
struct native_convert_return_generator;
struct native_convert_return_parameterized;
struct native_convert_return_variable_generator;
struct convert_function_pointer_generator;
struct native_convert_function_pointer_generator;
}
namespace efl { namespace eolian { namespace grammar {
template <>
struct is_eager_generator< ::eolian_mono::parameter_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::parameter_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::parameter_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::marshall_parameter_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::marshall_parameter_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::marshall_parameter_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::argument_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::argument_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::argument_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::argument_invocation_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::argument_invocation_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::argument_invocation_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_argument_invocation_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_argument_invocation_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_argument_invocation_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_convert_in_variable_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_in_variable_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_convert_in_variable_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::convert_in_variable_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::convert_in_variable_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::convert_in_variable_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::convert_out_variable_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::convert_out_variable_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::convert_out_variable_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_convert_out_variable_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_out_variable_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_convert_out_variable_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::convert_out_assign_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::convert_out_assign_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::convert_out_assign_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_convert_in_ptr_assign_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_in_ptr_assign_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_convert_in_ptr_assign_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::convert_in_ptr_assign_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::convert_in_ptr_assign_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::convert_in_ptr_assign_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::convert_return_variable_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::convert_return_variable_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::convert_return_variable_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::convert_return_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::convert_return_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::convert_return_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_convert_out_assign_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_out_assign_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_out_assign_parameterized> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_convert_out_assign_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_convert_return_variable_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_return_variable_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_convert_return_variable_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_convert_return_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_return_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_return_parameterized> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_convert_return_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::convert_function_pointer_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::convert_function_pointer_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::convert_function_pointer_generator> : std::integral_constant<int, 1> {};
}
template <>
struct is_eager_generator< ::eolian_mono::native_convert_function_pointer_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_function_pointer_generator> : std::true_type {};
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::native_convert_function_pointer_generator> : std::integral_constant<int, 1> {};
}
} } }
namespace eolian_mono {
namespace attributes = efl::eolian::grammar::attributes;
// Helper function to query parameter attributes
const static bool WANT_OWN = true;
const static bool WANT_OUT = true;
inline bool param_is_acceptable(attributes::parameter_def const &param, std::string c_type, bool want_own, bool want_out)
{
return (param.type.c_type == c_type)
&& ((param.direction != attributes::parameter_direction::in) == want_out)
&& (param.type.has_own == want_own);
}
inline bool param_should_use_out_var(attributes::parameter_def const& param, bool native)
{
if (param.direction == attributes::parameter_direction::in)
return false;
if ((native && param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
|| (native && param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Value", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Value", !WANT_OWN, WANT_OUT)
)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (helpers::need_struct_conversion(regular))
return true;
if (param.type.is_ptr && helpers::need_pointer_conversion(regular))
return true;
return false;
}
inline bool param_should_use_in_var(attributes::parameter_def const& param, bool /*native*/)
{
if (param.direction != attributes::parameter_direction::in)
return false;
if (param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Value", WANT_OWN, !WANT_OUT)
|| param_is_acceptable(param, "Eina_Value", !WANT_OWN, !WANT_OUT)
)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (helpers::need_struct_conversion(regular))
return true;
if (param.type.is_ptr && helpers::need_pointer_conversion(regular))
return true;
return false;
}
inline std::string out_variable_name(std::string const& param_name)
{
return "_out_" + escape_keyword(param_name);
}
inline std::string in_variable_name(std::string const& param_name)
{
return "_in_" + escape_keyword(param_name);
}
inline std::string direction_modifier(attributes::parameter_def const& param)
{
if (param.direction == attributes::parameter_direction::inout)
{
return " ref ";
}
else if (param.direction != attributes::parameter_direction::in)
{
if (param.type.c_type == "Eina_Slice" || param.type.c_type == "Eina_Rw_Slice")
return " ref ";
else
return " out ";
}
else if (param.direction == attributes::parameter_direction::in && param.type.is_ptr)
{
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (helpers::need_struct_conversion(regular))
return " ref "; // Don't add ref on Marshal if it is ptr
}
return " ";
}
std::string marshall_direction_modifier(attributes::parameter_def const& param)
{
if (param.direction == attributes::parameter_direction::in && param.type.is_ptr)
{
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (helpers::need_struct_conversion(regular) && param.type.has_own)
return " "; // Don't add ref on Marshal if it is ptr
}
return direction_modifier(param);
}
struct is_fp_visitor
{
typedef is_fp_visitor visitor_type;
typedef bool result_type;
bool operator()(grammar::attributes::regular_type_def const &type) const
{
return type.is_function_ptr();
}
template<typename T>
bool operator()(T const &) const
{
return false;
}
};
struct type_name_visitor
{
typedef type_name_visitor visitor_type;
typedef std::string result_type;
std::string operator()(grammar::attributes::regular_type_def const &type) const
{
return name_helpers::type_full_eolian_name(type);
}
template<typename T>
std::string operator()(T const &) const
{
return "";
}
};
struct parameter_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
std::string param_name = escape_keyword(param.param_name);
return as_generator(
direction_modifier(param) << type << " " << string
).generate(sink, std::make_tuple(param, param_name), context);
}
} const parameter {};
struct marshall_parameter_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
std::string param_name = escape_keyword(param.param_name);
if (!param.type.original_type.visit(is_fp_visitor{}))
return as_generator(
marshall_direction_modifier(param) << marshall_type << " " << string
).generate(sink, std::make_tuple(param, param_name), context);
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"IntPtr " << param_name << "_data, " << type << "Internal " << param_name << ", EinaFreeCb "
<< param_name << "_free_cb"
).generate(sink, param, context);
}
} const marshall_parameter {};
// FIXME This seems to be used only in the else branch of the native function definition. Is it really needed?
struct argument_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
std::string param_name = escape_keyword(param.param_name);
std::string direction = marshall_direction_modifier(param);
if (!param.type.original_type.visit(is_fp_visitor{}))
return as_generator(
direction << param_name
).generate(sink, attributes::unused, context);
return as_generator(
param_name << "_data, " << param_name << ", " << param_name << "_free_cb"
).generate(sink, attributes::unused, context);
}
} const argument {};
struct native_argument_invocation_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
std::string arg = direction_modifier(param);
if (param_should_use_out_var(param, true))
arg += out_variable_name(param.param_name);
else if (param_should_use_in_var(param, true))
arg += in_variable_name(param.param_name);
else if (param.type.original_type.visit(is_fp_visitor{}))
{
arg += escape_keyword(param.param_name) + "_wrapper.ManagedCb";
}
else // FIXME Wrap data and C function pointers into some kind of structure.
arg += escape_keyword(param.param_name);
return as_generator(arg).generate(sink, attributes::unused, context);
}
} const native_argument_invocation {};
// Generates the correct parameter name when invoking a function
struct argument_invocation_generator
{
constexpr argument_invocation_generator(bool conversion_vars)
: use_conversion_vars(conversion_vars)
{}
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
std::string arg = marshall_direction_modifier(param);
if (use_conversion_vars && param_should_use_out_var(param, false))
arg += out_variable_name(param.param_name);
else if (use_conversion_vars && param_should_use_in_var(param, false))
arg += in_variable_name(param.param_name);
else if (param.type.original_type.visit(is_fp_visitor{}))
{
std::string param_name = escape_keyword(param.param_name);
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
return as_generator("GCHandle.ToIntPtr(" << param_name << "_handle), " << type << "Wrapper.Cb, Efl.Eo.Globals.free_gchandle")
.generate(sink, param.type, context);
}
else
arg += escape_keyword(param.param_name);
return as_generator(arg).generate(sink, attributes::unused, context);
}
bool const use_conversion_vars;
} const argument_invocation {true};
argument_invocation_generator const argument_invocation_no_conversion {false};
struct native_convert_in_variable_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param.direction != attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(param, regular))
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"var " << string << " = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
"var " << string << " = " << type << "_StructConversion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"var " << string << " = new Eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
).generate(sink, in_variable_name(param.param_name), context);
}
else if (param.type.c_type == "Eina_Hash *" || param.type.c_type == "const Eina_Hash *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex || complex->subtypes.size() != 2)
return false;
return as_generator(
"var " << string << " = new " << type << "(" << escape_keyword(param.param_name)
<< ", " << (param.type.has_own ? "true" : "false")
<< ", " << (complex->subtypes.front().has_own ? "true" : "false")
<< ", " << (complex->subtypes.back().has_own ? "true" : "false")
<< ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *"
|| param.type.c_type == "Eina_Inarray *" || param.type.c_type == "const Eina_Inarray *"
|| param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *"
|| param.type.c_type == "Eina_Inlist *" || param.type.c_type == "const Eina_Inlist *"
|| param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *"
|| param.type.c_type == "Eina_Accessor *" || param.type.c_type == "const Eina_Accessor *"
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
return as_generator(
"var " << string << " = new " << type << "(" << escape_keyword(param.param_name)
<< ", " << (param.type.has_own ? "true" : "false")
<< ", " << (complex->subtypes.front().has_own ? "true" : "false")
<< ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Value")
{
return as_generator(
"var " << string << " = new " << type << "(" << string << ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type, param.param_name), context);
}
return true;
}
} const native_convert_in_variable {};
struct convert_in_variable_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param.direction != attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(param, regular))
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"var " << string << " = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, in_variable_name(param.param_name), context);
}
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
"var " << string << " = " << type << "_StructConversion.ToInternal(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
{
auto var_name = in_variable_name(param.param_name);
if (!as_generator(
"var " << string << " = " << escape_keyword(param.param_name) << ".Handle;\n"
).generate(sink, var_name, context))
return false;
if (param.type.has_own)
{
return as_generator(
escape_keyword(param.param_name) << ".Own = false;\n"
).generate(sink, attributes::unused, context);
}
}
else if (param.type.c_type == "Eina_Hash *" || param.type.c_type == "const Eina_Hash *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex || complex->subtypes.size() != 2)
return false;
auto var_name = in_variable_name(param.param_name);
if (!as_generator(
"var " << string << " = " << escape_keyword(param.param_name) << ".Handle;\n"
).generate(sink, var_name, context))
return false;
if (param.type.has_own && !as_generator(
escape_keyword(param.param_name) << ".SetOwn(false);\n"
).generate(sink, attributes::unused, context))
return false;
if (complex->subtypes.front().has_own && !as_generator(
escape_keyword(param.param_name) << ".SetOwnKey(false);\n"
).generate(sink, attributes::unused, context))
return false;
if (complex->subtypes.back().has_own && !as_generator(
escape_keyword(param.param_name) << ".SetOwnValue(false);\n"
<< escape_keyword(param.param_name) << ".UnSetFreeCb();\n"
).generate(sink, attributes::unused, context))
return false;
}
else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *"
|| param.type.c_type == "Eina_Inarray *" || param.type.c_type == "const Eina_Inarray *"
|| param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *"
|| param.type.c_type == "Eina_Inlist *" || param.type.c_type == "const Eina_Inlist *"
|| param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *"
|| param.type.c_type == "Eina_Accessor *" || param.type.c_type == "const Eina_Accessor *"
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
auto var_name = in_variable_name(param.param_name);
if (!as_generator(
"var " << string << " = " << escape_keyword(param.param_name) << ".Handle;\n"
).generate(sink, var_name, context))
return false;
if (param.type.has_own && !as_generator(
escape_keyword(param.param_name) << ".Own = false;\n"
).generate(sink, attributes::unused, context))
return false;
if (complex->subtypes.front().has_own && !as_generator(
escape_keyword(param.param_name) << ".OwnContent = false;\n"
).generate(sink, attributes::unused, context))
return false;
}
else if (param.type.c_type == "Eina_Value")
{
return as_generator(
"var " << string << " = " << string << ".GetNative();\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.param_name), context);
}
return true;
}
} const convert_in_variable {};
/* Some types require an intermediate variable to be filled as out parameter in the marshalled function */
struct convert_out_variable_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular))
{
return as_generator(
"System.IntPtr " << string << " = System.IntPtr.Zero;\n"
).generate(sink, out_variable_name(param.param_name), context);
}
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = new " << marshall_type << "();\n"
).generate(sink, std::make_tuple(out_variable_name(param.param_name), param), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
)
{
return as_generator(
"System.IntPtr " << string << " = System.IntPtr.Zero;\n"
).generate(sink, out_variable_name(param.param_name), context);
}
else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, WANT_OUT)
)
{
return as_generator(
"System.IntPtr " << string << " = System.IntPtr.Zero;\n"
).generate(sink, out_variable_name(param.param_name), context);
}
else if (param_is_acceptable(param, "Eina_Value", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Value", !WANT_OWN, WANT_OUT))
{
return as_generator(
marshall_type << " " << string << ";\n"
).generate(sink, std::make_tuple(param.type, out_variable_name(param.param_name)), context);
}
return true;
}
} const convert_out_variable {};
struct native_convert_out_variable_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular))
{
return as_generator(
type << " " << string << " = default(" << type << ");\n"
).generate(sink, std::make_tuple(param, out_variable_name(param.param_name), param), context);
}
else if (helpers::need_struct_conversion(regular)
|| param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
{
return as_generator(
type << " " << string << " = default(" << type << ");\n"
).generate(sink, std::make_tuple(param, out_variable_name(param.param_name), param), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
)
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"Eina.Binbuf " << string << " = default(Eina.Binbuf);\n"
).generate(sink, out_variable_name(param.param_name), context);
}
else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, WANT_OUT)
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
return as_generator(
type << " " << string << " = default(" << type << ");\n"
).generate(sink, std::make_tuple(param.type, out_variable_name(param.param_name), param.type), context);
}
else if (param_is_acceptable(param, "Eina_Value", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Value", !WANT_OWN, WANT_OUT))
{
return as_generator(
string << " = default(" << marshall_type << ");\n"
<< type << " " << string << " = null;\n"
).generate(sink, std::make_tuple(param.param_name, param, param, out_variable_name(param.param_name)), context);
}
else if (param.direction == attributes::parameter_direction::out)
{
// Assign a default value to the out variable in case we end up in the catch clause.
return as_generator(
string << " = default(" << type << ");"
).generate(sink, std::make_tuple(param.param_name, param), context);
}
return true;
}
} const native_convert_out_variable {};
/* Assign the Managed out variables from the marshalled intermediate ones if needed. */
struct convert_out_assign_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(param.type, param.direction))
{
bool ret = as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
string << " = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << out_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
if (param.type.has_own)
ret = ret && as_generator(scope_tab << scope_tab << "Marshal.FreeHGlobal(" << out_variable_name(param.param_name) << ");\n"
).generate(sink, attributes::unused, context);
return ret;
}
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
string << " = " << type << "_StructConversion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
)
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
string << " = new Eina.Binbuf(" << string << ", " << (param.type.has_own ? "true" : "false") << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", !WANT_OWN, WANT_OUT)
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex || complex->subtypes.size() != 2)
return false;
return as_generator(
string << " = new " << type << "(" << string
<< ", " << (param.type.has_own ? "true" : "false")
<< ", " << (complex->subtypes.front().has_own ? "true" : "false")
<< ", " << (complex->subtypes.back().has_own ? "true" : "false")
<< ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, WANT_OUT)
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
return as_generator(
string << " = new " << type << "(" << string
<< ", " << (param.type.has_own ? "true" : "false")
<< ", " << (complex->subtypes.front().has_own ? "true" : "false")
<< ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_Value", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Value", !WANT_OWN, WANT_OUT))
{
return as_generator(
string << " = new " << type << "(" << string << ");\n"
).generate(sink, std::make_tuple(param.param_name, param.type, out_variable_name(param.param_name)), context);
}
return true;
}
} const convert_out_assign {};
struct native_convert_in_ptr_assign_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param_should_use_in_var(param, true) && param.type.is_ptr && !param.type.has_own && helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
string << " = " << type << "_StructConversion.ToInternal(" << in_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
}
return true;
}
} const native_convert_in_ptr_assign {};
struct convert_in_ptr_assign_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param_should_use_in_var(param, true) && param.type.is_ptr && !param.type.has_own && helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
string << " = " << type << "_StructConversion.ToExternal(" << in_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
}
return true;
}
} const convert_in_ptr_assign {};
struct convert_return_variable_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
if (ret_type.c_type != "void")
return as_generator("var _ret_var = ").generate(sink, attributes::unused, context);
return true;
}
} const convert_return_variable {};
/* Converts the intermediate return variable to the proper API type */
struct convert_return_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
if (ret_type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(ret_type, attributes::parameter_direction::unknown))
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"var __ret_tmp = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(_ret_var);\n"
<< scope_tab << scope_tab << (ret_type.has_own ? ("Marshal.FreeHGlobal(_ret_var);\n"): "\n")
<< scope_tab << scope_tab << "return __ret_tmp;\n"
).generate(sink, ret_type, context);
}
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
"return " << type << "_StructConversion.ToExternal(_ret_var);\n"
).generate(sink, ret_type, context);
}
else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
{
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
if (!as_generator("var _binbuf_ret = new Eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n"
<< scope_tab << scope_tab << "return _binbuf_ret;\n")
.generate(sink, attributes::unused, context))
return false;
}
else if (ret_type.c_type == "Eina_Hash *" || ret_type.c_type == "const Eina_Hash *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex || complex->subtypes.size() != 2)
return false;
if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"}
<< ", " << (complex->subtypes.front().has_own ? "true" : "false")
<< ", " << (complex->subtypes.back().has_own ? "true" : "false")
<< ");\n")
.generate(sink, ret_type, context))
return false;
}
else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *"
|| ret_type.c_type == "Eina_Inarray *" || ret_type.c_type == "const Eina_Inarray *"
|| ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *"
|| ret_type.c_type == "Eina_Inlist *" || ret_type.c_type == "const Eina_Inlist *"
|| ret_type.c_type == "Eina_Iterator *" || ret_type.c_type == "const Eina_Iterator *"
|| ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *"
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"}
<< ", " << (complex->subtypes.front().has_own ? "true" : "false")
<< ");\n")
.generate(sink, ret_type, context))
return false;
}
else if (ret_type.c_type != "void")
{
return as_generator("return _ret_var;\n").generate(sink, ret_type, context);
}
return true;
}
} const convert_return {};
// Native (virtual wrappers) generators
struct native_convert_out_assign_generator
{
attributes::klass_def const* klass;
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_convert_out_assign_generator: " << param.param_name << std::endl;
if (param.direction == attributes::parameter_direction::in)
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(param.type, param.direction))
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
string << " = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << string << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
}
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
string << " = " << type << "_StructConversion.ToInternal(" << string << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
{
if (klass == nullptr)
{
EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to assign out stringshare from native wrapper." << std::endl;
return false;
}
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
string << "= Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, " << string << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
{
if (klass == nullptr)
{
EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to assign out string from native wrapper." << std::endl;
return false;
}
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
string << "= Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, " << string << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
)
{
if (!as_generator(
string << " = " << string << ".Handle;\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context))
return false;
if (param.type.has_own)
return as_generator(
string << ".Own = false;\n"
).generate(sink, out_variable_name(param.param_name), context);
}
else if (param_is_acceptable(param, "Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Hash *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Hash *", !WANT_OWN, WANT_OUT)
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex || complex->subtypes.size() != 2)
return false;
auto outvar = out_variable_name(param.param_name);
if (!as_generator(
string << " = " << string << ".Handle;\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context))
return false;
if (param.type.has_own && !as_generator(
string << ".SetOwn(false);\n"
).generate(sink, outvar, context))
return false;
if (complex->subtypes.front().has_own && !as_generator(
string << ".SetOwnKey(false);\n"
).generate(sink, outvar, context))
return false;
if (complex->subtypes.back().has_own && !as_generator(
string << ".SetOwnValue(false);\n"
<< string << ".UnSetFreeCb();\n"
).generate(sink, std::make_tuple(outvar, outvar), context))
return false;
}
else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inarray *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Inlist *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, WANT_OUT)
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
auto outvar = out_variable_name(param.param_name);
if (!as_generator(
string << " = " << string << ".Handle;\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context))
return false;
if (param.type.has_own && !as_generator(
string << ".Own = false;\n"
).generate(sink, outvar, context))
return false;
if (complex->subtypes.front().has_own && !as_generator(
string << ".OwnContent = false;\n"
).generate(sink, outvar, context))
return false;
}
return true;
}
};
struct native_convert_return_variable_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
if (ret_type.c_type != "void")
return as_generator(
type << " _ret_var = default(" << type << ");"
).generate(sink, std::make_tuple(ret_type, ret_type), context);
return true;
}
} const native_convert_return_variable {};
struct native_convert_return_generator
{
attributes::klass_def const* klass;
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
if (ret_type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(ret_type, attributes::parameter_direction::unknown) )
{
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"return Eina.PrimitiveConversion.ManagedToPointerAlloc(_ret_var);\n"
).generate(sink, attributes::unused, context);
}
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
2018-03-22 09:17:42 -07:00
"return " << type << "_StructConversion.ToInternal(_ret_var);\n"
).generate(sink, ret_type, context);
}
else if (ret_type.c_type == "const char *")
{
if(!ret_type.has_own)
{
if (klass == nullptr)
{
EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to return string from native wrapper." << std::endl;
return false;
}
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"return Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, _ret_var);\n"
).generate(sink, attributes::unused, context);
}
else
{
return as_generator("return _ret_var;\n"
).generate(sink, attributes::unused, context);
}
}
else if (ret_type.c_type == "Eina_Stringshare *") { // Correct check for string?
if (!ret_type.has_own)
{
if (klass == nullptr)
{
EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to return stringshare from native wrapper." << std::endl;
return false;
}
return as_generator(
csharp: Change to new class API. Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
2018-11-29 15:04:37 -08:00
"return Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, _ret_var);\n"
).generate(sink, attributes::unused, context);
}
else
{
return as_generator("return _ret_var;\n")
.generate(sink, attributes::unused, context);
}
}
else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
{
if (ret_type.has_own && !as_generator("_ret_var.Own = false; ")
.generate(sink, attributes::unused, context))
return false;
return as_generator("return _ret_var.Handle;\n")
.generate(sink, attributes::unused, context);
}
else if (ret_type.c_type == "Eina_Hash *" || ret_type.c_type == "const Eina_Hash *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex || complex->subtypes.size() != 2)
return false;
if (ret_type.has_own && !as_generator("_ret_var.SetOwn(false); ")
.generate(sink, attributes::unused, context))
return false;
if (complex->subtypes.front().has_own && !as_generator("_ret_var.SetOwnKey(false); ")
.generate(sink, attributes::unused, context))
return false;
if (complex->subtypes.back().has_own && !as_generator("_ret_var.SetOwnValue(false); _ret_var.UnSetFreeCb(); ")
.generate(sink, attributes::unused, context))
return false;
return as_generator("return _ret_var.Handle;\n")
.generate(sink, attributes::unused, context);
}
else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *"
|| ret_type.c_type == "Eina_Inarray *" || ret_type.c_type == "const Eina_Inarray *"
|| ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *"
|| ret_type.c_type == "Eina_Inlist *" || ret_type.c_type == "const Eina_Inlist *"
|| ret_type.c_type == "Eina_Iterator *" || ret_type.c_type == "const Eina_Iterator *"
|| ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *"
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
if (ret_type.has_own && !as_generator("_ret_var.Own = false; ")
.generate(sink, attributes::unused, context))
return false;
if (complex->subtypes.front().has_own && !as_generator("_ret_var.OwnContent = false; ")
.generate(sink, attributes::unused, context))
return false;
return as_generator("return _ret_var.Handle;\n")
.generate(sink, attributes::unused, context);
}
else if (ret_type.c_type != "void")
return as_generator("return _ret_var;\n").generate(sink, ret_type, context);
return true;
}
};
struct native_convert_out_assign_parameterized
{
native_convert_out_assign_generator const operator()(attributes::klass_def const &klass) const
{
return {&klass};
}
} const native_convert_out_assign;
struct native_convert_return_parameterized
{
native_convert_return_generator const operator()(attributes::klass_def const &klass) const
{
return {&klass};
}
} const native_convert_return;
struct convert_function_pointer_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param.direction != attributes::parameter_direction::in)
return true;
if (!param.type.original_type.visit(is_fp_visitor{}))
return true;
std::string param_name = escape_keyword(param.param_name);
// Allocate GCHandle in "param_name"_handle for param;
if (!as_generator(
"GCHandle " << param_name << "_handle = GCHandle.Alloc(" << param_name << ");\n"
).generate(sink, attributes::unused, context))
return false;
return true;
}
} const convert_function_pointer {};
struct native_convert_function_pointer_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
if (param.direction != attributes::parameter_direction::in)
return true;
if (!param.type.original_type.visit(is_fp_visitor{}))
return true;
// Getting the type through C api
std::string type_name = param.type.original_type.visit(type_name_visitor{});
const Eolian_Typedecl *tpd = ::eolian_unit_alias_by_name_get(param.unit, type_name.c_str());
if (!tpd)
{
EINA_LOG_ERR("Failed to get typedecl for c type [%s]", param.type.c_type.c_str());
return false;
}
if (eolian_typedecl_type_get(tpd) != EOLIAN_TYPEDECL_FUNCTION_POINTER)
return true;
const Eolian_Function *fd = eolian_typedecl_function_pointer_get(tpd);
if (!fd)
{
EINA_LOG_ERR("Failed to get function pointer info for c type [%s]", param.type.c_type.c_str());
return false;
}
attributes::function_def f(fd, EOLIAN_FUNCTION_POINTER, tpd, param.unit);
std::string param_name = escape_keyword(param.param_name);
// Allocate GCHandle in "param_name"_handle for param;
if (!as_generator(
scope_tab << type << "Wrapper " << param_name << "_wrapper = new " << type << "Wrapper("
<< param_name << ", " << param_name << "_data, " << param_name << "_free_cb);\n"
).generate(sink, std::make_tuple(param.type, param.type), context))
return false;
// FIXME What about calling the free function?
return true;
}
} const native_convert_function_pointer {};
}
#endif