summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono/eolian/mono/function_pointer.hh
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2017-11-23 21:50:16 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2017-12-04 15:47:50 -0300
commitd93e9ff286ce1961f530d56b5536881f47104ebd (patch)
treed9fd8cd25a64b9ab6b23ae34b92c342dc8e6b543 /src/bin/eolian_mono/eolian/mono/function_pointer.hh
parent9391407319424c503a78479b407737ccead945b7 (diff)
eolian_mono: Added code for eolian_mono generator
Based on the eolian_cxx library generators. Buildsystem files will come in a future commmit.
Diffstat (limited to 'src/bin/eolian_mono/eolian/mono/function_pointer.hh')
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
new file mode 100644
index 0000000000..84fdb79881
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -0,0 +1,95 @@
1#ifndef EOLIAN_MONO_FUNCTION_POINTER_HPP
2#define EOLIAN_MONO_FUNCTION_POINTER_HPP
3
4#include <Eolian.h>
5
6#include <vector>
7#include <string>
8
9namespace eolian_mono {
10
11// Blacklist structs that require some kind of manual binding.
12static bool is_function_ptr_blacklisted(attributes::function_def const& func, std::vector<std::string> const &namesp)
13{
14 std::stringstream full_name;
15
16 for (auto&& i : namesp)
17 full_name << i << ".";
18 full_name << func.name;
19
20 std::string name = full_name.str();
21
22 return name == "Efl.Ui.Format_Func_Cb";
23}
24
25struct function_pointer {
26 template <typename OutputIterator, typename Context>
27 bool generate(OutputIterator sink, attributes::function_def const& f, std::vector<std::string> const &namesp, Context const& context) const
28 {
29 // FIXME export Typedecl in eolian_cxx API
30 std::vector<std::string> namespaces = escape_namespace(namesp);
31
32 if (is_function_ptr_blacklisted(f, namesp))
33 return true;
34
35 auto open_namespace = *("namespace " << string << " {") << "\n";
36 if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(context))) return false;
37
38 // C# visible delegate
39 if (!as_generator("public delegate " << type << " " << string
40 << "(" << (parameter % ", ") << ");\n")
41 .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context))
42 return false;
43 // "Internal" delegate, 1-to-1 with the Unamaged function type
44 if (!as_generator("public delegate " << type << " " << string // public?
45 << "Internal(IntPtr data, " << (parameter % ", ") << ");\n")
46 .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context))
47 return false;
48
49 std::string f_name = escape_keyword(f.name);
50 // Wrapper type, with callback matching the Unamanaged one
51 if (!as_generator("public class " << f_name << "Wrapper\n"
52 << "{\n\n"
53 << scope_tab << "private " << f_name << "Internal _cb;\n"
54 << scope_tab << "private IntPtr _cb_data;\n"
55 << scope_tab << "private Eina_Free_Cb _cb_free_cb;\n\n"
56
57 << scope_tab << "public " << f_name << "Wrapper (" << f_name << "Internal _cb, IntPtr _cb_data, Eina_Free_Cb _cb_free_cb)\n"
58 << scope_tab << "{\n"
59 << scope_tab << scope_tab << "this._cb = _cb;\n"
60 << scope_tab << scope_tab << "this._cb_data = _cb_data;\n"
61 << scope_tab << scope_tab << "this._cb_free_cb = _cb_free_cb;\n"
62 << scope_tab << "}\n\n"
63
64 << scope_tab << "~" << f_name << "Wrapper()\n"
65 << scope_tab << "{\n"
66 << scope_tab << scope_tab << "if (this._cb_free_cb != null)\n"
67 << scope_tab << scope_tab << scope_tab << "this._cb_free_cb(this._cb_data);\n"
68 << scope_tab << "}\n\n"
69
70 << scope_tab << "public " << type << " ManagedCb(" << (parameter % ",") << ")\n"
71 << scope_tab << "{\n"
72 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation % ", ") << ");\n"
73 << scope_tab << "}\n\n"
74
75 << scope_tab << "public static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n"
76 << scope_tab << "{\n"
77 << scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
78 << scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n"
79 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation % ", ") << ");\n"
80 << scope_tab << "}\n"
81 << "}\n"
82 ).generate(sink, std::make_tuple(f.return_type, f.parameters, f.parameters, f.return_type, f.parameters, f_name, f_name, f.parameters), context))
83 return false;
84
85 auto close_namespace = *(lit("} ")) << "\n";
86 if(!as_generator(close_namespace).generate(sink, namespaces, context)) return false;
87
88 return true;
89 }
90};
91
92struct function_pointer const function_pointer = {};
93}
94
95#endif