Author Topic: about UITweener's fire event ( OnFinish and extended )  (Read 6092 times)

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
about UITweener's fire event ( OnFinish and extended )
« on: September 29, 2015, 04:57:22 AM »
  1. if (current == null)
  2. {
  3.         UITweener before = current;
  4.         current = this;
  5.  
  6.         if (onFinished != null)
  7.         {
  8.                 mTemp = onFinished;
  9.                 onFinished = new List<EventDelegate>();
  10.  
  11.                 // Notify the listener delegates
  12.                 EventDelegate.Execute(mTemp);
  13.  
  14.                 // Re-add the previous persistent delegates
  15.                 for (int i = 0; i < mTemp.Count; ++i)
  16.                 {
  17.                         EventDelegate ed = mTemp[i];
  18.                         if (ed != null && !ed.oneShot) EventDelegate.Add(onFinished, ed, ed.oneShot);
  19.                 }
  20.                 mTemp = null;
  21.         }
  22.  
  23.         // Deprecated legacy functionality support
  24.         if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished))
  25.                 eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver);
  26.  
  27.         current = before;
  28. }
  29.  

1. here:
if (current == null)
{
   UITweener before = current;
   current = this;

the 'before' will always be null, so why the code here do the 'current' cache?

2. sometimes we will have our new tweens that with new events,
could the event fire call of UITweener be a function to do the same job?

like this:
  1.         List<EventDelegate> temp = null;
  2.         protected virtual void FireEvent( List<EventDelegate> e )
  3.         {
  4.                 if (current == null)
  5.                 {
  6.                         UITweener before = current;
  7.                         current = this;
  8.                        
  9.                         if (e != null)
  10.                         {
  11.                                 temp = e;
  12.                                 e = new List<EventDelegate>();
  13.                                
  14.                                 // Notify the listener delegates
  15.                                 EventDelegate.Execute(temp);
  16.                                
  17.                                 // Re-add the previous persistent delegates
  18.                                 for (int i = 0; i < temp.Count; ++i)
  19.                                 {
  20.                                         EventDelegate ed = temp[i];
  21.                                         if (ed != null && !ed.oneShot) EventDelegate.Add(e, ed, ed.oneShot);
  22.                                 }
  23.                                 temp = null;
  24.                         }
  25.                        
  26.                         // Deprecated legacy functionality support
  27.                         if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished))
  28.                                 eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver);
  29.                        
  30.                         current = before;
  31.                 }
  32.         }
  33.  
« Last Edit: September 29, 2015, 05:30:34 AM by gyd »

Real World

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 15
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #1 on: September 29, 2015, 06:16:29 AM »
I was just coming here to post a bug about something very similar.

current is not always null but I still don't know what the point of the if check is as caching it in "before" should cover all the problems I can think of. I'm having an issue where the framerate drops and Time.deltaTime is higher than the animation duration. Here's what is happening for us:

First we set the event delegate for on finished and play the anim. The anim completes during the call to PlayForward due to the low framerate and the callback is immediately called.
  1. EventDelegate.Set( triangleTween.onFinished, delegate() { PlayTextBoxSizeTween( true ); } );
  2. triangleTween.PlayForward();
  3.  

The callback sets up a new callback on a different tween. This ALSO completes in the same frame.
  1.         public void PlayTextBoxSizeTween( bool forwards )
  2.         {
  3.                 if( forwards )
  4.                 {
  5.                         EventDelegate.Set( textBoxHeightTween.onFinished, delegate() { PlayInfoPanelAlphaTween( true ); } );
  6.                         textBoxHeightTween.PlayForward();
  7.                 }
  8.         }
  9.  

The problem is that now the callback hasn't been called. The reason is that current is not null, it is set to the value of the previous tween because we are still inside the first callback function. It's also NEVER called because enabled = false; is set before the if ( current == null ) check.

I would suggest that this is fixed by either removing the current == null check or by not disabling the component if we have a onFinished delegate set and current != null. This way the anim should complete on the next frame instead

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #2 on: September 29, 2015, 04:33:54 PM »
The null check is there so that you don't get an endless loop. You can probably fix it by changing the != null to
  1. if (current != this)

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #3 on: October 03, 2015, 01:09:26 PM »
The null check is there so that you don't get an endless loop. You can probably fix it by changing the != null to
  1. if (current != this)

what i mean is
UITweener before = current;
the value of before will always null, because of the null check.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #4 on: October 03, 2015, 06:42:04 PM »
It's not always null, as Real World pointed out. If you have a callback triggering another callback, then it won't be null. The check is there to prevent the callback from calling itself, and the same exclusion can be done using a (current != this) check.

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #5 on: October 03, 2015, 07:24:21 PM »
i don't understand,

if (current == null) // so the current will be null
{
    UITweener before = current; // so the before will be null
}

