forked from enlightenment/efl
csharp: Make classes abstract and rework casting
Summary: Abstract Eo classes are now proper C# abstract classes. As a side effect, returning Eo instances from native code was reworked to return instances of their actual Eo classes instead of previous behavior of returning a generic Efl.Object and using static_cast. Instead of `var window = Efl.Ui.Win.static_cast(widget.GetParent());` Use `var window = widget.GetParent() as Efl.Ui.Win;` Another side effect was that `efl_constructor` was removed from the list of supported `Efl.Object` overrides. It is invoked inside `efl_add_internal_start`, before the bindings makes the association of the newly created EoId with the C# instance that created it, making the managed delegate meaningless. C# users then can use regular C# constructors to initialize fields. Also changed to set the private data of C#-inherited classes before the call to constructing methods (aka constructor parameters) so C# classes can override them correctly. Fixes T7778 Fixes T7757 Reviewers: vitor.sousa, felipealmeida, segfaultxavi Reviewed By: vitor.sousa, segfaultxavi Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7778, T7757, T7702 Differential Revision: https://phab.enlightenment.org/D8550
This commit is contained in:
parent
4edf8036e0
commit
1e22db1150
|
@ -16,6 +16,7 @@ inline bool is_function_blacklisted(std::string const& c_name)
|
|||
{
|
||||
return
|
||||
c_name == "efl_event_callback_array_priority_add"
|
||||
|| c_name == "efl_constructor"
|
||||
|| c_name == "efl_player_position_get"
|
||||
|| c_name == "efl_ui_widget_focus_set"
|
||||
|| c_name == "efl_ui_widget_focus_get"
|
||||
|
|
|
@ -73,7 +73,7 @@ struct unpack_event_args_visitor
|
|||
}
|
||||
bool operator()(grammar::attributes::klass_name const& cls) const
|
||||
{
|
||||
return as_generator("new " + name_helpers::klass_full_concrete_name(cls) + "(evt.Info)").generate(sink, attributes::unused, *context);
|
||||
return as_generator("(Efl.Eo.Globals.CreateWrapperFor(evt.Info) as " + name_helpers::klass_full_concrete_name(cls) + ")").generate(sink, attributes::unused, *context);
|
||||
}
|
||||
bool operator()(attributes::complex_type_def const&) const
|
||||
{
|
||||
|
|
|
@ -103,7 +103,7 @@ struct native_function_definition_generator
|
|||
/****/
|
||||
<< scope_tab << scope_tab << "Eina.Log.Debug(\"function " << string << " was called\");\n"
|
||||
/****/
|
||||
<< scope_tab << scope_tab << "Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.data_get(pd);\n"
|
||||
<< scope_tab << scope_tab << "Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.PrivateDataGet(pd);\n"
|
||||
<< scope_tab << scope_tab << "if(wrapper != null) {\n"
|
||||
<< scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble()
|
||||
<< scope_tab << scope_tab << scope_tab << "try {\n"
|
||||
|
|
|
@ -31,20 +31,6 @@
|
|||
|
||||
namespace eolian_mono {
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
static bool generate_static_cast_method(OutputIterator sink, grammar::attributes::klass_def const& cls, Context const &context)
|
||||
{
|
||||
return as_generator(
|
||||
scope_tab << "///<summary>Casts obj into an instance of this type.</summary>\n"
|
||||
<< scope_tab << "public " << (helpers::has_regular_ancestor(cls) ? "new " : "") <<"static " << name_helpers::klass_concrete_name(cls) << " static_cast(Efl.Object obj)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "if (obj == null)\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "throw new System.ArgumentNullException(\"obj\");\n"
|
||||
<< scope_tab << scope_tab << "return new " << name_helpers::klass_concrete_name(cls) << "(obj.NativeHandle);\n"
|
||||
<< scope_tab << "}\n"
|
||||
).generate(sink, nullptr, context);
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
static bool generate_equals_method(OutputIterator sink, Context const &context)
|
||||
{
|
||||
|
@ -110,7 +96,7 @@ struct klass
|
|||
suffix = "CLASS";
|
||||
break;
|
||||
case attributes::class_type::abstract_:
|
||||
class_type = "class";
|
||||
class_type = "abstract class";
|
||||
suffix = "CLASS";
|
||||
break;
|
||||
case attributes::class_type::mixin:
|
||||
|
@ -207,7 +193,7 @@ struct klass
|
|||
});
|
||||
|
||||
// Concrete class for interfaces, mixins, etc.
|
||||
if(class_type != "class")
|
||||
if(class_type != "class" && class_type != "abstract class")
|
||||
{
|
||||
auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context);
|
||||
auto concrete_name = name_helpers::klass_concrete_name(cls);
|
||||
|
@ -234,7 +220,7 @@ struct klass
|
|||
<< ")] internal static extern System.IntPtr\n"
|
||||
<< scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
|
||||
<< scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
|
||||
<< scope_tab << "public " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
|
||||
<< scope_tab << "private " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
|
||||
<< scope_tab << scope_tab << "RegisterEventProxies();\n"
|
||||
|
@ -246,9 +232,6 @@ struct klass
|
|||
if (!generate_dispose_methods(sink, cls, concrete_cxt))
|
||||
return false;
|
||||
|
||||
if (!generate_static_cast_method(sink, cls, concrete_cxt))
|
||||
return false;
|
||||
|
||||
if (!generate_equals_method(sink, concrete_cxt))
|
||||
return false;
|
||||
|
||||
|
@ -296,7 +279,7 @@ struct klass
|
|||
}
|
||||
|
||||
// Inheritable class
|
||||
if(class_type == "class")
|
||||
if(class_type == "class" || class_type == "abstract class")
|
||||
{
|
||||
auto inherit_cxt = context_add_tag(class_context{class_context::inherit}, context);
|
||||
|
||||
|
@ -327,9 +310,6 @@ struct klass
|
|||
if (!generate_dispose_methods(sink, cls, inherit_cxt))
|
||||
return false;
|
||||
|
||||
if (!generate_static_cast_method(sink, cls, inherit_cxt))
|
||||
return false;
|
||||
|
||||
if (!generate_equals_method(sink, inherit_cxt))
|
||||
return false;
|
||||
|
||||
|
@ -430,7 +410,7 @@ struct klass
|
|||
<< scope_tab << "}\n"
|
||||
).generate(sink, attributes::unused, inative_cxt))
|
||||
return false;
|
||||
|
||||
|
||||
// Native method definitions
|
||||
if(!as_generator(*(native_function_definition(cls)))
|
||||
.generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false;
|
||||
|
@ -534,7 +514,7 @@ struct klass
|
|||
<< scope_tab << scope_tab << "FinishInstantiation();\n"
|
||||
<< scope_tab << "}\n"
|
||||
<< scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
|
||||
<< scope_tab << "public " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
|
||||
<< scope_tab << "protected " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
|
||||
<< scope_tab << scope_tab << "RegisterEventProxies();\n"
|
||||
|
@ -542,6 +522,23 @@ struct klass
|
|||
).generate(sink, std::make_tuple(constructors, constructors, constructors), context))
|
||||
return false;
|
||||
|
||||
// Some abstract classes (like Efl.App) have a simple regular class that is used to instantiate them
|
||||
// in a controlled manner. These fake-private classes can be returned from C and we use a similarly-named
|
||||
// private class to be able to instantiate them when they get to the C# world.
|
||||
if (cls.type == attributes::class_type::abstract_)
|
||||
{
|
||||
if (!as_generator(
|
||||
scope_tab << "[Efl.Eo.PrivateNativeClass]\n"
|
||||
<< scope_tab << "private class " << inherit_name << "Realized : " << inherit_name << "\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "private " << inherit_name << "Realized(IntPtr ptr) : base(ptr)\n"
|
||||
<< scope_tab << scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "}\n"
|
||||
<< scope_tab << "}\n"
|
||||
).generate(sink, attributes::unused, context))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Internal constructors
|
||||
if (!root)
|
||||
{
|
||||
|
@ -564,13 +561,14 @@ struct klass
|
|||
<< scope_tab << scope_tab << "}\n"
|
||||
<< scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n"
|
||||
<< scope_tab << scope_tab << "RegisterEventProxies();\n"
|
||||
<< scope_tab << scope_tab << "if (inherited)\n"
|
||||
<< scope_tab << scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.PrivateDataSet(this);\n"
|
||||
<< scope_tab << scope_tab << "}\n"
|
||||
<< scope_tab << "}\n"
|
||||
|
||||
<< scope_tab << "protected void FinishInstantiation()\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "if (inherited) {\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.data_set(this);\n"
|
||||
<< scope_tab << scope_tab << "}\n"
|
||||
<< scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_end(handle);\n"
|
||||
<< scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n"
|
||||
<< scope_tab << "}\n"
|
||||
|
|
|
@ -27,8 +27,7 @@ struct part_definition_generator
|
|||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "get\n"
|
||||
<< scope_tab << scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.IPartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n"
|
||||
<< scope_tab << scope_tab << scope_tab << "return Efl.IPartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\") as " << part_klass_name << ";\n"
|
||||
<< scope_tab << scope_tab << "}\n"
|
||||
<< scope_tab << "}\n"
|
||||
).generate(sink, part.documentation, context);
|
||||
|
|
|
@ -159,10 +159,8 @@ struct to_external_field_convert_generator
|
|||
if (!as_generator(
|
||||
"\n"
|
||||
<< indent << scope_tab << scope_tab << "_external_struct." << string
|
||||
<< " = (" << concrete_name << ") System.Activator.CreateInstance(typeof("
|
||||
<< concrete_name << "), new System.Object[] {_internal_struct." << string << "});\n"
|
||||
<< indent << scope_tab << scope_tab << "Efl.Eo.Globals.efl_ref(_internal_struct." << string << ");\n")
|
||||
.generate(sink, std::make_tuple(field_name, field_name, field_name), context))
|
||||
<< " = (" << concrete_name << ") Efl.Eo.Globals.CreateWrapperFor(_internal_struct." << string << ");\n"
|
||||
).generate(sink, std::make_tuple(field_name, field_name), context))
|
||||
return false;
|
||||
}
|
||||
else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
|
||||
|
|
|
@ -4,6 +4,7 @@ using System;
|
|||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using Eina.Callbacks;
|
||||
using static Eina.HashNativeFunctions;
|
||||
|
@ -196,13 +197,6 @@ public class StringElementTraits : IBaseElementTraits<string>
|
|||
|
||||
public class EflObjectElementTraits<T> : IBaseElementTraits<T>
|
||||
{
|
||||
private System.Type concreteType = null;
|
||||
|
||||
public EflObjectElementTraits(System.Type concrete)
|
||||
{
|
||||
concreteType = concrete;
|
||||
}
|
||||
|
||||
public IntPtr ManagedToNativeAlloc(T man)
|
||||
{
|
||||
IntPtr h = ((Efl.Eo.IWrapper)man).NativeHandle;
|
||||
|
@ -290,7 +284,7 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
|
|||
return default(T);
|
||||
}
|
||||
|
||||
return (T)Activator.CreateInstance(concreteType, Efl.Eo.Globals.efl_ref(nat));
|
||||
return (T) Efl.Eo.Globals.CreateWrapperFor(nat, shouldIncRef: true);
|
||||
}
|
||||
|
||||
public T NativeToManagedRef(IntPtr nat)
|
||||
|
@ -762,7 +756,9 @@ public static class TraitFunctions
|
|||
throw new Exception("Failed to get a suitable concrete class for this type.");
|
||||
}
|
||||
|
||||
traits = new EflObjectElementTraits<T>(concrete);
|
||||
// No need to pass concrete as the traits class will use reflection to get the actually most
|
||||
// derived type returned.
|
||||
traits = new EflObjectElementTraits<T>();
|
||||
}
|
||||
else if (IsString(type))
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ using System;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
using static Eina.NativeCustomExportFunctions;
|
||||
|
@ -289,7 +290,7 @@ public class Globals
|
|||
return ifaces_lst;
|
||||
}
|
||||
|
||||
private static Efl.Eo.NativeClass get_native_class(System.Type type)
|
||||
private static Efl.Eo.NativeClass GetNativeClass(System.Type type)
|
||||
{
|
||||
var attrs = System.Attribute.GetCustomAttributes(type);
|
||||
foreach (var attr in attrs)
|
||||
|
@ -306,7 +307,7 @@ public class Globals
|
|||
public static byte class_initializer_call(IntPtr klass, System.Type type)
|
||||
{
|
||||
Eina.Log.Debug($"called with 0x{klass.ToInt64():x} {type}");
|
||||
Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType);
|
||||
Efl.Eo.NativeClass nativeClass = GetNativeClass(type.BaseType);
|
||||
|
||||
if (nativeClass != null)
|
||||
{
|
||||
|
@ -320,7 +321,7 @@ public class Globals
|
|||
{
|
||||
if (!System.Array.Exists(base_interfaces, element => element == iface))
|
||||
{
|
||||
var nc = get_native_class(iface);
|
||||
var nc = GetNativeClass(iface);
|
||||
if (nc != null)
|
||||
{
|
||||
var moredescs = nc.GetEoOps(type);
|
||||
|
@ -442,7 +443,7 @@ public class Globals
|
|||
return eo;
|
||||
}
|
||||
|
||||
public static void data_set(Efl.Eo.IWrapper obj)
|
||||
public static void PrivateDataSet(Efl.Eo.IWrapper obj)
|
||||
{
|
||||
Eina.Log.Debug($"Calling data_scope_get with obj {obj.NativeHandle.ToInt64():x} and klass {obj.NativeClass.ToInt64():x}");
|
||||
IntPtr pd = Efl.Eo.Globals.efl_data_scope_get(obj.NativeHandle, obj.NativeClass);
|
||||
|
@ -454,7 +455,7 @@ public class Globals
|
|||
}
|
||||
}
|
||||
|
||||
public static Efl.Eo.IWrapper data_get(IntPtr pd)
|
||||
public static Efl.Eo.IWrapper PrivateDataGet(IntPtr pd)
|
||||
{
|
||||
EolianPD epd = (EolianPD)Marshal.PtrToStructure(pd, typeof(EolianPD));
|
||||
if (epd.pointer != IntPtr.Zero)
|
||||
|
@ -542,6 +543,80 @@ public class Globals
|
|||
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>Returns whether the given type was generated by eolian-mono</summary>
|
||||
/// <param name="managedType">The type to check.</param>
|
||||
/// <returns>True if generated by eolian-mono. False otherwise.</returns>
|
||||
private static bool IsGeneratedClass(System.Type managedType)
|
||||
{
|
||||
return GetNativeClass(managedType) != null;
|
||||
}
|
||||
|
||||
/// <summary>Creates a new wrapper for the given Eo id.
|
||||
///
|
||||
/// <para>If the Eo was created from a non-generated class (i.e. C#-pure class), it returns
|
||||
/// the C# instance handle stored in the Eo's private data.</para>
|
||||
///
|
||||
/// <para>For generated-class Eo instance, we use reflection to get the correct C# type to re-wrap
|
||||
/// it.</para>
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="handle">The Eo id to be wrapped.</param>
|
||||
/// <param name="shouldIncRef">Whether we should increase the refcount of the Eo instance.</param>
|
||||
/// <returns>The C# wrapper for this instance.</returns>
|
||||
public static Efl.Eo.IWrapper CreateWrapperFor(System.IntPtr handle, bool shouldIncRef=true)
|
||||
{
|
||||
IntPtr eoKlass = efl_class_get(handle);
|
||||
|
||||
if (eoKlass == IntPtr.Zero)
|
||||
{
|
||||
throw new InvalidOperationException($"Can't get Eo class for object handle 0x{handle.ToInt64():x}");
|
||||
}
|
||||
|
||||
var managedType = ClassRegister.GetManagedType(eoKlass);
|
||||
|
||||
if (managedType == null)
|
||||
{
|
||||
IntPtr nativeName = efl_class_name_get(eoKlass);
|
||||
var name = Eina.StringConversion.NativeUtf8ToManagedString(nativeName);
|
||||
|
||||
throw new InvalidOperationException($"Can't get Managed class for object handle 0x{handle.ToInt64():x} with native class [{name}]");
|
||||
}
|
||||
|
||||
// Pure C# classes that inherit from generated classes store their C# instance in their
|
||||
// Eo private data field.
|
||||
if (!IsGeneratedClass(managedType))
|
||||
{
|
||||
Efl.Eo.IWrapper instance = null;
|
||||
IntPtr pd = efl_data_scope_get(handle, eoKlass);
|
||||
|
||||
if (pd != IntPtr.Zero)
|
||||
{
|
||||
instance = PrivateDataGet(pd);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
System.Reflection.ConstructorInfo constructor = null;
|
||||
|
||||
try
|
||||
{
|
||||
var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
constructor = managedType.GetConstructor(flags, null, new Type[1] { typeof(System.IntPtr) }, null);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
throw new InvalidOperationException($"Can't get constructor for type {managedType}");
|
||||
}
|
||||
|
||||
var ret = constructor.Invoke(new object[1] { handle }) as Efl.Eo.IWrapper;
|
||||
|
||||
if (ret != null && shouldIncRef)
|
||||
Efl.Eo.Globals.efl_ref(handle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // Globals
|
||||
|
||||
public static class Config
|
||||
|
@ -560,7 +635,7 @@ public static class Config
|
|||
[System.AttributeUsage(System.AttributeTargets.Class |
|
||||
System.AttributeTargets.Interface,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)
|
||||
Inherited = false)
|
||||
]
|
||||
public abstract class NativeClass : System.Attribute
|
||||
{
|
||||
|
@ -568,6 +643,22 @@ public abstract class NativeClass : System.Attribute
|
|||
public abstract System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type);
|
||||
}
|
||||
|
||||
/// <summary>Attribute for private native classes.
|
||||
///
|
||||
/// <para>For internal usage by generated code only.</para></summary>
|
||||
public class PrivateNativeClass : NativeClass
|
||||
{
|
||||
public override IntPtr GetEflClass()
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public override System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IWrapper
|
||||
{
|
||||
/// <summary>Pointer to internal Eo instance.</summary>
|
||||
|
@ -605,6 +696,16 @@ public static class ClassRegister
|
|||
|
||||
var klass_type = Efl.Eo.Globals.efl_class_type_get(klass);
|
||||
|
||||
// Check if this is an internal implementation of an abstract class
|
||||
var abstract_impl_suffix = "Realized";
|
||||
if (name.EndsWith(abstract_impl_suffix))
|
||||
{
|
||||
name = name.Substring(0, name.Length - abstract_impl_suffix.Length);
|
||||
var lastDot = name.LastIndexOf(".");
|
||||
var klassName = name.Substring(lastDot + 1);
|
||||
name += "+" + klassName + abstract_impl_suffix; // '+' is the separator for nested classes
|
||||
}
|
||||
|
||||
// When converting to managed, interfaces and mixins gets the 'I' prefix.
|
||||
if (klass_type == Efl.Eo.Globals.EflClassType.Interface || klass_type == Efl.Eo.Globals.EflClassType.Mixin)
|
||||
{
|
||||
|
@ -795,6 +896,12 @@ public class MarshalTest<T, U> : ICustomMarshaler
|
|||
public IntPtr MarshalManagedToNative(object ManagedObj)
|
||||
{
|
||||
Eina.Log.Debug("MarshalTest.MarshallManagedToNative");
|
||||
|
||||
if (ManagedObj == null)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var r = ((IWrapper)ManagedObj).NativeHandle;
|
||||
if (typeof(U) == typeof(OwnTag))
|
||||
{
|
||||
|
@ -806,14 +913,7 @@ public class MarshalTest<T, U> : ICustomMarshaler
|
|||
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData)
|
||||
{
|
||||
Eina.Log.Debug("MarshalTest.MarshalNativeToManaged");
|
||||
if (typeof(U) != typeof(OwnTag))
|
||||
{
|
||||
Efl.Eo.Globals.efl_ref(pNativeData);
|
||||
}
|
||||
|
||||
return Activator.CreateInstance(typeof(T), new System.Object[] {pNativeData});
|
||||
//return null;
|
||||
return Efl.Eo.Globals.CreateWrapperFor(pNativeData, shouldIncRef : typeof(U) != typeof(OwnTag));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ class TestEoParent
|
|||
|
||||
Test.AssertEquals(parent, child.GetParent());
|
||||
|
||||
var parent_retrieved = Dummy.TestObject.static_cast(child.GetParent());
|
||||
var parent_retrieved = child.GetParent() as Dummy.TestObject;
|
||||
Test.AssertEquals(parent, parent_retrieved);
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ class TestEoParent
|
|||
|
||||
Test.AssertEquals(parent, child.GetParent());
|
||||
|
||||
Dummy.Numberwrapper parent_retrieved = Dummy.Numberwrapper.static_cast(child.GetParent());
|
||||
Dummy.Numberwrapper parent_retrieved = child.GetParent() as Dummy.Numberwrapper;
|
||||
Test.AssertEquals(parent, parent_retrieved);
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ class TestEoParent
|
|||
|
||||
Test.AssertEquals(parent, child.GetParent());
|
||||
|
||||
var parent_from_cast = Dummy.TestObject.static_cast(child.GetParent());
|
||||
var parent_from_cast = child.GetParent() as Derived;
|
||||
Test.AssertEquals(parent, parent_from_cast);
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ class TestInterfaceConcrete
|
|||
public static void test_iface_concrete_methods()
|
||||
{
|
||||
var obj = new Dummy.TestObject();
|
||||
Dummy.ITestIface iface = Dummy.ITestIfaceConcrete.static_cast(obj);
|
||||
Dummy.ITestIface iface = obj.ReturnIface();
|
||||
|
||||
iface.IfaceProp = 1970;
|
||||
Test.AssertEquals(iface.IfaceProp, 1970);
|
||||
|
@ -443,7 +443,7 @@ class TestProvider
|
|||
{
|
||||
// Tests only the direction C# -> C
|
||||
var obj = new Dummy.TestObject();
|
||||
Dummy.Numberwrapper provider = Dummy.Numberwrapper.static_cast(obj.FindProvider(typeof(Dummy.Numberwrapper)));
|
||||
Dummy.Numberwrapper provider = obj.FindProvider(typeof(Dummy.Numberwrapper)) as Dummy.Numberwrapper;
|
||||
Test.AssertEquals(provider.GetType(), typeof(Dummy.Numberwrapper));
|
||||
Test.AssertEquals(provider.GetNumber(), 1999);
|
||||
}
|
||||
|
|
|
@ -111,6 +111,10 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
|
|||
return: Dummy.Test_Object;
|
||||
}
|
||||
|
||||
return_iface {
|
||||
return: Dummy.Test_Iface;
|
||||
}
|
||||
|
||||
int_out {
|
||||
params {
|
||||
@in x: int;
|
||||
|
|
|
@ -45,11 +45,11 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#include "dummy_test_iface.eo.h"
|
||||
#include "dummy_inherit_iface.eo.h"
|
||||
#include "dummy_numberwrapper.eo.h"
|
||||
#include "dummy_test_object.eo.h"
|
||||
#include "dummy_child.eo.h"
|
||||
#include "dummy_test_iface.eo.h"
|
||||
#include "dummy_inherit_iface.eo.h"
|
||||
#include "dummy_inherit_helper.eo.h"
|
||||
#include "dummy_part_holder.eo.h"
|
||||
|
||||
|
@ -172,6 +172,11 @@ Efl_Object *_dummy_test_object_return_null_object(Eo *obj EINA_UNUSED, EINA_UNUS
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Dummy_Test_Iface *_dummy_test_object_return_iface(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
void _dummy_test_object_int_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, int x, int *y)
|
||||
{
|
||||
*y = -x;
|
||||
|
|
Loading…
Reference in New Issue