csharp: Add support for efl parts as Properties
Instead of var bg = efl.ui.Background.static_cast(myobj.Part("background")); Now do var bg = myobj.Background; Also a couple helper functions were added.
This commit is contained in:
parent
9a6dd32cb1
commit
f9586a831b
|
@ -78,6 +78,7 @@ bin_eolian_mono_eolian_mono_SOURCES = \
|
|||
bin/eolian_mono/eolian/mono/function_registration.hh \
|
||||
bin/eolian_mono/eolian/mono/enum_definition.hh \
|
||||
bin/eolian_mono/eolian/mono/struct_definition.hh \
|
||||
bin/eolian_mono/eolian/mono/part_definition.hh \
|
||||
bin/eolian_mono/eolian/mono/struct_fields.hh \
|
||||
bin/eolian_mono/eolian/mono/parameter.hh \
|
||||
bin/eolian_mono/eolian/mono/utils.hh \
|
||||
|
@ -424,6 +425,7 @@ tests_efl_mono_efl_mono_SOURCES = \
|
|||
tests/efl_mono/Evas.cs \
|
||||
tests/efl_mono/Events.cs \
|
||||
tests/efl_mono/FunctionPointers.cs \
|
||||
tests/efl_mono/Parts.cs \
|
||||
tests/efl_mono/Strings.cs \
|
||||
tests/efl_mono/Structs.cs \
|
||||
tests/efl_mono/TestUtils.cs \
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
#define EOLIAN_MONO_HELPERS_HH
|
||||
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "utils.hh"
|
||||
|
||||
/* General helper functions for the main generators.
|
||||
*
|
||||
* These range from blacklisting structures to 'nano-generators' (functions that receive
|
||||
* a binding-specifict structure and returns a string).
|
||||
*/
|
||||
|
||||
namespace eolian_mono {
|
||||
|
||||
|
@ -102,9 +109,19 @@ inline bool need_pointer_conversion(attributes::regular_type_def const* regular)
|
|||
|
||||
inline std::string to_field_name(std::string const& in)
|
||||
{
|
||||
std::string field_name = in;
|
||||
field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
|
||||
return field_name;
|
||||
return utils::capitalize(in);
|
||||
}
|
||||
|
||||
inline std::string klass_name_to_csharp(attributes::klass_name const& clsname)
|
||||
{
|
||||
std::ostringstream output;
|
||||
|
||||
for (auto namesp : clsname.namespaces)
|
||||
output << utils::to_lowercase(namesp) << ".";
|
||||
|
||||
output << clsname.eolian_name;
|
||||
|
||||
return output.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "function_registration.hh"
|
||||
#include "function_declaration.hh"
|
||||
#include "documentation.hh"
|
||||
#include "part_definition.hh"
|
||||
#include "grammar/string.hpp"
|
||||
#include "grammar/attribute_replace.hpp"
|
||||
#include "grammar/integral.hpp"
|
||||
|
@ -239,6 +240,10 @@ struct klass
|
|||
return false;
|
||||
}
|
||||
|
||||
for (auto &&p : cls.parts)
|
||||
if (!as_generator( klass_name_to_csharp(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n").generate(sink, attributes::unused, iface_cxt))
|
||||
return false;
|
||||
|
||||
// End of interface declaration
|
||||
if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) return false;
|
||||
}
|
||||
|
@ -331,6 +336,10 @@ struct klass
|
|||
if (!generate_events_registration(sink, cls, concrete_cxt))
|
||||
return false;
|
||||
|
||||
// Parts
|
||||
if(!as_generator(*(part_definition))
|
||||
.generate(sink, cls.get_all_parts(), concrete_cxt)) return false;
|
||||
|
||||
// Concrete function definitions
|
||||
if(!as_generator(*(function_definition))
|
||||
.generate(sink, methods, concrete_cxt)) return false;
|
||||
|
@ -431,6 +440,10 @@ struct klass
|
|||
if (!generate_events_registration(sink, cls, inherit_cxt))
|
||||
return false;
|
||||
|
||||
// Parts
|
||||
if(!as_generator(*(part_definition))
|
||||
.generate(sink, cls.get_all_parts(), inherit_cxt)) return false;
|
||||
|
||||
// Inherit function definitions
|
||||
if(!as_generator(*(function_definition(true)))
|
||||
.generate(sink, methods, inherit_cxt)) return false;
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef EOLIAN_MONO_PART_DEFINITION_HH
|
||||
#define EOLIAN_MONO_PART_DEFINITION_HH
|
||||
|
||||
#include <Eina.hh>
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/indentation.hpp"
|
||||
|
||||
#include "utils.hh"
|
||||
#include "documentation.hh"
|
||||
|
||||
namespace eolian_mono {
|
||||
|
||||
struct part_definition_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::part_def const& part, Context const& context) const
|
||||
{
|
||||
std::string part_klass_name = klass_name_to_csharp(part.klass);
|
||||
return as_generator(scope_tab << documentation
|
||||
<< scope_tab << "public " << part_klass_name << " " << utils::capitalize(part.name) << "\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "get\n"
|
||||
<< scope_tab << scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "efl.Object obj = efl_part(raw_handle, \"" << part.name << "\");\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "return " << part_klass_name << "Concrete.static_cast(obj);\n"
|
||||
<< scope_tab << scope_tab << "}\n"
|
||||
<< scope_tab << "}\n"
|
||||
).generate(sink, part.documentation, context);
|
||||
}
|
||||
|
||||
} const part_definition {};
|
||||
|
||||
}
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <>
|
||||
struct is_eager_generator< ::eolian_mono::part_definition_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_generator< ::eolian_mono::part_definition_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed< ::eolian_mono::part_definition_generator> : std::integral_constant<int, 1> {};
|
||||
|
||||
}
|
||||
} } }
|
||||
|
||||
#endif
|
||||
|
|
@ -4,19 +4,28 @@
|
|||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
/* Compared to the helpers.hh header, these functions are lower level, not dealing with
|
||||
* binding-specific structures or knowledge */
|
||||
|
||||
namespace eolian_mono { namespace utils {
|
||||
|
||||
// Helper method to avoid multiple as_generator calls when mixing case strings
|
||||
std::string to_uppercase(std::string s)
|
||||
inline std::string to_uppercase(std::string s)
|
||||
{
|
||||
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
|
||||
return s;
|
||||
}
|
||||
std::string to_lowercase(std::string s)
|
||||
inline std::string to_lowercase(std::string s)
|
||||
{
|
||||
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
|
||||
return s;
|
||||
}
|
||||
inline std::string capitalize(std::string const &s)
|
||||
{
|
||||
std::string ret = s;
|
||||
ret[0] = std::toupper(ret[0]);
|
||||
return ret;
|
||||
}
|
||||
} }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#define CODE_ANALYSIS
|
||||
|
||||
#pragma warning disable 1591
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace TestSuite {
|
||||
|
||||
|
||||
[SuppressMessage("Gendarme.Rules.Portability", "DoNotHardcodePathsRule")]
|
||||
public static class TestParts
|
||||
{
|
||||
public static void basic_part_test()
|
||||
{
|
||||
test.Testing t = new test.TestingConcrete();
|
||||
do_part_test(t);
|
||||
}
|
||||
|
||||
private class Child : test.TestingInherit
|
||||
{
|
||||
public Child() : base(null) {}
|
||||
}
|
||||
|
||||
public static void inherited_part_test() {
|
||||
var t = new Child();
|
||||
do_part_test(t);
|
||||
}
|
||||
|
||||
private static void do_part_test(test.Testing t)
|
||||
{
|
||||
var p1 = t.Part1;
|
||||
var p2 = t.Part2;
|
||||
Test.Assert(p1 is test.Testing);
|
||||
Test.AssertEquals("part1", p1.GetName());
|
||||
Test.Assert(p2 is test.Testing);
|
||||
Test.AssertEquals("part2", p2.GetName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -34,6 +34,8 @@
|
|||
#include "test_numberwrapper.eo.h"
|
||||
#include "test_testing.eo.h"
|
||||
|
||||
#include <interfaces/efl_part.eo.h>
|
||||
|
||||
#define EQUAL(a, b) ((a) == (b) ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s)", __FILE__, __LINE__, __FUNCTION__), fflush(stderr), 0))
|
||||
#define STR_EQUAL(a, b) (strcmp((a), (b)) == 0 ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s) '%s' != '%s'", __FILE__, __LINE__, __FUNCTION__, (a), (b)), fflush(stderr), 0))
|
||||
|
||||
|
@ -46,6 +48,8 @@ typedef struct Test_Testing_Data
|
|||
Eina_Value *stored_value;
|
||||
Test_StructSimple stored_struct;
|
||||
int stored_int;
|
||||
Eo *part1;
|
||||
Eo *part2;
|
||||
} Test_Testing_Data;
|
||||
|
||||
typedef struct Test_Numberwrapper_Data
|
||||
|
@ -3714,6 +3718,28 @@ void _test_testing_emit_event_with_obj(Eo *obj, EINA_UNUSED Test_Testing_Data *p
|
|||
efl_event_callback_legacy_call(obj, TEST_TESTING_EVENT_EVT_WITH_OBJ, data);
|
||||
}
|
||||
|
||||
Efl_Object *_test_testing_efl_part_part(const Eo *obj, Test_Testing_Data *pd, const char *name)
|
||||
{
|
||||
if (!strcmp(name, "part1"))
|
||||
{
|
||||
if (pd->part1 == NULL)
|
||||
{
|
||||
pd->part1 = efl_add(TEST_TESTING_CLASS, obj, efl_name_set(efl_added, "part1"));
|
||||
}
|
||||
return pd->part1;
|
||||
}
|
||||
else if (!strcmp(name, "part2"))
|
||||
{
|
||||
if (pd->part2 == NULL)
|
||||
{
|
||||
pd->part2 = efl_add(TEST_TESTING_CLASS, obj, efl_name_set(efl_added, "part2"));
|
||||
}
|
||||
return pd->part2;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include "test_testing.eo.c"
|
||||
#include "test_numberwrapper.eo.c"
|
||||
|
||||
|
|
|
@ -81,7 +81,12 @@ function Test.SimpleCb {
|
|||
return: int;
|
||||
};
|
||||
|
||||
class Test.Testing (Efl.Object) {
|
||||
class Test.Testing (Efl.Object, Efl.Part) {
|
||||
|
||||
parts {
|
||||
part1: Test.Testing; [[ Part number one. ]]
|
||||
part2: Test.Testing; [[ Part number two. ]]
|
||||
}
|
||||
methods {
|
||||
return_object {
|
||||
return: Test.Testing;
|
||||
|
@ -1547,6 +1552,7 @@ class Test.Testing (Efl.Object) {
|
|||
implements {
|
||||
class.constructor;
|
||||
class.destructor;
|
||||
Efl.Part.part;
|
||||
}
|
||||
events {
|
||||
evt,with,string @hot: string;
|
||||
|
|
Loading…
Reference in New Issue