On Wed, 10 Jan 2018 16:52:26 -0200 Gustavo Sverzut Barbieri
<barbi...@gmail.com> said:

> hi all,
> 
> jpeg, i think that this "destruct" event should have a counterpart
> method, like in GObject they have dispose + finalize, we could have
> something like that to allow two clearly distinct phases:
>    - one to release references to others (our invalidate/terminate),
> announces that everyone keeping a reference should stop using this
> object (~weak ref behavior)

what is what currently del events are for. they allow you to implement weak
refs yourself in any way you like. or that's the idea. eo also explicitly has a
weak ref system where you register (and unregister) pointers to objects as weak
refs and eo will NULL them in deletion of the referenced target since this is
so common. you just need to remember to unregister the weak ref ptr when it is
being freed (well the parent structure is generally).

>    - one to free memory handles and all backing structures, this one
> can be called after all references are gone.
> 
> https://developer.gnome.org/gobject/stable/howto-gobject-destruction.html
> 
> as per parent, as I wrote to some in private, I believe the current
> situation is that Eo tries to cope with an unusual system that was
> used in Evas_Object, which the objects were added to the canvas, which
> held the only reference to it... not by the caller (who created the
> visual object).
> 
> this is unusual in OOP, but improved usability of evas users, nobody
> had to manage object lifecycle, just delete the canvas and they all
> would go away. OTOH, to delete the visual object, an specific
> evas_object_del() was used, that would remove the canvas ref and
> destroy the object.

i don't think it's that unusual. in python, js or lua or java you'd store a
child object or widget inside the parent object's class data. when the parent
is deleted the reference to the child is also. they will all clean up children
because the gc will no longer find a reference to the child (if this was the
only reference) so it works the same really. it just is done by refcounting and
not a gc.

> however, in a more generic OOP system this makes things unusable, as
> we're discussing in this thread.
> 
> parents: wisely we're advertising almost all objects should have a
> parent, like a window, a widget, a loop... maybe it will boils down to
> a thread/process.
> 
> however, in these cases children is using/knowing about parents,
> parents rarely knows/deals with children -- UNLIKE EVAS.
> 
> --> That said, IMO parents should NOT have a reference to their children.
> 
> if we wish to do cascade deletion, which may be very helpful (delete a
> loop, get rid of all users... like done for evas + objects), then we

that is exactly what eo is doing. it's doing "automated cascade deletion" from
any point in a tree. if a parent goes, then the children go too (or at least
conceptually should go). yes. in theory - you delete a loop and everything
related to it should go away (that basically would be everything in that
thread) ... though as i mentioned already - if people add extra refs to objects
and then don't remove them when this happens some objects would get orphaned at
this point and this is a bit of a problem.

what do we do about these orphans? i think we may need to police them. i think
that objects that were a child of a parent, lose that parent (becomes NULL) but
the object is still alive with references should be explicitly tracked by eo
somehow in a list, alongside information where they were orphaned (a
backtrace?) when debugging is on (or maybe always?). and then some api's to
iterate over these orphans as well as just dump out their info (type/class,
eoid, their child trees if they have children, bt where the obj that was
orphaned was placed into this orphan list). this is basically a leak catcher.
catches excess refs that accidentally keep objects alive. i don't think we can
avoid this issue. it's like any of the "oo" stuff you mention above. is someone
keeps a reference (a variable with a ref to an obj) in java (or js, or lua
etc.), even if the parent object died, that child would stay around because
that ref exists. it may not be INTENDED to be like this and that was probably
intended as a weak reference or they just forgot to clean up/null their
reference, but having a way to debug this will be probably important for the
future. unless someone has a magic way of ensuring this never happens (i doubt
there is as it happens to this day in many languages).

> can dissociate terminate/invalidate from reference, but the last
> reference would invalidate:
> 
> --> NOTE: using efl_new() instead of efl_add() as I think this should
> be renamed for clarity...
> 
> basic usage:
>     o = efl_new(cls, parent, ...); // refcnt = 1, the caller's reference
>     efl_unref(o); // refcnt = 0, efl_invalidate(o) is auto-called
> 
> 
> explicit invalidate:
>     o = efl_new(cls, parent, ...); // refcnt = 1, the caller's reference
>     efl_invalidate(o); // refcnt = 1
>     efl_unref(o); // refcnt = 0, no call to efl_invalidate(o)
> 
> canvas usage #1 (basic usage):
>     o = efl_new(EFL_UI_BUTTON_CLASS, window, ...); // refcnt = 1, the
> caller's reference
>     efl_unref(o); // refcnt = 0, efl_invalidate(o) is auto-called,
> button is removed from window
> 
> canvas usage #2 (invalidate window):
>     o = efl_new(EFL_UI_BUTTON_CLASS, window, ...); // refcnt = 1, the
> caller's reference
>     efl_invalidate(window); // o.refcnt = 1, but efl_invalidate(o) is called
>     efl_unref(o); // refcnt = 0, no call efl_invalidate(o)
> 
> problem with this approach is that most people will forget to
> efl_unref(o), then while it will be invalidated, its memory will leak.

i thought cedric mentioned this already - efl_del would invalidate then unref
in one call, so you don't forget. ? i dont see why we should move to efl_new
from efl_add either. :)

> while this can be solved within evas legacy wrapper, the usability is
> not the best. Other systems "solve" this with one of two options:
> 
>  - reference transference: efl_adopt_ref(receiver, o), would give your
> reference of "o" to "receiver", which is supposed to release it on its
> "invalidate". That is: keep an Eina_List *adopted, that is
> automatically managed and efl_unref() on its own invalidate.
> 
>  - floating references: object starts "unowned" and the first "user"
> should own it, for details:
> https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#floating-ref

that is how eo currently works. eo tracks the first time an object gets a
parent. if we always start with a parent (as is central to this discussion)
then worrying about the other code path is kind of pointless. :)

> GObject UI and gstreamer use this "floating" and I always disliked it,
> finding it too error prone. It "looks easy" to use, but the situation
> is similar to what we have in EFL and led to this thread... so I'd
> avoid it.

i like it because it is easy. in c. because you have no automatic cleanup on
exit from scope.

> since unlike Gtk and GStreamer we're suggesting elements to be created
> with a parent, as opposed to adding to a parent, this is simpler.
> Compare:
> 
>     // GTK:
>    container = create_container ();
>    container_add_child (container, create_child());
> 
>    // EFL:
>    container = efl_new(CONTAINER_CLS, loop, ....);
>    child = efl_new(CHILD_CLS, container, efl_container_pack(container,
> efl_added), efl_adopt_ref(container, efl_added));

why would there need to be an explicit adopt? adding a new object with a parent
"container" already says exactly that. the container_pack is only needed as an
explicit "i want you to pack in the parent THIS way (at the end/start of a box
or at specific x/y/col/rows in a table etc.).

> this is explicit, clear what's happening. Since "efl_adopt_ref()" was
> written explicitly there, or called afterwards, it's easy to spot you
> don't own the reference anymore. Maybe coccinelle, coverity and the
> likes can told that rule to spot errors.

but parent obj already does this... it just makes everything so pointlessly
verbose. the add with a parent is telling the parent to take ownership of the
object. the handle you are returned is for usability so you can call methods on
it (outside of the add scope). just what you need for code like:

o = efl_add(CLASS, parent);
if (x) efl_whatever_x(o);
else efl_thing_y(o);

yes. technically it can be put inside the add() but eventually you'll want
something complex enough where it just doesn't look right there.

> others may claim efl_adopt_ref() is always the case, in that case
> keeping efl_invalidate() UNRELATED to efl_unref() is also helpful:

