1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "Animation.h" 21 #include "View/AnimationCurve.h" 22 23 #include <algorithm> 24 #include <cassert> 25 26 #include <wx/app.h> 27 #include <wx/timer.h> 28 29 namespace TrenchBroom { 30 namespace View { freeType()31 Animation::Type Animation::freeType() { 32 static Type type = 0; 33 return type++; 34 } 35 Animation(const Type type,const Curve curve,const wxLongLong duration)36 Animation::Animation(const Type type, const Curve curve, const wxLongLong duration) : 37 m_type(type), 38 m_curve(NULL), 39 m_duration(duration), 40 m_elapsed(0), 41 m_progress(0.0) { 42 assert(m_duration > 0); 43 switch (curve) { 44 case Curve_EaseInEaseOut: 45 m_curve = new EaseInEaseOutAnimationCurve(m_duration); 46 break; 47 case Curve_Flat: 48 m_curve = new FlatAnimationCurve(); 49 break; 50 } 51 } 52 ~Animation()53 Animation::~Animation() { 54 delete m_curve; 55 m_curve = NULL; 56 } 57 type() const58 Animation::Type Animation::type() const { 59 return m_type; 60 } 61 step(const wxLongLong delta)62 bool Animation::step(const wxLongLong delta) { 63 m_elapsed = std::min(m_elapsed + delta, m_duration); 64 m_progress = m_elapsed.ToDouble() / m_duration.ToDouble(); 65 return m_elapsed >= m_duration; 66 } 67 update()68 void Animation::update() { 69 doUpdate(m_progress); 70 } 71 ExecutableAnimation(const Animation::List & animations)72 ExecutableAnimation::ExecutableAnimation(const Animation::List& animations) : 73 m_animations(animations) {} 74 execute()75 void ExecutableAnimation::execute() { 76 Animation::List::const_iterator it, end; 77 for (it = m_animations.begin(), end = m_animations.end(); it != end; ++it) { 78 Animation& animation = **it; 79 animation.update(); 80 } 81 } 82 AnimationManager()83 AnimationManager::AnimationManager() : 84 m_lastTime(wxGetLocalTimeMillis()) { 85 Run(); 86 } 87 runAnimation(Animation * animation,const bool replace)88 void AnimationManager::runAnimation(Animation* animation, const bool replace) { 89 assert(animation != NULL); 90 91 Animation::List& list = m_animations[animation->type()]; 92 if (replace) 93 list.clear(); 94 list.push_back(Animation::Ptr(animation)); 95 } 96 Entry()97 wxThread::ExitCode AnimationManager::Entry() { 98 while (!TestDestroy()) { 99 const wxLongLong elapsed = wxGetLocalTimeMillis() - m_lastTime; 100 101 Animation::List updateAnimations; 102 if (!m_animations.empty()) { 103 AnimationMap::iterator mapIt = m_animations.begin(); 104 while (mapIt != m_animations.end()) { 105 Animation::List& list = mapIt->second; 106 Animation::List::iterator listIt = list.begin(); 107 while (listIt != list.end()) { 108 Animation::Ptr animation = *listIt; 109 if (animation->step(elapsed)) 110 listIt = list.erase(listIt); 111 updateAnimations.push_back(animation); 112 if (listIt != list.end()) 113 ++listIt; 114 } 115 116 if (list.empty()) 117 m_animations.erase(mapIt++); 118 else 119 ++mapIt; 120 } 121 } 122 m_lastTime += elapsed; 123 124 if (!TestDestroy() && wxTheApp != NULL && !updateAnimations.empty()) { 125 ExecutableEvent::Executable::Ptr executable(new ExecutableAnimation(updateAnimations)); 126 ExecutableEvent* event = new ExecutableEvent(executable); 127 wxTheApp->QueueEvent(event); 128 } 129 130 Sleep(20); 131 } 132 133 return static_cast<ExitCode>(0); 134 } 135 } 136 } 137