On Fri, 29 Apr 2016 11:32:39 +0900 Jean-Philippe André <j...@videolan.org> said:

> On 29 April 2016 at 00:51, Tom Hacohen <t...@osg.samsung.com> wrote:
> 
> > On 28/04/16 06:25, Jean-Philippe André wrote:
> > > On 27 April 2016 at 23:44, Tom Hacohen <t...@osg.samsung.com> wrote:
> > >
> > >> On 26/04/16 06:28, Jean-Philippe André wrote:
> > >>> Hello,
> > >>>
> > >>>
> > >>> I've just merged a series of commits dealing with the box & table APIs
> > >> for
> > >>> Edje.Object and Elm.Layout. Since we decided not to implement anything
> > >> like
> > >>> eo_part at the core eo level, I've implemented part_box and part_table
> > >>> support using fake objects.
> > >>>
> > >>>
> > >>> This code:
> > >>>> elm_layout_table_blah(ly, "part", args);
> > >>>
> > >>> now becomes:
> > >>>> efl_pack_blah(efl_content_get(ly, "part"), args);
> > >>>
> > >>>
> > >>> The EO returned by efl_content_get is not a real Evas Object, it's
> > only a
> > >>> temporary proxy object that knows about its parent (ly) and the part
> > name
> > >>> it refers to ("part"). It is attached to the underlying Evas Box or
> > Table
> > >>> created by edje, and should live
> > >>>
> > >>> eo_del() is legal, just call efl_content_get() again to create a new
> > >> handle.
> > >>> eo_ref() is not a good idea.
> > >>>
> > >>>
> > >>> Note that efl_content_get() also returns real swallowed objects if the
> > >>> "part" is a SWALLOW.
> > >>>
> > >>>
> > >>> I believe text part APIs should eventually move to the same concept,
> > once
> > >>> the text interface is finalized (or, well, good enough). efl_text_set()
> > >> on
> > >>> a Layout object (or any Widget) should set the text of the "default"
> > part
> > >>> (whatever that means). Other parts can be accessed by
> > efl_content_get().
> > >>>
> > >>>
> > >>> Comments? Suggestions on how to improve this?
> > >>>
> > >>>
> > >>
> > >> Proxy objects were one of the original ideas to do eo_part. After that
> > >> we decided to do the more lightweight version I proposed and after that
> > >> it was rejected altogether.
> > >>
> > >> I don't like this solution because it's essentially what everyone
> > >> (raster?) said he didn't want to do. I prefer doing the part_* versions
> > >> (i.e double the functions), the normal versions (passing NULL as part
> > >> name) or maybe even an eo_part.
> > >>
> > >
> > > The part version means we should probably have a series of part_pack
> > > interfaces then.
> > > Or duplicate each and every API.
> > >
> > > Honestly, I'm not sure which solution is best. Proxy object or part APIs.
> > > But I believe the API looks pretty decent like this.
> >
> > I also like the part API, it's essentially the same API I suggested a
> > while back:
> >
> > efl_text_set(eo_part(obj, "bla"), "text"));
> >
> > Raster objected...
> >
> 
> There's a difference between eo_part and the proxy object.
> 
> With eo_part we would use a solution like eo_super(), which I have to say
> is not incredibly pretty (internally: spinlock and extra bit use). I
> believe that's the bit (sic) that raster didn't like much. Please correct
> me if I'm wrong.
> Anyway, I don't think parts belong to EO outside of EFL

yup. i totally hate this.

1. on 32bit we had only 32 bits to play with. we halved our object address
space with the super bit. now we lose another with part. so before super we
could have up to ~8 million eo objects at max (on 32bit). then we went down to
4. another drops us down to 2 million. but... we dropped a generation count bit
(went rom 9 to 8). so ok. we lose another generation count bit. before super it
was 1/512 chance of a recycled eo id matching gen count and getting a false
positive. we went to 1/256 with super bit. with part we go to 1/128. it's
getting "not great"

on 32bit our eo base objects are 72 bytes (or so). on 32bit an app cannot
access > 4gb. let's be realistic and given memory mappings for code, libs,
video memory mappings etc. .. make that more like 3gb. foe eo base objects at
that limit we need only ~600m to store those. that means we already run out of
eiod space before e run out of memory. so we're already kind of in a pickle.
assuming the ~200 bytes 8 bits for gen count - rest for id would be about right.
we'd almost always run out of mem before we run out of id's. that'd be 16 mil
objects. 8 bits gen, 24 for id.

anyway my point is we're really compromising usability (run out of id space
before mem) or robustness (why we have gen count).

of course on 64bit it doesn't matter (atm).

> The proxy object is a real EO object so you can keep it around if you want.
> It's always attached to its parent.
> The internal Evas Object Box (or Edje_Real_Part that really is the part) is
> the owner of the proxy object.
> When the proxy dies (eo_del) then a del callback will remove the entry in
> the owner. This way, content_get() does not return a dead object.
> When the owner (Evas Box) dies, not only should it delete its children (the
> proxy object), but it should also set the weak reference to NULL. That way,
> even if a user called eo_ref() on a proxy object, internally the reference
> to the original Edje or Elm layout is reset to NULL. Calls won't work, but
> nothing should crash, and we can print nice error messages if we want.
> 
> In terms of API, the advantage for both eo_part and proxy object is that it
> looks like we have an object, and the API is the same for a normal box and
> an edje box.
> The advantage of proxy object over eo_part is that it's really an EO
> object. It's just not a real canvas object.

