1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTime.h" 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #ifndef AnimTimer_DEFINED 12*c8dee2aaSAndroid Build Coastguard Worker #define AnimTimer_DEFINED 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard Worker /** 15*c8dee2aaSAndroid Build Coastguard Worker * Class to track a "timer". It supports 3 states: stopped, paused, and running. 16*c8dee2aaSAndroid Build Coastguard Worker * Playback speed is variable. 17*c8dee2aaSAndroid Build Coastguard Worker * 18*c8dee2aaSAndroid Build Coastguard Worker * The caller must call updateTime() to resync with the clock (typically just before 19*c8dee2aaSAndroid Build Coastguard Worker * using the timer). Forcing the caller to do this ensures that the timer's return values 20*c8dee2aaSAndroid Build Coastguard Worker * are consistent if called repeatedly, as they only reflect the time since the last 21*c8dee2aaSAndroid Build Coastguard Worker * calle to updateTimer(). 22*c8dee2aaSAndroid Build Coastguard Worker */ 23*c8dee2aaSAndroid Build Coastguard Worker class AnimTimer { 24*c8dee2aaSAndroid Build Coastguard Worker public: 25*c8dee2aaSAndroid Build Coastguard Worker /** 26*c8dee2aaSAndroid Build Coastguard Worker * Class begins in the "stopped" state. 27*c8dee2aaSAndroid Build Coastguard Worker */ AnimTimer()28*c8dee2aaSAndroid Build Coastguard Worker AnimTimer() {} 29*c8dee2aaSAndroid Build Coastguard Worker 30*c8dee2aaSAndroid Build Coastguard Worker enum State { kStopped_State, kPaused_State, kRunning_State }; 31*c8dee2aaSAndroid Build Coastguard Worker state()32*c8dee2aaSAndroid Build Coastguard Worker State state() const { return fState; } 33*c8dee2aaSAndroid Build Coastguard Worker nanos()34*c8dee2aaSAndroid Build Coastguard Worker double nanos() const { return fElapsedNanos; } 35*c8dee2aaSAndroid Build Coastguard Worker 36*c8dee2aaSAndroid Build Coastguard Worker /** 37*c8dee2aaSAndroid Build Coastguard Worker * Control the rate at which time advances. 38*c8dee2aaSAndroid Build Coastguard Worker */ getSpeed()39*c8dee2aaSAndroid Build Coastguard Worker float getSpeed() const { return fSpeed; } setSpeed(float speed)40*c8dee2aaSAndroid Build Coastguard Worker void setSpeed(float speed) { fSpeed = speed; } 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker /** 43*c8dee2aaSAndroid Build Coastguard Worker * If the timer is paused or stopped, it will resume (or start if it was stopped). 44*c8dee2aaSAndroid Build Coastguard Worker */ run()45*c8dee2aaSAndroid Build Coastguard Worker void run() { 46*c8dee2aaSAndroid Build Coastguard Worker switch (this->state()) { 47*c8dee2aaSAndroid Build Coastguard Worker case kStopped_State: 48*c8dee2aaSAndroid Build Coastguard Worker fPreviousNanos = SkTime::GetNSecs(); 49*c8dee2aaSAndroid Build Coastguard Worker fElapsedNanos = 0; 50*c8dee2aaSAndroid Build Coastguard Worker break; 51*c8dee2aaSAndroid Build Coastguard Worker case kPaused_State: // they want "resume" 52*c8dee2aaSAndroid Build Coastguard Worker fPreviousNanos = SkTime::GetNSecs(); 53*c8dee2aaSAndroid Build Coastguard Worker break; 54*c8dee2aaSAndroid Build Coastguard Worker case kRunning_State: break; 55*c8dee2aaSAndroid Build Coastguard Worker } 56*c8dee2aaSAndroid Build Coastguard Worker fState = kRunning_State; 57*c8dee2aaSAndroid Build Coastguard Worker } 58*c8dee2aaSAndroid Build Coastguard Worker pause()59*c8dee2aaSAndroid Build Coastguard Worker void pause() { 60*c8dee2aaSAndroid Build Coastguard Worker if (kRunning_State == this->state()) { 61*c8dee2aaSAndroid Build Coastguard Worker fState = kPaused_State; 62*c8dee2aaSAndroid Build Coastguard Worker } // else stay stopped or paused 63*c8dee2aaSAndroid Build Coastguard Worker } 64*c8dee2aaSAndroid Build Coastguard Worker 65*c8dee2aaSAndroid Build Coastguard Worker /** 66*c8dee2aaSAndroid Build Coastguard Worker * If the timer is stopped, start running, else it toggles between paused and running. 67*c8dee2aaSAndroid Build Coastguard Worker */ togglePauseResume()68*c8dee2aaSAndroid Build Coastguard Worker void togglePauseResume() { 69*c8dee2aaSAndroid Build Coastguard Worker if (kRunning_State == this->state()) { 70*c8dee2aaSAndroid Build Coastguard Worker this->pause(); 71*c8dee2aaSAndroid Build Coastguard Worker } else { 72*c8dee2aaSAndroid Build Coastguard Worker this->run(); 73*c8dee2aaSAndroid Build Coastguard Worker } 74*c8dee2aaSAndroid Build Coastguard Worker } 75*c8dee2aaSAndroid Build Coastguard Worker 76*c8dee2aaSAndroid Build Coastguard Worker /** 77*c8dee2aaSAndroid Build Coastguard Worker * Call this each time you want to sample the clock for the timer. This is NOT done 78*c8dee2aaSAndroid Build Coastguard Worker * automatically, so that repeated calls to msec() or secs() will always return the 79*c8dee2aaSAndroid Build Coastguard Worker * same value. 80*c8dee2aaSAndroid Build Coastguard Worker * 81*c8dee2aaSAndroid Build Coastguard Worker * This may safely be called with the timer in any state. 82*c8dee2aaSAndroid Build Coastguard Worker */ updateTime()83*c8dee2aaSAndroid Build Coastguard Worker void updateTime() { 84*c8dee2aaSAndroid Build Coastguard Worker if (kRunning_State == this->state()) { 85*c8dee2aaSAndroid Build Coastguard Worker double now = SkTime::GetNSecs(); 86*c8dee2aaSAndroid Build Coastguard Worker fElapsedNanos += (now - fPreviousNanos) * fSpeed; 87*c8dee2aaSAndroid Build Coastguard Worker fPreviousNanos = now; 88*c8dee2aaSAndroid Build Coastguard Worker } 89*c8dee2aaSAndroid Build Coastguard Worker } 90*c8dee2aaSAndroid Build Coastguard Worker 91*c8dee2aaSAndroid Build Coastguard Worker private: 92*c8dee2aaSAndroid Build Coastguard Worker double fPreviousNanos = 0; 93*c8dee2aaSAndroid Build Coastguard Worker double fElapsedNanos = 0; 94*c8dee2aaSAndroid Build Coastguard Worker float fSpeed = 1; 95*c8dee2aaSAndroid Build Coastguard Worker State fState = kStopped_State; 96*c8dee2aaSAndroid Build Coastguard Worker }; 97*c8dee2aaSAndroid Build Coastguard Worker 98*c8dee2aaSAndroid Build Coastguard Worker #endif 99