anything i missed?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #6 on: October 03, 2015, 07:30:45 PM »
The change I was talking about makes it:
  1. if (current != this)
  2. {
  3.     UITweener before = current;
  4. }

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #7 on: October 03, 2015, 08:03:18 PM »
The change I was talking about makes it:
  1. if (current != this)
  2. {
  3.     UITweener before = current;
  4. }

ok, that makes sense :)

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #8 on: October 05, 2015, 01:52:35 PM »
i notice that i have 2 issue here haha,

how about the suggestion add a function to do the work of fireEvent?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #9 on: October 07, 2015, 07:55:55 PM »
I am not sure what you meant by your event thing. Tweener calls delegates, not events. If you want to call an event, just do an anonymous delegate that will do whatever you need it to do inside -- such as triggering your event.

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #10 on: October 08, 2015, 02:13:23 AM »
in my case, i have my own Tweener, ex: TweenProgress to tween a progress's value.
and it contains a OnValueChanged ( eventDelegate ), like the OnFinish.

should I call EventDelagate.Execute( OnValueChanged ) in the same way you call OnFinish?

if I should( I think so ), what I talked about is to make the call easier by add a method to do that :)

  1.     List<EventDelegate> temp = null;
  2.     protected virtual void CallDelegate( List<EventDelegate> e )
  3.     {
  4.         if (current == null)
  5.         {
  6.             UITweener before = current;
  7.             current = this;
  8.            
  9.             if (e != null)
  10.             {
  11.                 temp = e;
  12.                 e = new List<EventDelegate>();
  13.                
  14.                 // Notify the listener delegates
  15.                 EventDelegate.Execute(temp);
  16.                
  17.                 // Re-add the previous persistent delegates
  18.                 for (int i = 0; i < temp.Count; ++i)
  19.                 {
  20.                     EventDelegate ed = temp[i];
  21.                     if (ed != null && !ed.oneShot) EventDelegate.Add(e, ed, ed.oneShot);
  22.                 }
  23.                 temp = null;
  24.             }
  25.            
  26.             // Deprecated legacy functionality support
  27.             if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished))
  28.                 eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver);
  29.            
  30.             current = before;
  31.         }
  32.     }
  33.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #11 on: October 10, 2015, 11:13:11 PM »
Why do this when the progress bar already has an OnChange notification? Can't you just use that one?

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #12 on: October 12, 2015, 01:31:31 PM »
ok, i didn't explain the whole thing.

I add a script, TweenProgress, to do a job that tween a ProgressBar, and it could assign a value > 1, ex: 3.5, from 0, then it will tween the ProgressBar from 0 and to 1, then set 0, to 1, 3 times and stop at 0.5. I use it to do progress effect like gains EXP and level up.
 
so it contains 2 callback, one is OnValueChange( and yes, i could just use that one on UIProgressBar, stupid miss ),
and another is OnPass01, called when the progress's value is passed 0 or 1.

This is just A CASE. what my question is :
1. Should we do the same thing like the OnFinish do when we execute a custom eventDelegate list?
  1. if (current == null)
  2.         {
  3.             UITweener before = current;
  4.             current = this;
  5.            
  6.             if (e != null)
  7.             {
  8.                 temp = e;
  9.                 e = new List<EventDelegate>();
  10.                
  11.                 // Notify the listener delegates
  12.                 EventDelegate.Execute(temp);
  13.                
  14.                 // Re-add the previous persistent delegates
  15.                 for (int i = 0; i < temp.Count; ++i)
  16.                 {
  17.                     EventDelegate ed = temp[i];
  18.                     if (ed != null && !ed.oneShot) EventDelegate.Add(e, ed, ed.oneShot);
  19.                 }
  20.                 temp = null;
  21.             }
  22.            
  23.             // Deprecated legacy functionality support
  24.             if (eventReceiver != null && !string.IsNullOrEmpty(callWhenFinished))
  25.                 eventReceiver.SendMessage(callWhenFinished, this, SendMessageOptions.DontRequireReceiver);
  26.            
  27.             current = before;
  28.         }
  29.  
2. If so, could the api be added into UITweener?
If we don't have to, then it's okay that i could just execute the callback list. ( should I set the current? i think it will happen the loop issue you mentioned if i don't. )


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #13 on: October 12, 2015, 11:10:19 PM »
The short answer is no, you shouldn't. EventDelegate.Execute is all you need. The tweener does extra work to make it possible to modify the list that's being executed while it's being executed -- that's why all that extra code is there.

gyd

  • Jr. Member
  • **
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 87
    • View Profile
Re: about UITweener's fire event ( OnFinish and extended )
« Reply #14 on: October 13, 2015, 03:31:22 PM »
ok, that's all information i need, thx :D