/// <summary>
 /// Flag a Tweener that implements IAutoKillableTweener to be auto killed if another tween targeting the same object is played. 
 /// Until the Tweener is either killed, or finished, it will be eligible for being automatically 
 /// killed if another Tweener starts playing that tweens the same target object. Note that other tweener 
 /// must implement IAutoKillableTweener as well (though doesn't have to be flagged to AutoKill).
 /// </summary>
 /// <param name="tween"></param>
 public static void AutoKill(Tweener tween)
 {
     if (tween == null || !(tween is IAutoKillableTweener)) return;
     if (GameLoopEntry.ApplicationClosing) return;
     if (_instance == null) _instance = Singleton.CreateSpecialInstance<SPTween>(SPECIAL_NAME, true);
     _instance.AutoKill_Imp(tween as IAutoKillableTweener);
 }
        public Tweener Create()
        {
            if (_targ == null)
            {
                return(null);
            }

            //set curves
            Tweener tween = null;

            if (_props.Count > 1)
            {
                var grp = new TweenCurveGroup();
                for (int i = 0; i < _props.Count; i++)
                {
                    var curve = this.CreateCurve(_props[i]);
                    if (curve == null)
                    {
                        Debug.LogWarning("Failed to create tween for property '" + _props[i].name + "' on target.", _targ as Object);
                    }
                    else
                    {
                        grp.Curves.Add(curve);
                    }
                }
                tween = new ObjectTweener(_targ, grp);
            }
            else if (_props.Count == 1)
            {
                var curve = this.CreateCurve(_props[0]);
                if (curve == null)
                {
                    Debug.LogWarning("Failed to create tween for property '" + _props[0].name + "' on target.", _targ as UnityEngine.Object);
                    return(new ObjectTweener(_targ, TweenCurve.Null));
                }
                else
                {
                    tween = new ObjectTweener(_targ, curve);
                }
            }
            else
            {
                tween = new ObjectTweener(_targ, TweenCurve.Null);
            }

            //set props
            if (_id != null)
            {
                tween.Id = _id;
            }
            tween.UpdateType   = _updateType;
            tween.TimeSupplier = _timeSupplier;
            tween.SpeedScale   = _speedScale;
            tween.WrapMode     = _wrap;
            tween.WrapCount    = _wrapCount;
            tween.Reverse      = _reverse;
            tween.Delay        = _delay;
            if (_onStep != null)
            {
                tween.OnStep += _onStep;
            }
            if (_onWrap != null)
            {
                tween.OnWrap += _onWrap;
            }
            if (_onFinish != null)
            {
                tween.OnFinish += _onFinish;
            }
            if (_onStopped != null)
            {
                tween.OnStopped += _onStopped;
            }

            if (_prevNode != null)
            {
                var seq = new TweenSequence();
                seq.Id = tween.Id;
                seq.Tweens.Add(tween);

                var node = _prevNode;
                while (node != null)
                {
                    seq.Tweens.Insert(0, node.Create());
                    node = node._prevNode;
                }

                tween = seq;
            }

            return(tween);
        }
 protected internal virtual void Init(Tweener twn)
 {
     if (_tween != null) throw new System.InvalidOperationException("Curve can only be registered with one Tweener at a time, and should not be doubly nested in any Curve collections.");
     _tween = twn;
 }
        public void FadeOut(float dur, EaseStyle ease = EaseStyle.LinearEaseOut)
        {
            _active = true;
            _fades.Add(this);

            if (_tween != null)
            {
                _tween.Stop();
                _tween = null;
            }
            _totalDuration = dur;
            _direction = 1;
            if(dur <= 0f)
            {
                this.OnFadeOutComplete(null, null);
            }
            else
            {
                _tween = SPTween.Tween(this.OnTweenStep, dur)
                                .Use(_timeSupplier ?? SPTime.Real)
                                .OnFinish(this.OnFadeOutComplete)
                                .Play();
            }
        }
 private void OnTweenStep(Tweener twn, float dt, float t)
 {
     if(_direction > 0)
     {
         this.UpdateFade(Mathf.Clamp01(t / _totalDuration));
     }
     else
     {
         this.UpdateFade(Mathf.Clamp01((_totalDuration - t) / _totalDuration));
     }
 }
        public void FadeIn(float dur, EaseStyle ease = EaseStyle.LinearEaseIn, bool destroyOnComplete = true)
        {
            if (!_active) throw new System.InvalidOperationException("Cannot FadeIn a CameraFade that isnot currently faded out.");

            if (_tween != null)
            {
                _tween.Stop();
                _tween = null;
            }
            _totalDuration = dur;
            _direction = -1;

            _tween = SPTween.Tween(this.OnTweenStep, dur)
                            .Use(_timeSupplier ?? SPTime.Real)
                            .OnFinish(this.OnFadeInComplete)
                            .Play();
        }
 internal TweenerGroup(Tweener[] tweens)
 {
     _tweens = tweens;
 }
 protected internal override void Init(Tweener twn)
 {
     //don't init
 }
 private void RemoveReference_Imp(Tweener tween)
 {
     if (_inUpdate)
     {
         if (!_runningTweens.Contains(tween)) return;
         if (_toRemove.Contains(tween)) return;
         _toRemove.Add(tween);
     }
     else
     {
         _runningTweens.Remove(tween);
         if(tween is IAutoKillableTweener && tween.IsComplete)
         {
             var auto = tween as IAutoKillableTweener;
             if(_autoKillDict.Reverse.ContainsKey(auto))
             {
                 _autoKillDict.Reverse.Remove(auto);
             }
         }
     }
 }
 private void AddReference_Imp(Tweener tween)
 {
     if(_inUpdate)
     {
         if (_runningTweens.Contains(tween) || _toAdd.Contains(tween)) return;
         _toAdd.Add(tween);
     }
     else
     {
         if (_runningTweens.Contains(tween)) return;
         _runningTweens.Add(tween);
         if(tween is IAutoKillableTweener)
         {
             var auto = tween as IAutoKillableTweener;
             var targ = auto.Token;
             IAutoKillableTweener old;
             if(_autoKillDict.TryGetValue(targ, out old))
             {
                 old.Kill();
             }
         }
     }
 }
 internal static void RemoveReference(Tweener tween)
 {
     if (GameLoopEntry.ApplicationClosing) return;
     if (_instance == null) return;
     _instance.RemoveReference_Imp(tween);
 }
 internal static bool IsRunning(Tweener tween)
 {
     if (GameLoopEntry.ApplicationClosing) return false;
     if (_instance == null) return false;
     return _instance._runningTweens.Contains(tween) || _instance._toAdd.Contains(tween);
 }
 internal static void AddReference(Tweener tween)
 {
     if (GameLoopEntry.ApplicationClosing) return;
     if (_instance == null) _instance = Singleton.CreateSpecialInstance<SPTween>(SPECIAL_NAME, true);
     _instance.AddReference_Imp(tween);
 }
 protected internal override void Init(Tweener twn)
 {
     //don't init
 }