On Fri, Jul 17, 2009 at 12:52 PM, Andreas Volz<li...@brachttal.net> wrote:
> Am Fri, 17 Jul 2009 10:38:04 -0300 schrieb Gustavo Sverzut Barbieri:
>
>> On Fri, Jul 17, 2009 at 6:13 AM, Andreas Volz<li...@brachttal.net>
>> wrote:
>> > Hello,
>> >
>> > while wrapping Elementary to C++ I have this problem:
>> >
>> > How could I find out in the parent container widget that a child
>> > widget has been added or removed. I tried the "sub-object-add" and
>> > "sub-object-del" callback, but it's not what I want as it calls this
>> > signal more often than when I add/del an object to a container.
>> > Maybe the member_add and member_del callbacks in ESMART are what I
>> > need, but they're not used in Elementary. Any other ideas?
>>
>> member_add() should be called on children, at least that's what I
>> remember... if not I guess is missing as one object should contain the
>> children (given the container member).
>>
>> anyway, I wish I had time to merge guarana and elementary as guarana
>> way of creating widgets makes things much easier for bindings and all.
>
> Any ideas when you've time for it. Then I'll stop my work and continue
> after this merge.

No idea other than "not soon". Really, the changes are nothing that
different, just require lots of effort to port it and i don't have
that time now. So don't halt your work for that, but keep in mind it
could change in future

The major change, if someone want to implement, is to follow
ClippedSmartObject, Box and Table way of doing inheritance. It would
be extending Evas_Smart_Class and overriding methods, possibly calling
methods from parent class and such. This is in contrast with current
codebase that just have one "widget" class where you set hooks when
objects are created. Things would be much easier to wrappers since you
could check for Evas_Smart_Class.


>> > I tried to suicide my C++ object if the C object deletes itself and
>> > throws the delete signal, but that's a very bad design. It's the job
>> > of the container to destroy the widgets.
>>
>> this is the way to go. Each shell/wrapper object should listen to
>> EVAS_CALLBACK_DEL and EVAS_CALLBACK_FREE (pre/post memory being
>> deleted) and either delete itself or make it shallow (make the now
>> dead wrapped pointer NULL).
>
> I'll show you my current implementation and the problem I have with it. For 
> more
> code look in SVN...
>
> ElmWidget is the base class of all Elementary widgets and EvasSmart itself.
>
> #ifdef HAVE_CONFIG_H
>  #include <config.h>
> #endif
>
> #include "../include/elementaryxx/ElmWidget.h"
>
> using namespace std;
>
> namespace efl {
>
> ElmWidget::ElmWidget ()
> {
>
> }
>
> ElmWidget::~ElmWidget ()
> {
> }
>
> void ElmWidget::elmInit ()
> {
>  init (); // call init() from EvasObject
>
>  // this is EVAS_CALLBACK_FREE
>  signalHandleFree.connect (sigc::mem_fun (this, 
> &ElmWidget::freeSignalHandler));
> }
>
> void ElmWidget::freeSignalHandler ()
> {
>  //cout << "freeSignalHandler()" << endl;
>  mFree = false; // mark the object to don't delete the C object. In this case 
> it's yet deleted.
>  delete (this);
>  // !!!ATTENTION!!!
>  // suicide for a C++ object is dangerous, but allowed
>  // the simple rule is that no member functions or member variables are 
> allowed to access
>  // FIXME: Here is a design problem as child destructors access mFree member 
> variable. Solution needed!
> }
>
> Then all ElmWidgets do it like this:
>
> // private
> ElmButton::ElmButton (EvasObject &parent)
> {
>  o = elm_button_add (parent.obj ());
>
>  elmInit ();
> }
>
> ElmButton::~ElmButton ()
> {
>  if (mFree)
>  {
>    evas_object_del (o);
>  }
> }
>
> ElmButton *ElmButton::factory (EvasObject &parent)
> {
>  return new ElmButton (parent);
> }
>
> I use a factory design to be sure that Elementary widgets are only
> constructed on the heap and could be deleted. The implementation works,
> but I found a problem. After the delete(this) the destructor of ElmButton
> is called and access mFree again, but it's not longer existing, as it's
> as member deleted with the class itself.
>
> I thought about several solutions:
>
> 1) Make a private destructor and tell the user to use a destroy() member 
> function.
> Then the C++ destructor is empty and does nothing. This gives the library 
> control
> when to delete only the wrapper and when to delete also the C object.
>
> 2) Implement a global map where all deleted wrappers are marked and look in 
> the
> destructor in this map if to delete the C object or not.
>
> 3) As two, but let a second thread do this. More like a garbage collector.
>
> I think I'll check solution 1. Any comment about it. The C design here is 
> really hard
> to wrap with a good C++ design.

Look at Python, the way I do it should work for you if you refcount
the shell/wrapper:

   
http://trac.enlightenment.org/e/browser/trunk/BINDINGS/python/python-evas/evas/evas.c_evas_object.pxi

the wrapper it just deleted when refcount drops to 0. When object is
created, it will get an extra reference since canvas owns it as well.
When C object dies it looses this reference, but Python code keep its
reference. If there was no python code holding references, then
wrapper is really deleted. If python code holds reference, then
self.obj (C object) is now NULL and this should cause no harm to users
as Evas ignores obj == NULL, but I could add checkers for that and
even raise exception in such case.

I know that some libs (boost) do automatic refcount using operator
overloading, that may be a solution for you as well.

Something else is to make object destructor to check if o == NULL
before calling evas_object_delete() and  make o = NULL on
EVAS_CALLBACK_DEL/FREE.

-- 
Gustavo Sverzut Barbieri
http://profusion.mobi embedded systems
--------------------------------------
MSN: barbi...@gmail.com
Skype: gsbarbieri
Mobile: +55 (19) 9225-2202

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to