After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 672945 - Fixes for the implicit actor animation API
Fixes for the implicit actor animation API
Status: RESOLVED FIXED
Product: clutter
Classification: Platform
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: clutter-maint
clutter-maint
Depends on:
Blocks:
 
 
Reported: 2012-03-27 19:08 UTC by Jasper St. Pierre (not reading bugmail)
Modified: 2012-04-16 15:20 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
actor: Invalidate the current state when popping easing states (671 bytes, patch)
2012-03-27 19:08 UTC, Jasper St. Pierre (not reading bugmail)
committed Details | Review
actor: Clear outstanding transitions when setting fixed values (5.12 KB, patch)
2012-03-27 19:08 UTC, Jasper St. Pierre (not reading bugmail)
rejected Details | Review
actor: Simplify setters of animatable properties (17.96 KB, patch)
2012-03-28 10:55 UTC, Emmanuele Bassi (:ebassi)
committed Details | Review

Description Jasper St. Pierre (not reading bugmail) 2012-03-27 19:08:27 UTC
See patches.
Comment 1 Jasper St. Pierre (not reading bugmail) 2012-03-27 19:08:29 UTC
Created attachment 210719 [details] [review]
actor: Invalidate the current state when popping easing states
Comment 2 Jasper St. Pierre (not reading bugmail) 2012-03-27 19:08:33 UTC
Created attachment 210720 [details] [review]
actor: Clear outstanding transitions when setting fixed values
Comment 3 Emmanuele Bassi (:ebassi) 2012-03-27 19:17:10 UTC
Review of attachment 210719 [details] [review]:

looks good to me
Comment 4 Emmanuele Bassi (:ebassi) 2012-03-27 19:18:10 UTC
Review of attachment 210720 [details] [review]:

