diff options
author | reed <reed@google.com> | 2015-02-02 12:55:02 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-02 12:55:02 -0800 |
commit | 76113a9b7716748c70ea0ecf7aacbabe4cce5009 (patch) | |
tree | 57d91f56a717a0ffcb829b00c71e17195491753c /gm | |
parent | a669bc7a7ae7580c5cd92067aeb95d09e64ea720 (diff) |
add SkAnimTimer, SPACE = pause/resume, ESP = stop
BUG=skia:
Review URL: https://codereview.chromium.org/894083003
Diffstat (limited to 'gm')
-rw-r--r-- | gm/SkAnimTimer.h | 139 | ||||
-rw-r--r-- | gm/addarc.cpp | 5 | ||||
-rw-r--r-- | gm/gm.cpp | 4 | ||||
-rw-r--r-- | gm/gm.h | 6 |
4 files changed, 148 insertions, 6 deletions
diff --git a/gm/SkAnimTimer.h b/gm/SkAnimTimer.h new file mode 100644 index 0000000000..725171a8fe --- /dev/null +++ b/gm/SkAnimTimer.h @@ -0,0 +1,139 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkTime.h" + +#ifndef SkAnimTimer_DEFINED +#define SkAnimTimer_DEFINED + +/** + * Class to track a "timer". It supports 3 states: stopped, paused, running. + * + * The caller must call updateTime() to resync with the clock (typically just before + * using the timer). Forcing the caller to do this ensures that the timer's return values + * are consistent if called repeatedly, as they only reflect the time since the last + * calle to updateTimer(). + */ +class SkAnimTimer { +public: + enum State { + kStopped_State, + kPaused_State, + kRunning_State + }; + + /** + * Class begins in the "stopped" state. + */ + SkAnimTimer() : fBaseTime(0), fCurrTime(0), fState(kStopped_State) {} + + bool isStopped() const { return kStopped_State == fState; } + bool isRunning() const { return kRunning_State == fState; } + bool isPaused() const { return kPaused_State == fState; } + + /** + * Stops the timer, and resets it, such that the next call to run or togglePauseResume + * will begin at time 0. + */ + void stop() { + this->setState(kStopped_State); + } + + /** + * If the timer is paused or stopped, it will resume (or start if it was stopped). + */ + void run() { + this->setState(kRunning_State); + } + + /** + * If the timer is stopped, this has no effect, else it toggles between paused and running. + */ + void togglePauseResume() { + if (kRunning_State == fState) { + this->setState(kPaused_State); + } else { + this->setState(kRunning_State); + } + } + + /** + * Call this each time you want to sample the clock for the timer. This is NOT done + * automatically, so that repeated calls to msec() or secs() will always return the + * same value. + * + * This may safely be called with the timer in any state. + */ + void updateTime() { + if (kRunning_State == fState) { + fCurrTime = SkTime::GetMSecs(); + } + } + + /** + * Return the time in milliseconds the timer has been in the running state. + * Returns 0 if the timer is stopped. + */ + SkMSec msec() const { return fCurrTime - fBaseTime; } + + /** + * Return the time in seconds the timer has been in the running state. + * Returns 0 if the timer is stopped. + */ + double secs() const { + return this->msec() * 0.001; + } + + /** + * Return the time in seconds the timer has been in the running state, + * scaled by "speed" and (if not zero) mod by period. + * Returns 0 if the timer is stopped. + */ + SkScalar scaled(SkScalar speed, SkScalar period = 0) const { + double value = this->secs() * speed; + if (period) { + value = ::fmod(value, SkScalarToDouble(period)); + } + return SkDoubleToScalar(value); + } + +private: + SkMSec fBaseTime; + SkMSec fCurrTime; + State fState; + + void setState(State newState) { + switch (newState) { + case kStopped_State: + fBaseTime = fCurrTime = 0; + fState = kStopped_State; + break; + case kPaused_State: + if (kRunning_State == fState) { + fState = kPaused_State; + } // else stay stopped or paused + break; + case kRunning_State: + switch (fState) { + case kStopped_State: + fBaseTime = fCurrTime = SkTime::GetMSecs(); + break; + case kPaused_State: {// they want "resume" + SkMSec now = SkTime::GetMSecs(); + fBaseTime += now - fCurrTime; + fCurrTime = now; + } break; + case kRunning_State: + break; + } + fState = kRunning_State; + break; + } + } +}; + +#endif diff --git a/gm/addarc.cpp b/gm/addarc.cpp index 1386cdd0e7..e6fad25772 100644 --- a/gm/addarc.cpp +++ b/gm/addarc.cpp @@ -6,6 +6,7 @@ */ #include "gm.h" +#include "SkAnimTimer.h" #include "SkCanvas.h" #include "SkRandom.h" @@ -49,8 +50,8 @@ protected: } } - bool onAnimatePulse(SkMSec curr, SkMSec prev) SK_OVERRIDE { - fRotate = SkDoubleToScalar(fmod(curr * 0.001, 360)); + bool onAnimate(const SkAnimTimer& timer) SK_OVERRIDE { + fRotate = timer.scaled(1, 360); return true; } @@ -51,8 +51,8 @@ void GM::setBGColor(SkColor color) { fBGColor = color; } -bool GM::animatePulse(SkMSec curr, SkMSec prev) { - return this->onAnimatePulse(curr, prev); +bool GM::animate(const SkAnimTimer& timer) { + return this->onAnimate(timer); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -16,6 +16,8 @@ #include "SkTRegistry.h" #include "sk_tool_utils.h" +class SkAnimTimer; + #if SK_SUPPORT_GPU #include "GrContext.h" #endif @@ -92,7 +94,7 @@ namespace skiagm { fStarterMatrix = matrix; } - bool animatePulse(SkMSec curr, SkMSec prev); + bool animate(const SkAnimTimer&); protected: /** draws a standard message that the GM is only intended to be used with the GPU.*/ @@ -103,7 +105,7 @@ namespace skiagm { virtual SkISize onISize() = 0; virtual SkString onShortName() = 0; - virtual bool onAnimatePulse(SkMSec curr, SkMSec prev) { return false; } + virtual bool onAnimate(const SkAnimTimer&) { return false; } virtual SkMatrix onGetInitialTransform() const { return SkMatrix::I(); } private: |