Re: custom vfunc problem



Thanks Kjell. I wasn't sure if I was dealing with a common situation or an outlier, and whether I was missing an obvious solution.

Ian.

On 22/03/16 21:59, Kjell Ahlstedt wrote:
Sorry, my previous reply was wrong. What will happen with get_paint_volume is this (and I suppose that's what you have found):

If the user of the C++ code does not override get_paint_volume_vfunc(), clutter_actor_real_get_paint_volume() will be called, but klass->get_paint_volume will not be equal to clutter_actor_real_get_paint_volume.

A simple "solution" would be to not wrap get_paint_volume in C++ code. Then the C++ class, gtkmm__ClutterActor, would inherit klass->get_paint_volume from from the C class, ClutterActor. It would be impossible for a user of your C++ class to override get_paint_volume_vfunc(), because there would be no such vfunc. I suppose that's unacceptable or at least a serious drawback.

I don't know how to solve this problem. The long-term solution is to change the C code. Tests like
klass->get_paint_volume == clutter_actor_real_get_paint_volume
are bad. Comments in the C code show that the clutter developers are aware of that.

Kjell

Den 2016-03-21 kl. 21:38, skrev Ian Martin:
Hi,
Thanks.

Sorry Kjell, I clipped the init function. All of the non-deprecated methods and signals are pointed to the _real_ version of the vfunc or signal in clutter_actor_class_init(), and I'm wondering if using that to ensure the object is not a derived class is preventing cluttermm from calling the appropriate vfuncs. Stepping through the code the _real_functions are being skipped from C++ code, but being called when the identical C code is run.

Running a program with a debug flag( --clutter-debug=layout) I'm seeing lines like the following:
Clutter-Message: [ +58820]:[LAYOUT]:clutter-actor.c:2342: Querying the layout manager 'gtkmm__ClutterBoxLayout'[0x2922670] for the preferred height
where the C code gives
Clutter-Message: [ +85160]:[LAYOUT]:clutter-actor.c:2342: Querying the layout manager 'ClutterBoxLayout'[0xb1ea10] for the preferred height

which looks to me like the C++ object used is a derived class given the gtkmm_ prefix; that would explain why it wouldn't call the base methods if a check for a _real_ vfunc is present, and that would explain what I'm seeing happen. I can't see anywhere in the gtkmm code where the same problem occurs; lots of gtk+ classes - GtkButton for one - have a series of _real_ signals, but I don't see anywhere the same use of the _real_ function as a way of blocking derived classes from using C code. clutter_actor_allocate_vfunc I got around by making sure a flag was set; now I'm stuck trying to get around clutter_get_paint_volume, and there's no flags to use to get around it- this piece of code in clutter_actor_real_get_paint_volume ensures any derived class returns false, and therefore any update won't happen.
  if (klass->paint == clutter_actor_real_paint &&
      klass->get_paint_volume == clutter_actor_real_get_paint_volume)
    {
      res = TRUE;
    }
else
    {
      /* this is the default return value: we cannot know if a class
       * is going to paint outside its allocation, so we take the
       * conservative approach.
       */
      res = FALSE;
    }


I can't point the C++ vfuncs to the _real_ vfuncs (as is done in clutter_actor_class_init) because they're declared in the .c files, not the public header.

Ian






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]