aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-03-21 22:39:17 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2018-04-03 17:29:41 -0300
commitbffe42e71ba12292d4969bba729e67ddf03cc111 (patch)
tree629e3f9cf0381fcdd8e2e2c97cf22eb9ea2a4985 /src
parentcsharp: Provisionally fix conversion of eina.Value (diff)
downloadefl-bffe42e71ba12292d4969bba729e67ddf03cc111.tar.gz
csharp: Support argument marshalling in func ptrs
Function pointers now go through the same argument marshalling pipeline as normal functions. This will enable interfaces like Efl.Ui.Format to work properly.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Efl_Mono.am3
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_blacklist.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_helpers.hh10
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh40
-rw-r--r--src/bin/eolian_mono/eolian/mono/generation_contexts.hh1
-rw-r--r--src/examples/elementary/efl_ui_slider_mono.cs11
-rw-r--r--src/tests/efl_mono/FunctionPointerMarshalling.cs31
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c7
-rw-r--r--src/tests/efl_mono/test_testing.eo14
9 files changed, 99 insertions, 19 deletions
diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index beb287ce3f..45928f977a 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -429,6 +429,7 @@ TESTS += tests/efl_mono/mono_test_driver.sh
tests_efl_mono_efl_mono_SOURCES = \
tests/efl_mono/Main.cs \
+ tests/efl_mono/TestUtils.cs \
tests/efl_mono/BasicDirection.cs \
tests/efl_mono/Eina.cs \
tests/efl_mono/Eldbus.cs \
@@ -437,11 +438,11 @@ tests_efl_mono_efl_mono_SOURCES = \
tests/efl_mono/Evas.cs \
tests/efl_mono/Events.cs \
tests/efl_mono/FunctionPointers.cs \
+ tests/efl_mono/FunctionPointerMarshalling.cs \
tests/efl_mono/Parts.cs \
tests/efl_mono/Strbuf.cs \
tests/efl_mono/Strings.cs \
tests/efl_mono/Structs.cs \
- tests/efl_mono/TestUtils.cs \
tests/efl_mono/Value.cs \
tests/efl_mono/ValueEolian.cs
diff --git a/src/bin/eolian_mono/eolian/mono/function_blacklist.hh b/src/bin/eolian_mono/eolian/mono/function_blacklist.hh
index b2d712c6ac..f3ec3011d5 100644
--- a/src/bin/eolian_mono/eolian/mono/function_blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_blacklist.hh
@@ -27,7 +27,6 @@ inline bool is_function_blacklisted(std::string const& c_name)
|| c_name == "efl_ui_focus_user_parent_get"
|| c_name == "efl_canvas_object_scale_get" // duplicated signature
|| c_name == "efl_canvas_object_scale_set" // duplicated signature
- || c_name == "efl_ui_format_cb_set"
|| c_name == "efl_access_parent_get"
|| c_name == "efl_access_name_get"
|| c_name == "efl_access_name_set"
diff --git a/src/bin/eolian_mono/eolian/mono/function_helpers.hh b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
index 2b8c912d44..acfe850032 100644
--- a/src/bin/eolian_mono/eolian/mono/function_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
@@ -10,13 +10,7 @@
#include "grammar/list.hpp"
#include "grammar/alternative.hpp"
#include "grammar/attribute_reorder.hpp"
-/* #include "type.hh" */
-/* #include "marshall_type.hh" */
#include "parameter.hh"
-#include "function_pointer.hh"
-/* #include "keyword.hh" */
-/* #include "using_decl.hh" */
-/* #include "generation_contexts.hh" */
namespace eolian_mono {
@@ -164,6 +158,10 @@ struct native_function_definition_epilogue_parameterized
{
return {&klass};
}
+ native_function_definition_epilogue_generator const operator()(attributes::klass_def const* klass=nullptr) const
+ {
+ return {klass};
+ }
} const native_function_definition_epilogue;
struct function_definition_epilogue_terminal
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index 0890edcb51..2c0c193c33 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -6,7 +6,9 @@
#include <vector>
#include <string>
+#include "function_helpers.hh"
#include "documentation.hh"
+#include "generation_contexts.hh"
namespace eolian_mono {
@@ -21,7 +23,7 @@ static bool is_function_ptr_blacklisted(attributes::function_def const& func, st
std::string name = full_name.str();
- return name == "Efl.Ui.Format_Func_Cb";
+ return false;
}
struct function_pointer {
@@ -30,23 +32,29 @@ struct function_pointer {
{
// FIXME export Typedecl in eolian_cxx API
std::vector<std::string> namespaces = escape_namespace(namesp);
+ auto funcptr_ctx = context_add_tag(class_context{class_context::function_ptr}, context);
+
+ std::string return_type;
+ if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
+ return false;
if (is_function_ptr_blacklisted(f, namesp))
return true;
auto open_namespace = *("namespace " << string << " {") << "\n";
- if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(context))) return false;
+ if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(funcptr_ctx))) return false;
// C# visible delegate
if (!as_generator(documentation
<< "public delegate " << type << " " << string
<< "(" << (parameter % ", ") << ");\n")
- .generate(sink, std::make_tuple(f, f.return_type, escape_keyword(f.name), f.parameters), context))
+ .generate(sink, std::make_tuple(f, f.return_type, escape_keyword(f.name), f.parameters), funcptr_ctx))
return false;
// "Internal" delegate, 1-to-1 with the Unamaged function type
- if (!as_generator("internal delegate " << type << " " << string // public?
- << "Internal(IntPtr data, " << (parameter % ", ") << ");\n")
- .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context))
+ if (!as_generator(marshall_native_annotation(true)
+ << "internal delegate " << marshall_type(true) << " " << string // public?
+ << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ");\n")
+ .generate(sink, std::make_tuple(f.return_type, f.return_type, escape_keyword(f.name), f.parameters), funcptr_ctx))
return false;
std::string f_name = escape_keyword(f.name);
@@ -72,21 +80,31 @@ struct function_pointer {
<< scope_tab << "internal " << type << " ManagedCb(" << (parameter % ",") << ")\n"
<< scope_tab << "{\n"
- << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation_no_conversion % ", ") << ");\n"
+ << function_definition_preamble << "_cb(_cb_data, " << (argument_invocation % ", ") << ");\n"
+ << function_definition_epilogue
<< scope_tab << "}\n\n"
- << scope_tab << "internal static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n"
+
+ << scope_tab << marshall_native_annotation(true)
+ << scope_tab << "internal static " << marshall_type(true) << " Cb(IntPtr cb_data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ")\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
<< scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n"
- << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation_no_conversion % ", ") << ");\n"
+ << native_function_definition_preamble
+ << scope_tab << scope_tab << "try {\n"
+ << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "cb(" << (native_argument_invocation % ", ") << ");\n"
+ << scope_tab << scope_tab << "} catch (Exception e) {\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Log.Warning($\"Callback error: {e.ToString()}\");\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
+ << scope_tab << scope_tab << "}\n"
+ << native_function_definition_epilogue(nullptr)
<< scope_tab << "}\n"
<< "}\n"
- ).generate(sink, std::make_tuple(f.return_type, f.parameters, f.parameters, f.return_type, f.parameters, f_name, f_name, f.parameters), context))
+ ).generate(sink, std::make_tuple(f.return_type, f.parameters, f, f.parameters, f, f.return_type, f.return_type, f.parameters, f_name, f_name, f, f.parameters, f), funcptr_ctx))
return false;
auto close_namespace = *(lit("} ")) << "\n";
- if(!as_generator(close_namespace).generate(sink, namespaces, context)) return false;
+ if(!as_generator(close_namespace).generate(sink, namespaces, funcptr_ctx)) return false;
return true;
}
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index 8563afcb12..d7e31ddae2 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -11,6 +11,7 @@ struct class_context
inherit,
inherit_native,
structs,
+ function_ptr,
};
wrapper_kind current_wrapper_kind;
};
diff --git a/src/examples/elementary/efl_ui_slider_mono.cs b/src/examples/elementary/efl_ui_slider_mono.cs
index d458104cc9..64c31ab921 100644
--- a/src/examples/elementary/efl_ui_slider_mono.cs
+++ b/src/examples/elementary/efl_ui_slider_mono.cs
@@ -15,6 +15,16 @@ public class Example
return button;
}
+ public static void Formatter(eina.Strbuf buf, eina.Value val){
+ double ratio;
+ if (val.Get(out ratio)) {
+ buf.Append($"{(int)(ratio*100)}%");
+ } else {
+ buf.Append("Error");
+ }
+ }
+
+
#if WIN32 // Passed to the C# compiler with -define:WIN32
// Mono on Windows by default uses multi-thread apartments for COM stuff while
// OLE - used by ecore win32 DnD requires single threading for COM.
@@ -41,6 +51,7 @@ public class Example
efl.ui.Progressbar bar = new efl.ui.ProgressbarConcrete(box);
bar.SetSize(new eina.Size2D(W, H));
+ bar.SetFormatCb(Formatter);
efl.ui.Slider slider = new efl.ui.SliderConcrete(box);
slider.SetSize(new eina.Size2D(W, H));
diff --git a/src/tests/efl_mono/FunctionPointerMarshalling.cs b/src/tests/efl_mono/FunctionPointerMarshalling.cs
new file mode 100644
index 0000000000..e7627a87f1
--- /dev/null
+++ b/src/tests/efl_mono/FunctionPointerMarshalling.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace TestSuite
+{
+
+class TestFunctionPointerMarshalling
+{
+ public static void func_pointer_marshalling()
+ {
+ test.Testing obj = new test.TestingConcrete();
+ bool called = false;
+ eina.Strbuf buf = new eina.Strbuf();
+ string argument = "Some String";
+ eina.Value v = new eina.Value(eina.ValueType.String);
+ v.Set(argument);
+ string reference = new string(argument.ToCharArray().Reverse().ToArray());
+
+ obj.CallFormatCb(buf, v, (eina.Strbuf ibuf, eina.Value val) => {
+ called = true;
+ string str = null;
+ val.Get(out str);
+ buf.Append(new string(str.ToCharArray().Reverse().ToArray()));
+ });
+
+ Test.Assert(called, "Callback was not called");
+ Test.AssertEquals(reference, buf.Steal());
+ }
+}
+}
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c
index f16c8957c3..fff2173ae8 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -3756,6 +3756,13 @@ void _test_testing_call_append_to_strbuf(Eo * obj, EINA_UNUSED Test_Testing_Data
test_testing_append_to_strbuf(obj, buf, str);
}
+void _test_testing_call_format_cb(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Eina_Strbuf *buf, const Eina_Value value,
+ void *func_data, Test_FormatCb func, Eina_Free_Cb func_free_cb)
+{
+ func(func_data, buf, value);
+ func_free_cb(func_data);
+}
+
#include "test_testing.eo.c"
#include "test_numberwrapper.eo.c"
diff --git a/src/tests/efl_mono/test_testing.eo b/src/tests/efl_mono/test_testing.eo
index 5d1e7aa503..9a9aa0f2d1 100644
--- a/src/tests/efl_mono/test_testing.eo
+++ b/src/tests/efl_mono/test_testing.eo
@@ -81,6 +81,13 @@ function Test.SimpleCb {
return: int;
};
+function Test.FormatCb {
+ params {
+ @in str: strbuf;
+ @in value: const(any_value);
+ }
+};
+
class Test.Testing (Efl.Object, Efl.Part) {
parts {
@@ -1569,6 +1576,13 @@ class Test.Testing (Efl.Object, Efl.Part) {
}
}
+ call_format_cb {
+ params {
+ @in str: strbuf;
+ @in value: const(any_value);
+ @in func: Test.FormatCb;
+ }
+ }
}
implements {
class.constructor;