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

Reply via email to