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( std::function<void ()> action, float atTime ); 00128 00129 template<typename T> 00130 FnTweenRef<T> applyFn( std::function<void (T)> fn, T startValue, T endValue, float duration, EaseFn easeFunction = easeNone, 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 TimelineItemRef find( void *target ); 00155 TimelineItemRef findLast( void *target ); 00157 float findEndTimeOf( void *target, bool *found = NULL ); 00159 void remove( TimelineItemRef item ); 00161 void removeTarget( void *target ); 00163 void cloneAndReplaceTarget( void *target, void *replacementTarget ); 00165 void replaceTarget( void *target, void *replacementTarget ); 00166 00168 void clear(); 00170 void reset( bool unsetStarted = false ); 00171 00173 void setDefaultAutoRemove( bool defaultAutoRemove ) { mDefaultAutoRemove = defaultAutoRemove; } 00175 bool getDefaultAutoRemove() const { return mDefaultAutoRemove; } 00176 00178 void itemTimeChanged( TimelineItem *item ); 00179 00180 TimelineRef thisRef() { 00181 TimelineItemRef thisTimelineItem = TimelineItem::thisRef(); 00182 TimelineRef result = std::static_pointer_cast<Timeline>( thisTimelineItem ); 00183 return result; 00184 } 00185 00187 virtual void stepTo( float absoluteTime, bool reverse ) { stepTo( absoluteTime ); } 00189 00190 protected: 00191 Timeline(); 00192 00193 virtual void reverse(); 00194 virtual TimelineItemRef cloneReverse() const; 00195 virtual TimelineItemRef clone() const; 00196 virtual void start( bool reverse ) {} // no-op 00197 virtual void loopStart(); 00198 virtual void update( float absTime ); 00199 virtual void complete( bool reverse ) {} // no-op 00200 00201 void eraseMarked(); 00202 virtual float calcDuration() const; 00203 00204 bool mDefaultAutoRemove; 00205 float mCurrentTime; 00206 00207 std::multimap<void*,TimelineItemRef> mItems; 00208 00209 private: 00210 Timeline( const Timeline &rhs ); // private to prevent copying; use clone() method instead 00211 Timeline& operator=( const Timeline &rhs ); // not defined to prevent copying 00212 }; 00213 00214 class Cue : public TimelineItem { 00215 public: 00216 Cue( std::function<void ()> fn, float atTime = 0 ); 00217 00218 CueRef create( std::function<void ()> fn, float atTime = 0 ) { return CueRef( new Cue( fn, atTime ) ); } 00219 00220 void setFn( std::function<void ()> fn ) { mFunction = fn; } 00221 std::function<void ()> getFn() const { return mFunction; } 00222 00223 protected: 00224 virtual void reverse() { /* no-op */ } 00225 virtual TimelineItemRef cloneReverse() const; 00226 virtual TimelineItemRef clone() const; 00227 00228 virtual void start( bool reverse ) {} // starting is a no-op for Cues 00229 virtual void loopStart(); 00230 virtual void update( float relativeTime ) {} // update is a no-op for Cues 00231 virtual void complete( bool reverse ) {} // completion is a no-op for Cues 00232 virtual bool updateAtLoopStart() { return true; } 00233 00234 std::function<void ()> mFunction; 00235 }; 00236 00237 } // namespace cinder