its nice BUT... lifecycle is an issue. how long does it stay around for etc.
etc.

technically you can protect it with the del intercepts and make sure it's never
accidentally deleted if exposed, but what about parts of things that have no eo
object? the owner has to create one now and worry about how long it's used by
someone else, deal with caching these objects and deleting them if not needed
anymore... you don't want to force everyone to create these objects for
everything if needed or not.

so this is really the issue.

> > I don't like proxy object because of the implications I described about
> > life-cycle, and I actually wonder about the implications of your
> > solution for bindings. I think it just won't work because the bindings
> > won't know which functions are available (with the part API, it's just
> > part-enabled functions on the current class).
> >
> 
> The lifecycle is handled. If there's a bug then it's an implementation bug,
> not a design bug (at least I believe so).

HOW is it handled? as above... ?

> As for bindings, they need to be able to dynamically know which functions
> an object support based on its class (here the object is an instance of a
> class implementing Efl.Pack). Otherwise I don't see how any binding would
> work at all. (In C++ I would cast to the efl_pack class, but that doesn't
> work for Lua/JS).
> 
> 
> >
> > If you can convince raster, I'll happily go back to the original
> > eo_part() solution.
> >
> > >
> > > If we (or "people") really want the part APIs then I think we can just
> > add
> > > static inline / macros for C.
> >
> > Static inline, not macros. :) Yeah, that's the plan.
> >
> > >
> > > Anyway, remember the scope of these proxy objects: Edje BOX and TABLE.
> > > No one uses that. Proxy objects make the API behave the same as a
> > swallowed
> > > Box or Table.
> > >
> > > My biggest concern with this is the "eo_del() is legal, just call ..."
> > >> paragraph. You need to describe the lifecycle properly and not leave it
> > >> to chance because people will use it and you need to make sure they know
> > >> what's allowed, what's not and what they should do. For example, it's
> > >> not obvious to me if I get a ref out if I do content_get(). If I don't I
> > >> risk the object being deleted underneath my feet. If I do, it becomes
> > >> more of a PITA to deal with. Which one is it?
> > >>
> > >
> > > You don't get a reference. The object keeps it. There is no own().
> > > content_get() creates an object if there is not one already, eo_del()
> > nulls
> > > out the reference inside the object. So another content_get() triggers a
> > > new object creation.
> > >
> > > The proxy object can't die under your feet as it's bound to the main
> > > object. Unless you eo_del() the container.
> > > It's basically the same as eo_data_scope_get().
> > >
> > > Is this a documentation issue or a design issue?
> > >
> >
> > A design issue.
> >
> 
> Clearly this is a documentation issue, because your argument below is based
> on assumptions.
> 
> 
> part = efl_content_get(obj, "bla");
> >
> > how do you deal with the lifecycle of part? You mentioned eo_del(), if
> > that's the case, you can't do:
> >
> > efl_text_set(efl_content_get(obj, "bla"), "test");
> >
> 
> You can.
> 
> Because it would never get deleted. You can only have one or the other
> > unless you do some ugly magic (which you don't at the moment), so there
> > is a problem there.
> >
> 
> Wrong assumption.


i would never returned an obj expecting the caller to unref here... the problem
then is you never know the lifetime of it. :(

> > If it's kept alive and you don't del it at all you have a leak. If you
> > del it implicitly under some conditions (you have an object pool of 5)
> > it will die under the user's feet if they call it on more than 5
> > different parts. I'm talking about the "part = " option because that's
> > the only relevant one for lifecycle.
> >
> 
> No pool. Each part represents a real object, so they can track each other's
> death.
> The "leak" side of it is that instead of just having an Edje_Real_Part
> struct and an Evas_Object_Box EO you now also have a proxy EO in memory.
> They all die together.

there are issues requiring a real object. let's pretend we optimize edje and
only create real objects (txt, rect, box, whatever) when they are
visible/needed as we are storing state outside the real evas object in the part
structure data in the edje obj.. we can create and delete on the fly.

your way here would require we always have real objects and we can't create on
he fly and delete when not needed anymore. we lost ourselves a pretty juicy
optimization opportunity. :(

on the other handy once you get a part by name lookups don't need to happen so
they are free right from the obj handle as opposed to continually hash table
looking up etc. all the time by name if we pass in name...

> Finally, the thing is there was no clear consensus over the best solution
> for part APIs. I implemented something that works NOW. And I'm pretty happy
> with the result from a user point of view.
> 
> 
> -- 
> Jean-Philippe André
> ------------------------------------------------------------------------------
> Find and fix application performance issues faster with Applications Manager
> Applications Manager provides deep performance insights into multiple tiers of
> your business applications. It resolves application problems quickly and
> reduces your MTTR. Get your free trial!
> https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
> _______________________________________________
> 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" --------------
The Rasterman (Carsten Haitzler)    ras...@rasterman.com


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to