include/cinder/Timeline.h
Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2011, The Cinder Project, All rights reserved.
00003  This code is intended for use with the Cinder C++ library: http://libcinder.org
00004 
00005  Based on the sc-Choreograph CinderBlock by David Wicks: http://sansumbrella.com/
00006 
00007  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00008  the following conditions are met:
00009 
00010     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00011     the following disclaimer.
00012     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00013     the following disclaimer in the documentation and/or other materials provided with the distribution.
00014 
00015  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00016  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00017  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00018  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00019  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00020  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00021  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00022  POSSIBILITY OF SUCH DAMAGE.
00023 */
00024 
00025 #pragma once
00026 
00027 #include "cinder/Cinder.h"
00028 #include "cinder/TimelineItem.h"
00029 #include "cinder/Easing.h"
00030 #include "cinder/Tween.h"
00031 #include "cinder/Function.h"
00032 
00033 #include <vector>
00034 #include <list>
00035 #include <map>
00036 
00037 namespace cinder {
00038 
00039 typedef std::shared_ptr<class Cue>          CueRef;
00040 typedef std::shared_ptr<class Timeline>     TimelineRef;
00041     
00042 class Timeline : public TimelineItem {      
00043   public:
00045     static TimelineRef  create() { TimelineRef result( new Timeline() ); result->setInfinite( true ); return result; }
00046 
00048     void    step( float timestep );
00050     void    stepTo( float absoluteTime );
00051     
00053     float   getCurrentTime() const { return mCurrentTime; }
00054     
00056     template<typename T>
00057     typename Tween<T>::Options apply( Anim<T> *target, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> )
00058     {
00059         target->setParentTimeline( thisRef() );
00060         return applyPtr( target->ptr(), endValue, duration, easeFunction, lerpFunction );
00061     }
00062 
00064     template<typename T>
00065     typename Tween<T>::Options apply( Anim<T> *target, T startValue, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> )
00066     {
00067         target->setParentTimeline( thisRef() );
00068         return applyPtr( target->ptr(), startValue, endValue, duration, easeFunction, lerpFunction );
00069     }
00070 
00072     template<typename T>
00073     typename Tween<T>::Options appendTo( Anim<T> *target, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> )
00074     {
00075         target->setParentTimeline( thisRef() );
00076         return appendToPtr( target->ptr(), endValue, duration, easeFunction, lerpFunction );
00077     }
00078 
00080     template<typename T>
00081     typename Tween<T>::Options appendTo( Anim<T> *target, T startValue, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> )
00082     {
00083         target->setParentTimeline( thisRef() );
00084         return appendToPtr( target->ptr(), startValue, endValue, duration, easeFunction, lerpFunction );
00085     }
00086 
00088     template<typename T>
00089     typename Tween<T>::Options applyPtr( T *target, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> )
00090     {
00091         TweenRef<T> newTween( new Tween<T>( target, endValue, mCurrentTime, duration, easeFunction, lerpFunction ) );
00092         newTween->setAutoRemove( mDefaultAutoRemove );
00093         apply( newTween );
00094         return typename Tween<T>::Options( newTween, thisRef() );
00095     }
00096     
00098     template<typename T>
00099     typename Tween<T>::Options applyPtr( T *target, T startValue, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> ) {
00100         TweenRef<T> newTween( new Tween<T>( target, startValue, endValue, mCurrentTime, duration, easeFunction, lerpFunction ) );
00101         newTween->setAutoRemove( mDefaultAutoRemove );
00102         apply( newTween );
00103         return typename Tween<T>::Options( newTween, thisRef() );
00104     }
00105 
00107     template<typename T>
00108     typename Tween<T>::Options appendToPtr( T *target, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> ) {
00109         float startTime = findEndTimeOf( target );
00110         TweenRef<T> newTween( new Tween<T>( target, endValue, std::max( mCurrentTime, startTime ), duration, easeFunction, lerpFunction ) );
00111         newTween->setAutoRemove( mDefaultAutoRemove );
00112         insert( newTween );
00113         return typename Tween<T>::Options( newTween, thisRef() );
00114     }
00115     
00117     template<typename T>
00118     typename Tween<T>::Options appendToPtr( T *target, T startValue, T endValue, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> ) {
00119         float startTime = findEndTimeOf( target );
00120         TweenRef<T> newTween( new Tween<T>( target, startValue, endValue, std::max( mCurrentTime, startTime ), duration, easeFunction, lerpFunction ) );
00121         newTween->setAutoRemove( mDefaultAutoRemove );
00122         insert( newTween );
00123         return typename Tween<T>::Options( newTween, thisRef() );
00124     }
00125 
00127     CueRef add( const std::function<void ()> &action, float atTime );
00128 
00129     template<typename T>
00130     FnTweenRef<T> applyFn( const std::function<void (T)> &fn, T startValue, T endValue, float duration, const EaseFn &easeFunction = easeNone, const typename Tween<T>::LerpFn &lerpFunction = &tweenLerp<T> ) {
00131         FnTweenRef<T> newTween( new FnTween<T>( fn, startValue, endValue, mCurrentTime, duration, easeFunction, lerpFunction ) );
00132         newTween->setAutoRemove( mDefaultAutoRemove );
00133         apply( newTween );
00134         return newTween;
00135     }
00136 
00138     void appendPingPong();
00139 
00141     void apply( TimelineItemRef item );
00142     
00144     void add( TimelineItemRef item );
00146     void insert( TimelineItemRef item );
00148     void insert( TimelineItemRef item, float atTime ) { item->mStartTime = atTime; insert( item ); }
00149 
00151     size_t              getNumItems() const { return mItems.size(); }
00153     bool                empty() const { return mItems.empty(); }
00155     TimelineItemRef     find( void *target ) const;
00157     TimelineItemRef     findLast( void *target ) const;
00159     TimelineItemRef     findLastEnd( void *target ) const;
00161     float               findEndTimeOf( void *target, bool *found = NULL ) const;
00163     void                remove( TimelineItemRef item );
00165     void                removeTarget( void *target );
00167     void                cloneAndReplaceTarget( void *target, void *replacementTarget );
00169     void                replaceTarget( void *target, void *replacementTarget );
00170     
00172     void clear();
00174     void reset( bool unsetStarted = false );
00175 
00177     void    setDefaultAutoRemove( bool defaultAutoRemove ) { mDefaultAutoRemove = defaultAutoRemove; }
00179     bool    getDefaultAutoRemove() const { return mDefaultAutoRemove; }
00180 
00182     void    itemTimeChanged( TimelineItem *item );
00183 
00184     TimelineRef thisRef() { 
00185         TimelineItemRef thisTimelineItem = TimelineItem::thisRef();
00186         TimelineRef result = std::static_pointer_cast<Timeline>( thisTimelineItem );
00187         return result;
00188     }
00189 
00191     virtual void    stepTo( float absoluteTime, bool reverse ) { stepTo( absoluteTime ); }
00193     
00194   protected:  
00195     Timeline();
00196     
00197     virtual void reverse();
00198     virtual TimelineItemRef cloneReverse() const;
00199     virtual TimelineItemRef clone() const;
00200     virtual void start( bool reverse ) {} // no-op
00201     virtual void loopStart();
00202     virtual void update( float absTime );
00203     virtual void complete( bool reverse ) {} // no-op
00204 
00205     void                        eraseMarked();
00206     virtual float               calcDuration() const;
00207 
00208     bool                        mDefaultAutoRemove;
00209     float                       mCurrentTime;
00210     
00211     std::multimap<void*,TimelineItemRef>        mItems;
00212     
00213   private:
00214     Timeline( const Timeline &rhs ); // private to prevent copying; use clone() method instead
00215     Timeline& operator=( const Timeline &rhs ); // not defined to prevent copying
00216 };
00217 
00218 class Cue : public TimelineItem {
00219   public:
00220     Cue( const std::function<void ()> &fn, float atTime = 0 );
00221 
00222     CueRef  create( const std::function<void ()> &fn, float atTime = 0 ) { return CueRef( new Cue( fn, atTime ) ); }
00223 
00224     void                    setFn( const std::function<void ()> &fn ) { mFunction = fn; }
00225     std::function<void ()>  getFn() const { return mFunction; }
00226     
00227   protected:
00228     virtual void                reverse() { /* no-op */ }
00229     virtual TimelineItemRef cloneReverse() const;
00230     virtual TimelineItemRef clone() const;
00231 
00232     virtual void start( bool reverse ) {} // starting is a no-op for Cues
00233     virtual void loopStart();
00234     virtual void update( float relativeTime ) {} // update is a no-op for Cues
00235     virtual void complete( bool reverse ) {} // completion is a no-op for Cues
00236     virtual bool updateAtLoopStart() { return true; }
00237   
00238     std::function<void ()>      mFunction;
00239 };
00240 
00241 } // namespace cinder