one question: why?
Comment 5 Jasper St. Pierre (not reading bugmail) 2012-03-27 19:36:28 UTC
(In reply to comment #4)
> Review of attachment 210720 [details] [review]:
> 
> one question: why?

If I add a 500ms duration on the actor's x position, and then 250ms later set the x directly, it should stop the current animation and warp to the position.
Comment 6 Emmanuele Bassi (:ebassi) 2012-03-27 20:14:18 UTC
(In reply to comment #5)
> (In reply to comment #4)
> > Review of attachment 210720 [details] [review] [details]:
> > 
> > one question: why?
> 
> If I add a 500ms duration on the actor's x position, and then 250ms later set
> the x directly, it should stop the current animation and warp to the position.

no, it should not, unless you set the easing duration to 0, and set the position - or you get the transition for the "x" property and remove it yourself.
Comment 7 Emmanuele Bassi (:ebassi) 2012-03-27 20:20:09 UTC
to be even more explicit: the *intent* of the API is that changing the state of the actor should always be a transition - unless you go out of your way to make it "jump" to the final state. any change that allows you to do a jump without explicitly telling the actor to do so is in direct opposition to the intent of the API, and as such it won't be accepted.
Comment 8 Jasper St. Pierre (not reading bugmail) 2012-03-27 20:31:52 UTC
Then we need to update the transition in both cases, otherwise with something like:

    clutter_actor_save_easing_state (actor);
    clutter_actor_set_x (actor, 200);
    clutter_actor_restore_easing_state (actor);
    clutter_actor_set_x (actor, 100);

the second set_x will be ignored, as the easing duration is back to 0, which means that it just updates fixed_x, and not the transition.
Comment 9 Emmanuele Bassi (:ebassi) 2012-03-28 10:55:46 UTC
Created attachment 210771 [details] [review]
actor: Simplify setters of animatable properties

Instead of checking the duration of the current easing state we should
check if there's a transition in progress, and update it
unconditionally.

If there is no easing state, or the easing state has a duration of zero
milliseconds, then create_transition() should bail out early and set the
requested final state.

This allows us to write:

  clutter_actor_save_easing_state (actor);
  clutter_actor_set_x (actor, 200);
  clutter_actor_restore_easing_state (actor);

  [...]

  clutter_actor_set_x (actor, 100);

and have the second set_x() update the easing in progress, instead of
being ignored.
Comment 10 Emmanuele Bassi (:ebassi) 2012-03-28 11:03:10 UTC
Attachment 210719 [details] pushed as 628ffa7 - actor: Invalidate the current state when popping easing states
Attachment 210771 [details] pushed as fa8d431 - actor: Simplify setters of animatable properties
Comment 11 Jasper St. Pierre (not reading bugmail) 2012-03-28 11:17:08 UTC
(In reply to comment #9)
> This allows us to write:
> 
>   clutter_actor_save_easing_state (actor);
>   clutter_actor_set_x (actor, 200);
>   clutter_actor_restore_easing_state (actor);
> 
>   [...]
> 
>   clutter_actor_set_x (actor, 100);
> 
> and have the second set_x() update the easing in progress, instead of
> being ignored.

I still think that this is a bad decision, and will break existing behavior. Here's a code sample:

    static void
    button_press_cb (...)
    {
      if (button == 1)
        {
          clutter_actor_save_easing_state (actor);
          clutter_actor_set_x (actor, 200);
          clutter_actor_restore_easing_state (actor);
        }
      else
        {
          clutter_actor_set_x (actor, 50);
        }
    }

If you left-mouse-click, you get a nice animation to 200. If you right-mouse-click fast, you get a transition back to 50, otherwise the actor gets warped back to 50.

As an example, see test-scrolling. If you re-grab the actor as it's animating the drag-end, the drag is now animating as well.

Using the implicit animation API like this is just going to introduce race conditions. Just stop.

Additionally, the comment that you added that says that actors are going to have a default easing state. That's going to make it hard to just "set the x" of an actor without animating, which is very useful to do, especially if we use Tweener in the shell -- now we have *two* competing animation frameworks.

( Rant: The one thing I'll suggest is to sit down and write a complex application like GNOME Shell, or go through and try and hack on GNOME Shell and port it to the new API for a day or two, and hopefully you'll realize how your API changes are really, really inconvenient. You're blindly writing an API without use cases or existing applications, so you're yourself distant from the users of the API, and you're designing something that looks nice on paper. )
Comment 12 Emmanuele Bassi (:ebassi) 2012-03-28 11:27:30 UTC
(In reply to comment #11)
> (In reply to comment #9)
> > This allows us to write:
> > 
> >   clutter_actor_save_easing_state (actor);
> >   clutter_actor_set_x (actor, 200);
> >   clutter_actor_restore_easing_state (actor);
> > 
> >   [...]
> > 
> >   clutter_actor_set_x (actor, 100);
> > 
> > and have the second set_x() update the easing in progress, instead of
> > being ignored.
> 
> I still think that this is a bad decision, and will break existing behavior.

there is no existing behaviour that uses implicit animations with easing states, so how can it break?

> Here's a code sample:
> 
>     static void
>     button_press_cb (...)
>     {
>       if (button == 1)
>         {
>           clutter_actor_save_easing_state (actor);
>           clutter_actor_set_x (actor, 200);
>           clutter_actor_restore_easing_state (actor);
>         }
>       else
>         {
>           clutter_actor_set_x (actor, 50);
>         }
>     }
> 
> If you left-mouse-click, you get a nice animation to 200. If you
> right-mouse-click fast, you get a transition back to 50, otherwise the actor
> gets warped back to 50.
> 
> As an example, see test-scrolling. If you re-grab the actor as it's animating
> the drag-end, the drag is now animating as well.
> 
> Using the implicit animation API like this is just going to introduce race
> conditions. Just stop.

it's a race only insofar as you try to mix both immediate and tweened behaviours at the same time; it's not a good plan, so stop doing that.

> Additionally, the comment that you added that says that actors are going to
> have a default easing state. That's going to make it hard to just "set the x"
> of an actor without animating, which is very useful to do, especially if we use
> Tweener in the shell -- now we have *two* competing animation frameworks.

> ( Rant: The one thing I'll suggest is to sit down and write a complex
> application like GNOME Shell, or go through and try and hack on GNOME Shell and
> port it to the new API for a day or two, and hopefully you'll realize how your
> API changes are really, really inconvenient. You're blindly writing an API
> without use cases or existing applications, so you're yourself distant from the
> users of the API, and you're designing something that looks nice on paper. )

the use of Tweener in Shell is inconsequential: you are using a random API that is based on the assumption that setting a value on an actor's state will always yield an immediate jump there, which is a guarantee we never made, and that I only respect out of the kindness of my heart. your usage of an external API and mixing it with the Clutter animation API (*any* animation API)  is something I have no intention or inclination to consider a valid use case.

the implicit animation API is just a basic evolution of clutter_actor_animate(): it works under the same assumptions and following the same rules. if you're using clutter_actor_animate() and Tweenet at the same time you're going to fall into the same issues - same thing applies for State or Animator.

the real solution is to stop moaning and use the Clutter animation API for Clutter elements, instead of trying to bend Clutter into the wrong shape against the intent of the Clutter maintainer.
Comment 13 Jasper St. Pierre (not reading bugmail) 2012-03-28 11:44:28 UTC
(In reply to comment #12)
> it's a race only insofar as you try to mix both immediate and tweened
> behaviours at the same time; it's not a good plan, so stop doing that.

    static void
    button_press_cb (...)
    {
      if (button == 1)
        {
          clutter_actor_save_easing_state (actor);
          clutter_actor_set_easing_duration (actor, 500);
          clutter_actor_set_x (actor, 400);
          clutter_actor_restore_easing_state (actor);
        }
      else
       {
          clutter_actor_save_easing_state (actor);
          clutter_actor_set_easing_duration (actor, 5000);
          clutter_actor_set_x (actor, 50);
          clutter_actor_restore_easing_state (actor);
       }
    }

Left click, watch the fast transition to the right. Right-click after the animation is finished, and you get a slow transition. Perfect.

Now right-click while animating to the right. A fast transition back. And now left-click while animating to the left. A slow transition back to the right. More race conditions.

Of course, you can fix these bugs like whack-a-mole as they come up, but I'd just suggest to quit while you're ahead and realize that this API as you want it implemented is going to be full of bugs and worms. You shouldn't care if a transition exists, you should always stop any existing transitions and always use the current easing state of the actor... Yes, I know my patch didn't account for this.
Comment 14 Jasper St. Pierre (not reading bugmail) 2012-03-28 13:32:18 UTC
Review of attachment 210771 [details] [review]:

This broke the Shell. Please revert. I am currently investigating why.
Comment 15 Emmanuele Bassi (:ebassi) 2012-03-28 13:57:28 UTC
these commits are on master; gnome-shell should be using the clutter-1.10 branch, given that we branched for GNOME 3.4.
Comment 16 Emmanuele Bassi (:ebassi) 2012-04-16 15:20:31 UTC
I guess this can be closed.