Merge branch 'master' into devs/hermet/lottie

This commit is contained in:
Hermet Park 2019-01-15 13:32:33 +09:00
commit 1ce86269ae
95 changed files with 1624 additions and 882 deletions

View File

@ -7,7 +7,7 @@ set -e
if [ "$BUILDSYSTEM" = "ninja" ] ; then
if [ "$DISTRO" != "" ] ; then
# Normal build test of all targets
OPTS=" -Decore-imf-loaders-disabler=scim,ibus -Davahi=false -Dmono=false -Dcxx=false"
OPTS=" -Decore-imf-loaders-disabler=scim,ibus -Davahi=false -Dbindings=luajit"
WAYLAND_LINUX_COPTS=" -Dwl=true -Ddrm=true -Dopengl=es-egl"
@ -41,7 +41,7 @@ if [ "$BUILDSYSTEM" = "ninja" ] ; then
export CFLAGS="-I/usr/local/opt/openssl/include -frewrite-includes $CFLAGS"
export LDFLAGS="-L/usr/local/opt/openssl/lib $LDFLAGS"
export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig"
mkdir build && meson build -Decore-imf-loaders-disabler=scim,ibus -Dx11=false -Davahi=false -Dmono=false -Dcxx=false -Deeze=false -Dsystemd=false -Dnls=false -Dcocoa=true -Demotion-loaders-disabler=gstreamer,gstreamer1,libvlc,xine
mkdir build && meson build -Decore-imf-loaders-disabler=scim,ibus -Dx11=false -Davahi=false -Dbindings=luajit -Deeze=false -Dsystemd=false -Dnls=false -Dcocoa=true -Demotion-loaders-disabler=gstreamer,gstreamer1,libvlc,xine
fi
else
CI_BUILD_TYPE="$1"

View File

@ -228,6 +228,10 @@ config_h.set_quoted('MOD_SUFFIX', '.'+sys_mod_extension)
config_h.set_quoted('EXE_SUFFIX', '.'+sys_exe_extension)
config_h.set('EFL_BUILD', '1')
if get_option('tslib') == true
config_h.set('HAVE_TSLIB', '1')
endif
subdir('header_checks')
subdir('po')
@ -406,12 +410,10 @@ subdir(join_paths('src', 'generic', 'evas'))
subdir(join_paths('src', 'generic', 'emotion'))
subdir('cmakeconfig')
bindings = ['luajit', 'cxx', 'mono']
bindings = get_option('bindings')
foreach binding : bindings
if get_option(binding)
subdir(join_paths('src', 'bindings', binding))
endif
subdir(join_paths('src', 'bindings', binding))
endforeach
subdir(join_paths('src', 'edje_external'))

View File

