diff --git a/include/tween.h b/include/tween.h index ad64dfd..1e5bf46 100644 --- a/include/tween.h +++ b/include/tween.h @@ -250,7 +250,8 @@ namespace tweeny { * @param suppressCallbacks (Optional) Suppress callbacks registered with tween::onStep() * @returns std::tuple with the current tween values. */ - const typename detail::tweentraits::valuesType & step(float dp, bool suppressCallbacks = false); + const typename detail::tweentraits::valuesType &step( + float dp, bool suppressCallbacks = false); /** * @brief Seeks to a specified point in time based on the currentProgress. @@ -261,7 +262,8 @@ namespace tweeny { * @param suppressCallbacks (Optional) Suppress callbacks registered with tween::onSeek() * @returns std::tuple with the current tween values. */ - const typename detail::tweentraits::valuesType & seek(float p, bool suppressCallbacks = false); + const typename detail::tweentraits::valuesType &seek( + float p, bool suppressCallbacks = false); /** * @brief Seeks to a specified point in time. @@ -285,7 +287,8 @@ namespace tweeny { * @returns std::tuple with the current tween values. * @see duration */ - const typename detail::tweentraits::valuesType & seek(uint32_t d, bool suppressCallbacks = false); + const typename detail::tweentraits::valuesType &seek( + uint32_t d, bool suppressCallbacks = false); /** * @brief Adds a callback that will be called when stepping occurs, accepting both the tween and @@ -506,6 +509,13 @@ namespace tweeny { */ const typename detail::tweentraits::valuesType peek(uint32_t time) const; + /** + * @brief Returns the current time point of the interpolation. + * + * @returns the current timr point between 0 and total time point (inclusive) + */ + uint32_t currentTimePoint() const; ///< @sa tween::currenttimepoint + /** * @brief Returns the current currentProgress of the interpolation. * @@ -514,6 +524,13 @@ namespace tweeny { */ float progress() const; + /** + * @brief Returns true if tween reach to end of interpolation progress. + * + * @returns True means its finished, false means its in progress. + */ + bool isFinished() const; + /** * @brief Sets the direction of this tween forward. * @@ -564,7 +581,7 @@ namespace tweeny { private /* member variables */: uint32_t total = 0; // total runtime uint16_t currentPoint = 0; // current point - float currentProgress = 0; // current progress + uint32_t currentProgress = 0; // current progress std::vector> points; typename traits::valuesType current; std::vector onStepCallbacks; @@ -574,11 +591,18 @@ namespace tweeny { private: /* member functions */ tween(T t, Ts... vs); - template void interpolate(float prog, unsigned point, typename traits::valuesType & values, detail::int2type) const; - void interpolate(float prog, unsigned point, typename traits::valuesType & values, detail::int2type<0>) const; - void render(float p); + template + void interpolate(uint32_t prog, + unsigned point, + typename traits::valuesType &values, + detail::int2type) const; + void interpolate(uint32_t prog, + unsigned point, + typename traits::valuesType &values, + detail::int2type<0>) const; + void render(uint32_t p); void dispatch(std::vector & cbVector); - uint16_t pointAt(float progress) const; + uint16_t pointAt(uint32_t progress) const; }; /** @@ -607,8 +631,12 @@ namespace tweeny { template tween & during(Ds... ds); ///< @sa tween::during const T & step(int32_t dt, bool suppressCallbacks = false); ///< @sa tween::step(int32_t dt, bool suppressCallbacks) const T & step(uint32_t dt, bool suppressCallbacks = false); ///< @sa tween::step(uint32_t dt, bool suppressCallbacks) - const T & step(float dp, bool suppressCallbacks = false); ///< @sa tween::step(float dp, bool suppressCallbacks) - const T & seek(float p, bool suppressCallbacks = false); ///< @sa tween::seek(float p, bool suppressCallbacks) + const T &step(float dp, + bool suppressCallbacks + = false); ///< @sa tween::step(float dp, bool suppressCallbacks) + const T &seek(float p, + bool suppressCallbacks + = false); ///< @sa tween::seek(float p, bool suppressCallbacks) const T & seek(int32_t d, bool suppressCallbacks = false); ///< @sa tween::seek(int32_t d, bool suppressCallbacks) const T & seek(uint32_t d, bool suppressCallbacks = false); ///< @sa tween::seek(uint32_t d, bool suppressCallbacks) tween & onStep(typename detail::tweentraits::callbackType callback); ///< @sa tween::onStep @@ -621,7 +649,9 @@ namespace tweeny { T peek(float progress) const; ///< @sa tween::peek T peek(uint32_t time) const; ///< @sa tween::peek uint32_t duration() const; ///< @sa tween::duration - float progress() const; ///< @sa tween::progress + uint32_t currentTimePoint() const; ///< @sa tween::currenttimepoint + float progress() const; ///< @sa tween::progress + bool isFinished() const; ///< @sa tween::isFinished tween & forward(); ///< @sa tween::forward tween & backward(); ///< @sa tween::backward int direction() const; ///< @sa tween::direction @@ -634,7 +664,7 @@ namespace tweeny { private /* member variables */: uint32_t total = 0; // total runtime uint16_t currentPoint = 0; // current point - float currentProgress = 0; // current progress + uint32_t currentProgress = 0; // current progress std::vector> points; T current; std::vector onStepCallbacks; @@ -644,10 +674,10 @@ namespace tweeny { private: /* member functions */ tween(T t); - void interpolate(float prog, unsigned point, T & value) const; - void render(float p); + void interpolate(uint32_t prog, unsigned point, T &value) const; + void render(uint32_t p); void dispatch(std::vector & cbVector); - uint16_t pointAt(float progress) const; + uint16_t pointAt(uint32_t progress) const; }; } diff --git a/include/tween.tcc b/include/tween.tcc index dd0e77f..ae19008 100644 --- a/include/tween.tcc +++ b/include/tween.tcc @@ -29,8 +29,9 @@ #ifndef TWEENY_TWEEN_TCC #define TWEENY_TWEEN_TCC -#include "tween.h" #include "dispatcher.h" +#include "tween.h" +#include namespace tweeny { @@ -165,7 +166,11 @@ namespace tweeny { template inline const typename detail::tweentraits::valuesType & tween::step(int32_t dt, bool suppress) { - return step(static_cast(dt)/static_cast(total), suppress); + dt *= currentDirection; + seek(currentProgress + dt, true); + if (!suppress) + dispatch(onStepCallbacks); + return current; } template @@ -174,25 +179,34 @@ namespace tweeny { } template - inline const typename detail::tweentraits::valuesType & tween::step(float dp, bool suppress) { - dp *= currentDirection; - seek(currentProgress + dp, true); - if (!suppress) dispatch(onStepCallbacks); - return current; + inline const typename detail::tweentraits::valuesType &tween::step( + float dp, bool suppress) + { + return step(static_cast(dp * total), suppress); } template - inline const typename detail::tweentraits::valuesType & tween::seek(float p, bool suppress) { - p = detail::clip(p, 0.0f, 1.0f); + inline const typename detail::tweentraits::valuesType &tween::seek( + uint32_t p, bool suppress) + { + p = detail::clip(p, 0u, total); currentProgress = p; render(p); - if (!suppress) dispatch(onSeekCallbacks); + if (!suppress) + dispatch(onSeekCallbacks); return current; } template inline const typename detail::tweentraits::valuesType & tween::seek(int32_t t, bool suppress) { - return seek(static_cast(t) / static_cast(total), suppress); + return seek(static_cast(std::abs(t)), suppress); + } + + template + inline const typename detail::tweentraits::valuesType &tween::seek( + float p, bool suppress) + { + return seek(static_cast(p * total), suppress); } template @@ -202,9 +216,13 @@ namespace tweeny { template template - inline void tween::interpolate(float prog, unsigned point, typename traits::valuesType & values, detail::int2type) const { + inline void tween::interpolate(uint32_t prog, + unsigned point, + typename traits::valuesType &values, + detail::int2type) const + { auto & p = points.at(point); - auto pointDuration = uint32_t(p.duration() - (p.stacked - (prog * static_cast(total)))); + auto pointDuration = uint32_t(p.duration() - (p.stacked - prog)); float pointTotal = static_cast(pointDuration) / static_cast(p.duration(I)); if (pointTotal > 1.0f) pointTotal = 1.0f; auto easing = std::get(p.easings); @@ -213,9 +231,13 @@ namespace tweeny { } template - inline void tween::interpolate(float prog, unsigned point, typename traits::valuesType & values, detail::int2type<0>) const { + inline void tween::interpolate(uint32_t prog, + unsigned point, + typename traits::valuesType &values, + detail::int2type<0>) const + { auto & p = points.at(point); - auto pointDuration = uint32_t(p.duration() - (p.stacked - (prog * static_cast(total)))); + auto pointDuration = uint32_t(p.duration() - (p.stacked - prog)); float pointTotal = static_cast(pointDuration) / static_cast(p.duration(0)); if (pointTotal > 1.0f) pointTotal = 1.0f; auto easing = std::get<0>(p.easings); @@ -223,7 +245,8 @@ namespace tweeny { } template - inline void tween::render(float p) { + inline void tween::render(uint32_t p) + { currentPoint = pointAt(p); interpolate(p, currentPoint, current, detail::int2type{ }); } @@ -290,23 +313,42 @@ namespace tweeny { template const typename detail::tweentraits::valuesType tween::peek(float progress) const { typename detail::tweentraits::valuesType values; - interpolate(progress, pointAt(progress), values, detail::int2type{ }); + uint32_t time = progress * total; + interpolate(time, + pointAt(time), + values, + detail::int2type{}); return values; } template const typename detail::tweentraits::valuesType tween::peek(uint32_t time) const { typename detail::tweentraits::valuesType values; - float progress = static_cast(time) / static_cast(total); - interpolate(progress, pointAt(progress), values, detail::int2type{ }); + interpolate(time, + pointAt(time), + values, + detail::int2type{}); return values; } - template - float tween::progress() const { + template + uint32_t tween::currentTimePoint() const + { return currentProgress; } + template + float tween::progress() const + { + return static_cast(currentProgress) / static_cast(total); + } + + template + bool tween::isFinished() const + { + return currentProgress == total; + } + template tween & tween::forward() { currentDirection = 1; @@ -334,12 +376,15 @@ namespace tweeny { return currentPoint; } - template inline uint16_t tween::pointAt(float progress) const { - progress = detail::clip(progress, 0.0f, 1.0f); - uint32_t t = static_cast(progress * total); + template + inline uint16_t tween::pointAt(uint32_t progress) const + { + progress = detail::clip(progress, 0u, total); uint16_t point = 0; - while (t > points.at(point).stacked) point++; - if (point > 0 && t <= points.at(point - 1u).stacked) point--; + while (progress > points.at(point).stacked) + point++; + if (point > 0 && progress <= points.at(point - 1u).stacked) + point--; return point; } } diff --git a/include/tweenone.tcc b/include/tweenone.tcc index c2a52ad..ec07c69 100644 --- a/include/tweenone.tcc +++ b/include/tweenone.tcc @@ -157,7 +157,11 @@ namespace tweeny { template inline const T & tween::step(int32_t dt, bool suppress) { - return step(static_cast(dt)/static_cast(total), suppress); + dt *= currentDirection; + seek(currentProgress + dt, true); + if (!suppress) + dispatch(onStepCallbacks); + return current; } template @@ -166,30 +170,30 @@ namespace tweeny { } template - inline const T & tween::step(float dp, bool suppress) { - dp *= currentDirection; - seek(currentProgress + dp, true); - if (!suppress) dispatch(onStepCallbacks); - return current; + inline const T &tween::step(float dp, bool suppress) + { + return step(static_cast(dp * total), suppress); } template - inline const T & tween::seek(float p, bool suppress) { - p = detail::clip(p, 0.0f, 1.0f); - currentProgress = p; - render(p); - if (!suppress) dispatch(onSeekCallbacks); - return current; + inline const T &tween::seek(float p, bool suppress) + { + return seek(static_cast(p * total), suppress); } template inline const T & tween::seek(int32_t t, bool suppress) { - return seek(static_cast(t) / static_cast(total), suppress); + t = detail::clip(t, 0, (int32_t) total); + currentProgress = t; + render(t); + if (!suppress) + dispatch(onSeekCallbacks); + return current; } template inline const T & tween::seek(uint32_t t, bool suppress) { - return seek(static_cast(t) / static_cast(total), suppress); + return seek(static_cast(t), suppress); } template @@ -198,9 +202,10 @@ namespace tweeny { } template - inline void tween::interpolate(float prog, unsigned point, T & value) const { + inline void tween::interpolate(uint32_t prog, unsigned point, T &value) const + { auto & p = points.at(point); - auto pointDuration = uint32_t(p.duration() - (p.stacked - (prog * static_cast(total)))); + auto pointDuration = uint32_t(p.duration() - (p.stacked - prog)); float pointTotal = static_cast(pointDuration) / static_cast(p.duration()); if (pointTotal > 1.0f) pointTotal = 1.0f; auto easing = std::get<0>(p.easings); @@ -208,7 +213,8 @@ namespace tweeny { } template - inline void tween::render(float p) { + inline void tween::render(uint32_t p) + { currentPoint = pointAt(p); interpolate(p, currentPoint, current); } @@ -276,26 +282,38 @@ namespace tweeny { template T tween::peek(float progress) const { T value; - interpolate(progress, pointAt(progress), value); + interpolate(progress * total, pointAt(progress * total), value); return value; } template T tween::peek(uint32_t time) const { T value; - float progress = static_cast(time) / static_cast(total); - interpolate(progress, pointAt(progress), value); + interpolate(time, pointAt(time), value); return value; } - - template - float tween::progress() const { + template + uint32_t tween::currentTimePoint() const + { return currentProgress; } template - tween & tween::forward() { + float tween::progress() const + { + return static_cast(currentProgress) / static_cast(total); + } + + template + bool tween::isFinished() const + { + return currentProgress == total; + } + + template + tween &tween::forward() + { currentDirection = 1; return *this; } @@ -321,11 +339,11 @@ namespace tweeny { return currentPoint; } - - - template inline uint16_t tween::pointAt(float progress) const { - progress = detail::clip(progress, 0.0f, 1.0f); - auto t = static_cast(progress * total); + template + inline uint16_t tween::pointAt(uint32_t timePoint) const + { + timePoint = detail::clip(timePoint, 0u, total); + auto t = static_cast(timePoint); uint16_t point = 0; while (t > points.at(point).stacked) point++; if (point > 0 && t <= points.at(point - 1u).stacked) point--;