i think they are unrelated except that if invalidation is a standard part of
the destruction cycle then it must be called when refs go to 0 even if that's
thanks to an unref.

> --> NOTE: using efl_add(), since here parents keep the reference
> 
> WRONG/BUG usage:
>     o = efl_add(cls, parent, ...); // refcnt = 1, the PARENT's reference
>     efl_unref(o); // refcnt = 0, but parent held the reference
> 
> basic usage:
>     o = efl_add(cls, parent, ...); // refcnt = 1, the PARENT's reference
>     efl_invalidate(o); // refcnt = 0, since parent will unref based on
> invalidate event
> 
> cascade delete usage:
>     o = efl_add(cls, parent, ...); // refcnt = 1, the PARENT's reference
>     efl_invalidate(parent); // refcnt = 0, cascade invalidate, leading
> to parents unref children.
> 
> ref usage (when you can't monitor EFL_EVENT_INVALIDATE or weak-ref):
>     o = efl_add(cls, parent, ...); // refcnt = 1, the PARENT's reference
>     efl_ref(o); // refcnt = 2, PARENT + caller
>     efl_invalidate(o); // refcnt = 1, since parent will unref based on
> invalidate event
>     efl_unref(o); // refcnt = 0
> 
> 
> as a last note to this long email, shall we opt to use the "parent
> keeps a ref" method, since we use the eoid abstraction, I'd highly
> recommend that efl_ref() creates ANOTHER eoid for the same object,
> with associated WARN_UNUSED_RESULT/MALLOC and efl_unref() behaves like
> free(), considering the handle to be destroyed. This should help
> finding bugs... it's worth since efl_ref() will be rarely used.

oh no no. efl_ref() is lightweight and slim. creating more eoid's is going to
be super heavy in comparison.

> On Wed, Jan 10, 2018 at 5:31 AM, Jean-Philippe André <j...@videolan.org>
> wrote:
> > Hi,
> >
> > I created a new event "destruct" in Efl.Object.
> > It's triggered just before removing the callbacks, in the base class
> > destructor, as it's both easier and safer this way. I guess this can be
> > used in bindings too.
> >
> > As for the rest, I need to think about it more.
> >
> > Best regards,
> >
> >
> > On Wed, Jan 10, 2018 at 1:50 AM, Carsten Haitzler <ras...@rasterman.com>
> > wrote:
> >
> >> On Tue, 9 Jan 2018 21:03:53 +0900 Jean-Philippe André <j...@videolan.org>
> >> said:
> >>
> >> > On Tue, Jan 9, 2018 at 3:17 PM, Carsten Haitzler <ras...@rasterman.com>
> >> > wrote:
> >> >
> >> > > On Mon, 8 Jan 2018 18:15:13 +0900 Jean-Philippe André <
> >> j...@videolan.org>
> >> > > said:
> >> > >
> >> > > > Hi,
> >> > > >
> >> > > >
> >> > > > Some of the argumentation here seems to lack a bit of a scientific
> >> > > > approach...
> >> > > > So, I looked for all occurrences of efl_add() (see PS for
> >> methodology).
> >> > > >
> >> > > > In all of EFL, without specific filters:
> >> > > >
> >> > > > Overall: 244 unique classes / 1572 occurrences
> >> > > > No parent: 119 unique classes / 472 occurrences
> >> > > > 48% of classes used without parent, accounting for 30% of all uses.
> >> > >
> >> > > i argue that the vast majority of those no parent cases should have a
> >> > > parent. i
> >> > > actually did a grep -r through efl too looking and almost all the cases
> >> > > with a
> >> > > null parent i noted were bugs and should be fixed. :) i specifically
> >> noted
> >> > > some
> >> > > of those examples (the efl_anim stuff for example - i filed a bug for
> >> it
> >> > > too).
> >> > > so while i didn't do numbers... i did do an analysis. quickly in about
> >> 2
> >> > > minutes. for a more detailed analysis. note when i say "loop should be
> >> > > parent"
> >> > > i mean loop directly OR some object that ultimately has a parent that
> >> is
> >> > > loop
> >> > > at the top of the object tree:
> >> > >
> >> > > src/benchmarks/eo/eo_bench_* (11)
> >> > >   just benchmarking so not real code. (ignore)
> >> > > src/bin/elementary/test_*.c (86)
> >> > >   all are bugs. every one should have loop as parent.
> >> > > src/examples/ecore/ecore_audio*.c: (7)
> >> > >   all are bugs. loop should be parent (loop drives i/o for audio and
> >> cb's)
> >> > > src/examples/ecore/ecore_idler_example.c: (1)
> >> > >   bug. loop as parent (commented out though)
> >> > > src/examples/ecore/ecore_poller_*.c (3)
> >> > >   bug. loop should be parent
> >> > > src/examples/ecore/efl_io_*.c (8)
> >> > >   bug. loop should be parent
> >> > > src/examples/ecore/efl_net_*.c (6)
> >> > >   bug. loop should be parent
> >> > > src/examples/eio/eio_sentry.c (1)
> >> > >   unknown
> >> > > src/examples/elementary/efl_ui_*.c (4)
> >> > >   bug. loop should be parent
> >> > > src/examples/elementary/file*.c (9)
> >> > >   bug. loop should be parent
> >> > > src/lib/ecore/ecore.c (1)
> >> > >   bug. singleton vpath object will fail with multiple loops, so loop
> >> > > should be
> >> > > parent, but this is unused atm so it doesn't matter yet.
> >> > > src/lib/ecore/efl_loop.c (1)
> >> > >   correct null parent usage
> >> > > src/lib/ecore/efl_model_composite_*.c (2)
> >> > >   relatively sure these are bugs. in fact these files do a lot of:
> >> > >   Efl_Promise *promise = efl_add(EFL_PROMISE_CLASS,
> >> efl_main_loop_get());
> >> > >   and similar assuming only the main loop... which is wrong. they
> >> should
> >> > > get
> >> > >   the correct loop, not always the main loop. lots of examples of this
> >> > > through
> >> > >   efl.
> >> > > src/lib/ecore_con/ecore_con_*.c (5)
> >> > >   bug. should use loop as parent
> >> > > src/lib/ector/cairo/ector_cairo_surface.c: (3)
> >> > > src/lib/ector/gl/ector_gl_surface.c: (3)
> >> > > src/lib/ector/software/ector_software_surface.c: (3) (9 total)
> >> > >   this is actually ok since ector doesn't use any async events and
> >> needs
> >> > > no loop
> >> > > src/lib/edje/edje_*.c (10)
> >> > >   bug. loop should be parent
> >> > > src/lib/efl/interfaces/efl_vpath_core.c: (1)
> >> > >   bug. vpath needs to be loop driven due to the ability to do async
> >> lookups
> >> > > src/lib/efl/interfaces/efl_vpath_manager.c (1)
> >> > >   bug. same as above
> >> > > src/lib/eio/eio_model.c: (1)
> >> > >   smells like a bug. eoi would need a loop to drive it
> >> > > src/lib/elementary/efl_access.c: (1)
> >> > >   bug. access relies on events and async (e.g. dbus) and so must have
> >> loop
> >> > > src/lib/elementary/efl_ui_*.c: (15)
> >> > >   bug. need loop parent
> >> > > src/lib/elementary/elm_*.c (5)
> >> > >   all look like bugs. need loop parent
> >> > > src/lib/evas/canvas/efl_animation*.c (7)
> >> > >   bug. need loop parent
> >> > > src/lib/evas/canvas/efl_canvas_vg.c: (1)
> >> > >   bug. need loop parent
> >> > >
> >> > > src/lib/evas/canvas/evas_main.c: (1)
> >> > >   bug. need loop parent
> >> > > src/lib/evas/canvas/evas_vg_node.c: (1)
> >> > >   bug. vg nodes should have a parent object - always
> >> > > src/lib/evas/gesture/efl_gesture_manager.c: (1)
> >> > >   bug. need loop parent
> >> > > src/modules/evas/engines/gl_generic/evas_engine.c (3)
> >> > > src/modules/evas/engines/software_generic/evas_engine.c: (3) (6 total)
> >> > >   correct. ector objects
> >> > > src/tests/ecore/ecore_test_ecore_audio.c (16)
> >> > >   bug. need loop parent
> >> > > src/tests/ecore/ecore_test_promise2.c: (2)
> >> > >   bug. need loop parent
> >> > > src/tests/ecore_con/ecore_con_test_efl_net_ip_address.c: (14)
> >> > >   bug. need loop parent
> >> > > src/tests/efl/efl_test_model_*.c: (5)
> >> > >   bug. need loop parent
> >> > > src/tests/efl_js/benchmark_object_impl.cc: (1)
> >> > >   artificial benchmarking (so ignore)
> >> > > src/tests/efl_mono/libefl_mono_native_test.c: (1)
> >> > >   artificial benchmarking (ignore)
> >> > > src/tests/eina_cxx/eina_cxx_test_*.cc (54)
> >> > >   artificial testing of basic input/output through eo api
> >> > > src/tests/eio/eio_test_sentry.c: (20)
> >> > >   bug. should have parent loop
> >> > > src/tests/eldbus/eldbus_test_*.c: (3)
> >> > >   bug. should have loop parent
> >> > > src/tests/elementary/elm_test_*.c: (31)
> >> > >   bug. should have loop parent
> >> > > src/tests/eo/access/access_main.c: (1)
> >> > >   bug. should have loop parent
> >> > > src/tests/eo/children/children_main.c: (1)
> >> > >   artificial eo testing - ignore
> >> > > src/tests/eo/composite_objects/composite_objects_main.c: (1)
> >> > >   artificial eo testing - ignore
> >> > > src/tests/eo/constructors/constructors_main.c: (1)
> >> > >   artificial testing - ignore
> >> > > src/tests/eo/function_overrides/function_overrides_main.c: (4)
> >> > >   artificial testing - ignore
> >> > > src/tests/eo/interface/interface_main.c: (1)
> >> > >   artificial testing - ignore
> >> > > src/tests/eo/mixin/mixin_main.c: (1)
> >> > >   artificial testing - ignore
> >> > > src/tests/eo/signals/signals_main.c: (1)
> >> > >   artificial testing - ignore
> >> > > src/tests/eo/suite/eo_test_*.c: (94)
> >> > >   artificial test suite - ignore
> >> > > src/tests/eolian_js/eolian_js_test_constructor_method_impl.c: (2)
> >> > >   artificial test suite (ignore)
> >> > >
> >> > > so i spent a lot of time going over every instance (well with a git
> >> grep
> >> > > for
> >> > > eo_add( and NULL on the same line).
> >> > >
> >> > >
> >> > > 459 instances of an eo_add with NULL. i get 1572 eo_add's with a git
> >> grep
> >> > > ...
> >> > > uses. my numbers differ from yours, but ok. we're doing rough stats
> >> here.
> >> > >
> >> > > 173 instances are artificial testing so let's remove them from our
> >> stats.
> >> > >
> >> > > 286 eo_adds with null that are "real". 1399 total adds when we remove
> >> the
> >> > > artificial testing ones. of those 286 instances, 1 is "unknown" if it's
> >> > > correct. let's remove that from our stats for now. 285 null adds, 1398
> >> > > total
> >> > > eo_add's. of the 285 null adds.. only 16 are correct uses with null
> >> > > parent. the
> >> > > rest are bugs. so ... 16/1398 are valid uses of null parent adds.
> >> that's
> >> > > 1.1%
> >> > > of use cases.
> >> > >
> >> > > but wait... of those 16 "null parent is ok" examples... 1 (the main
> >> loop
> >> > > add)
> >> > > is internal to efl only and never seen or used outside. loops are and
> >> will
> >> > > be
> >> > > created for you. so it's actually 15. 15/1398 is almost exactly 1%.
> >> > >
> >> > > my "spitballing rough number from a glance at git grep and where the
> >> calls
> >> > > were" was almost EXACTLY spot on. so i totally stand by my 1-2% number
> >> i
> >> > > roughly
> >> > > guessed in a 1 minute scan. of course now you forced me to spend an
> >> hour
> >> > > doing
> >> > > the above.
> >> > >
> >> > > now an accurate evaluation says it's 1%. and that's WITHIN efl. the 1
> >> case
> >> > > of
> >> > > the main loop of the 16 will not exist outside of efl itself as loops
> >> will
> >> > > be
> >> > > created for you, and the other 15 are all ector.
> >> > >
> >> > > imho ector is a low level api for doing raw rendering and describing a
> >> > > display
> >> > > graph. in fact for sheer performance reasons as long as it's kept
> >> internal
> >> > > to
> >> > > efl it shouldn't be an eo api for speed reasons.
> >> > >
> >> > > will we ever expose a "direct immediate mode rendering api" to users?
> >> like
> >> > > ector? especially when we have evas vg objects that hide this? and in
> >> the
> >> > > event
> >> > > you used such an object... and if we exposed ector objects as the
> >> actual
> >> > > "vector tree/graph" ... they will then all have a parent - the vg
> >> object
> >> > > containing them.
> >> > >
> >> > > so i actually argue that the 16 cases i counted are actually 0. either
> >> > > ector
> >> > > shouldn't be eo and stay a low level api internally to efl, or we
> >> expose
> >> > > ector
> >> > > node graph within a vg object and then they all have parents.
> >> > >
> >> > > so after some analysis of the above... no a single "external use" of
> >> > > efl_add
> >> > > should be done with a null parent. and the only internal "valid" use
> >> is the
> >> > > efl_add of the loop objects. ector is kind of an odd/exception state
> >> atm as
> >> > > above.
> >> > >
> >> >
> >> > Well if the thinking is "all objects should have a parent" then of course
> >> > exactly 0% of them will have no parent. Basically only a "thread" object
> >> > would be allowed to be parentless. Windows should then be created with a
> >> > loop as parent, internally reparented to evas if needed.
> >>
> >> that is exactly my thinking and it's where i'm coming from. i thought i
> >> made
> >> that clear in prior emails that i think this is where it's boiling down to
> >> -
> >> that i see efl as a "basically almost no objects have NULL parents, so
> >> what's
> >> the fuss all about? what we need to do is police parents and ensure they
> >> are
> >> correct (that the parent is a mainloop object where it must be main loop
> >> only
> >> or is non-null in almost all other cases)". it's a policing issue not an
> >> api
> >> issue.
> >>
> >> > If we take this approach then @noparent is not even required (only one
> >> > special kind of object should have no parent, for which we could have an
> >> > internal api).
> >> > This could solve inconsistencies.
> >>
> >> well we'd have to hide the ability to efl_add that class outside of efl
> >> itself.
> >> for now just documenting that all objects must have a parent, then moving
> >> to
> >> enforcing it (well first fixing all the bugs we know about then fixing
> >> them to
> >> have the correct parent so it properly works with multi-loop/thread later
> >> then
> >> putting in policing/enforcement code in eo... or something like this). but
> >> going in this direction i think is the way to go. we can have some
> >> exceptions
> >> for now that don't need a parent (ector and loop objects - loop objects
> >> can be
> >> documented with "never create one of these yourself"... for now).
> >>
> >> > > In all of EFL, without EFL_UI_WIN_CLASS or ECORE_XXX:
> >> > > >
> >> > > > Overall: 226 unique classes / 1438 occurrences
> >> > > > No parent: 89 unique classes / 358 occurrences
> >> > > > 42% of classes used without parent, accounting for 27% of all uses.
> >> > > >
> >> > > >
> >> > > > Only in src/examples, without EFL_UI_WIN_CLASS or ECORE:
> >> > > >
> >> > > > Overall: 44 unique classes / 474 occurrences
> >> > > > No parent: 12 unique classes / 27 occurrences
> >> > > > 27% of classes used without parent, accounting for 5.7% of all uses.
> >> > > > (note: only one example with EFL_UI_WIN_CLASS)
> >> > > >
> >> > > >
> >> > > > In src/bin/elementary, without EFL_UI_WIN_CLASS or ECORE:
> >> > > >
> >> > > > Overall: 49 unique classes / 303 occurrences
> >> > > > No parent: 14 unique classes / 54 occurrences
> >> > > > 29% of classes used without parent, accounting for 18% of all uses.
> >> > > > (note: those classes are animation and interpolator)
> >> > > > (note2: 34 occurences of WIN class - no parent)
> >> > > >
> >> > > >
> >> > > > Conclusions:
> >> > > >
> >> > > > 0. This analysis is flawed by design due to a lack of real usage.
> >> > >
> >> > > correct. the above numbers include lots of code that needs to not use
> >> null
> >> > > parents. my more detailed analysis shows my numbers of 1-5% to be
> >> > > incredibly
> >> > > generous... in current efl it's actually 0%. every existing instance
> >> of an
> >> > > efl
> >> > > add with null inside efl or in tests is a bug (excepting the above as i
> >> > > described).
> >> > >
> >> > > > 1. Those numbers differ from the values given in the below email.
> >> > > > While I understand where this "maybe 1 or 2% of all objects [are
> >> created
> >> > > > without a parent]" comes from, it's not based on facts.
> >> > >
> >> > > actually it is... because almost all the instances of adding with null
> >> > > parents
> >> > > are bugs atm. even many without null parents are currently bugs (they
> >> use
> >> > > the
> >> > > wrong parent - eg always get the mainloop singleton instead of use the
> >> > > correct
> >> > > loop parent of that object like the model examples i pointed to).
> >> > >
> >> > > > @noparent makes sense. A NULL check in efl_add would then help.
> >> > >
> >> > > that is my compromise. or what i am thinking is a good compromise.
> >> that in
> >> > > the
> >> > > very very very very few exceptions where we allow null parents... we
> >> > > specifically tag it.
> >> > >
> >> >
> >> > Might as well have no exception, except internally for a special TLS
> >> > "thread" object that would be the root object to rule them all.
> >>
> >> actually my thoughts are the loop object is that root. when you create a
> >> new
> >> thread you get a thread object on the creator side, and then the thread
> >> itself
> >> starts with a loop object like EFL_MAIN does with an args callback. so the
> >> loop
> >> object within that thread is also thread-local ... and the loop
> >> communicates
> >> back to the thread object on the "creator/parent" side e.g. via pipes.
> >>
> >> > > A different API then wouldn't hurt either IMHO (maybe efl_new?
> >> > > > efl_add_single? efl_create? or whatever -- efl_add then can NOT be
> >> called
> >> > > > with NULL).
> >> > >
> >> > > once the bugs are fixed... at this point we'll be create an api though
> >> with
> >> > > ZERO external use outside of efl and only 16 instances within efl
> >> itself.
> >> > >
> >> >
> >> > There were no "bugs" until it somehow was decided that all objects should
> >> > have a parent.
> >>
> >> i thought we talked about this long enough - that objects will be driven by
> >> their loop and the loop will be a parent so they know what they are driven
> >> by.
> >> we cant have multiple loops unless we do this because then objects have no
> >> idea
> >> what loop will drive their async i/o at all.
> >>
> >> > as i said. we should be policing the null parents because basically 99%
> >> of
> >> > > efl
> >> > > objects (or instances of their adds) do not allow null parents.. or
> >> SHOULD
> >> > > not
> >> > > once we've fixed everything up.
> >> > >
> >> > > > 2. The argumentation in this email chain again leads nowhere. The
> >> > > original
> >> > > > confusion remains mostly unaddressed.
> >> > >
> >> > > i think not. i made the argument that it's not really confusing - it
> >> > > follows a
> >> > > simple rule... BUT that reality is in no real life cases will anyone
> >> using
> >> > > the
> >> > > efl api be adding objects with a null parent. it's a "0% of use cases"
> >> > > thing.
> >> > > so as there is no valid instance of doing an add with a null parent...
> >> why
> >> > > do
> >> > > we have to make things more confusing by even having an api that
> >> > > encourages it?
> >> > >
> >> > > > Felipe mentioned that ownership and references are mixed. So the
> >> proposal
> >> > > > for efl_release (or detach, close, invalidate, ...) makes sense to
> >> me.
> >> > > > In fact we have issues sometimes with efl_del as inside a destructor
> >> we
> >> > > > already lost our parent (thus all efl_provider_find and related calls
> >> > > will
> >> > > > fail).
> >> > >
> >> > > i brought up this issue specifically already in this and related
> >> threads
> >> > > and
> >> > > said it's horrible and painful and unparenting should be done outside
> >> the
> >> > > the
> >> > > constructor (after last constructor called). not having a parent when
> >> > >
> >> >
> >> > "destructor (after last destructor called)" -- I guess?
> >>
> >> sure. but we kind of agree here. :)
> >>
> >> > > destructor is called is leading to some major ugliness in objects
> >> having to
> >> > > manually track their loop so they at least know what loop they did
> >> belong
> >> > > to
> >> > > during destruction so they can clean up some internals like "fd
> >> handlers"
> >> > > etc.
> >> >
> >> > yup
> >>
> >> seems we agree. :)
> >>
> >> > > > Also, quite a few times I've also been looking for a "deleted" event
> >> that
> >> > > > would happen after destruction, and not before.
> >> > >
> >> > > well there is the case for a del that is called just before
> >> destructors are
> >> > > called so everything in the object is still there. that's what we have
> >> now
> >> > > (or
> >> > > should have). there might be the case for another callback to be
> >> called in
> >> > > the
> >> > > finally destructor just when all the event callbacks are about to be
> >> > > cleaned
> >> > > out. you couldnt call something after the actual final destruction
> >> though
> >> > > as
> >> > > the object now no longer exists... :)
> >> >
> >> > > I had to introduce a very ugly API very badly called
> >> "allow_parent_unref"
> >> > > > in efl.object because some objects need a parent but they should be
> >> > > > unref'ed by someone else (efl_part objects but not only).
> >> > > >
> >> > > > So, I think it would make sense to investigate efl_terminate, and
> >> > > > evas_object_del would just call efl_terminate, hiding the object or
> >> > > > starting destruction, then let the parent (either evas or another
> >> canvas
> >> > > > object) do the final unref/unparent and destroying everything that's
> >> > > left.
> >> > > >
> >> > > >
> >> > > > Last note: @owned is rarely used with objects:
> >> > > > - Efl.Net.Ip_Address create (factory pattern, replaces efl_add, but I
> >> > > think
> >> > > > if there's a parent then we shouldn't tag as @owned)
> >> > > > - efl_duplicate (creates a new object like efl_add)
> >> > > >
> >> > > >
> >> > > > Anyway I think experiments only can tell us what's best. I see 3
> >> items:
> >> > > > - @noparent tag
> >> > >
> >> > > that i agreed with... and there are almost no instances that would use
> >> it.
> >> > > loop
> >> > > is one. in fact it should have a "never call efl_add on me - ever". ...
> >> > > unless
> >> > > we want to get into the complexity of child and parent loops within one
> >> > > thread.
> >> > > i really dislike that complexity and would at this stage want to just
> >> ban
> >> > > it
> >> > > entirely thus no one ever should efl_add a loop. ... except inside efl
> >> ...
> >> > >
> >> > > > - efl_new (= efl_add without a parent -- requires @noparent if we
> >> want
> >> > > > strong NULL check)
> >> > >
> >> > > right now we have no "public" instances of this being allowed. in
> >> future i
> >> > > am
> >> > > imagining possibly shared objects that are transported from thread to
> >> > > thread
> >> > > being able to be like this (that's my 1-2% number). even then they may
> >> > > still
> >> > > have some global parent "app" object they belong to. and that app
> >> object
> >> > > would
> >> > > be "created for you". so even then... i don't see a need to allow null
> >> > > parents
> >> > > (except the app object itself which will like loop, be created for
> >> you).
> >> > >
> >> > > > - efl_invalidate / efl_terminate (I prefer efl_close :P)
> >> > >
> >> > > i actually prefer close too. shorter.
> >> >
> >> > But as cedric said there is file close (and specifically
> >> > efl.io.closer.close). Assuming this "invalidate" is a method (declared in
> >> > .eo, available in bindings), its name shouldn't conflict :)
> >> >
> >> > Anyway this opens some questions:
> >> > - do we really want to have parents for all objects? (basically except
> >> for
> >> > loop or app or some thread root object)
> >>
> >> without this hjow can an object do any async i/o - how can it register
> >> fd's or
> >> timers/timeouts, jobs, handle animation or just about anything i/o related.
> >> having a parent means you know which loop to look at to add these things.
> >> without that you don't know. yes - ui will only allow 1 loop to be the
> >> parent,
> >> but in the general sens, for elf.net, efl.model and so much mucre - they
> >> need a
> >> loop to drive them and that would necessitate a loop being a parent
> >> (somewhere
> >> in the tree so it's findable)..
> >>
> >> > - should we even go as far as forbidding null parent? or do we still want
> >> > to have this exceptional case?
> >>
> >> i think in 99% of cases - yes. it's just a few cases where we would allow
> >> it
> >> and only for internal purposes (otherwise how do we create the toplevel
> >> loop
> >> object then at all?). for now just documenting all objects need a parent
> >> is a
> >> good step and ensuring our test and sample and internal code follows that.
> >> this
> >> is exactly why i know i had to do this efl loop work to have the ability
> >> to do
> >> multiple ones so it'd bring out this issue and require it to be fixed.
> >> it's a
> >> baseline assumption for eo/efl going forward.
> >>
> >> we could have eo eventually enforce this, and maybe have a backdoor to
> >> disable
> >> it for only the exceptions we are talking about. for now i think we just
> >> need
> >> to document and clean up the code we have. enforcing can be done later.
> >>
> >> > - then what happens when parent_set(NULL) is called? should this call
> >> > invalidate automatically?
> >>
> >> imho it should either be an error (not allowed) ... or it should
> >> unref+invalidate.
> >>
> >> > Or am I going too far here and we should just try to have parents on all
> >> > objects for our API as a policy only (objects declared outside of EFL
> >> would
> >> > then chose if they need a parent or not)
> >>
> >> for now i think a policy will be good. it'll be one of those "1+1 is 2"
> >> rules
> >> - basic things you need to know when dealing with efl. all objects must
> >> have a
> >> parent. that parent will trace back to a loop object and  loop objects
> >> "drive"
> >> timeline, async i/o and events etc.
> >>
> >> eventually i think:
> >>
> >> 1. efl_add() with a null parent will fail and return null EXCEPT for the
> >> excepted classes (2 of them only i think in the end. definitely the loop
> >> class
> >> and maybe the "process" class that is a shared object covering the entire
> >> process and thus will be auto-locked and threadsafe for you. this process
> >> class
> >> i think is still up for debate, but i see it as a useful shared data store
> >> for
> >> a process as a whole).
> >> 2. like #1 - efl_parent_set to NULL will result in an unref+terminate
> >>
> >> one question is:
> >>
> >> if a child object has more refs than the parent... when the parent is
> >> destroyed... what happens to the child? i mean ... it must logically be
> >> unparented... but then it's floating... :( this is not pretty. that's why i
> >> think parent set to null does a terminate and unref so the object goes
> >> into a
> >> terminated state and is floating only because someone added more refs to
> >> it.
> >> this still has issues where the destructor now doesn't know what loop it
> >> belongs to... :(
> >>
> >> > //The following thoughts assume we have parents on ALL objects (except
> >> app
> >> > magic obj).//
> >>
> >> btw - i think we're on the same page here now where my point of view has
> >> been
> >> coming from the above (that we have an object tree where every object
> >> traces
> >> back to some parent than owns it with very few exceptions, and that the
> >> vast
> >> majority must trace back to a loop object out of the necessity to have a
> >> loop
> >> driving async i/o etc.).
> >>
> >> > So, to summarize the idea:
> >> >
> >> > - efl_add() -> always with a parent
> >>
> >> ultimately - yes. initially just by policy for efl everything will/must
> >> have a
> >> parent (with the few exceptions as discussed - loops, maybe process class
> >> and
> >> ector objects).
> >>
> >> > - efl_invalidate() -> ??? does not unref
> >>
> >> agree
> >>
> >> > - efl_parent_set(null) -> the parent calls invalidate, then unrefs which
> >> > calls the destructor and then actually set parent to null
> >>
> >> agree
> >>
> >> > - efl_del() -> always parent_set(null), no if
> >>
> >> hmm i think efl_del is just inavlidate + unref? or just an alias for unref?
> >>
> >> > - efl_unref() -> only to be used after efl_ref()
> >> > - efl_unref() to 0 ref -> error case as it is now, destroys the object
> >> but
> >> > prints an ERR (bindings should be safe). normal for efl_part().
> >>
> >> imho this should not be an error.
> >>
> >> > - efl_add_ref() -> only to be used by bindings, always with a parent,
> >> > always has 2 refs. requires implicit (by binding) efl_unref(). if used in
> >> > C, requires both efl_del and efl_unref to delete, unref only if we leave
> >> it
> >> > to the parent
> >>
> >> agreed... with the addition of "OR if you want to use this api like a
> >> gc'd/scope referenced language and you WILL do all the unrefs on scope exit
> >> yourself and get it right 100% guaranteed 0 but your job, so only use this
> >> if
> >> you really are sure."
> >>
> >> > - efl_destructor() -> called with a parent, but zero ref.
> >>
> >> agree
> >>
> >> > - efl_part() -> no change (returns an auto-deleted object except in
> >> > bindings -- as implemented for C++ already)
> >>
> >> agree
> >>
> >> > what exactly should happen in invalidate? for evas object just hide and
> >> > mark as delete_me?
> >>
> >> yeah. files close(), maybe any async actions like futures/promises get
> >> cancelled
> >> etc.?
> >>
> >> > one can then wonder if the parent ref is necessary: no ref + no parent =
> >> > deleted, no ref but parent = still alive.
> >>
> >> well strictly the parent -> child relationship ... is a reference. :)
> >>
> >> > - "invalidate" event is called when invalidate begins, "del" event is
> >> > emitted when destruction begins, "destroyed" event emitted after it's all
> >> > done
> >>
> >> yes, yes, and i prefer "deleted" rather than "destroyed" ... :)
> >>
> >> > Sorry... I think I'm still tired from jetlag... So please correct me if
> >> I'm
> >> > wrong.
> >> > But I am worried of making any radical change at this point in time... So
> >> > let's make sure we have something solid that we're all happy about. The
> >> > less changes the better.
> >>
> >> well i think the loop as parent is a change that is a long time coming
> >> that we
> >> all know has been needed for reasons above, but we've just glossed over it
> >> and
> >> ignored it etc. ... :)
> >>
> >> > Best regards,
> >> >
> >> >
> >> > >
> >> > > > Best regards,
> >> > > >
> >> > > >
> >> > > > On Fri, Jan 5, 2018 at 2:43 PM, Carsten Haitzler <
> >> ras...@rasterman.com>
> >> > > > wrote:
> >> > > >
> >> > > > > On Thu, 04 Jan 2018 17:18:35 +0000 Andrew Williams <
> >> > > a...@andywilliams.me>
> >> > > > > said:
> >> > > > >
> >> > > > > > Hi,
> >> > > > > >
> >> > > > > > I don't think I can do this any longer. Any comment I make about
> >> > > > > usability
> >> > > > > > is met with
> >> > > > > >
> >> > > > > > "it's easy to understand if you know the internal
> >> state/functioning
> >> > > of
> >> > > > > the
> >> > > > > > object".
> >> > > > >
> >> > > > > believe what you want... i described it in a single if statement.
> >> it
> >> > > > > requires
> >> > > > > no knowledge of internal state. it requires knowing just this:
> >> > > > >
> >> > > > > if (parent) { parent now responsible for unreffing }
> >> > > > > else { you (the caller) are responsible for unreffing when done }
> >> > > > >
> >> > > > > requires nothing more than that. why do you claim you need to know
> >> > > internal
> >> > > > > state? the above if has nothing to do with internal state. it has
> >> > > TOTALLy
> >> > > > > to do
> >> > > > > with externally provided params. it's the same logic as (assuming
> >> > > there is
> >> > > > > an
> >> > > > > efl_child_add that has a parent param that must be non-null, and
> >> > > efl_add
> >> > > > > now
> >> > > > > drops parent param as it's assumed to be NULL):
> >> > > > >
> >> > > > > if (used efl_child_add) { parent now responsible for unreffing }
> >> > > > > else (used efl_add) { you (the caller) are responsible for
> >> unreffing
> >> > > when
> >> > > > > done }
> >> > > > >
> >> > > > > both are conditions/data provided by the caller. one is a choice by
> >> > > > > parameter
> >> > > > > and the other is a choice by function call name.
> >> > > > >
> >> > > > > > My premise is still
> >> > > > > >
> >> > > > > > "with efl_add sometimes returning ownership and other times not
> >> this
> >> > > is
> >> > > > > > confusing for the developer"
> >> > > > >
> >> > > > > totally based on input provided by the caller. examples:
> >> > > > >
> >> > > > > fopen("filename", "r");
> >> > > > > vs
> >> > > > > fopen("filename", "w");
> >> > > > >
> >> > > > > with one i can only call fread() on the result anxd the other i can
> >> > > only
> >> > > > > call
> >> > > > > fwrite(). by your logic this is highly confusing to developers and
> >> libc
> >> > > > > should
> >> > > > > have:
> >> > > > >
> >> > > > > fopen_read("filename");
> >> > > > > +
> >> > > > > fopen_write("filename");
> >> > > > >
> >> > > > > because developers would otherwise be confused.
> >> > > > >
> >> > > > > > I wanted for us to present something that is clear and simple
> >> without
> >> > > > > > needing to know internal state or reading the EFL source code.
> >> > > > > > It seems I will not succeed.
> >> > > > >
> >> > > > > my argument is that more constructors make for something LESS
> >> simple.
> >> > > > > while it
> >> > > > > removes the parameter you do not like, it means you have to choose
> >> > > which
> >> > > > > constructor to use based on situation and know about both.
> >> > > > >
> >> > > > > also i argue that 95%+ of uses will be with pent not allowed to be
> >> > > NULL.
> >> > > > > efl.net is reliant on a loop to drive it. all of the ui is too.
> >> the
> >> > > loop
> >> > > > > and
> >> > > > > its related constructs are too. ecore_audio is too. well it is
> >> reliant
> >> > > on
> >> > > > > the
> >> > > > > main loop to drive it but it may not actually technically rely on
> >> > > parent
> >> > > > > object
> >> > > > > (yet, but it should). eio is reliant on parent objects too. ledbus
> >> too.
> >> > > > >
> >> > > > > in fact a quick look at out current efl interfaces means EVERY
> >> SINGLE
> >> > > > > object we
> >> > > > > have requires a parent EXCEPT the loop object ... and that is
> >> created
> >> > > for
> >> > > > > you
> >> > > > > (and will be in future with threads and their loops). so in fact
> >> using
> >> > > a
> >> > > > > non-NULL parent is in fact invalid in 100% of efl use cases. this
> >> is
> >> > > why i
> >> > > > > keep
> >> > > > > pushing back strongly. your argument for confusion is actually
> >> > > covering 0
> >> > > > > use
> >> > > > > cases (and the only reason objects can be created with NULL parents
> >> > > now is
> >> > > > > that
> >> > > > > we aren't policing or enforcing parents at this point and we SHOULD
> >> > > be. we
> >> > > > > SHOULD have a specific "@noparent" tag for classes that indicate an
> >> > > object
> >> > > > > is
> >> > > > > allowed to have no parent - it'll be by far the exception and not
> >> the
> >> > > > > rule...
> >> > > > > by exception i mean maybe 1 or 2% of all objects). does this
> >> incredibly
> >> > > > > rare
> >> > > > > case justify multiplying the number of constructors we have and
> >> making
> >> > > a
> >> > > > > longer
> >> > > > > winded one (efl_child_add) which will be actually 99% of use cases?
> >> > > > >
> >> > > > > i think we're at a position where we see 2 totally different
> >> things. i
> >> > > see
> >> > > > > an
> >> > > > > efl api where parent is basically always used.  you don't. you
> >> believe
> >> > > > > it'll be
> >> > > > > "random" or basically sometimes NULL, sometimes not.
> >> > > > >
> >> > > > > as i already mentioned in another mail. we're missing the policing
> >> of
> >> > > > > this. we
> >> > > > > should actually have eo require a non-null parent for essentially
> >> every
> >> > > > > object
> >> > > > > we have with some exceptions (like loop objects... which will be
> >> > > created
> >> > > > > for
> >> > > > > you buy efl itself anyway - but in this case the check, when it
> >> finally
> >> > > > > exists,
> >> > > > > should be disabled).
> >> > > > >
> >> > > > > at this point in time, it'd be bad to put in a forced non-null
> >> check
> >> > > > > because
> >> > > > > we're still mis-using efl's api a lot and need to clean this up so
> >> > > it's a
> >> > > > > very
> >> > > > > small number of instances to fix before enforcing. we could add ERR
> >> > > logs to
> >> > > > > non-null parents and add a lot of noise at this point... but IMHO
> >> this
> >> > > is
> >> > > > > what
> >> > > > > we should do.
> >> > > > >
> >> > > > > now what do we do if you, by accident, pass in a null parent on
> >> add? as
> >> > > > > long as
> >> > > > > it's not one of the "i allow null parents" object types (which
> >> frankly
> >> > > > > will be
> >> > > > > a handful in the end), we probably should not even begin
> >> construction
> >> > > and
> >> > > > > error
> >> > > > > log and return NULL as the object as it's invalid. but first we
> >> need
> >> > > the
> >> > > > > ability to flag objects as allowing null parents and then begin
> >> > > cleaning
> >> > > > > up our
> >> > > > > code to match.
> >> > > > >
> >> > > > > > Andy
> >> > > > > >
> >> > > > > > On Thu, 4 Jan 2018 at 06:32 Carsten Haitzler <
> >> ras...@rasterman.com>
> >> > > > > wrote:
> >> > > > > >
> >> > > > > > > On Wed, 03 Jan 2018 09:43:16 +0000 Andrew Williams <
> >> > > > > a...@andywilliams.me>
> >> > > > > > > said:
> >> > > > > > >
> >> > > > > > > > Hi Cedric,
> >> > > > > > > >
> >> > > > > > > > I think I agree, if we can tidy the definitions then
> >> everything
> >> > > > > should
> >> > > > > > > get
> >> > > > > > > > clearer.
> >> > > > > > > >
> >> > > > > > > > efl_add_ref being needed for bindings implies that our
> >> > > definition of
> >> > > > > > > > efl_add was not clean enough in the first place.
> >> > > > > > >
> >> > > > > > > we were very clear on that. for bindings it's needed (or if you
> >> > > want to
> >> > > > > > > write
> >> > > > > > > code in that style) but it's highly inconvenient and we've been
> >> > > over
> >> > > > > that.
> >> > > > > > >
> >> > > > > > > > If efl_del is "hide and unparent" then maybe what we really
> >> need
> >> > > is
> >> > > > > > > > efl_gfx_hide and efl_parent_unset - but I don't see why we
> >> need
> >> > > to
> >> > > > > > > unparent
> >> > > > > > > > anyhow...
> >> > > > > > >
> >> > > > > > > well if it's the last ref... the unparenting cleanly removes
> >> from
> >> > > the
> >> > > > > > > parent
> >> > > > > > > AND removes the last ref as a result.
> >> > > > > > >
> >> > > > > > > BUT i kind of agree with you here. the unparenting is proving
> >> to
> >> > > be a
> >> > > > > major
> >> > > > > > > pain in the rear. by that i mean the unparenting happens and
> >> then
> >> > > > > parent is
> >> > > > > > > NULL and THEN as a result of this reference goes to 0 and
> >> > > destructors
> >> > > > > get
> >> > > > > > > called. when the destructors are called, the parent is already
> >> > > NULL and
> >> > > > > > > this
> >> > > > > > > has proven an "odd" case i've been dealing with the efl loop
> >> > > work...
> >> > > > > > > because on
> >> > > > > > > destruction the object doesn't know what loop it belonged to
> >> > > anymore...
> >> > > > > > > yes -
> >> > > > > > > you have to handle parent_set to NULL then but it means this
> >> has
> >> > > to do
> >> > > > > some
> >> > > > > > > kind of destruction of loop bound resources... :(
> >> > > > > > >
> >> > > > > > > IMHO when the destructors are called the object should still
> >> have a
> >> > > > > parent
> >> > > > > > > and
> >> > > > > > > be removed from the child list as a very last "after last
> >> > > destructor is
> >> > > > > > > called"
> >> > > > > > > step, not "before destructors are called".
> >> > > > > > >
> >> > > > > > > also we need to do better parent policing.
> >> > > > > > >
> >> > > > > > > 1. objects that can never have a NULL parent need to be marked
> >> as
> >> > > such
> >> > > > > > > 1.2 objects that MUST have a loop parent at the top of their
> >> parent
> >> > > > > tree or
> >> > > > > > > somewhere in it (provider_find for a loop class must fund a
> >> > > non-null
> >> > > > > loop
> >> > > > > > > object).
> >> > > > > > > 1.3 objects MUST have a loop object and it MUST be the main
> >> loop
> >> > > > > object and
> >> > > > > > > only that one.
> >> > > > > > > 2. some objects are intended to be toplevels (with NULL as the
> >> > > parent)
> >> > > > > and
> >> > > > > > > should be marked as such (e.g. loop objects).
> >> > > > > > >
> >> > > > > > > > If we are delegating to a parent to manage the lifecycle of
> >> the
> >> > > > > object
> >> > > > > > > then
> >> > > > > > > > we should step away from the reference and forget it - that
> >> is
> >> > > the
> >> > > > > most
> >> > > > > > > > "convenient" behaviour I guess.
> >> > > > > > > >
> >> > > > > > > > if:
> >> > > > > > > > efl_add *always* returned an owned reference and took no
> >> parent
> >> > > > > > > > efl_add_child *never* returned an owned reference and
> >> required a
> >> > > > > parent
> >> > > > > > > >
> >> > > > > > > > then:
> >> > > > > > > > efl_add_ref* would no longer be required right? (if the
> >> binding
> >> > > > > requires
> >> > > > > > > a
> >> > > > > > > > ref after efl_add_child we have efl_ref that it could wrap
> >> up)
> >> > > > > > > > efl_del would take a reference and dec (probably not needed
> >> as we
> >> > > > > have
> >> > > > > > > > efl_unref?)
> >> > > > > > > > efl_del_child seems unlikely to be needed as all that is
> >> left is
> >> > > > > hiding
> >> > > > > > > > which is a graphics call, not an eo lifecycle one.
> >> > > > > > > >
> >> > > > > > > > The more I look at it the more I think we have too much UI
> >> > > related
> >> > > > > > > thinking
> >> > > > > > > > in our object lifecycle.
> >> > > > > > >
> >> > > > > > > that's because 90% of our objects have been UI related in the
> >> past
> >> > > sand
> >> > > > > > > pretty
> >> > > > > > > much still are. for us, i think this is the right thing.
> >> > > > > > >
> >> > > > > > > > Andy
> >> > > > > > > >
> >> > > > > > > > On Wed, 3 Jan 2018 at 05:41 Cedric Bail <ced...@ddlm.me>
> >> wrote:
> >> > > > > > > >
> >> > > > > > > > > > The whole efl_del argument just exist because it is kinda
> >> > > poorly
> >> > > > > > > > > > named. IMO, del means: get this object to an "empty"
> >> state.
> >> > > > > > > > > > Just like close to files and hide and unparent to UI
> >> objects.
> >> > > > > efl_del
> >> > > > > > > > > > should not steal references under people who owns it, the
> >> > > object
> >> > > > > > > > > > would get deleted at a later time when everybody using
> >> the
> >> > > object
> >> > > > > > > > > > stops doing so, we could even return errors from
> >> efl_del'eted
> >> > > > > > > > > > objects for methods that do not make sense anymore,
> >> causing
> >> > > > > > > > > > most actions to, possibly, halt earlier rather than
> >> later.
> >> > > > > > > > >
> >> > > > > > > > > So, if efl_del does not still a references under people who
> >> > > owns
> >> > > > > it,
> >> > > > > > > how
> >> > > > > > > > > do we fix it ? Should it still magically reset its parent
> >> to
> >> > > NULL
> >> > > > > when
> >> > > > > > > > > there is one and just efl_unref in the other case ? Should
> >> it
> >> > > be
> >> > > > > > > symetric
> >> > > > > > > > > to efl_add_ref and always reset the parent to NULL along
> >> with
> >> > > > > unref ?
> >> > > > > > > Or
> >> > > > > > > > > should it do none of this at all and you have to manually
> >> do
> >> > > the
> >> > > > > > > parent set
> >> > > > > > > > > and the unref ?
> >> > > > > > > > >
> >> > > > > > > > > Trying to figure out what behavior would make it work for
> >> > > binding,
> >> > > > > I
> >> > > > > > > would
> >> > > > > > > > > guess it would be best to just make it symetric to
> >> efl_add_ref.
> >> > > > > This
> >> > > > > > > will
> >> > > > > > > > > give a predictable outcome I think, but I am not sure it is
> >> > > enough.
> >> > > > > > > What do
> >> > > > > > > > > you think ?
> >> > > > > > > > >
> >> > > > > > > > > >   IMO, the whole problem with efl_add/efl_add_ref is that
> >> > > > > > > > > > "parents" are treated specially, which they should not.
> >> > > > > parent_set
> >> > > > > > > > > > should increment efl_ref and parent_unset should
> >> decrement
> >> > > it.
> >> > > > > > > > >
> >> > > > > > > > > Agreed and surprised it is not the case.
> >> > > > > > > > >
> >> > > > > > > > > > For C, OTH, where we do expect some "automatism" on
> >> resource
> >> > > > > > > > > > handling, efl_unref'ing may be too much of a hassle when
> >> a
> >> > > > > > > > > > parent is already going to handle the lifetime of the
> >> > > object. So,
> >> > > > > > > > > > it would make sense, IMO, for efl_add_scope. It could
> >> even be
> >> > > > > > > > > > that efl_add_scope is named efl_add, no problem, as long
> >> as
> >> > > > > > > > > > there's a efl_add that keeps this semantics for binding
> >> > > > > > > > > > development. Which also means that parent_set/unset must
> >> > > > > > > > > > be fixed.
> >> > > > > > > > >
> >> > > > > > > > > I think that once efl_del behavior is clearly defined, the
> >> > > > > existence
> >> > > > > > > of an
> >> > > > > > > > > efl_add_scope/efl_add will also be clearer to everyone.
> >> > > > > > > > >
> >> > > > > > > > > >   Also, @own tags must not relate to parent_set, because
> >> that
> >> > > > > > > > > > has no useful information for tags or users, if needed
> >> we can
> >> > > > > > > > > > add a @reparent tag, but that's not really special
> >> > > information
> >> > > > > > > > > > such as real owernship information.
> >> > > > > > > > >
> >> > > > > > > > > I am still wondering what the @own really mean. Does that
> >> mean
> >> > > > > that the
> >> > > > > > > > > object own at least one reference of it ? But in that case,
> >> > > doesn't
> >> > > > > > > that
> >> > > > > > > > > mean that the user need to always ref it, if it plans to
> >> keep
> >> > > it
> >> > > > > > > around.
> >> > > > > > > > >
> >> > > > > > > > > As for @reparent, I am not sure we have case yet where we
> >> > > return an
> >> > > > > > > object
> >> > > > > > > > > that can not be reparented, do we have such a case ?
> >> > > > > > > > >
> >> > > > > > > > > Cedric
> >> > > > > > > > >
> >> > > > > > > > >
> >> > > > > > > ------------------------------------------------------------
> >> > > > > ------------------
> >> > > > > > > > > Check out the vibrant tech community on one of the world's
> >> most
> >> > > > > > > > > engaging tech sites, Slashdot.org!
> >> http://sdm.link/slashdot
> >> > > > > > > > > _______________________________________________
> >> > > > > > > > > enlightenment-devel mailing list
> >> > > > > > > > > enlightenment-devel@lists.sourceforge.net
> >> > > > > > > > > https://lists.sourceforge.net/
> >> lists/listinfo/enlightenment-
> >> > > devel
> >> > > > > > > > >
> >> > > > > > > >
> >> > > > > > > >
> >> > > > > > > > --
> >> > > > > > > > http://andywilliams.me
> >> > > > > > > > http://ajwillia.ms
> >> > > > > > > >
> >> > > > > > > ------------------------------------------------------------
> >> > > > > ------------------
> >> > > > > > > > Check out the vibrant tech community on one of the world's
> >> most
> >> > > > > > > > engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> >> > > > > > > > _______________________________________________
> >> > > > > > > > enlightenment-devel mailing list
> >> > > > > > > > enlightenment-devel@lists.sourceforge.net
> >> > > > > > > > https://lists.sourceforge.net/lists/listinfo/enlightenment-d
> >> evel
> >> > > > > > > >
> >> > > > > > >
> >> > > > > > >
> >> > > > > > > --
> >> > > > > > > ------------- Codito, ergo sum - "I code, therefore I am"
> >> > > > > --------------
> >> > > > > > > Carsten Haitzler - ras...@rasterman.com
> >> > > > > > >
> >> > > > > > >
> >> > > > > >
> >> > > > > > --
> >> > > > > > http://andywilliams.me
> >> > > > > > http://ajwillia.ms
> >> > > > >
> >> > > > >
> >> > > > > --
> >> > > > > ------------- Codito, ergo sum - "I code, therefore I am"
> >> > > --------------
> >> > > > > Carsten Haitzler - ras...@rasterman.com
> >> > > > >
> >> > > > >
> >> > > > > ------------------------------------------------------------
> >> > > > > ------------------
> >> > > > > Check out the vibrant tech community on one of the world's most
> >> > > > > engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> >> > > > > _______________________________________________
> >> > > > > enlightenment-devel mailing list
> >> > > > > enlightenment-devel@lists.sourceforge.net
> >> > > > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> >> > > > >
> >> > > > >
> >> > > >
> >> > > > PS: The command lines are as follows (remove the grep -v for the
> >> first
> >> > > > stats):
> >> > > >
> >> > > > git grep --color=never -E "efl_add\(.*CLASS," |grep -v
> >> EFL_UI_WIN_CLASS
> >> > > > |grep -v ECORE |sed -e 's/.*efl_add(\([^,]\+\),.*/\1/' |sort -u|wc
> >> > > > git grep --color=never -E "efl_add\(.*CLASS," |grep -v
> >> EFL_UI_WIN_CLASS
> >> > > > |grep -v ECORE |sed -e 's/.*efl_add(\([^,]\+\),.*/\1/' |wc
> >> > > >
> >> > > > git grep --color=never -E "efl_add\(.*CLASS, NULL" |grep -v
> >> > > > EFL_UI_WIN_CLASS |grep -v ECORE |sed -e
> >> 's/.*efl_add(\([^,]\+\),.*/\1/'
> >> > > > |sort -u|wc
> >> > > > git grep --color=never -E "efl_add\(.*CLASS, NULL" |grep -v
> >> > > > EFL_UI_WIN_CLASS |grep -v ECORE |sed -e
> >> 's/.*efl_add(\([^,]\+\),.*/\1/'
> >> > > |wc
> >> > > >
> >> > > >
> >> > > > --
> >> > > > Jean-Philippe André
> >> > > > ------------------------------------------------------------
> >> > > ------------------
> >> > > > Check out the vibrant tech community on one of the world's most
> >> > > > engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> >> > > > _______________________________________________
> >> > > > enlightenment-devel mailing list
> >> > > > enlightenment-devel@lists.sourceforge.net
> >> > > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> >> > >
> >> > >
> >> > > --
> >> > > ------------- Codito, ergo sum - "I code, therefore I am"
> >> --------------
> >> > > Carsten Haitzler - ras...@rasterman.com
> >> > >
> >> > >
> >> >
> >> >
> >> > --
> >> > Jean-Philippe André
> >> > ------------------------------------------------------------
> >> ------------------
> >> > Check out the vibrant tech community on one of the world's most
> >> > engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> >> > _______________________________________________
> >> > enlightenment-devel mailing list
> >> > enlightenment-devel@lists.sourceforge.net
> >> > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> >>
> >>
> >> --
> >> ------------- Codito, ergo sum - "I code, therefore I am" --------------
> >> Carsten Haitzler - ras...@rasterman.com
> >>
> >>
> >>
> >>
> >>
> >
> >
> > --
> > Jean-Philippe André
> > ------------------------------------------------------------------------------
> > Check out the vibrant tech community on one of the world's most
> > engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> > _______________________________________________
> > enlightenment-devel mailing list
> > enlightenment-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> 
> 
> 
> -- 
> Gustavo Sverzut Barbieri
> --------------------------------------
> Mobile: +55 (16) 99354-9890
> 


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - ras...@rasterman.com


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to