@ -97,7 +97,7 @@ option('build-examples',
option('build-tests',
type : 'boolean',
value : true,
description : 'build examples'
description : 'build tests'
)
option('crypto',
@ -310,22 +310,11 @@ option('nls',
description: 'enable localization: (default=true)'
)
option('luajit',
type: 'boolean',
value: true,
description: 'Flag for handling lua bindings'
)
option('cxx',
type: 'boolean',
value: true,
description: 'Flag for handling cxx bindings'
)
option('mono',
type: 'boolean',
value: false,
description: 'Flag for handling c# bindings'
option('bindings',
type : 'array',
choices : ['luajit', 'cxx', 'mono'],
value : ['luajit', 'cxx'],
description : 'Add values here to enable the bindings',
)
option('native-arch-optimization',
@ -346,3 +335,15 @@ option('windows-version',
value : 'win7',
description : 'When host_machine is windows, compile the efl with the specified version of Windows'
)
option('dictionaries-hyphen-dir',
type : 'string',
value : '/usr/share/hyphen/',
description : 'Put the path to hyphen dictionaries directory'
)
option('elementary-base-dir',
type : 'string',
value : '.elementary',
description : 'Put the name of a base directory for elementary data'
)

View File

@ -78,6 +78,7 @@ efl_eolian_files = \
lib/efl/interfaces/efl_gfx_text_class.eo \
lib/efl/interfaces/efl_gfx_size_class.eo \
lib/efl/interfaces/efl_interpolator.eo \
lib/efl/interfaces/efl_cached_item.eo \
$(efl_eolian_legacy_files) \
$(NULL)
@ -114,7 +115,7 @@ lib_LTLIBRARIES += lib/efl/libefl.la
lib_efl_libefl_la_SOURCES = \
lib/efl/interfaces/efl_interfaces_main.c \
lib/efl/interfaces/efl_model_common.c \
lib/efl/interfaces/efl_mvvm_common.c \
lib/efl/interfaces/efl_gfx_path.c \
lib/efl/interfaces/efl_gfx_shape.c \
lib/efl/interfaces/efl_input_device.c \
@ -140,7 +141,7 @@ lib_efl_libefl_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
installed_eflheadersdir = $(includedir)/efl-@VMAJ@
dist_installed_eflheaders_DATA = \
lib/efl/Efl_Config.h \
lib/efl/Efl_Model_Common.h \
lib/efl/Efl_MVVM_Common.h \
lib/efl/Efl.h
installed_eflinterfacesdir = $(includedir)/efl-@VMAJ@/interfaces

View File

@ -463,7 +463,9 @@ tests_efl_mono_efl_mono_SOURCES = \
tests/efl_mono/Strings.cs \
tests/efl_mono/Structs.cs \
tests/efl_mono/Value.cs \
tests/efl_mono/ValueEolian.cs
tests/efl_mono/ValueEolian.cs \
tests/efl_mono/EinaTestData.cs \
tests/efl_mono/StructHelpers.cs
tests/efl_mono/efl_mono$(EXEEXT): $(tests_efl_mono_efl_mono_SOURCES) tests/efl_mono/$(am__dirstamp) lib/efl_mono/libefl_mono.dll tests/efl_mono/libefl_mono_test.dll tests/efl_mono/efl_mono$(EXEEXT).config
@rm -f $@

View File

@ -134,6 +134,7 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_tab_page_part_tab.eo \
lib/elementary/efl_ui_widget_focus_manager.eo \
lib/elementary/efl_ui_text_part.eo \
lib/elementary/efl_ui_caching_factory.eo \
$(NULL)
# More public files -- FIXME
@ -889,6 +890,7 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/efl_ui_tab_bar.c \
lib/elementary/efl_ui_tab_page.c \
lib/elementary/efl_ui_widget_focus_manager.c \
lib/elementary/efl_ui_caching_factory.c \
$(NULL)

View File

@ -103,6 +103,8 @@ tests/eolian/data/typedef.eo \
tests/eolian/data/var.eo \
tests/eolian/data/function_types.eot \
tests/eolian/data/import_types.eot \
tests/eolian/data/class_requires.eo \
tests/eolian/data/mixins_require.eo \
tests/eolian/data_aux/aux_a.eo \
tests/eolian/data_aux/aux_b.eo \
tests/eolian/data_aux/aux_c.eo

View File

@ -127,7 +127,7 @@ source_client_complex_method_call_generate(const DBus_Method *method, Eina_Strbu
eina_strbuf_append_printf(c_code, " p = eldbus_proxy_send(proxy, msg, %s, cb, -1);\n", method->cb_name);
eina_strbuf_append_printf(c_code, " if (data)\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " return p;\n");
eina_strbuf_append_printf(c_code, "}\n");
@ -210,7 +210,7 @@ source_client_simple_method_call_generate(const DBus_Method *method, Eina_Strbuf
eina_strbuf_append_printf(c_code, " p = eldbus_proxy_send(proxy, msg, %s, cb, -1);\n", method->cb_name);
eina_strbuf_append_printf(c_code, " if (data)\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " return p;\n");
eina_strbuf_append_printf(c_code, "}\n");
@ -228,7 +228,7 @@ source_client_complex_method_callback_generate(const DBus_Method *method, Eina_S
eina_strbuf_append_printf(c_code, " %s cb = data;\n", prefix_append(method->function_cb));
eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n");
eina_strbuf_append_printf(c_code, " Eina_Value *value;\n");
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n");
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n");
eina_strbuf_append_printf(c_code, " if (eldbus_message_error_get(msg, &error, &error_msg))\n");
eina_strbuf_append_printf(c_code, " {\n");
eina_strbuf_append_printf(c_code, " Eldbus_Error_Info error_info = {error, error_msg};\n");
@ -256,7 +256,7 @@ source_client_simple_method_callback_generate(const DBus_Method *method, Eina_St
eina_strbuf_append_printf(c_code, " void *user_data = eldbus_pending_data_del(pending, \"__user_data\");\n");
eina_strbuf_append_printf(c_code, " %s cb = data;\n", prefix_append(method->function_cb));
eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n");
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n");
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n");
EINA_INLIST_FOREACH(method->args, arg)
{
@ -436,7 +436,7 @@ source_client_property_generate_get(const DBus_Property *prop, Eina_Strbuf *c_co
eina_strbuf_append_printf(c_code, " void *user_data = eldbus_pending_data_del(pending, \"__user_data\");\n");
eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n");
eina_strbuf_append_printf(c_code, " %s cb = data;\n", prop_cb_get(prop));
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n");
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n");
eina_strbuf_append_printf(c_code, " Eldbus_Message_Iter *variant;\n");
if (prop->complex)
eina_strbuf_append_printf(c_code, " Eina_Value *v, stack_value;\n");
@ -485,7 +485,7 @@ source_client_property_generate_get(const DBus_Property *prop, Eina_Strbuf *c_co
eina_strbuf_append_printf(c_code, " p = eldbus_proxy_property_get(proxy, \"%s\", %s, cb);\n", prop->name, prop->cb_name);
eina_strbuf_append_printf(c_code, " if (data)\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " return p;\n");
eina_strbuf_append_printf(c_code, "}\n");
}
@ -497,7 +497,7 @@ source_client_property_generate_set(const DBus_Property *prop, Eina_Strbuf *c_co
eina_strbuf_append_printf(c_code, "\nstatic void\n%s_set(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)\n{\n", prop->cb_name);
eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n");
eina_strbuf_append_printf(c_code, " void *user_data = eldbus_pending_data_del(pending, \"__user_data\");\n");
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n");
eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n");
eina_strbuf_append_printf(c_code, " Eldbus_Codegen_Property_Set_Cb cb = data;\n");
eina_strbuf_append_printf(c_code, " if (eldbus_message_error_get(msg, &error, &error_msg))");
eina_strbuf_append_printf(c_code, " {\n");
@ -517,7 +517,7 @@ source_client_property_generate_set(const DBus_Property *prop, Eina_Strbuf *c_co
eina_strbuf_append_printf(c_code, " EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL);\n");
eina_strbuf_append_printf(c_code, " p = eldbus_proxy_property_set(proxy, \"%s\", \"%s\", value, %s_set, cb);\n", prop->name, prop->type, prop->cb_name);
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n");
eina_strbuf_append_printf(c_code, " return p;\n");
eina_strbuf_append_printf(c_code, "}\n");
}

View File

@ -157,7 +157,8 @@ elementary_test_src = [
]
if sys_windows == false
link_args = '-rdynamic'
link_args = ['-rdynamic', '-fPIC', '-pie']
package_c_args = package_c_args + ['-fPIC']
else
link_args = []
endif

View File

@ -33,7 +33,7 @@ struct alias_definition_generator
if (!name_helpers::open_namespaces(sink, alias.namespaces, context))
return false;
std::string const& alias_name = alias.eolian_name;
std::string const alias_name = utils::remove_all(alias.eolian_name, '_');
if (!as_generator(
"public struct " << alias_name << " {\n"
<< scope_tab << "private " << type << " payload;\n"

View File

@ -45,6 +45,7 @@ inline bool is_function_blacklisted(std::string const& c_name)
|| c_name == "efl_ui_spin_button_loop_get"
|| c_name == "efl_ui_list_model_size_get"
|| c_name == "efl_ui_list_relayout_layout_do"
|| c_name == "efl_event_callback_forwarder_priority_add" // Depends on constants support.
;
}

View File

@ -25,10 +25,19 @@ struct unpack_event_args_visitor
std::string const& arg = "evt.Info";
std::string arg_type = name_helpers::type_full_managed_name(regular);
// Structs are usually passed by pointer to events, like having a ptr<> modifier
if (type.is_ptr || regular.is_struct())
return as_generator("(" + arg_type + ")Marshal.PtrToStructure(" + arg + ", typeof(" + arg_type + "))")
if (regular.is_struct())
{
// Structs are usually passed by pointer to events, like having a ptr<> modifier
// Uses implicit conversion from IntPtr
return as_generator(
" evt.Info;"
).generate(sink, attributes::unused, *context);
}
else if (type.is_ptr)
{
return as_generator("(" + arg_type + ")Marshal.PtrToStructure(" + arg + ", typeof(" + arg_type + "))")
.generate(sink, attributes::unused, *context);
}
using attributes::regular_type_def;
struct match
@ -84,21 +93,15 @@ struct event_argument_wrapper_generator
return true;
std::string evt_name = name_helpers::managed_event_name(evt.name);
std::string arg_type;
if (!as_generator(type).generate(std::back_inserter(arg_type), *etype, efl::eolian::grammar::context_null()))
{
EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Failed to get argument type for event " << evt.name;
return false;
}
return as_generator("///<summary>Event argument wrapper for event <see cref=\""
<< join_namespaces(evt.klass.namespaces, '.', managed_namespace)
<< klass_interface_name(evt.klass) << "." << evt_name << "\"/>.</summary>\n"
<< "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n"
<< scope_tab << "///<summary>Actual event payload.</summary>\n"
<< scope_tab << "public " << arg_type << " arg { get; set; }\n"
<< scope_tab << "public " << type << " arg { get; set; }\n"
<< "}\n"
).generate(sink, attributes::unused, context);
).generate(sink, *etype, context);
}
} const event_argument_wrapper {};

View File

@ -194,7 +194,9 @@ inline std::string managed_method_name(attributes::function_def const& f)
inline std::string alias_full_eolian_name(attributes::alias_def const& alias)
{
return join_namespaces(alias.namespaces, '.') + alias.eolian_name;
std::string eolian_name = utils::remove_all(alias.eolian_name, '_');
return join_namespaces(alias.namespaces, '.') + eolian_name;
}
inline std::string managed_async_method_name(attributes::function_def const& f)
@ -368,7 +370,7 @@ inline std::string klass_full_native_inherit_name(T const& klass)
template<typename T>
inline std::string klass_get_name(T const& clsname)
{
return utils::to_lowercase(join_namespaces(clsname.namespaces, '_') + clsname.eolian_name + "_class_get");
return clsname.klass_get_name;
}
inline std::string klass_get_full_name(attributes::klass_name const& clsname)

View File

@ -559,7 +559,7 @@ struct native_convert_in_variable_generator
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = " << type << "_StructConversion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
"var " << string << " = " << type << "_StructConversion.ToManaged(" << 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 *")
@ -898,7 +898,7 @@ struct convert_out_assign_generator
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
string << " = " << type << "_StructConversion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
string << " = " << type << "_StructConversion.ToManaged(" << 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)
@ -1002,7 +1002,7 @@ struct convert_in_ptr_assign_generator
if (param_should_use_in_var(param, true) && param.type.is_ptr && !param.type.has_own && helpers::need_struct_conversion(regular))
{
return as_generator(
string << " = " << type << "_StructConversion.ToExternal(" << in_variable_name(param.param_name) << ");\n"
string << " = " << type << "_StructConversion.ToManaged(" << in_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
}
@ -1040,7 +1040,7 @@ struct convert_return_generator
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
"return " << type << "_StructConversion.ToExternal(_ret_var);\n"
"return " << type << "_StructConversion.ToManaged(_ret_var);\n"
).generate(sink, ret_type, context);
}
else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")

View File

@ -56,6 +56,8 @@ struct struct_definition_generator
return false;
}
auto struct_name = binding_struct_name(struct_);
// Check whether this is an extern struct without declared fields in .eo file and generate a
// placeholder field if positive.
// Mono's JIT is picky when generating function pointer for delegates with empty structs, leading to
@ -68,7 +70,6 @@ struct struct_definition_generator
else
{
// Constructor with default parameters for easy struct initialization
auto struct_name = binding_struct_name(struct_);
if(!as_generator(
scope_tab << "///<summary>Constructor for " << string << ".</summary>\n"
<< scope_tab << "public " << string << "(\n"
@ -81,6 +82,16 @@ struct struct_definition_generator
return false;
}
if(!as_generator(
"public static implicit operator " << struct_name << "(IntPtr ptr)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var tmp = (" << struct_name << "_StructInternal)Marshal.PtrToStructure(ptr, typeof(" << struct_name << "_StructInternal));\n"
<< scope_tab << scope_tab << "return " << struct_name << "_StructConversion.ToManaged(tmp);\n"
<< scope_tab << "}\n"
).generate(sink, attributes::unused, context))
return false;
if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
return true;
@ -120,7 +131,8 @@ struct struct_internal_definition_generator
.generate(sink, nullptr, context))
return false;
}
else if (!as_generator(eolian_mono::marshall_annotation(false) << " public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
else if (!as_generator(scope_tab << eolian_mono::marshall_annotation(false) << "\n"
<< scope_tab << "public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
.generate(sink, std::make_tuple(field.type, field.type, field_name), context))
return false;
}
@ -142,7 +154,7 @@ struct struct_internal_definition_generator
scope_tab << "///<summary>Implicit conversion to the internal/marshalling representation.</summary>\n"
<< scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "return " << string << "_StructConversion.ToExternal(struct_);\n"
<< scope_tab << scope_tab << "return " << string << "_StructConversion.ToManaged(struct_);\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Implicit conversion to the managed representation.</summary>\n"
<< scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n"
@ -315,7 +327,7 @@ struct to_external_field_convert_generator
else if (helpers::need_struct_conversion(regular))
{
if (!as_generator(
scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConversion.ToExternal(_internal_struct." << string << ");\n")
scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConversion.ToManaged(_internal_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
@ -406,7 +418,7 @@ struct struct_binding_conversion_functions_generator
// to external
if (!as_generator
(
scope_tab << "internal static " << string << " ToExternal(" << string << " _internal_struct)\n"
scope_tab << "internal static " << string << " ToManaged(" << string << " _internal_struct)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var _external_struct = new " << string << "();\n\n"
)

View File

@ -792,6 +792,83 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
this.Ownership = Ownership.Managed;
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(byte x) : this(ValueType.Byte)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(sbyte x) : this(ValueType.SByte)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(short x) : this(ValueType.Short)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(ushort x) : this(ValueType.UShort)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(int x) : this(ValueType.Int32)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(uint x) : this(ValueType.UInt32)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(long x) : this(ValueType.Long)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(ulong x) : this(ValueType.ULong)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(float x) : this(ValueType.Float)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(double x) : this(ValueType.Double)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(string x) : this(ValueType.String)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Implicit conversion from managed value to native struct representation.</summary>
public static implicit operator ValueNative(Value v)
{

View File

@ -134,19 +134,6 @@ public struct ActionData {
public IntPtr func;
}
public struct StateSet {
private ulong val;
public static implicit operator StateSet(ulong x)
{
return new StateSet{val=x};
}
public static implicit operator ulong(StateSet x)
{
return x.val;
}
}
} // namespace Access
} // namespace Efl

View File

@ -7,7 +7,6 @@ examples = [
'ecore_file_download_example',
'ecore_idler_example',
'ecore_job_example',
'ecore_pipe_gstreamer_example',
'ecore_pipe_simple_example',
'ecore_poller_example',
'ecore_thread_example',
@ -22,9 +21,20 @@ examples += ['ecore_fd_handler_gnutls_example']
endif
foreach example : examples
executable(example, example + '.c', dependencies: [eina, ecore, gstreamer, ecore_file, gnutls])
executable(example, example + '.c', dependencies: [eina, ecore, ecore_file, gnutls])
endforeach
if get_option('gstreamer') == true
examples = [
'ecore_pipe_gstreamer_example',
]
foreach example : examples
executable(example, example + '.c', dependencies: [eina, ecore, gstreamer, ecore_file])
endforeach
endif
examples = [
# 'ecore_audio_custom',
# 'ecore_audio_playback',

View File

@ -87,7 +87,7 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
);
factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win);
efl_ui_model_connect(factory, "signal/elm,state,%v", "odd_style");
efl_ui_model_connect(factory, "signal/efl,state,%v", "odd_style");
efl_ui_model_connect(factory, "signal/efl,state,%{selected;unselected}", "selected");
efl_ui_model_connect(factory, "efl.text", "name");
efl_ui_layout_factory_theme_config(factory, "list_item", NULL, "default");

View File

@ -10,5 +10,8 @@ generic_src = files([
'main.c'
])
generic_deps = [dependency('gstreamer-1.0')]
generic_deps = []
if get_option('gstreamer') == true
generic_deps += dependency('gstreamer-1.0')
endif
generic_support = ['264','3g2','3gp','3gp2','3gpp','3gpp2','3p2','asf','avi','bdm','bdmv','clpi','cpi','dv','fla','flv','m1v','m2t','m2v','m4v','mkv','mov','mp2','mp2ts','mp4','mpe','mpeg','mpg','mpl','mpls','mts','mxf','nut','nuv','ogg','ogm','ogv','qt','rm','rmj','rmm','rms','rmx','rmvb','rv','swf','ts','webm','weba','wmv']

View File

@ -1895,6 +1895,9 @@ EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread);
* @param thread The thread to wait on.
* @param wait Maximum time to wait before exiting anyway.
* @return EINA_TRUE if the thread execution is over.
*
* Note: This function should only be called in the main loop.
*
*/
EAPI Eina_Bool ecore_thread_wait(Ecore_Thread *thread, double wait);

View File

@ -1,4 +1,4 @@
mixin Efl.Io.Closer_Fd (Efl.Io.Closer, Efl.Object) {
mixin Efl.Io.Closer_Fd requires Efl.Object extends Efl.Io.Closer {
[[Close fd using close(2).
@since 1.19

View File

@ -76,7 +76,6 @@ _efl_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block)
return _ecore_main_loop_iterate_may_block(obj, pd, may_block);
}
// FIXME: This should return an Eina_Value, but that doesn't work at the moment
EOLIAN static Eina_Value *
_efl_loop_begin(Eo *obj, Efl_Loop_Data *pd)
{

View File

@ -380,26 +380,6 @@ _efl_task_flags_get(const Eo *obj EINA_UNUSED, Efl_Task_Data *pd)
return pd->flags;
}
EOLIAN static Eina_Future *
_efl_task_run(Eo *obj EINA_UNUSED, Efl_Task_Data *pd EINA_UNUSED)
{
// NOP
return NULL;
}
EOLIAN static void
_efl_task_end(Eo *obj EINA_UNUSED, Efl_Task_Data *pd EINA_UNUSED)
{
// NOP
}
EOLIAN static Efl_Object *
_efl_task_efl_object_constructor(Eo *obj, Efl_Task_Data *pd EINA_UNUSED)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
return obj;
}
EOLIAN static void
_efl_task_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Task_Data *pd)
{

View File

@ -15,7 +15,7 @@ enum Efl.Task_Flags {
no_exit_code_error = 4,
}
class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer)
abstract Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer)
{
[[ ]]
methods {
@ -138,11 +138,11 @@ class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer)
flags: Efl.Task_Flags; [[ ]]
}
}
run {
run @pure_virtual {
[[ Actually run the task ]]
return: future<void> @owned; [[ A future triggered when task exits and is passed int exit code ]]
}
end {
end @pure_virtual {
[[ Request the task end (may send a signal or interrupt
signal resulting in a terminate event being tiggered in the
target task loop) ]]
@ -151,7 +151,6 @@ class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer)
events {
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Object.parent { set; }
}

View File

@ -371,22 +371,20 @@ _efl_net_control_technology_scan_cb(void *data, const Eldbus_Message *msg, Eldbu
}
static void
_efl_net_control_technology_scan_promise_del(void *data, Efl_Loop_Consumer *consumer, const Eina_Promise *dead_ptr)
_efl_net_control_technology_scan_promise_del(void *data EINA_UNUSED, Efl_Loop_Consumer *consumer EINA_UNUSED, const Eina_Promise *dead_ptr)
{
Eldbus_Pending *p = consumer;
Eldbus_Pending *p;
Efl_Net_Control_Technology_Data *pd;
Eo *o;
if (!p) return ;
p = eina_promise_data_get(dead_ptr);
if (!p) return; /* already gone, nothing to do */
o = eldbus_pending_data_get(p, ".object");
pd = efl_data_scope_get(o, MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN(pd);
p = eina_promise_data_get(dead_ptr);
if (!p) return; /* already gone, nothing to do */
pd->pending = eina_list_remove(pd->pending, p);
DBG("cancel pending scan %p", p);
eldbus_pending_cancel(p);

View File

@ -1,6 +1,10 @@
ecore_fb_deps = [ecore, ecore_input]
ecore_fb_pub_deps = [eina]
if get_option('tslib')
ecore_fb_deps += dependency('tslib')
endif
ecore_fb_header_src = [
'Ecore_Fb.h'
]

View File

@ -1,4 +1,7 @@
ecore_wl2_deps = [dependency('wayland-client'), dependency('wayland-server'), dependency('xkbcommon'), wayland_protocol, dependency('wayland-client')]
ecore_wl2_deps = [
dependency('wayland-client'), dependency('wayland-server'), dependency('xkbcommon'),
wayland_protocol, dl, m, ecore, ecore_input, libdrm, buildsystem
]
ecore_wl2_pub_deps = [eina, ecore]
ecore_wl2_header_src = [
@ -20,7 +23,7 @@ ecore_wl2_src = [
ecore_wl2_lib = library('ecore_wl2',
ecore_wl2_src, pub_eo_file_target,
dependencies: ecore_wl2_pub_deps + [dl, m, ecore, ecore_input, ecore_wl2_deps, libdrm, buildsystem],
dependencies: ecore_wl2_deps + ecore_wl2_pub_deps,
include_directories : config_dir,
install: true,
version : meson.project_version()

View File

@ -1,4 +1,4 @@
mixin Ector.Renderer.Gradient (Efl.Gfx.Gradient, Efl.Object)
mixin Ector.Renderer.Gradient requires Efl.Object extends Efl.Gfx.Gradient
{
[[Ector gradient renderer mixin]]
eo_prefix: ector_renderer_gradient;

View File

@ -1,6 +1,6 @@
import ector_renderer;
mixin Ector.Renderer.Shape (Efl.Gfx.Shape, Efl.Object)
mixin Ector.Renderer.Shape requires Efl.Object extends Efl.Gfx.Shape
{
[[Ector shape renderer mixin]]
eo_prefix: ector_renderer_shape;

View File

@ -2024,12 +2024,11 @@ _edje_file_del(Edje *ed)
// fallthrough intentional
case EDJE_PART_TYPE_GROUP:
evas_object_del(rp->typedata.swallow->swallowed_object);
rp->typedata.swallow->swallowed_object = NULL;
default:
break;
}
_edje_real_part_swallow_clear(ed, rp);
rp->typedata.swallow->swallowed_object = NULL;
}
free(rp->typedata.swallow);
rp->typedata.swallow = NULL;

View File

@ -73,7 +73,7 @@ typedef struct _Efl_Text_Annotate_Annotation Efl_Text_Annotate_Annotation;
#include "interfaces/efl_types.eot.h"
#include <Efl_Model_Common.h>
#include <Efl_MVVM_Common.h>
/* Data types */
#include "interfaces/efl_gfx_types.eot.h"
@ -149,6 +149,7 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
#include "interfaces/efl_ui_model_connect.eo.h"
#include "interfaces/efl_ui_factory.eo.h"
#include "interfaces/efl_ui_format.eo.h"
#include "interfaces/efl_cached_item.eo.h"
/* Observable interface */
#include "interfaces/efl_observer.eo.h"

View File

@ -12,6 +12,8 @@ EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE;
EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED;
EAPI extern Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT; /**< @since 1.19 */
EAPI extern Eina_Error EFL_FACTORY_ERROR_NOT_SUPPORTED; /**< Returned error when factory got a request that it can't fullfil due to a set of unsupported parameters @since 1.22 */
#include "interfaces/efl_model.eo.h"
EAPI int efl_model_init(void);

View File

@ -0,0 +1,14 @@
interface Efl.Cached.Item
{
[[Efl Cached Item interface]]
methods {
@property memory_size {
get {
[[Get the memory size associated with an object.]]
}
values {
consumed: uint; [[Bytes of memory consumed by this object.]]
}
}
}
}

View File

@ -81,6 +81,8 @@
#include "interfaces/efl_ui_multi_selectable.eo.c"
#include "interfaces/efl_ui_zoom.eo.c"
#include "interfaces/efl_cached_item.eo.c"
static void
_noref_death(void *data EINA_UNUSED, const Efl_Event *event)
{

View File

@ -3,7 +3,7 @@
#endif
#include "Efl.h"
#include "Efl_Model_Common.h"
#include "Efl_MVVM_Common.h"
EAPI Eina_Error EFL_MODEL_ERROR_UNKNOWN = 0;
EAPI Eina_Error EFL_MODEL_ERROR_NOT_SUPPORTED = 0;
@ -14,6 +14,8 @@ EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0;
EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0;
EAPI Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT = 0;
EAPI Eina_Error EFL_FACTORY_ERROR_NOT_SUPPORTED = 0;
static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error";
static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported";
static const char EFL_MODEL_ERROR_NOT_FOUND_STR[] = "Value not found";
@ -23,11 +25,12 @@ static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied";
static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value";
static const char EFL_MODEL_ERROR_INVALID_OBJECT_STR[] = "Object is invalid";
#define _ERROR(Name) EFL_MODEL_ERROR_##Name = eina_error_msg_static_register(EFL_MODEL_ERROR_##Name##_STR);
static const char EFL_FACTORY_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported";
EAPI int
efl_model_init(void)
{
#define _ERROR(Name) EFL_MODEL_ERROR_##Name = eina_error_msg_static_register(EFL_MODEL_ERROR_##Name##_STR);
_ERROR(INCORRECT_VALUE);
_ERROR(UNKNOWN);
_ERROR(NOT_SUPPORTED);
@ -37,6 +40,10 @@ efl_model_init(void)
_ERROR(PERMISSION_DENIED);
_ERROR(INVALID_OBJECT);
#undef _ERROR
#define _ERROR(Name) EFL_FACTORY_ERROR_##Name = eina_error_msg_static_register(EFL_FACTORY_ERROR_##Name##_STR);
_ERROR(NOT_SUPPORTED);
return EINA_TRUE;
}

View File

@ -104,6 +104,7 @@ pub_eo_files = [
'efl_gfx_color_class.eo',
'efl_gfx_text_class.eo',
'efl_gfx_size_class.eo',
'efl_cached_item.eo',
]
foreach eo_file : pub_eo_files
@ -155,7 +156,7 @@ pub_eo_types_files = []
efl_src += files([
'efl_interfaces_main.c',
'efl_model_common.c',
'efl_mvvm_common.c',
'efl_gfx_path.c',
'efl_gfx_shape.c',
'efl_gfx_color.c',

View File

@ -3,7 +3,7 @@ efl_pub_deps = [eo]
efl_header_src = [
'Efl.h',
'Efl_Model_Common.h'
'Efl_MVVM_Common.h'
]
efl_src = []

View File

@ -207,6 +207,8 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_calendar.h>
# include <efl_ui_button_eo.h>
# include "efl_ui_caching_factory.eo.h"
/* FIXME: Multibuttonentry must not use elm_widget_item */
# warning Efl.Ui.Multibutton is not available yet without Elementary.h
# if 0

View File

@ -348,6 +348,7 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_ui_list_view_relayout.eo.h>
# include <efl_ui_list_view.eo.h>
# include <efl_ui_list_view_pan.eo.h>
# include <efl_ui_caching_factory.eo.h>
# include <efl_ui_pan.eo.h>
# include <efl_ui_scroll_manager.eo.h>
# include <efl_ui_scroller.eo.h>

View File

@ -239,7 +239,7 @@ struct Efl.Access.Relation
objects: list<Efl.Object>; [[List with relation objects]]
}
mixin Efl.Access.Object (Efl.Interface, Efl.Object)
mixin Efl.Access.Object requires Efl.Object
{
[[Accessibility accessible mixin]]
eo_prefix: efl_access_object;

View File

@ -0,0 +1,218 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Elementary.h>
#include "elm_priv.h"
typedef struct _Efl_Ui_Caching_Factory_Data Efl_Ui_Caching_Factory_Data;
struct _Efl_Ui_Caching_Factory_Data
{
const Efl_Class *klass;
// Simple list of ready-to-use objects. They are all equal so it does not matter from which
// end of the list objects are added and removed.
Eina_List *cache;
struct {
unsigned int memory;
unsigned int items;
} limit, current;
};
// Clear the cache until it meet the constraint
static void
_efl_ui_caching_factory_remove(Efl_Ui_Caching_Factory_Data *pd, Eina_List *l, Efl_Gfx_Entity *entity)
{
pd->cache = eina_list_remove_list(pd->cache, l);
pd->current.items--;
pd->current.memory -= efl_class_memory_size_get(entity);
if (efl_isa(entity, EFL_CACHED_ITEM_INTERFACE))
pd->current.memory -= efl_cached_item_memory_size_get(entity);
}
static void
_efl_ui_caching_factory_flush(Efl_Ui_Caching_Factory_Data *pd)
{
while (pd->limit.items != 0 &&
pd->current.items > pd->limit.items)
{
Efl_Gfx_Entity *entity;
entity = eina_list_data_get(eina_list_last(pd->cache));
_efl_ui_caching_factory_remove(pd, eina_list_last(pd->cache), entity);
efl_del(entity);
}
while (pd->limit.memory != 0 &&
pd->current.memory > pd->limit.memory)
{
Efl_Gfx_Entity *entity;
entity = eina_list_data_get(eina_list_last(pd->cache));
_efl_ui_caching_factory_remove(pd, eina_list_last(pd->cache), entity);
efl_del(entity);
}
}
static Eina_Future *
_efl_ui_caching_factory_efl_ui_factory_create(Eo *obj,
Efl_Ui_Caching_Factory_Data *pd,
Efl_Model *model, Efl_Gfx_Entity *parent)
{
Efl_Gfx_Entity *r;
if (pd->cache)
{
r = eina_list_data_get(pd->cache);
_efl_ui_caching_factory_remove(pd, pd->cache, r);
efl_parent_set(r, parent);
}
else
{
r = efl_add(pd->klass, parent);
}
efl_ui_view_model_set(r, model);
return efl_loop_future_resolved(obj, eina_value_object_init(r));
}
static void
_efl_ui_caching_factory_item_class_set(Eo *obj,
Efl_Ui_Caching_Factory_Data *pd,
const Efl_Object *klass)
{
if (!efl_isa(klass, EFL_GFX_ENTITY_INTERFACE) ||
!efl_isa(klass, EFL_UI_VIEW_INTERFACE))
{
ERR("Provided class '%s' for factory '%s' doesn't implement '%s' and '%s' interfaces.",
efl_class_name_get(klass),
efl_class_name_get(obj),
efl_class_name_get(EFL_GFX_ENTITY_INTERFACE),
efl_class_name_get(EFL_UI_VIEW_INTERFACE));
return ;
}
pd->klass = klass;
}
static const Efl_Object *
_efl_ui_caching_factory_item_class_get(const Eo *obj EINA_UNUSED,
Efl_Ui_Caching_Factory_Data *pd)
{
return pd->klass;
}
static void
_efl_ui_caching_factory_memory_limit_set(Eo *obj EINA_UNUSED,
Efl_Ui_Caching_Factory_Data *pd,
unsigned int limit)
{
pd->limit.memory = limit;
_efl_ui_caching_factory_flush(pd);
}
static unsigned int
_efl_ui_caching_factory_memory_limit_get(const Eo *obj EINA_UNUSED,
Efl_Ui_Caching_Factory_Data *pd)
{
return pd->limit.memory;
}
static void
_efl_ui_caching_factory_items_limit_set(Eo *obj EINA_UNUSED,
Efl_Ui_Caching_Factory_Data *pd,
unsigned int limit)
{
pd->limit.items = limit;
_efl_ui_caching_factory_flush(pd);
}
static unsigned int
_efl_ui_caching_factory_items_limit_get(const Eo *obj EINA_UNUSED,
Efl_Ui_Caching_Factory_Data *pd)
{
return pd->limit.items;
}
static void
_efl_ui_caching_factory_efl_ui_factory_release(Eo *obj,
Efl_Ui_Caching_Factory_Data *pd,
Efl_Gfx_Entity *ui_view)
{
// Change parent, disconnect the object and make it invisible
efl_parent_set(ui_view, obj);
efl_gfx_entity_visible_set(ui_view, EINA_FALSE);
efl_ui_view_model_set(ui_view, NULL);
// Add to the cache
pd->cache = eina_list_prepend(pd->cache, ui_view);
pd->current.items++;
pd->current.memory += efl_class_memory_size_get(ui_view);
if (efl_isa(ui_view, EFL_CACHED_ITEM_INTERFACE))
pd->current.memory += efl_cached_item_memory_size_get(ui_view);
// And check if the cache need some triming
_efl_ui_caching_factory_flush(pd);
}
static void
_efl_ui_caching_factory_efl_object_invalidate(Eo *obj EINA_UNUSED,
Efl_Ui_Caching_Factory_Data *pd)
{
// As all the objects in the cache have the factory as parent, there's no need to unparent them
pd->cache = eina_list_free(pd->cache);
}
static Efl_App *
_efl_ui_caching_factory_app_get(Eo *obj)
{
Efl_Object *p;
p = efl_parent_get(obj);
if (!p) return NULL;
// It is acceptable to just have a loop as parent and not an app
return efl_provider_find(obj, EFL_APP_CLASS);
}
static void
_efl_ui_caching_factory_pause(void *data, const Efl_Event *event EINA_UNUSED)
{
Efl_Ui_Caching_Factory_Data *pd = data;
Efl_Gfx_Entity *entity;
// Application is going into background, let's free ressource
// Possible improvement would be to delay that by a few second.
EINA_LIST_FREE(pd->cache, entity)
efl_del(entity);
pd->current.items = 0;
pd->current.memory = 0;
}
static void
_efl_ui_caching_factory_efl_object_parent_set(Eo *obj, Efl_Ui_Caching_Factory_Data *pd, Efl_Object *parent)
{
Efl_App *a;
a = _efl_ui_caching_factory_app_get(obj);
if (a) efl_event_callback_del(a, EFL_APP_EVENT_PAUSE, _efl_ui_caching_factory_pause, pd);
efl_parent_set(efl_super(obj, EFL_UI_CACHING_FACTORY_CLASS), parent);
// We are fetching the parent again, just in case the update was denied
a = _efl_ui_caching_factory_app_get(obj);
if (a) efl_event_callback_add(a, EFL_APP_EVENT_PAUSE, _efl_ui_caching_factory_pause, pd);
}
#include "efl_ui_caching_factory.eo.c"

View File

@ -0,0 +1,48 @@
class Efl.Ui.Caching_Factory (Efl.Loop_Consumer, Efl.Ui.Factory)
{
[[Efl Ui Factory that provides object caching.
This factory handles caching of one type of object and automatically empties the cache
when the application goes into pause.
Creating objects is costly and time consuming, keeping a few on hand for when you next will need them helps a lot.
This is what this factory caching infrastructure provides. It will create the object from the class defined on it and
set the parent and the model as needed for all created items. The View has to release the Item using the
release function of the Factory interface for all of this to work properly.
The cache might decide to flush itself when the application event pause is triggered.
]]
methods {
@property item_class {
[[Define the class of the item returned by this factory.]]
get {}
set {}
values {
klass: const(Efl.Class); [[The class identifier to create item from.]]
}
}
@property memory_limit {
[[Define the maxium size in Bytes that all the object waiting on standby in the cache take. They must provide the @Efl.Cached.Item interface for an accurate accounting.]]
get {}
set {}
values {
limit: uint; [[When set to zero, there is no limit on the amount of memory the cache will use.]]
}
}
@property items_limit {
[[Define how many maximum number of items are waiting on standby in the cache.]]
get {}
set {}
values {
limit: uint; [[When set to zero, there is no limit to the amount of items stored in the cache.]]
}
}
}
implements {
Efl.Ui.Factory.create;
Efl.Ui.Factory.release;
Efl.Object.invalidate;
Efl.Object.parent { set; }
}
}

View File

@ -20,6 +20,9 @@ struct _Efl_Ui_Dnd_Container_Data
};
extern int _wl_default_seat_id_get(Evas_Object *obj);
#ifdef HAVE_ELEMENTARY_WL2
Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj);
#endif
Eo*
_efl_ui_selection_manager_get(Eo *obj)
@ -339,7 +342,7 @@ elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
sl.mem = data;
sl.len = strlen(data);
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
ic->icon_data = icon_create_data;
@ -366,7 +369,7 @@ elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action)
int seatid = 1;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
efl_ui_selection_manager_drag_action_set(sel_man, obj, (Efl_Ui_Selection_Action)action, seatid);
@ -380,7 +383,7 @@ elm_drag_cancel(Evas_Object *obj)
int seatid = 1;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
efl_ui_selection_manager_drag_cancel(sel_man, obj, seatid);
@ -433,7 +436,7 @@ elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
drop = calloc(1, sizeof(Dnd_Drop));
if (!enter || !leave || !pos || !drop) goto on_error;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
enter->state_cb = enter_cb;
enter->state_data = enter_data;
@ -489,7 +492,7 @@ elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
Dnd_Drop *drop;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
drop_list = efl_key_data_get(obj, "__drop_list");
@ -650,7 +653,7 @@ elm_drop_item_container_add(Evas_Object *obj,
drop = calloc(1, sizeof(Dnd_Cont_Drop));
if (!enter || !leave || !pos || !drop) goto on_error;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
enter->state_cb = enter_cb;
@ -703,7 +706,7 @@ elm_drop_item_container_del(Evas_Object *obj)
int seatid = 1;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
_cont_drop_free_data(obj);
@ -806,7 +809,7 @@ elm_drag_item_container_add(Evas_Object *obj, double anim_tm, double tm_to_drag,
Item_Container_Drag_Info *di;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
di = calloc(1, sizeof(Item_Container_Drag_Info));
@ -833,7 +836,7 @@ elm_drag_item_container_del(Evas_Object *obj)
int seatid = 1;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
_cont_drag_free_data(obj);

View File

@ -1,4 +1,4 @@
mixin Efl.Ui.Focus.Composition (Efl.Interface, Efl.Ui.Widget) {
mixin Efl.Ui.Focus.Composition requires Efl.Ui.Widget {
[[This defines the inheriting widget as Composition widget.
A composition widget is a widget that's the logical parent of another set of widgets which can be used for interaction.

View File

@ -1,4 +1,4 @@
mixin Efl.Ui.Focus.Layer (Efl.Interface, Efl.Ui.Widget, Efl.Ui.Widget_Focus_Manager) {
mixin Efl.Ui.Focus.Layer requires Efl.Ui.Widget extends Efl.Ui.Widget_Focus_Manager {
[[This defines the inheriting widget as focus layer
A focus layer is the uppermost one which received input and handles all focus related events for as long as it exists and is visible. It's NOT possible to escape this layer with focus movement.

View File

@ -1,4 +1,4 @@
mixin Efl.Ui.Focus.Manager_Sub (Efl.Interface, Efl.Ui.Focus.Manager, Efl.Object)
mixin Efl.Ui.Focus.Manager_Sub requires Efl.Object extends Efl.Ui.Focus.Manager
{
[[A class that automatically registers its border elements in the parent manager

View File

@ -17,6 +17,7 @@ EOLIAN static Eo *
_efl_ui_image_factory_efl_object_constructor(Eo *obj, Efl_Ui_Image_Factory_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_ui_caching_factory_item_class_set(obj, EFL_UI_IMAGE_CLASS);
pd->property = NULL;
@ -32,27 +33,33 @@ _efl_ui_image_factory_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Ui_Image_Fa
efl_destructor(efl_super(obj, MY_CLASS));
}
static Eina_Value
_efl_ui_image_factory_connect(Eo *obj EINA_UNUSED, void *data, const Eina_Value value)
{
Efl_Gfx_Entity *entity = NULL;
Efl_Ui_Image_Factory_Data *pd = data;
eina_value_pget(&value, &entity);
efl_ui_model_connect(entity, "filename", pd->property);
return value;
}
EOLIAN static Eina_Future *
_efl_ui_image_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Image_Factory_Data *pd, Efl_Model *model, Efl_Gfx_Entity *parent)
{
Efl_Gfx_Entity *ui_view;
Eina_Value r;
Eina_Future *f;
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->property, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ui_view = efl_add(EFL_UI_IMAGE_CLASS, parent);
efl_ui_view_model_set(ui_view, model);
efl_ui_model_connect(ui_view, "filename", pd->property);
if (!parent) return efl_loop_future_rejected(obj, EFL_FACTORY_ERROR_NOT_SUPPORTED);
if (!pd->property) return efl_loop_future_rejected(obj, EFL_FACTORY_ERROR_NOT_SUPPORTED);
r = eina_value_object_init(ui_view);
f = efl_ui_factory_create(efl_super(obj, EFL_UI_IMAGE_FACTORY_CLASS), model, parent);
return eina_future_resolved(efl_loop_future_scheduler_get(obj), r);
}
EOLIAN static void
_efl_ui_image_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd EINA_UNUSED, Efl_Gfx_Entity *ui_view)
{
efl_parent_set(ui_view, NULL);
return efl_future_then(obj, f,
.success_type = EINA_VALUE_TYPE_OBJECT,
.success = _efl_ui_image_factory_connect,
.data = pd);
}
EOLIAN static void

View File

@ -1,11 +1,10 @@
class Efl.Ui.Image_Factory (Efl.Object, Efl.Ui.Factory)
class Efl.Ui.Image_Factory (Efl.Ui.Caching_Factory)
{
[[Efl UI image factory class]]
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Ui.Factory.create;
Efl.Ui.Factory.release;
Efl.Ui.Model.Connect.connect;
}
}

View File

@ -45,6 +45,8 @@ _efl_ui_layout_factory_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Factory_Dat
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_ui_caching_factory_item_class_set(obj, EFL_UI_LAYOUT_CLASS);
pd->connects = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del));
pd->factory_connects = eina_hash_stringshared_new(EINA_FREE_CB(efl_unref));
@ -64,17 +66,15 @@ _efl_ui_layout_factory_efl_object_destructor(Eo *obj, Efl_Ui_Layout_Factory_Data
efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static Eina_Future *
_efl_ui_layout_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Layout_Factory_Data *pd,
Efl_Model *model, Efl_Gfx_Entity *parent)
static Eina_Value
_efl_ui_layout_factory_connect(Eo *obj EINA_UNUSED, void *data, const Eina_Value value)
{
Eina_Value r;
Efl_Ui_Layout_Factory_Data *pd = data;
Efl_Gfx_Entity *layout;
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
layout = efl_add(EFL_UI_LAYOUT_CLASS, parent,
efl_ui_view_model_set(efl_added, model),
efl_ui_layout_theme_set(efl_added, pd->klass, pd->group, pd->style));
eina_value_pget(&value, &layout);
efl_ui_layout_theme_set(layout, pd->klass, pd->group, pd->style);
eina_hash_foreach(pd->connects, _model_connect, layout);
eina_hash_foreach(pd->factory_connects, _factory_model_connect, layout);
@ -82,16 +82,21 @@ _efl_ui_layout_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Layout_Factory_Data
evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
r = eina_value_object_init(layout);
return eina_future_resolved(efl_loop_future_scheduler_get(obj), r);
return value;
}
EOLIAN static void
_efl_ui_layout_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd EINA_UNUSED, Efl_Gfx_Entity *layout)
EOLIAN static Eina_Future *
_efl_ui_layout_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Layout_Factory_Data *pd,
Efl_Model *model, Efl_Gfx_Entity *parent)
{
efl_ui_view_model_set(layout, NULL);
efl_del(layout);
Eina_Future *f;
f = efl_ui_factory_create(efl_super(obj, EFL_UI_LAYOUT_FACTORY_CLASS), model, parent);
return efl_future_then(obj, f,
.success_type = EINA_VALUE_TYPE_OBJECT,
.success = _efl_ui_layout_factory_connect,
.data = pd);
}
EOLIAN static void

View File

@ -1,4 +1,4 @@
class Efl.Ui.Layout_Factory (Efl.Object, Efl.Ui.Factory)
class Efl.Ui.Layout_Factory (Efl.Ui.Caching_Factory)
{
[[Efl Ui Layout Factory class]]
methods {
@ -16,7 +16,6 @@ class Efl.Ui.Layout_Factory (Efl.Object, Efl.Ui.Factory)
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Ui.Factory.create;
Efl.Ui.Factory.release;
Efl.Ui.Factory.model_connect;
Efl.Ui.Model.Connect.connect;
}

View File

@ -32,7 +32,6 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
void _efl_ui_list_view_custom_layout(Efl_Ui_List_View *);
void _efl_ui_list_view_item_select_set(Efl_Ui_List_View_Layout_Item*, Eina_Bool);
static void _layout(Efl_Ui_List_View_Data* pd);
static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
@ -166,7 +165,7 @@ _on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o EINA_UNUSED
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
v = efl_model_property_get(item->children, SELECTED_PROP);
if (!eina_value_get(v, &select))
if (!eina_value_get(v, &select))
{
WRN("Could not get the select value");
eina_value_free(v);
@ -239,7 +238,11 @@ _efl_ui_list_view_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_List_View_Data *pd, Ei
EOLIAN static void
_efl_ui_list_view_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Data *pd)
{
_layout(pd);
if (!pd->model)
return;
efl_ui_list_view_relayout_layout_do(pd->relayout, pd->obj, pd->seg_array_first, pd->seg_array);
}
EOLIAN static void
@ -841,15 +844,6 @@ _efl_ui_list_view_relayout_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_View_Data
return pd->relayout;
}
static void
_layout(Efl_Ui_List_View_Data *pd)
{
if (!pd->model)
return;
efl_ui_list_view_relayout_layout_do(pd->relayout, pd->obj, pd->seg_array_first, pd->seg_array);
}
static Eina_Value
_children_slice_then(void * data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
{
@ -941,8 +935,11 @@ _content_created(Eo *obj, void *data, const Eina_Value value)
evt.layout = item->layout;
evt.index = efl_ui_list_view_item_index_get(item);
efl_event_callback_call(obj, EFL_UI_LIST_VIEW_EVENT_ITEM_REALIZED, &evt);
efl_ui_focus_composition_dirty(obj);
tracking->item->layout_request = NULL;
efl_ui_list_view_relayout_content_created(tracking->pd->relayout, item);
efl_ui_focus_composition_dirty(obj);
evas_object_show(item->layout);
return value;

View File

@ -22,7 +22,6 @@ typedef struct _Efl_Ui_List_View_Precise_Layouter_Data
unsigned int calc_progress;
int first;
int count_total;
Eina_Bool initialized : 1;
@ -118,21 +117,26 @@ _item_size_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Lay
}
}
static void
_item_min_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item* item
, Eina_Size2D min, Efl_Ui_List_View_Seg_Array_Node *itemnode)
static Eina_Size2D
_item_min_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item* item)
{
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = itemnode->layout_data;
Efl_Ui_List_View_Seg_Array_Node *itemnode = item->tree_node;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata;
Efl_Ui_List_View_Layout_Item *layout_item;
int i, pad[4];
efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]);
Eina_Size2D min = efl_gfx_size_hint_combined_min_get(item->layout);
efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]);
min.w += pad[0] + pad[1];
min.h += pad[2] + pad[3];
if (item->min.h == min.h && item->min.w == min.w)
return;
return min;
EINA_SAFETY_ON_NULL_RETURN_VAL(itemnode, min);
EINA_SAFETY_ON_NULL_RETURN_VAL(itemnode->layout_data, min);
nodedata = itemnode->layout_data;
pd->min.h += min.h - item->min.h;
nodedata->min.h += min.h - item->min.h;
@ -175,13 +179,12 @@ _item_min_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layo
item->min.w = min.w;
item->min.h = min.h;
_item_size_calc(pd, item);
return item->min;
}
static void
_on_item_size_hint_change(void *data, Evas *e EINA_UNUSED,
Evas_Object *obj, void *event_info EINA_UNUSED)
Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data = data;
Efl_Ui_List_View_Precise_Layouter_Data *pd = cb_data->pd;
@ -189,8 +192,7 @@ _on_item_size_hint_change(void *data, Evas *e EINA_UNUSED,
Efl_Ui_List_View_Seg_Array_Node *node = item->tree_node;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data;
Eina_Size2D min = efl_gfx_size_hint_combined_min_get(obj);
_item_min_calc(pd, item, min, node);
_item_min_calc(pd, item);
if (!nodedata->realized)
{
free(evas_object_event_callback_del(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change));
@ -273,17 +275,17 @@ _child_removed_cb(void *data, const Efl_Event *event)
nodedata->min.w = 0;
for (i = 0; i != itemnode->length; ++i)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)itemnode->pointers[i];
if (nodedata->min.w < layout_item->min.w)
nodedata->min.w = layout_item->min.w;
{
layout_item = (Efl_Ui_List_View_Layout_Item *)itemnode->pointers[i];
if (nodedata->min.w < layout_item->min.w)
nodedata->min.w = layout_item->min.w;
if (litem->min.w == layout_item->min.w)
{
nodedata->min.w = layout_item->min.w;
break;
}
}
if (litem->min.w == layout_item->min.w)
{
nodedata->min.w = layout_item->min.w;
break;
}
}
if (pd->min.w == litem->min.w)
{
@ -300,9 +302,8 @@ _child_removed_cb(void *data, const Efl_Event *event)
if (litem->min.w == nodedata2->min.w)
break;
}
eina_accessor_free(nodes);
eina_accessor_free(nodes);
}
efl_ui_list_view_model_unrealize(pd->modeler, litem);
free(litem);
@ -391,7 +392,6 @@ static void
_node_realize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg_Array_Node *node)
{
Efl_Ui_List_View_Layout_Item* layout_item;
Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data;
int i;
@ -405,15 +405,6 @@ _node_realize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg_A
{
layout_item = (Efl_Ui_List_View_Layout_Item *)node->pointers[i];
efl_ui_list_view_model_realize(pd->modeler, layout_item);
if (layout_item->layout)
{
cb_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Callback_Data));
cb_data->pd = pd;
cb_data->item = layout_item;
evas_object_event_callback_add(layout_item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data);
_item_size_calc(pd, layout_item);
}
}
}
@ -438,8 +429,8 @@ _node_unrealize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg
{
cb_data = evas_object_event_callback_del(layout_item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change);
free(cb_data);
efl_ui_list_view_model_unrealize(pd->modeler, layout_item);
}
efl_ui_list_view_model_unrealize(pd->modeler, layout_item);
}
}
@ -485,8 +476,8 @@ _calc_size_job(void *data)
Efl_Ui_List_View_Precise_Layouter_Data *pd;
Efl_Ui_List_View_Seg_Array_Node *node;
Efl_Ui_List_View_Layout_Item *layout_item;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata;
Eo *obj = data;
Eina_Size2D min;
int i;
double start_time = ecore_time_get();
@ -501,52 +492,36 @@ _calc_size_job(void *data)
if (!node->layout_data)
node->layout_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Node_Data));
nodedata = node->layout_data;
if (pd->calc_progress == 1)
nodedata->realized = EINA_TRUE;
for (i = 0; i != node->length; ++i)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)node->pointers[i];
EINA_SAFETY_ON_NULL_RETURN(layout_item);
// cache size of new items
if ((layout_item->min.w == 0) && (layout_item->min.h == 0))
{
if (!layout_item->layout)
{
efl_ui_list_view_model_realize(pd->modeler, layout_item);
}
min = efl_gfx_size_hint_combined_min_get(layout_item->layout);
if (min.w && min.h)
{
_item_min_calc(pd, layout_item, min, node);
efl_ui_list_view_model_unrealize(pd->modeler, layout_item);
}
else
{
Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Callback_Data));
cb_data->pd = pd;
cb_data->item = layout_item;
evas_object_event_callback_add(layout_item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data);
}
}
if ((layout_item->min.w == 0) && (layout_item->min.h == 0) && (!layout_item->layout))
efl_ui_list_view_model_realize(pd->modeler, layout_item);
}
if ( (ecore_time_get() - start_time ) > 0.01 )
{
ecore_job_del(pd->calc_job);
pd->calc_job = ecore_job_add(_calc_size_job, obj);
eina_accessor_free(nodes);
return;
}
}
}
eina_accessor_free(nodes);
pd->calc_progress = 0;
pd->calc_job = NULL;
pd->recalc = EINA_FALSE;
evas_object_smart_changed(pd->modeler);
}
EOLIAN static Efl_Object *
_efl_ui_list_view_precise_layouter_efl_object_constructor(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd)
_efl_ui_list_view_precise_layouter_efl_object_constructor(Eo *obj, Efl_Ui_List_View_Precise_Layouter_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->initialized = EINA_FALSE;
@ -554,6 +529,31 @@ _efl_ui_list_view_precise_layouter_efl_object_constructor(Eo *obj EINA_UNUSED, E
return obj;
}
EOLIAN static void
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_content_created(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item *item)
{
Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data;
EINA_SAFETY_ON_NULL_RETURN(item);
EINA_SAFETY_ON_NULL_RETURN(item->layout);
Efl_Ui_List_View_Seg_Array_Node *node = item->tree_node;
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data;
Eina_Size2D min = _item_min_calc(pd, item);
if (min.w && min.h && !nodedata->realized)
{
efl_ui_list_view_model_unrealize(pd->modeler, item);
return;
}
cb_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Callback_Data));
cb_data->pd = pd;
cb_data->item = item;
evas_object_event_callback_add(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data);
_item_size_calc(pd, item);
}
EOLIAN static Eina_List *
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd)
{
@ -569,7 +569,7 @@ _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const
if (!nodedata || !nodedata->realized)
continue;
for(j = 0; j != items_node->length;++j)
for (j = 0; j != items_node->length;++j)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j];
if (layout_item->layout)
@ -582,7 +582,7 @@ _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const
}
EOLIAN static void
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_model_set(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Model *model)
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_model_set(Eo *obj, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Model *model)
{
_finalize(obj, pd);
@ -607,11 +607,11 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd)
Efl_Ui_List_View_Layout_Item* layout_item;
Efl_Ui_List_View_Seg_Array_Node *items_node;
int i, j = 0;
int boxx, boxy, boxw, boxh, extra = 0, rounding = 0;
int boxl = 0, boxr = 0, boxt = 0, boxb = 0;
_calc_range(pd);
int boxx, boxy, boxw, boxh, extra = 0, rounding = 0;
int boxl = 0, boxr = 0, boxt = 0, boxb = 0;
evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh);
efl_gfx_size_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb);
@ -621,13 +621,6 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd)
boxx += boxl;
boxy += boxt;
//padding can not be squeezed (note: could make it an option)
// int pad;
// double scale;
// scale = evas_object_scale_get(pd->modeler);
// pad = 0;//pd->pad.scalable ? (pd->pad.v * scale) : pd->pad.v;
// length -= pad * (pd->count_total - 1);
// available space. if <0 we overflow
extra = boxh - pd->min.h;
if (extra < 0) extra = 0;
@ -641,46 +634,50 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd)
EINA_ACCESSOR_FOREACH(nodes, i, items_node)
{
Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = items_node->layout_data;
if (!nodedata)
{
continue;
}
if (!items_node->layout_data)
continue;
if (nodedata->realized)
{
for(j = 0; j != items_node->length;++j)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j];
double x, y, w, h;
double weight_x, weight_y;
if (layout_item->min.w && layout_item->min.h)
{
assert(layout_item->layout != NULL);
if (pd->resize)
_item_size_calc(pd, layout_item);
efl_gfx_size_hint_weight_get(layout_item->layout, &weight_x, &weight_y);
// extra rounding up (compensate cumulative error)
if ((i == (pd->count_total - 1)) && (cur_pos - floor(cur_pos) >= 0.5))
rounding = 1;
x = layout_item->pos.x;
y = layout_item->pos.y + cur_pos;
w = layout_item->size.w;
h = layout_item->size.h + rounding + weight_y * extra;
cur_pos += h;
if (w < pd->min.w) w = pd->min.w;
if (w > vgmt.w) w = vgmt.w;
evas_object_geometry_set(layout_item->layout, (x + 0 - spos.x), (y + 0 - spos.y), w, h);
}
}
}
else
if (!nodedata->realized)
{
cur_pos += nodedata->min.h;
continue;
}
for (j = 0; j != items_node->length;++j)
{
layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j];
double x, y, w, h;
double weight_x, weight_y;
if (!(layout_item->min.w && layout_item->min.h))
continue;
// extra rounding up (compensate cumulative error)
if ((i == (pd->count_total - 1)) && (cur_pos - floor(cur_pos) >= 0.5))
rounding = 1;
if (layout_item->layout)
{
if (pd->resize)
_item_size_calc(pd, layout_item);
efl_gfx_size_hint_weight_get(layout_item->layout, &weight_x, &weight_y);
}
else
{
cur_pos += layout_item->size.h;
continue;
}
x = layout_item->pos.x;
y = layout_item->pos.y + cur_pos;
w = layout_item->size.w;
h = layout_item->size.h + rounding + weight_y * extra;
cur_pos += h;
if (w < pd->min.w) w = pd->min.w;
if (w > vgmt.w) w = vgmt.w;
evas_object_geometry_set(layout_item->layout, (x + 0 - spos.x), (y + 0 - spos.y), w, h);
}
}
eina_accessor_free(nodes);
@ -691,18 +688,15 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd)
EOLIAN static void
_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_layout_do
(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd
, Efl_Ui_List_View_Model *modeler, int first, Efl_Ui_List_View_Seg_Array *seg_array)
, Efl_Ui_List_View_Model *modeler, int first EINA_UNUSED, Efl_Ui_List_View_Seg_Array *seg_array)
{
if (!_initilize(obj, pd, modeler, seg_array) || !pd->seg_array)
return;
pd->first = first;
if (pd->recalc && efl_ui_list_view_seg_array_count(seg_array) > 0)
if (!pd->calc_job && pd->recalc && efl_ui_list_view_seg_array_count(seg_array) > 0)
{
// cache size of new items
pd->calc_progress = 0;
ecore_job_del(pd->calc_job);
pd->calc_job = ecore_job_add(_calc_size_job, obj);
return;
}

View File

@ -3,6 +3,7 @@ class Efl.Ui.List_View_Precise_Layouter (Efl.Object, Efl.Ui.List_View_Relayout)
implements {
Efl.Object.constructor;
Efl.Ui.List_View_Relayout.layout_do;
Efl.Ui.List_View_Relayout.content_created;
Efl.Ui.List_View_Relayout.model { set; }
Efl.Ui.List_View_Relayout.elements { get; }
}

View File

@ -8,6 +8,11 @@ interface Efl.Ui.List_View_Relayout (Efl.Interface)
children: Efl.Ui.List_View_Seg_Array;
}
}
content_created {
params {
item: ptr(Efl.Ui.List_View_Layout_Item);
}
}
@property model {
[[Model that is/will be ]]
set {}

View File

@ -10,6 +10,10 @@
#define MY_CLASS EFL_UI_SELECTION_MIXIN
#define MY_CLASS_NAME "Efl.Ui.Selection"
#ifdef HAVE_ELEMENTARY_WL2
Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj);
#endif
EOLIAN static void
_efl_ui_selection_selection_get(Eo *obj, void *pd EINA_UNUSED, Efl_Ui_Selection_Type type, Efl_Ui_Selection_Format format,
void *data_func_data, Efl_Ui_Selection_Data_Ready data_func, Eina_Free_Cb data_func_free_cb, unsigned int seat)
@ -72,34 +76,6 @@ _wl_is_wl(const Evas_Object *obj)
return NULL;
}
static Ecore_Wl2_Window *
_wl_window_get(const Evas_Object *obj)
{
Evas_Object *top;
Ecore_Wl2_Window *win = NULL;
if (elm_widget_is(obj))
{
top = elm_widget_top_get(obj);
if (!top) top = elm_widget_top_get(elm_widget_parent_widget_get(obj));
if (top && (efl_isa(top, EFL_UI_WIN_CLASS)))
win = elm_win_wl_window_get(top);
}
if (!win)
{
Ecore_Evas *ee = _wl_is_wl(obj);
if (ee)
{
/* In case the engine is not a buffer, we want to check once. */
win = ecore_evas_wayland2_window_get(ee);
if (!win) return NULL;
}
}
return win;
}
int
_wl_default_seat_id_get(Evas_Object *obj)
{
@ -212,8 +188,7 @@ elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type type,
if (!wdata) return EINA_FALSE;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get((Evas_Object *)obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get((Evas_Object *)obj);
#endif
wdata->udata = udata;
wdata->datacb = datacb;
@ -238,7 +213,7 @@ elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type type,
data.mem = selbuf;
data.len = buflen;
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
f = efl_ui_selection_manager_selection_set(sel_man, obj, (Efl_Ui_Selection_Type)type,
(Efl_Ui_Selection_Format)format, data, seatid);
@ -257,7 +232,7 @@ elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type type)
Eo *sel_man = _efl_ui_selection_manager_get((Evas_Object *)obj);
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
efl_ui_selection_manager_selection_clear(sel_man, obj, (Efl_Ui_Selection_Type)type, seatid);
@ -289,7 +264,7 @@ elm_selection_selection_has_owner(Evas_Object *obj)
Eo *sel_man = _efl_ui_selection_manager_get((Evas_Object *)obj);
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
return efl_ui_selection_manager_selection_has_owner(sel_man, obj,
@ -303,7 +278,7 @@ elm_cnp_clipboard_selection_has_owner(Evas_Object *obj)
Eo *sel_man = _efl_ui_selection_manager_get((Evas_Object *)obj);
#ifdef HAVE_ELEMENTARY_WL2
seatid = _wl_default_seat_id_get(obj);
if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj);
#endif
return efl_ui_selection_manager_selection_has_owner(sel_man, obj,
EFL_UI_SELECTION_TYPE_CLIPBOARD, seatid);

View File

@ -37,7 +37,7 @@ static Ecore_X_Window _x11_xwin_get(const Evas_Object *obj);
#endif
#ifdef HAVE_ELEMENTARY_WL2
static Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj);
Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj);
static Ecore_Wl2_Input *_wl_seat_get(Ecore_Wl2_Window *win, Evas_Object *obj, unsigned int seat_id);
#endif
@ -738,14 +738,16 @@ _x11_data_preparer_uri(Sel_Manager_Seat_Selection *seat_sel, Ecore_X_Event_Selec
return EINA_FALSE;
}
free(seat_sel->saved_types->imgfile);
#if 0 // this seems to be broken - we should be handling uri lists as text
if (seat_sel->saved_types->textreq)
{
seat_sel->saved_types->textreq = 0;
seat_sel->saved_types->imgfile = stripstr;
}
else
#endif
{
ddata->format = EFL_UI_SELECTION_FORMAT_IMAGE;
ddata->format = EFL_UI_SELECTION_FORMAT_TEXT;
ddata->content.mem = stripstr;
ddata->content.len = strlen(stripstr);
seat_sel->saved_types->imgfile = NULL;
@ -944,7 +946,7 @@ _efl_sel_manager_x11_selection_notify(void *udata, int type EINA_UNUSED, void *e
{
if (pd->atom_list[i].x_data_preparer)
{
Efl_Ui_Selection_Data ddata;
Efl_Ui_Selection_Data ddata = { 0 };
Tmp_Info *tmp_info = NULL;
Eina_Bool success;
sel_debug("Found something: %s", pd->atom_list[i].name);
@ -1960,11 +1962,9 @@ _x11_dnd_drop(void *data, int etype EINA_UNUSED, void *ev)
Efl_Ui_Selection_Manager_Data *pd = seat_sel->pd;
Ecore_X_Event_Xdnd_Drop *drop;
Sel_Manager_Dropable *dropable = NULL;
Efl_Ui_Selection_Data ddata;
Evas_Coord x = 0, y = 0;
Efl_Ui_Selection_Action act = EFL_UI_SELECTION_ACTION_UNKNOWN;
Eina_List *l;
Eina_Inlist *itr;
Sel_Manager_Selection *sel;
drop = ev;
@ -2000,6 +2000,10 @@ found:
dropable->last.in = EINA_FALSE;
sel_debug("Last type: %s - Last format: %X\n", dropable->last.type, dropable->last.format);
#if 0 // this seems to be broken and causes dnd to stop working e.g. to/from
// rage even though iut used to work fine.
Efl_Ui_Selection_Data ddata;
Eina_Inlist *itr;
if ((!strcmp(dropable->last.type, pd->text_uri)))
{
sel_debug("We found a URI... (%scached) %s\n",
@ -2061,7 +2065,7 @@ found:
return EINA_TRUE;
}
}
#endif
sel = seat_sel->sel_list + EFL_UI_SELECTION_TYPE_DND;
sel_debug("doing a request then: %s\n", dropable->last.type);
sel->xwin = drop->win;
@ -2069,6 +2073,7 @@ found:
sel->request_format = dropable->last.format;
sel->active = EINA_TRUE;
sel->action = act;
sel->asked++;
ecore_x_selection_xdnd_request(drop->win, dropable->last.type);
return EINA_TRUE;
@ -2806,7 +2811,7 @@ _wl_seat_get(Ecore_Wl2_Window *win, Evas_Object *obj, unsigned int seat_id)
evas_device_seat_id_get(seat));
}
static Ecore_Wl2_Window *
Ecore_Wl2_Window *
_wl_window_get(const Evas_Object *obj)
{
Evas_Object *top;
@ -5269,7 +5274,7 @@ _efl_ui_selection_manager_efl_object_constructor(Eo *obj, Efl_Ui_Selection_Manag
#endif
pd->atom_list[SELECTION_ATOM_TEXT_URILIST].name = "text/uri-list";
pd->atom_list[SELECTION_ATOM_TEXT_URILIST].format = EFL_UI_SELECTION_FORMAT_IMAGE;
pd->atom_list[SELECTION_ATOM_TEXT_URILIST].format = EFL_UI_SELECTION_FORMAT_TEXT;
#ifdef HAVE_ELEMENTARY_X
pd->atom_list[SELECTION_ATOM_TEXT_URILIST].x_converter = _x11_general_converter;
pd->atom_list[SELECTION_ATOM_TEXT_URILIST].x_data_preparer = _x11_data_preparer_uri;

View File

@ -2168,7 +2168,6 @@ _efl_ui_text_efl_object_finalize(Eo *obj,
//efl_text_font_set(sd->text_obj, "Sans", 12);
sd->single_line = !efl_text_multiline_get(sd->text_obj);
efl_text_set(sd->text_obj, "");
efl_pack_table(sd->text_table, sd->text_obj, 0, 0, 1, 1);
efl_pack_table(sd->text_table, sd->text_guide_obj, 0, 0, 1, 1);

View File

@ -1,4 +1,4 @@
mixin Efl.Ui.Widget_Focus_Manager (Efl.Interface, Efl.Ui.Widget, Efl.Ui.Focus.Manager)
mixin Efl.Ui.Widget_Focus_Manager requires Efl.Ui.Widget extends Efl.Ui.Focus.Manager
{
methods {
focus_manager_create @protected @pure_virtual {

View File

@ -3564,7 +3564,7 @@ _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize)
double wx, wy;
evas_object_size_hint_combined_min_get(sd->legacy.edje, &minw, &minh);
if ((!minw) && (!minh)) return;
if ((!minw) && (!minh) && (!sd->deferred_resize_job)) return;
// If content has a weight, make resizable
efl_gfx_size_hint_weight_get(sd->legacy.edje, &wx, &wy);
@ -3610,6 +3610,12 @@ _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize)
sd->tmp_updating_hints = 0;
_elm_win_size_hints_update(obj, sd);
if (sd->deferred_resize_job)
_elm_win_resize_job(sd->obj);
/* do not need to go below. if you go, ee could become 0. */
if ((!minw) && (!minh)) return;
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
w = ow;
h = oh;

View File

@ -27,7 +27,7 @@ enum Elm.Scroller.Single_Direction
last [[Sentinel value to indicate last enum field during iteration]]
}
mixin Elm.Interface_Scrollable(Efl.Ui.Scrollable, Efl.Ui.Focus.Manager_Sub, Efl.Ui.Widget, Efl.Ui.Widget_Focus_Manager)
mixin Elm.Interface_Scrollable requires Efl.Ui.Widget extends Efl.Ui.Scrollable, Efl.Ui.Focus.Manager_Sub, Efl.Ui.Widget_Focus_Manager
{
[[Elm scrollable mixin]]
eo_prefix: elm_interface_scrollable;

View File

@ -1607,6 +1607,8 @@ _overlay_default_content_update(Overlay_Default *ovl,
if (ovl->content == content) return;
evas_object_del(ovl->content);
ovl->content = content;
evas_object_smart_member_add(ovl->content, ovl->wsd->pan_obj);
evas_object_stack_above(ovl->content, ovl->wsd->sep_maps_overlays);
if (ovl->content)
evas_object_event_callback_add(ovl->content, EVAS_CALLBACK_MOUSE_DOWN,

View File

@ -281,7 +281,8 @@ pub_eo_files = [
'elm_view_form.eo',
'elm_web.eo',
'elm_widget_item.eo',
'efl_ui_text_part.eo'
'efl_ui_text_part.eo',
'efl_ui_caching_factory.eo',
]
foreach eo_file : pub_eo_files
@ -908,7 +909,8 @@ elementary_src = [
'efl_ui_tab_pager.c',
'efl_ui_tab_bar.c',
'efl_ui_tab_page.c',
'efl_ui_widget_focus_manager.c'
'efl_ui_widget_focus_manager.c',
'efl_ui_caching_factory.c'
]
elementary_deps = [emile, eo, efl, edje, ethumb, ethumb_client, emotion, ecore_imf, ecore_con, eldbus, efreet, efreet_mime, efreet_trash, eio, atspi, dl, intl]
@ -919,7 +921,7 @@ elm_options = configuration_data()
config_h.set_quoted('ELM_TOP_BUILD_DIR', meson.build_root())
config_h.set_quoted('MODULES_PATH', join_paths(dir_lib, 'modules'))
config_h.set_quoted('ELEMENTARY_BASE_DIR', '.elementary')
config_h.set_quoted('ELEMENTARY_BASE_DIR', get_option('elementary-base-dir'))
config_h.set_quoted('ICON_DIR', join_paths(dir_lib, 'icons'))
if sys_windows == false

View File

@ -918,13 +918,22 @@ EAPI Eina_Bool efl_isa(const Eo *obj, const Efl_Class *klass);
/**
* @brief Gets the name of the passed class.
* @param klass the class to work on.
* @param[in] klass The class (or object) to work on.
* @return The class' name.
*
* @see efl_class_get()
*/
EAPI const char *efl_class_name_get(const Efl_Class *klass);
/**
* @brief Gets the amount of memory this class object would use.
* @param[in] klass The class (or object) to work on.
* @return The amount of memory in Bytes.
*
* @see efl_class_get()
*/
EAPI size_t efl_class_memory_size_get(const Efl_Class *klass);
/**
* @brief Gets a debug name for this object
* @param obj_id The object (or class)
@ -2008,7 +2017,7 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_
/**
* @def efl_event_callback_add(obj, desc, cb, data)
* Add a callback for an event.
* @param[in] desc The description of the event to listen to.
* @param[in] desc An #Efl_Event_Description of the event to listen to.
* @param[in] cb the callback to call.
* @param[in] data additional data to pass to the callback.
*
@ -2024,6 +2033,7 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_
* @def efl_event_callback_array_add(obj, desc, cb, data)
* Add an array of callbacks for an event.
*
* @param[in] obj The object.
* @param[in] array an #Efl_Callback_Array_Item of events to listen to.
* @param[in] data additional data to pass to the callback.
*
@ -2044,7 +2054,7 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_
* @brief Add an event callback forwarder for an event and an object.
*
* @param[in] obj The object.
* @param[in] desc The description of the event to listen to
* @param[in] desc An #Efl_Event_Description of the event to forward to.
* @param[in] new_obj The object to emit events from
*
* @ingroup Efl_Object

View File

@ -13,6 +13,10 @@ type Efl.Callback_Priority : short;
[[
Callback priority. Range is -32k - 32k. The lower the number, the higher the priority.
This is used to insert an event handler relative to the existing stack of sorted event
handlers according to that priority. All event handlers always have a priority. If not
specified @Efl.Callback_Priority_Default is to be assumed.
See @Efl.Callback_Priority_Before @Efl.Callback_Priority_Default @Efl.Callback_Priority_After
]]
@ -166,7 +170,7 @@ abstract Efl.Object
If this is not done the class cannot be found up in the object tree.
]]
params {
klass : const(Efl.Object); [[The class identifier to search for]]
klass : const(Efl.Class); [[The class identifier to search for]]
}
return : Efl.Object; [[Object from the provider list]]
}
@ -245,15 +249,31 @@ abstract Efl.Object
]]
}
event_callback_forwarder_priority_add {
[[Add an event callback forwarder for an event and an object.]]
[[Add an event callback forwarder that will make this object emit an event whenever another
object ($source) emits it. The event is said to be forwarded from $source to this object.
The event is unaffected on $source and behave like any other event being propagated on
any object and will trigger all the handler registered on $source like nothing special
happened.
This allow object that hide internally another object to easily be able to propagate an event
without the need to add custom handler.
Note: The priority is used to make sure that you are intercepting the event when you expect
by inserting a handler at the right position in the stack of event handler on the object that
emit the event.]]
params {
@cref desc: Efl.Event_Description; [[The description of the event to listen to]]
@in priority: short; [[The priority at which to insert the callback handler.]]
@in new_obj: Efl.Object @nonull; [[The object to emit events from]]
@in priority: Efl.Callback_Priority; [[The priority at which to insert the event forwarder handler
in the existing list of handler on the source of event object. The lower the number, the higher
the priority. As a shortcut @Efl.Callback_Priority_Before,
@Efl.Callback_Priority_Default and @Efl.Callback_Priority_After can be used. See
@Efl.Callback_Priority for more details.]]
@in source: Efl.Object @nonull; [[The object which emits the initial event]]
}
}
event_callback_forwarder_del {
[[Remove an event callback forwarder for an event and an object.]]
[[Remove an event callback forwarder for a specified event and object.]]
params {
@cref desc: Efl.Event_Description; [[The description of the event to listen to]]
@in new_obj: Efl.Object @nonull; [[The object to emit events from]]

View File

@ -1150,6 +1150,31 @@ err_obj:
return NULL;
}
EAPI size_t
efl_class_memory_size_get(const Efl_Class *eo_id)
{
const _Efl_Class *klass;
if (_eo_is_a_class(eo_id))
{
EO_CLASS_POINTER_GOTO(eo_id, _klass, err_klass);
klass = _klass;
}
else
{
EO_OBJ_POINTER_GOTO(eo_id, obj, err_obj);
klass = obj->klass;
EO_OBJ_DONE(eo_id);
}
return klass->obj_size;
err_klass:
_EO_POINTER_ERR(eo_id, "Class (%p) is an invalid ref.", eo_id);
err_obj:
return 0;
}
static void
_vtable_init(Eo_Vtable *vtable, size_t size)
{

View File

@ -508,6 +508,12 @@ _get_impl_class(const Eolian_Class *cl, const char *cln)
if (fcl)
return fcl;
}
EINA_LIST_FOREACH(cl->requires, l, icl)
{
const Eolian_Class *fcl = _get_impl_class(icl, cln);
if (fcl)
return fcl;
}
EINA_LIST_FOREACH(cl->extends, l, icl)
{
const Eolian_Class *fcl = _get_impl_class(icl, cln);
@ -743,9 +749,10 @@ _db_fill_inherits(Eolian_Class *cl, Eina_Hash *fhash)
if (eina_hash_find(cl->base.unit->state->main.unit.classes, cl->base.name))
return EINA_TRUE;
Eina_List *il = cl->extends;
Eina_List *il = cl->extends, *rl = cl->requires;
Eina_Stringshare *inn = NULL;
cl->extends = NULL;
cl->requires = NULL;
Eina_Bool succ = EINA_TRUE;
if (cl->parent_name)
@ -771,6 +778,30 @@ _db_fill_inherits(Eolian_Class *cl, Eina_Hash *fhash)
succ = _db_fill_inherits(out_cl, fhash);
}
if (succ && cl->type == EOLIAN_CLASS_MIXIN)
{
EINA_LIST_FREE(rl, inn)
{
Eolian_Class *out_cl = NULL;
succ = _db_swap_inherit(cl, succ, inn, &out_cl);
if (succ && !(out_cl->type == EOLIAN_CLASS_REGULAR || out_cl->type == EOLIAN_CLASS_ABSTRACT))
{
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "requires only allows regulars or abstracts");
_obj_error(&cl->base, buf);
succ = EINA_FALSE;
}
if (succ)
{
_db_fill_inherits(out_cl, fhash);
}
if (!succ)
continue;
if (!eina_list_data_find(cl->requires, out_cl))
cl->requires = eina_list_append(cl->requires, out_cl);
}
}
/* failed on the way, no point in filling further
* the failed stuff will get dropped so it's ok if it's inconsistent
*/
@ -805,6 +836,24 @@ _validate_implement(Eolian_Implement *impl)
return _validate(&impl->base);
}
static Eina_List*
_required_classes(Eolian_Class *mixin)
{
Eina_List *result = NULL, *n;
Eolian_Class *extension;
result = eina_list_clone(mixin->requires);
if (mixin->parent)
result = eina_list_merge(result, _required_classes(mixin->parent));
EINA_LIST_FOREACH(mixin->extends, n, extension)
result = eina_list_merge(result, _required_classes(extension));
return result;
}
static Eina_Bool
_validate_class(Validate_State *vals, Eolian_Class *cl,
Eina_Hash *nhash, Eina_Hash *ehash, Eina_Hash *chash)
@ -815,6 +864,7 @@ _validate_class(Validate_State *vals, Eolian_Class *cl,
Eolian_Part *part;
Eolian_Implement *impl;
Eolian_Class *icl;
Eina_List *required_classes = NULL;
if (!cl)
return EINA_FALSE; /* if this happens something is very wrong though */
@ -849,6 +899,17 @@ _validate_class(Validate_State *vals, Eolian_Class *cl,
EINA_LIST_FOREACH(cl->extends, l, icl)
{
if (icl->type == EOLIAN_CLASS_MIXIN)
{
Eina_List *res = _required_classes(icl);
Eolian_Class *required_class;
Eina_List *n;
EINA_LIST_FOREACH(res, n, required_class)
{
if (!eina_list_data_find(required_classes, required_class))
required_classes = eina_list_append(required_classes, required_class);
}
}
if (!valid && vals->ext_regular) switch (icl->type)
{
case EOLIAN_CLASS_REGULAR:
@ -869,6 +930,35 @@ _validate_class(Validate_State *vals, Eolian_Class *cl,
if (!_validate_class(vals, icl, nhash, ehash, chash))
return EINA_FALSE;
}
if (cl->type == EOLIAN_CLASS_ABSTRACT || cl->type == EOLIAN_CLASS_REGULAR)
{
//walk up the parent list and remove all classes from there
icl = cl;
while (icl)
{
required_classes = eina_list_remove(required_classes, icl);
icl = icl->parent;
}
//if there are a few left, drop, and error
if (required_classes)
{
Eina_Strbuf *classes = eina_strbuf_new();
Eolian_Class *required_class;
Eina_List *n;
EINA_LIST_FOREACH(required_classes, n, required_class)
{
eina_strbuf_append(classes, required_class->base.name);
eina_strbuf_append_char(classes, ' ');
}
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "required classes %sare not in the inherit chain of %s",
eina_strbuf_string_get(classes), cl->base.name);
eina_strbuf_free(classes);
_obj_error(&cl->base, buf);
return EINA_FALSE;
}
}
EINA_LIST_FOREACH(cl->properties, l, func)
if (!_validate_function(vals, func, nhash))

View File

@ -28,7 +28,7 @@ enum Tokens
KW(destructor), KW(eo), KW(eo_prefix), KW(event_prefix), KW(events), \
KW(extends), KW(free), KW(get), KW(implements), KW(import), KW(interface), \
KW(keys), KW(legacy), KW(legacy_prefix), KW(methods), KW(mixin), KW(params), \
KW(parse), KW(parts), KW(ptr), KW(set), KW(type), KW(values), KW(var), \
KW(parse), KW(parts), KW(ptr), KW(set), KW(type), KW(values), KW(var), KW(requires), \
\
KWAT(auto), KWAT(beta), KWAT(class), KWAT(const), KWAT(cref), KWAT(empty), \
KWAT(extern), KWAT(free), KWAT(hot), KWAT(in), KWAT(inout), KWAT(nonull), \

View File

@ -2009,6 +2009,24 @@ inherit_dup:
eo_lexer_syntax_error(ls, ebuf);
}
static void
_requires_add(Eo_Lexer *ls, Eina_Strbuf *buf)
{
const char *required;
char *fnm;
eo_lexer_context_push(ls);
parse_name(ls, buf);
required = eina_strbuf_string_get(buf);
fnm = database_class_to_filename(required);
ls->klass->requires = eina_list_append(ls->klass->requires, eina_stringshare_add(required));
database_defer(ls->state, fnm, EINA_TRUE);
eo_lexer_context_pop(ls);
free(fnm);
}
static void
parse_class(Eo_Lexer *ls, Eolian_Class_Type type)
{
@ -2052,6 +2070,20 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type)
Eina_Strbuf *ibuf = eina_strbuf_new();
eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf);
/* new inherits syntax, keep alongside old for now */
if (ls->t.kw == KW_requires)
{
if (type != EOLIAN_CLASS_MIXIN)
{
eo_lexer_syntax_error(ls, "\"requires\" keyword is only needed for mixin classes");
}
eo_lexer_get(ls);
do
_requires_add(ls, ibuf);
while (test_next(ls, ','));
if (ls->t.token == '{')
goto inherit_done;
}
if (ls->t.kw == KW_extends || (is_reg && (ls->t.kw == KW_implements)))
{
Eina_Bool ext = (ls->t.kw == KW_extends);

View File

@ -191,6 +191,7 @@ struct _Eolian_Class
Eina_List *constructors; /* Eolian_Constructor */
Eina_List *events; /* Eolian_Event */
Eina_List *parts; /* Eolian_Part */
Eina_List *requires; /* a list of required other classes only used internally */
Eina_Bool class_ctor_enable:1;
Eina_Bool class_dtor_enable:1;
};

View File

@ -106,18 +106,20 @@ struct klass_name
std::string eolian_name;
qualifier_def base_qualifier;
class_type type;
std::string klass_get_name;
klass_name() {
}
klass_name(std::vector<std::string> namespaces
, std::string eolian_name, qualifier_def base_qualifier
, class_type type)
, class_type type, std::string klass_get_name)
: namespaces(namespaces), eolian_name(eolian_name), base_qualifier(base_qualifier)
, type(type) {}
, type(type), klass_get_name(klass_get_name) {}
klass_name(Eolian_Class const* klass, qualifier_def base_qualifier)
: eolian_name( ::eolian_class_short_name_get(klass))
, base_qualifier(base_qualifier)
, klass_get_name( ::eolian_class_c_get_function_name_get(klass))
{
for(efl::eina::iterator<const char> namespace_iterator ( ::eolian_class_namespaces_get(klass))
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
@ -1003,6 +1005,7 @@ struct klass_def
std::set<klass_name, compare_klass_name_by_name> immediate_inherits;
eina::optional<klass_name> parent;
std::set<klass_name, compare_klass_name_by_name> extensions;
std::string klass_get_name;
std::set<part_def> parts;
Eolian_Unit const* unit;
@ -1018,7 +1021,8 @@ struct klass_def
&& lhs.inherits == rhs.inherits
&& lhs.type == rhs.type
&& lhs.events == rhs.events
&& lhs.parts == rhs.parts;
&& lhs.parts == rhs.parts
&& lhs.klass_get_name == rhs.klass_get_name;
}
friend inline bool operator!=(klass_def const& lhs, klass_def const& rhs)
{
@ -1039,24 +1043,29 @@ struct klass_def
, std::vector<property_def> properties
, std::set<klass_name, compare_klass_name_by_name> inherits
, class_type type
, std::set<klass_name, compare_klass_name_by_name> immediate_inherits)
, std::set<klass_name, compare_klass_name_by_name> immediate_inherits
, std::string klass_get_name)
: eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
, documentation(documentation)
, namespaces(namespaces)
, functions(functions), properties(properties), inherits(inherits), type(type)
, immediate_inherits(immediate_inherits)
, klass_get_name(klass_get_name)
{}
klass_def(std::string _eolian_name, std::string _cxx_name
, std::vector<std::string> _namespaces
, std::vector<function_def> _functions
, std::vector<property_def> _properties
, std::set<klass_name, compare_klass_name_by_name> _inherits
, class_type _type, Eolian_Unit const* unit)
, class_type _type, Eolian_Unit const* unit
, std::string klass_get_name)
: eolian_name(_eolian_name), cxx_name(_cxx_name)
, namespaces(_namespaces)
, functions(_functions), properties(_properties), inherits(_inherits), type(_type), unit(unit)
, klass_get_name(klass_get_name)
{}
klass_def(Eolian_Class const* klass, Eolian_Unit const* unit) : unit(unit)
, klass_get_name( ::eolian_class_c_get_function_name_get(klass))
{
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_class_namespaces_get(klass))
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
@ -1349,7 +1358,7 @@ struct struct_def
inline klass_name get_klass_name(klass_def const& klass)
{
return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, klass.type};
return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, klass.type, klass.klass_get_name};
}
inline Eolian_Class const* get_klass(klass_name const& klass_name_, Eolian_Unit const* unit)

View File

@ -41,7 +41,7 @@ struct Efl.Canvas.Filter.State
pos: double; [[Position]]
}
mixin Efl.Canvas.Filter.Internal (Efl.Gfx.Filter, Efl.Object)
mixin Efl.Canvas.Filter.Internal requires Efl.Object extends Efl.Gfx.Filter
{
[[Evas internal implementation of filters.]]

View File

@ -1,4 +1,4 @@
mixin Efl.Gfx.Map (Efl.Interface, Efl.Object)
mixin Efl.Gfx.Map requires Efl.Object
{
[[Texture UV mapping for all objects (rotation, perspective, 3d, ...).

View File

@ -1,6 +1,6 @@
import efl_input_types;
mixin Efl.Input.Event (Efl.Interface, Efl.Object, Efl.Duplicate)
mixin Efl.Input.Event requires Efl.Object extends Efl.Duplicate
{
[[Represents a generic event data.

View File

@ -2842,7 +2842,8 @@ _format_dup(Evas_Object *eo_obj, const Evas_Object_Textblock_Format *fmt)
fmt2->gfx_filter = malloc(sizeof(*fmt2->gfx_filter));
memcpy(fmt2->gfx_filter, fmt->gfx_filter, sizeof(*fmt->gfx_filter));
fmt2->gfx_filter->name = eina_stringshare_ref(fmt->gfx_filter->name);
fmt2->gfx_filter->dc = ENFN->context_dup(ENC, fmt->gfx_filter->dc);
if (fmt->gfx_filter->dc)
fmt2->gfx_filter->dc = ENFN->context_dup(ENC, fmt->gfx_filter->dc);
}
return fmt2;
@ -6787,6 +6788,8 @@ _relayout_if_needed(const Evas_Object *eo_obj, Efl_Canvas_Text_Data *o)
ASYNC_BLOCK;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
if (obj->delete_me) return EINA_TRUE;
/* XXX const */
evas_object_textblock_coords_recalc((Evas_Object *)eo_obj, obj, obj->private_data);
if (o->formatted.valid)
@ -14855,7 +14858,11 @@ evas_object_textblock_render_pre(Evas_Object *eo_obj,
if ((obj->cur->color.r != obj->prev->color.r) ||
(obj->cur->color.g != obj->prev->color.g) ||
(obj->cur->color.b != obj->prev->color.b) ||
(obj->cur->color.a != obj->prev->color.a))
(obj->cur->color.a != obj->prev->color.a) ||
(obj->cur->cache.clip.r != obj->prev->cache.clip.r) ||
(obj->cur->cache.clip.g != obj->prev->cache.clip.g) ||
(obj->cur->cache.clip.b != obj->prev->cache.clip.b) ||
(obj->cur->cache.clip.a != obj->prev->cache.clip.a))
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
eo_obj, obj);

View File

@ -139,7 +139,7 @@ if (get_option('hyphen'))
evas_deps += cc.find_library('hyphen')
endif
evas_deps += hyphen
config_h.set_quoted('EVAS_DICTS_HYPHEN_DIR', '/usr/share/hyphen')
config_h.set_quoted('EVAS_DICTS_HYPHEN_DIR', get_option('dictionaries-hyphen-dir'))
endif
subdir('include')

View File

@ -4,22 +4,19 @@ subdir('shm')
#common dri packages
libtbm = dependency('libtbm', required: false)
libdrm = dependency('libdrm', required: false)
if libtbm.found() == true and libdrm.found() == true
if libtbm.found() == true
libdri2 = dependency('libdri2', required: false)
if libdri2.found()
subdir('x11_dri2')
endif
endif
if libtbm.found() == true and libdrm.found() == true
xshmfence = dependency('xshmfence', required: false)
xcb = dependency('xcb', required: false)
x11_xcb = dependency('x11_xcb', required: false)
xcb_sync = dependency('xcb_sync', required: false)
xcb_dri3 = dependency('xkb_dri3', required: false)
if xshmfence.found() == true and xcb.found() == true and x11_xcb.found() and xcb_sync.found() and xkb_dri3.found()
subdir('x11_dri3')
subdir('x11_dri3')
endif
endif

View File

@ -5,7 +5,7 @@ evas_gl_font_texture_new(void *context, RGBA_Font_Glyph *fg)
{
Evas_Engine_GL_Context *gc = context;
Evas_GL_Texture *tex;
int w, h, j, nw, fh, x, y;
int w, h, j, nw, fh, y;
DATA8 *ndata, *data, *p1, *p2;
if (fg->ext_dat) return fg->ext_dat; // FIXME: one engine at a time can do this :(
@ -22,19 +22,21 @@ evas_gl_font_texture_new(void *context, RGBA_Font_Glyph *fg)
// expand to 32bit (4 byte) aligned rows for texture upload
nw = ((w + 3) / 4) * 4;
ndata = alloca(nw *h);
if (!ndata) return NULL;
for (y = 0; y < h; y++)
{
// if image already (4 byte) aligned rows then assign old image data to new data(ndata) to
if(nw == w){
ndata = data;
} else {
ndata = alloca(nw *h);
if (!ndata) return NULL;
// else copy row by row
for (y = 0; y < h; y++)
{
p1 = data + (j * y);
p2 = ndata + (nw * y);
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
memcpy(p2,p1,w);
}
}
fh = fg->fi->max_h;
tex = evas_gl_common_texture_alpha_new(gc, ndata, w, h, fh);
if (!tex) goto done;

View File

@ -1341,7 +1341,7 @@ test_got_int(Eo *o EINA_UNUSED, void *data EINA_UNUSED, const Eina_Value value)
}
static Eina_Value
test_error_not_reached(Eo *o EINA_UNUSED, void *data EINA_UNUSED, Eina_Error error)
test_error_not_reached(Eo *o EINA_UNUSED, void *data EINA_UNUSED, Eina_Error error EINA_UNUSED)
{
abort();

View File

@ -214,7 +214,7 @@ _efl_test_model_view_child_get(Eo *obj EINA_UNUSED,
static Eina_Value
_efl_test_model_view_child_fetch(Eo *mv,
void *data EINA_UNUSED,
const Eina_Value v)
const Eina_Value v EINA_UNUSED)
{
Eina_Future *r;

View File

@ -7,283 +7,6 @@ using System.Runtime.CompilerServices;
using EinaTestData;
using static EinaTestData.BaseData;
namespace EinaTestData
{
class BaseSequence
{
public static byte[] Values()
{
return new byte[3]{0x0,0x2A,0x42};
}
}
public static class BaseData
{
public static readonly int[] base_seq_int = {0x0,0x2A,0x42};
public static readonly int[] append_seq_int = {42,43,33};
public static readonly int[] modified_seq_int = {0x0,0x2A,0x42,42,43,33};
public static readonly string[] base_seq_str = {"0x0","0x2A","0x42"};
public static readonly string[] append_seq_str = {"42","43","33"};
public static readonly string[] modified_seq_str = {"0x0","0x2A","0x42","42","43","33"};
public static Dummy.Numberwrapper NW(int n)
{
var nw = new Dummy.Numberwrapper();
nw.SetNumber(n);
return nw;
}
public static Dummy.Numberwrapper[] BaseSeqObj()
{
var a = new Dummy.Numberwrapper();
var b = new Dummy.Numberwrapper();
var c = new Dummy.Numberwrapper();
a.SetNumber(0x0);
b.SetNumber(0x2A);
c.SetNumber(0x42);
return new Dummy.Numberwrapper[]{a,b,c};
}
public static Dummy.Numberwrapper[] AppendSeqObj()
{
var a = new Dummy.Numberwrapper();
var b = new Dummy.Numberwrapper();
var c = new Dummy.Numberwrapper();
a.SetNumber(42);
b.SetNumber(43);
c.SetNumber(33);
return new Dummy.Numberwrapper[]{a,b,c};
}
public static Dummy.Numberwrapper[] ModifiedSeqObj()
{
var a = new Dummy.Numberwrapper();
var b = new Dummy.Numberwrapper();
var c = new Dummy.Numberwrapper();
var d = new Dummy.Numberwrapper();
var e = new Dummy.Numberwrapper();
var f = new Dummy.Numberwrapper();
a.SetNumber(0x0);
b.SetNumber(0x2A);
c.SetNumber(0x42);
d.SetNumber(42);
e.SetNumber(43);
f.SetNumber(33);
return new Dummy.Numberwrapper[]{a,b,c,d,e,f};
}
public static void NumberwrapperSequenceAssertEqual(
Dummy.Numberwrapper[] a
, Dummy.Numberwrapper[] b
, [CallerLineNumber] int line = 0
, [CallerFilePath] string file = null
, [CallerMemberName] string member = null)
{
Test.Assert(a.Length == b.Length, "Different lenght", line, file, member);
for (int i = 0; i < a.Length; ++i)
{
int av = a[i].GetNumber();
int bv = b[i].GetNumber();
Test.Assert(av == bv, $"Different values for element [{i}]: {av} == {bv}", line, file, member);
}
}
}
class NativeInheritImpl : Dummy.TestObject
{
public NativeInheritImpl(Efl.Object parent = null) : base(parent) {}
public bool slice_in_flag = false;
public bool rw_slice_in_flag = false;
public bool slice_out_flag = false;
public bool rw_slice_out_flag = false;
public bool binbuf_in_flag = false;
public bool binbuf_in_own_flag = false;
public bool binbuf_out_flag = false;
public bool binbuf_out_own_flag = false;
public bool binbuf_return_flag = false;
public bool binbuf_return_own_flag = false;
override public bool EinaSliceIn(Eina.Slice slice)
{
slice_in_flag = true;
return slice.GetBytes().SequenceEqual(BaseSequence.Values());
}
override public bool EinaRwSliceIn(Eina.RwSlice slice)
{
rw_slice_in_flag = true;
return slice.GetBytes().SequenceEqual(BaseSequence.Values());
}
private byte[] slice_out_seq = null;
private GCHandle slice_out_pinned;
override public bool EinaSliceOut(ref Eina.Slice slice)
{
slice_out_flag = true;
slice_out_seq = (byte[]) BaseSequence.Values();
slice_out_pinned = GCHandle.Alloc(slice_out_seq, GCHandleType.Pinned);
IntPtr ptr = slice_out_pinned.AddrOfPinnedObject();
slice.Mem = ptr;
slice.Len = (UIntPtr) slice_out_seq.Length;
return true;
}
private byte[] rw_slice_out_seq = null;
private GCHandle rw_slice_out_pinned;
override public bool EinaRwSliceOut(ref Eina.RwSlice slice)
{
rw_slice_out_flag = true;
rw_slice_out_seq = (byte[]) BaseSequence.Values();
rw_slice_out_pinned = GCHandle.Alloc(rw_slice_out_seq, GCHandleType.Pinned);
IntPtr ptr = rw_slice_out_pinned.AddrOfPinnedObject();
slice.Mem = ptr;
slice.Len = (UIntPtr) rw_slice_out_seq.Length;
return true;
}
// //
//
override public bool EinaBinbufIn(Eina.Binbuf binbuf)
{
binbuf_in_flag = true;
bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && !binbuf.Own;
binbuf.Insert(42, 0);
binbuf.Insert(43, 0);
binbuf.Append(33);
binbuf.Dispose();
return r;
}
private Eina.Binbuf binbuf_in_own_binbuf = null;
override public bool EinaBinbufInOwn(Eina.Binbuf binbuf)
{
binbuf_in_own_flag = true;
bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && binbuf.Own;
binbuf.Insert(42, 0);
binbuf.Insert(43, 0);
binbuf.Append(33);
binbuf_in_own_binbuf = binbuf;
return r;
}
public bool binbuf_in_own_still_usable()
{
bool r = binbuf_in_own_binbuf.GetBytes().SequenceEqual(new byte[]{43,42,0x0,0x2A,0x42,33});
r = r && binbuf_in_own_binbuf.Own;
binbuf_in_own_binbuf.Dispose();
binbuf_in_own_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_out_binbuf = null;
override public bool EinaBinbufOut(out Eina.Binbuf binbuf)
{
binbuf_out_flag = true;
binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_out_binbuf = binbuf;
return true;
}
public bool binbuf_out_still_usable()
{
bool r = binbuf_out_binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && binbuf_out_binbuf.Own;
binbuf_out_binbuf.Dispose();
binbuf_out_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_out_own_binbuf = null;
override public bool EinaBinbufOutOwn(out Eina.Binbuf binbuf)
{
binbuf_out_own_flag = true;
binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_out_own_binbuf = binbuf;
return true;
}
public bool binbuf_out_own_no_longer_own()
{
bool r = !binbuf_out_own_binbuf.Own;
binbuf_out_own_binbuf.Dispose();
binbuf_out_own_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_return_binbuf = null;
override public Eina.Binbuf EinaBinbufReturn()
{
binbuf_return_flag = true;
var binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_return_binbuf = binbuf;
return binbuf;
}
public bool binbuf_return_still_usable()
{
bool r = binbuf_return_binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && binbuf_return_binbuf.Own;
binbuf_return_binbuf.Dispose();
binbuf_return_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_return_own_binbuf = null;
override public Eina.Binbuf EinaBinbufReturnOwn()
{
binbuf_return_own_flag = true;
var binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_return_own_binbuf = binbuf;
return binbuf;
}
public bool binbuf_return_own_no_longer_own()
{
bool r = !binbuf_return_own_binbuf.Own;
binbuf_return_own_binbuf.Dispose();
binbuf_return_own_binbuf = null;
return r;
}
}
} // EinaTestData
namespace TestSuite
{

View File

@ -0,0 +1,283 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
namespace EinaTestData
{
class BaseSequence
{
public static byte[] Values()
{
return new byte[3]{0x0,0x2A,0x42};
}
}
public static class BaseData
{
public static readonly int[] base_seq_int = {0x0,0x2A,0x42};
public static readonly int[] append_seq_int = {42,43,33};
public static readonly int[] modified_seq_int = {0x0,0x2A,0x42,42,43,33};
public static readonly string[] base_seq_str = {"0x0","0x2A","0x42"};
public static readonly string[] append_seq_str = {"42","43","33"};
public static readonly string[] modified_seq_str = {"0x0","0x2A","0x42","42","43","33"};
public static Dummy.Numberwrapper NW(int n)
{
var nw = new Dummy.Numberwrapper();
nw.SetNumber(n);
return nw;
}
public static Dummy.Numberwrapper[] BaseSeqObj()
{
var a = new Dummy.Numberwrapper();
var b = new Dummy.Numberwrapper();
var c = new Dummy.Numberwrapper();
a.SetNumber(0x0);
b.SetNumber(0x2A);
c.SetNumber(0x42);
return new Dummy.Numberwrapper[]{a,b,c};
}
public static Dummy.Numberwrapper[] AppendSeqObj()
{
var a = new Dummy.Numberwrapper();
var b = new Dummy.Numberwrapper();
var c = new Dummy.Numberwrapper();
a.SetNumber(42);
b.SetNumber(43);
c.SetNumber(33);
return new Dummy.Numberwrapper[]{a,b,c};
}
public static Dummy.Numberwrapper[] ModifiedSeqObj()
{
var a = new Dummy.Numberwrapper();
var b = new Dummy.Numberwrapper();
var c = new Dummy.Numberwrapper();
var d = new Dummy.Numberwrapper();
var e = new Dummy.Numberwrapper();
var f = new Dummy.Numberwrapper();
a.SetNumber(0x0);
b.SetNumber(0x2A);
c.SetNumber(0x42);
d.SetNumber(42);
e.SetNumber(43);
f.SetNumber(33);
return new Dummy.Numberwrapper[]{a,b,c,d,e,f};
}
public static void NumberwrapperSequenceAssertEqual(
Dummy.Numberwrapper[] a
, Dummy.Numberwrapper[] b
, [CallerLineNumber] int line = 0
, [CallerFilePath] string file = null
, [CallerMemberName] string member = null)
{
Test.Assert(a.Length == b.Length, "Different lenght", line, file, member);
for (int i = 0; i < a.Length; ++i)
{
int av = a[i].GetNumber();
int bv = b[i].GetNumber();
Test.Assert(av == bv, $"Different values for element [{i}]: {av} == {bv}", line, file, member);
}
}
}
class NativeInheritImpl : Dummy.TestObject
{
public NativeInheritImpl(Efl.Object parent = null) : base(parent) {}
public bool slice_in_flag = false;
public bool rw_slice_in_flag = false;
public bool slice_out_flag = false;
public bool rw_slice_out_flag = false;
public bool binbuf_in_flag = false;
public bool binbuf_in_own_flag = false;
public bool binbuf_out_flag = false;
public bool binbuf_out_own_flag = false;
public bool binbuf_return_flag = false;
public bool binbuf_return_own_flag = false;
override public bool EinaSliceIn(Eina.Slice slice)
{
slice_in_flag = true;
return slice.GetBytes().SequenceEqual(BaseSequence.Values());
}
override public bool EinaRwSliceIn(Eina.RwSlice slice)
{
rw_slice_in_flag = true;
return slice.GetBytes().SequenceEqual(BaseSequence.Values());
}
private byte[] slice_out_seq = null;
private GCHandle slice_out_pinned;
override public bool EinaSliceOut(ref Eina.Slice slice)
{
slice_out_flag = true;
slice_out_seq = (byte[]) BaseSequence.Values();
slice_out_pinned = GCHandle.Alloc(slice_out_seq, GCHandleType.Pinned);
IntPtr ptr = slice_out_pinned.AddrOfPinnedObject();
slice.Mem = ptr;
slice.Len = (UIntPtr) slice_out_seq.Length;
return true;
}
private byte[] rw_slice_out_seq = null;
private GCHandle rw_slice_out_pinned;
override public bool EinaRwSliceOut(ref Eina.RwSlice slice)
{
rw_slice_out_flag = true;
rw_slice_out_seq = (byte[]) BaseSequence.Values();
rw_slice_out_pinned = GCHandle.Alloc(rw_slice_out_seq, GCHandleType.Pinned);
IntPtr ptr = rw_slice_out_pinned.AddrOfPinnedObject();
slice.Mem = ptr;
slice.Len = (UIntPtr) rw_slice_out_seq.Length;
return true;
}
// //
//
override public bool EinaBinbufIn(Eina.Binbuf binbuf)
{
binbuf_in_flag = true;
bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && !binbuf.Own;
binbuf.Insert(42, 0);
binbuf.Insert(43, 0);
binbuf.Append(33);
binbuf.Dispose();
return r;
}
private Eina.Binbuf binbuf_in_own_binbuf = null;
override public bool EinaBinbufInOwn(Eina.Binbuf binbuf)
{
binbuf_in_own_flag = true;
bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && binbuf.Own;
binbuf.Insert(42, 0);
binbuf.Insert(43, 0);
binbuf.Append(33);
binbuf_in_own_binbuf = binbuf;
return r;
}
public bool binbuf_in_own_still_usable()
{
bool r = binbuf_in_own_binbuf.GetBytes().SequenceEqual(new byte[]{43,42,0x0,0x2A,0x42,33});
r = r && binbuf_in_own_binbuf.Own;
binbuf_in_own_binbuf.Dispose();
binbuf_in_own_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_out_binbuf = null;
override public bool EinaBinbufOut(out Eina.Binbuf binbuf)
{
binbuf_out_flag = true;
binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_out_binbuf = binbuf;
return true;
}
public bool binbuf_out_still_usable()
{
bool r = binbuf_out_binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && binbuf_out_binbuf.Own;
binbuf_out_binbuf.Dispose();
binbuf_out_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_out_own_binbuf = null;
override public bool EinaBinbufOutOwn(out Eina.Binbuf binbuf)
{
binbuf_out_own_flag = true;
binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_out_own_binbuf = binbuf;
return true;
}
public bool binbuf_out_own_no_longer_own()
{
bool r = !binbuf_out_own_binbuf.Own;
binbuf_out_own_binbuf.Dispose();
binbuf_out_own_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_return_binbuf = null;
override public Eina.Binbuf EinaBinbufReturn()
{
binbuf_return_flag = true;
var binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_return_binbuf = binbuf;
return binbuf;
}
public bool binbuf_return_still_usable()
{
bool r = binbuf_return_binbuf.GetBytes().SequenceEqual(BaseSequence.Values());
r = r && binbuf_return_binbuf.Own;
binbuf_return_binbuf.Dispose();
binbuf_return_binbuf = null;
return r;
}
private Eina.Binbuf binbuf_return_own_binbuf = null;
override public Eina.Binbuf EinaBinbufReturnOwn()
{
binbuf_return_own_flag = true;
var binbuf = new Eina.Binbuf();
binbuf.Append(33);
binbuf_return_own_binbuf = binbuf;
return binbuf;
}
public bool binbuf_return_own_no_longer_own()
{
bool r = !binbuf_return_own_binbuf.Own;
binbuf_return_own_binbuf.Dispose();
binbuf_return_own_binbuf = null;
return r;
}
}
} // EinaTestData

View File

@ -148,6 +148,22 @@ class TestEoEvents
Test.AssertEquals(sent_struct.Fstring, received_struct.Fstring);
}
public static void event_with_struct_complex_payload()
{
var obj = new Dummy.TestObject();
Dummy.StructComplex received_struct = default(Dummy.StructComplex);
obj.EvtWithStructComplexEvt += (object sender, Dummy.TestObjectEvtWithStructComplexEvt_Args e) => {
received_struct = e.arg;
};
Dummy.StructComplex sent_struct = StructHelpers.structComplexWithValues();
obj.EmitEventWithStructComplex(sent_struct);
Test.AssertEquals(sent_struct.Fobj, received_struct.Fobj);
}
public static void event_in_init_callback()
{
int received = 0;

View File

@ -0,0 +1,235 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using static EinaTestData.BaseData;
namespace TestSuite
{
internal class StructHelpers
{
// Auxiliary function //
internal static Dummy.StructSimple structSimpleWithValues()
{
var simple = new Dummy.StructSimple();
simple.Fbyte = (sbyte)-126;
simple.Fubyte = (byte) 254u;
simple.Fchar = '~';
simple.Fshort = (short) -32766;
simple.Fushort = (ushort) 65534u;
simple.Fint = -32766;
simple.Fuint = 65534u;
simple.Flong = -2147483646;
simple.Fulong = 4294967294u;
simple.Fllong = -9223372036854775806;
simple.Fullong = 18446744073709551614u;
simple.Fint8 = (sbyte) -126;
simple.Fuint8 = (byte) 254u;
simple.Fint16 = (short) -32766;
simple.Fuint16 = (ushort) 65534u;
simple.Fint32 = -2147483646;
simple.Fuint32 = 4294967294u;
simple.Fint64 = -9223372036854775806;
simple.Fuint64 = 18446744073709551614u;
simple.Fssize = -2147483646;
simple.Fsize = 4294967294u;
simple.Fintptr = (IntPtr) 0xFE;
simple.Fptrdiff = -2147483646;
simple.Ffloat = -16777216.0f;
simple.Fdouble = -9007199254740992.0;
simple.Fbool = true;
simple.Fvoid_ptr = (IntPtr) 0xFE;
simple.Fenum = Dummy.SampleEnum.V2;
simple.Fstring = "test/string";
simple.Fmstring = "test/mstring";
simple.Fstringshare = "test/stringshare";
return simple;
}
internal static void checkStructSimple(Dummy.StructSimple simple)
{
Test.Assert(simple.Fbyte == (sbyte) -126);
Test.Assert(simple.Fubyte == (byte) 254u);
Test.Assert(simple.Fchar == '~');
Test.Assert(simple.Fshort == (short) -32766);
Test.Assert(simple.Fushort == (ushort) 65534u);
Test.Assert(simple.Fint == -32766);
Test.Assert(simple.Fuint == 65534u);
Test.Assert(simple.Flong == -2147483646);
Test.Assert(simple.Fulong == 4294967294u);
Test.Assert(simple.Fllong == -9223372036854775806);
Test.Assert(simple.Fullong == 18446744073709551614u);
Test.Assert(simple.Fint8 == (sbyte) -126);
Test.Assert(simple.Fuint8 == (byte) 254u);
Test.Assert(simple.Fint16 == (short) -32766);
Test.Assert(simple.Fuint16 == (ushort) 65534u);
Test.Assert(simple.Fint32 == -2147483646);
Test.Assert(simple.Fuint32 == 4294967294u);
Test.Assert(simple.Fint64 == -9223372036854775806);
Test.Assert(simple.Fuint64 == 18446744073709551614u);
Test.Assert(simple.Fssize == -2147483646);
Test.Assert(simple.Fsize == 4294967294u);
Test.Assert(simple.Fintptr == (IntPtr) 0xFE);
Test.Assert(simple.Fptrdiff == -2147483646);
Test.Assert(simple.Ffloat == -16777216.0f);
Test.Assert(simple.Fdouble == -9007199254740992.0);
Test.Assert(simple.Fbool == true);
Test.Assert(simple.Fvoid_ptr == (IntPtr) 0xFE);
Test.Assert(simple.Fenum == Dummy.SampleEnum.V2);
Test.Assert(simple.Fstring == "test/string");
Test.Assert(simple.Fmstring == "test/mstring");
Test.Assert(simple.Fstringshare == "test/stringshare");
}
internal static void checkZeroedStructSimple(Dummy.StructSimple simple)
{
Test.Assert(simple.Fbyte == 0);
Test.Assert(simple.Fubyte == 0);
Test.Assert(simple.Fchar == '\0');
Test.Assert(simple.Fshort == 0);
Test.Assert(simple.Fushort == 0);
Test.Assert(simple.Fint == 0);
Test.Assert(simple.Fuint == 0);
Test.Assert(simple.Flong == 0);
Test.Assert(simple.Fulong == 0);
Test.Assert(simple.Fllong == 0);
Test.Assert(simple.Fullong == 0);
Test.Assert(simple.Fint8 == 0);
Test.Assert(simple.Fuint8 == 0);
Test.Assert(simple.Fint16 == 0);
Test.Assert(simple.Fuint16 == 0);
Test.Assert(simple.Fint32 == 0);
Test.Assert(simple.Fuint32 == 0);
Test.Assert(simple.Fint64 == 0);
Test.Assert(simple.Fuint64 == 0);
Test.Assert(simple.Fssize == 0);
Test.Assert(simple.Fsize == 0);
Test.Assert(simple.Fintptr == IntPtr.Zero);
Test.Assert(simple.Fptrdiff == 0);
Test.Assert(simple.Ffloat == 0);
Test.Assert(simple.Fdouble == 0);
Test.Assert(simple.Fbool == false);
Test.Assert(simple.Fvoid_ptr == IntPtr.Zero);
Test.Assert(simple.Fenum == Dummy.SampleEnum.V0);
Test.Assert(simple.Fstring == null);
Test.Assert(simple.Fmstring == null);
Test.Assert(simple.Fstringshare == null);
}
internal static Dummy.StructComplex structComplexWithValues()
{
var complex = new Dummy.StructComplex();
complex.Farray = new Eina.Array<int>();
complex.Farray.Push(0x0);
complex.Farray.Push(0x2A);
complex.Farray.Push(0x42);
complex.Finarray = new Eina.Inarray<int>();
complex.Finarray.Push(0x0);
complex.Finarray.Push(0x2A);
complex.Finarray.Push(0x42);
complex.Flist = new Eina.List<string>();
complex.Flist.Append("0x0");
complex.Flist.Append("0x2A");
complex.Flist.Append("0x42");
complex.Finlist = new Eina.Inlist<int>();
complex.Finlist.Append(0x0);
complex.Finlist.Append(0x2A);
complex.Finlist.Append(0x42);
complex.Fhash = new Eina.Hash<string, string>();
complex.Fhash["aa"] = "aaa";
complex.Fhash["bb"] = "bbb";
complex.Fhash["cc"] = "ccc";
complex.Fiterator = complex.Farray.GetIterator();
complex.Fany_value = new Eina.Value(Eina.ValueType.Double);
complex.Fany_value.Set(-9007199254740992.0);
complex.Fany_value_ptr = new Eina.Value(Eina.ValueType.String);
complex.Fany_value_ptr.Set("abc");
complex.Fbinbuf = new Eina.Binbuf();
complex.Fbinbuf.Append(126);
complex.Fslice.Length = 1;
complex.Fslice.Mem = Eina.MemoryNative.Alloc(1);
Marshal.WriteByte(complex.Fslice.Mem, 125);
complex.Fobj = new Dummy.Numberwrapper();
complex.Fobj.SetNumber(42);
return complex;
}
internal static void checkStructComplex(Dummy.StructComplex complex)
{
Test.Assert(complex.Farray.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Finarray.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Flist.ToArray().SequenceEqual(base_seq_str));
Test.Assert(complex.Finlist.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Fhash["aa"] == "aaa");
Test.Assert(complex.Fhash["bb"] == "bbb");
Test.Assert(complex.Fhash["cc"] == "ccc");
int idx = 0;
foreach (int e in complex.Fiterator)
{
Test.Assert(e == base_seq_int[idx]);
++idx;
}
double double_val = 0;
Test.Assert(complex.Fany_value.Get(out double_val));
Test.Assert(double_val == -9007199254740992.0);
string str_val = null;
Test.Assert(complex.Fany_value_ptr.Get(out str_val));
Test.Assert(str_val == "abc");
Test.Assert(complex.Fbinbuf.Length == 1);
Test.Assert(complex.Fbinbuf.GetBytes()[0] == 126);
Test.Assert(complex.Fslice.Length == 1);
Test.Assert(complex.Fslice.GetBytes()[0] == 125);
Test.Assert(complex.Fobj != null);
Test.Assert(complex.Fobj.GetNumber() == 42);
}
internal static void checkZeroedStructComplex(Dummy.StructComplex complex)
{
Test.Assert(complex.Farray == null);
Test.Assert(complex.Finarray == null);
Test.Assert(complex.Flist == null);
Test.Assert(complex.Finlist == null);
Test.Assert(complex.Fhash == null);
Test.Assert(complex.Fiterator == null);
Test.Assert(complex.Fany_value == null);
Test.Assert(complex.Fany_value_ptr == null);
Test.Assert(complex.Fbinbuf == null);
Test.Assert(complex.Fslice.Length == 0);
Test.Assert(complex.Fslice.Mem == IntPtr.Zero);
Test.Assert(complex.Fobj == null);
}
}
}

View File

@ -3,232 +3,13 @@ using System.Runtime.InteropServices;
using System.Linq;
using static EinaTestData.BaseData;
using static TestSuite.StructHelpers;
namespace TestSuite
{
class TestStructs
internal class TestStructs
{
// Auxiliary function //
private static Dummy.StructSimple structSimpleWithValues()
{
var simple = new Dummy.StructSimple();
simple.Fbyte = (sbyte)-126;
simple.Fubyte = (byte) 254u;
simple.Fchar = '~';
simple.Fshort = (short) -32766;
simple.Fushort = (ushort) 65534u;
simple.Fint = -32766;
simple.Fuint = 65534u;
simple.Flong = -2147483646;
simple.Fulong = 4294967294u;
simple.Fllong = -9223372036854775806;
simple.Fullong = 18446744073709551614u;
simple.Fint8 = (sbyte) -126;
simple.Fuint8 = (byte) 254u;
simple.Fint16 = (short) -32766;
simple.Fuint16 = (ushort) 65534u;
simple.Fint32 = -2147483646;
simple.Fuint32 = 4294967294u;
simple.Fint64 = -9223372036854775806;
simple.Fuint64 = 18446744073709551614u;
simple.Fssize = -2147483646;
simple.Fsize = 4294967294u;
simple.Fintptr = (IntPtr) 0xFE;
simple.Fptrdiff = -2147483646;
simple.Ffloat = -16777216.0f;
simple.Fdouble = -9007199254740992.0;
simple.Fbool = true;
simple.Fvoid_ptr = (IntPtr) 0xFE;
simple.Fenum = Dummy.SampleEnum.V2;
simple.Fstring = "test/string";
simple.Fmstring = "test/mstring";
simple.Fstringshare = "test/stringshare";
return simple;
}
private static void checkStructSimple(Dummy.StructSimple simple)
{
Test.Assert(simple.Fbyte == (sbyte) -126);
Test.Assert(simple.Fubyte == (byte) 254u);
Test.Assert(simple.Fchar == '~');
Test.Assert(simple.Fshort == (short) -32766);
Test.Assert(simple.Fushort == (ushort) 65534u);
Test.Assert(simple.Fint == -32766);
Test.Assert(simple.Fuint == 65534u);
Test.Assert(simple.Flong == -2147483646);
Test.Assert(simple.Fulong == 4294967294u);
Test.Assert(simple.Fllong == -9223372036854775806);
Test.Assert(simple.Fullong == 18446744073709551614u);
Test.Assert(simple.Fint8 == (sbyte) -126);
Test.Assert(simple.Fuint8 == (byte) 254u);
Test.Assert(simple.Fint16 == (short) -32766);
Test.Assert(simple.Fuint16 == (ushort) 65534u);
Test.Assert(simple.Fint32 == -2147483646);
Test.Assert(simple.Fuint32 == 4294967294u);
Test.Assert(simple.Fint64 == -9223372036854775806);
Test.Assert(simple.Fuint64 == 18446744073709551614u);
Test.Assert(simple.Fssize == -2147483646);
Test.Assert(simple.Fsize == 4294967294u);
Test.Assert(simple.Fintptr == (IntPtr) 0xFE);
Test.Assert(simple.Fptrdiff == -2147483646);
Test.Assert(simple.Ffloat == -16777216.0f);
Test.Assert(simple.Fdouble == -9007199254740992.0);
Test.Assert(simple.Fbool == true);
Test.Assert(simple.Fvoid_ptr == (IntPtr) 0xFE);
Test.Assert(simple.Fenum == Dummy.SampleEnum.V2);
Test.Assert(simple.Fstring == "test/string");
Test.Assert(simple.Fmstring == "test/mstring");
Test.Assert(simple.Fstringshare == "test/stringshare");
}
private static void checkZeroedStructSimple(Dummy.StructSimple simple)
{
Test.Assert(simple.Fbyte == 0);
Test.Assert(simple.Fubyte == 0);
Test.Assert(simple.Fchar == '\0');
Test.Assert(simple.Fshort == 0);
Test.Assert(simple.Fushort == 0);
Test.Assert(simple.Fint == 0);
Test.Assert(simple.Fuint == 0);
Test.Assert(simple.Flong == 0);
Test.Assert(simple.Fulong == 0);
Test.Assert(simple.Fllong == 0);
Test.Assert(simple.Fullong == 0);
Test.Assert(simple.Fint8 == 0);
Test.Assert(simple.Fuint8 == 0);
Test.Assert(simple.Fint16 == 0);
Test.Assert(simple.Fuint16 == 0);
Test.Assert(simple.Fint32 == 0);
Test.Assert(simple.Fuint32 == 0);
Test.Assert(simple.Fint64 == 0);
Test.Assert(simple.Fuint64 == 0);
Test.Assert(simple.Fssize == 0);
Test.Assert(simple.Fsize == 0);
Test.Assert(simple.Fintptr == IntPtr.Zero);
Test.Assert(simple.Fptrdiff == 0);
Test.Assert(simple.Ffloat == 0);
Test.Assert(simple.Fdouble == 0);
Test.Assert(simple.Fbool == false);
Test.Assert(simple.Fvoid_ptr == IntPtr.Zero);
Test.Assert(simple.Fenum == Dummy.SampleEnum.V0);
Test.Assert(simple.Fstring == null);
Test.Assert(simple.Fmstring == null);
Test.Assert(simple.Fstringshare == null);
}
private static Dummy.StructComplex structComplexWithValues()
{
var complex = new Dummy.StructComplex();
complex.Farray = new Eina.Array<int>();
complex.Farray.Push(0x0);
complex.Farray.Push(0x2A);
complex.Farray.Push(0x42);
complex.Finarray = new Eina.Inarray<int>();
complex.Finarray.Push(0x0);
complex.Finarray.Push(0x2A);
complex.Finarray.Push(0x42);
complex.Flist = new Eina.List<string>();
complex.Flist.Append("0x0");
complex.Flist.Append("0x2A");
complex.Flist.Append("0x42");
complex.Finlist = new Eina.Inlist<int>();
complex.Finlist.Append(0x0);
complex.Finlist.Append(0x2A);
complex.Finlist.Append(0x42);
complex.Fhash = new Eina.Hash<string, string>();
complex.Fhash["aa"] = "aaa";
complex.Fhash["bb"] = "bbb";
complex.Fhash["cc"] = "ccc";
complex.Fiterator = complex.Farray.GetIterator();
complex.Fany_value = new Eina.Value(Eina.ValueType.Double);
complex.Fany_value.Set(-9007199254740992.0);
complex.Fany_value_ptr = new Eina.Value(Eina.ValueType.String);
complex.Fany_value_ptr.Set("abc");
complex.Fbinbuf = new Eina.Binbuf();
complex.Fbinbuf.Append(126);
complex.Fslice.Length = 1;
complex.Fslice.Mem = Eina.MemoryNative.Alloc(1);
Marshal.WriteByte(complex.Fslice.Mem, 125);
complex.Fobj = new Dummy.Numberwrapper();
complex.Fobj.SetNumber(42);
return complex;
}
private static void checkStructComplex(Dummy.StructComplex complex)
{
Test.Assert(complex.Farray.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Finarray.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Flist.ToArray().SequenceEqual(base_seq_str));
Test.Assert(complex.Finlist.ToArray().SequenceEqual(base_seq_int));
Test.Assert(complex.Fhash["aa"] == "aaa");
Test.Assert(complex.Fhash["bb"] == "bbb");
Test.Assert(complex.Fhash["cc"] == "ccc");
int idx = 0;
foreach (int e in complex.Fiterator)
{
Test.Assert(e == base_seq_int[idx]);
++idx;
}
double double_val = 0;
Test.Assert(complex.Fany_value.Get(out double_val));
Test.Assert(double_val == -9007199254740992.0);
string str_val = null;
Test.Assert(complex.Fany_value_ptr.Get(out str_val));
Test.Assert(str_val == "abc");
Test.Assert(complex.Fbinbuf.Length == 1);
Test.Assert(complex.Fbinbuf.GetBytes()[0] == 126);
Test.Assert(complex.Fslice.Length == 1);
Test.Assert(complex.Fslice.GetBytes()[0] == 125);
Test.Assert(complex.Fobj != null);
Test.Assert(complex.Fobj.GetNumber() == 42);
}
private static void checkZeroedStructComplex(Dummy.StructComplex complex)
{
Test.Assert(complex.Farray == null);
Test.Assert(complex.Finarray == null);
Test.Assert(complex.Flist == null);
Test.Assert(complex.Finlist == null);
Test.Assert(complex.Fhash == null);
Test.Assert(complex.Fiterator == null);
Test.Assert(complex.Fany_value == null);
Test.Assert(complex.Fany_value_ptr == null);
Test.Assert(complex.Fbinbuf == null);
Test.Assert(complex.Fslice.Length == 0);
Test.Assert(complex.Fslice.Mem == IntPtr.Zero);
Test.Assert(complex.Fobj == null);
}
// Test cases //
// Default initialization (C# side)

View File

@ -151,7 +151,14 @@ public static class TestEinaValueEolian {
Test.AssertEquals(expected, received);
Test.AssertEquals(Eina.ValueType.Double, received.GetValueType());
// Check for 0
// This is a special value, since C# can silently convert it to an enum
// leading to collisions with Eina.ValueType
expected = new Eina.Value(0);
obj.SetValue(0);
obj.OutValue(out received);
Test.AssertEquals(expected, received);
Test.AssertEquals(Eina.ValueType.Int32, received.GetValueType());
}
}
#pragma warning restore 1591

View File

@ -1577,6 +1577,12 @@ class Dummy.Test_Object extends Efl.Object implements Efl.Part, Dummy.Test_Iface
}
}
emit_event_with_struct_complex {
params {
@in data: Dummy.StructComplex;
}
}
append_to_strbuf {
params {
@in buf: strbuf;
@ -1671,5 +1677,6 @@ class Dummy.Test_Object extends Efl.Object implements Efl.Part, Dummy.Test_Iface
evt,with,obj @hot: Dummy.Test_Object;
evt,with,error @hot: Eina.Error;
evt,with,struct @hot: Dummy.StructSimple;
evt,with,struct,complex @hot: Dummy.StructComplex;
}
}

View File

@ -3754,6 +3754,10 @@ void _dummy_test_object_emit_event_with_struct(Eo *obj, EINA_UNUSED Dummy_Test_O
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_STRUCT, &data);
}
void _dummy_test_object_emit_event_with_struct_complex(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Dummy_StructComplex data)
{
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_STRUCT_COMPLEX, &data);
}
Efl_Object *_dummy_test_object_efl_part_part_get(EINA_UNUSED const Eo *obj, Dummy_Test_Object_Data *pd, const char *name)
{

View File

@ -39,6 +39,8 @@ efl_mono_test = library('efl_mono_test',
efl_mono_src = [
'Main.cs',
'TestUtils.cs',
'EinaTestData.cs',
'StructHelpers.cs',
'BasicDirection.cs',
'Eina.cs',
'Eldbus.cs',

View File

@ -95,7 +95,6 @@ _children_added_cb(void *d EINA_UNUSED, const Efl_Event* event)
EFL_START_TEST(eio_model_test_test_monitor_add)
{
Eo *filemodel = NULL;
Eina_Future* future;
tmpdir = eina_environment_tmp_get();

View File

@ -1788,6 +1788,14 @@ EFL_START_TEST(efl_object_auto_unref_test)
}
EFL_END_TEST
EFL_START_TEST(efl_object_size)
{
// This test is checking that we are not increasing the size of our object over time
// Update this number only if you modified the class size on purpose
ck_assert_int_le(efl_class_memory_size_get(SIMPLE_CLASS), 148);
}
EFL_END_TEST
void eo_test_general(TCase *tc)
{
tcase_add_test(tc, eo_simple);
@ -1815,4 +1823,5 @@ void eo_test_general(TCase *tc)
tcase_add_test(tc, efl_cast_test);
tcase_add_test(tc, efl_object_destruct_test);
tcase_add_test(tc, efl_object_auto_unref_test);
tcase_add_test(tc, efl_object_size);
}

View File

@ -0,0 +1,8 @@
import base;
import mixins_require;
class Class.Requires (Base, Mixins.Require) {
methods {
}
}

View File

@ -0,0 +1,13 @@
import base;
import class_simple;
mixin Mixins.Require requires Base {
methods {
test {
}
}
implements {
Base.constructor;
}
}

View File

@ -1552,6 +1552,66 @@ EFL_START_TEST(eolian_parts)
}
EFL_END_TEST
EFL_START_TEST(eolian_mixins_require)
{
const Eolian_Unit *unit;
const Eolian_Class *cl;
const Eolian_Class *base;
Eolian_State *eos = eolian_state_new();
fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data"));
fail_if(!(unit = eolian_state_file_parse(eos, TESTS_SRC_DIR"/data/mixins_require.eo")));
fail_if (!(cl = eolian_state_class_by_name_get(eos, "Mixins.Require")));
fail_if (!(base = eolian_state_class_by_name_get(eos, "Base")));
ck_assert_ptr_eq(eolian_class_parent_get(cl), NULL);
//Check that implements is empty
{
Eolian_Class *extc;
Eina_Iterator *ext = eolian_class_extensions_get (cl);
EINA_ITERATOR_FOREACH(ext, extc)
{
ck_abort_msg("Iterator should be empty");
}
eina_iterator_free(ext);
}
//check that implements contains this one class
{
Eolian_Implement *impl;
Eina_Iterator *i = eolian_class_extensions_get (cl);
EINA_ITERATOR_FOREACH(i, impl)
{
ck_assert_ptr_eq(eolian_implement_class_get(impl), base);
}
eina_iterator_free(i);
}
eolian_state_free(eos);
}
EFL_END_TEST
EFL_START_TEST(eolian_class_requires_classes)
{
const Eolian_Unit *unit;
const Eolian_Class *cl;
Eolian_State *eos = eolian_state_new();
fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data"));
fail_if(!(unit = eolian_state_file_parse(eos, TESTS_SRC_DIR"/data/class_requires.eo")));
fail_if (!(cl = eolian_state_class_by_name_get(eos, "Class.Requires")));
eolian_state_free(eos);
}
EFL_END_TEST
void eolian_parsing_test(TCase *tc)
{
tcase_add_test(tc, eolian_simple_parsing);
@ -1575,4 +1635,6 @@ void eolian_parsing_test(TCase *tc)
tcase_add_test(tc, eolian_function_types);
tcase_add_test(tc, eolian_function_as_arguments);
tcase_add_test(tc, eolian_parts);
tcase_add_test(tc, eolian_mixins_require);
tcase_add_test(tc, eolian_class_requires_classes);
}

View File

@ -309,6 +309,19 @@ EFL_START_TEST(eolian_cxx_test_parent_extensions)
}
EFL_END_TEST
EFL_START_TEST(eolian_cxx_test_cls_get)
{
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def cls = init_test_data("generic.eo", "Generic", eolian_state);
ck_assert_str_eq("generic_class_get", cls.klass_get_name.c_str());
klass_def iface = init_test_data("generic_interface.eo", "Generic_Interface", eolian_state);
ck_assert_str_eq("generic_interface_interface_get", iface.klass_get_name.c_str());
}
EFL_END_TEST
void
eolian_cxx_test_binding(TCase* tc)
{
@ -321,4 +334,5 @@ eolian_cxx_test_binding(TCase* tc)
tcase_add_test(tc, eolian_cxx_test_type_callback);
tcase_add_test(tc, eolian_cxx_test_properties);
tcase_add_test(tc, eolian_cxx_test_parent_extensions);
tcase_add_test(tc, eolian_cxx_test_cls_get);
}