Tweeny 4.1.0
A Tweening library for modern C++
Loading...
Searching...
No Matches
Migrating from Tweeny 3.x to 4.x

This guide helps you migrate code from Tweeny 3.x to 4.x. While the core concepts remain the same, version 4 introduces significant API changes centered around a builder pattern and a new event system.

Overview of Changes

The main changes in Tweeny 4.x are:

  • Builder Pattern: tweeny::from now returns a builder; you must call build() to create a tween
  • Immutable Tweens: Once built, keyframes, durations, and easings cannot be changed
  • New Event System: Callbacks are now registered via on() with event types instead of onStep()/onSeek()
  • Type System Changes: Duration and step parameters are now strongly typed (uint32_t and int32_t)
  • Return Value Changes: Multi-value tweens now return tuples instead of arrays
  • New peek() Method: Query values without changing tween state
  • Direction API Removed: forward()/backward() removed; use negative steps instead

The Builder Pattern

Basic Usage

Tweeny 3.x:

auto tween = tweeny::from(0).to(100).during(100);
tweeny_builder< true, FirstValue, RemainingValues... > to(const FirstValue &firstComponent, const RemainingValues &... remainingComponents) &
Adds a target keyframe to the tween.
Definition tweeny.h:109
tweeny_builder & during(FrameCountsType... frame_counts)
Specifies per-component frame durations for the last keyframe segment.
Definition tweeny.h:245
tweeny_builder< false, FirstValue, RemainingValues... > from(FirstValue firstComponent, RemainingValues... remainingComponents)
Creates a new tween builder starting from the specified value(s).
Definition tweeny.h:347

Tweeny 4.x:

auto tween = tweeny::from(0).to(100).during(100U).build();

The key difference: you must explicitly call build() to create the tween. The builder is reusable:

auto builder = tweeny::from(0).to(100).during(60U);
auto tween1 = builder.build(); // First tween
builder.to(200).during(120U); // Add keyframe
auto tween2 = builder.build(); // Different tween (0→100→200)

Compile-Time Safety

Tweeny 4.x enforces that you call to() at least once before building:

Tweeny 3.x: (would create invalid tween)

auto tween = tweeny::from(0).during(100); // Creates tween with no target

Tweeny 4.x: (compilation error)

// auto tween = tweeny::from(0).during(100U).build(); // ERROR: no to() called
auto tween = tweeny::from(0).to(100).during(100U).build(); // OK

Type System Changes

Duration Types

Tweeny 3.x: Durations could be any unsigned integer type

auto tween = tweeny::from(0).to(100).during(100); // int literal

Tweeny 4.x: Durations must be uint32_t (use the U suffix)

auto tween = tweeny::from(0).to(100).during(100U).build(); // uint32_t

Step Types

Tweeny 3.x: step() accepted floats (percentage) or integers (duration)

tween.step(0.5f); // Step by 50%
tween.step(10); // Step by 10 units

Tweeny 4.x: step() only accepts int32_t (duration), no percentage mode

tween.step(10); // Step forward by 10 frames
tween.step(-5); // Step backward by 5 frames

Seek Types

Tweeny 3.x: seek() accepted floats (percentage) or integers (absolute position)

tween.seek(0.5f); // Seek to 50%
tween.seek(500); // Seek to frame 500

Tweeny 4.x: seek() only accepts uint32_t (absolute frame position)

auto tween = tweeny::from(0).to(100).during(1000U).build();
tween.seek(500U); // Seek to frame 500 (50% of a 1000-frame tween)

Return Values

Tweeny 3.x: Multi-value tweens returned std::array

auto tween = tweeny::from(0, 0).to(100, 200).during(100);
std::array<int, 2> values = tween.step(10);
int x = values[0];
int y = values[1];

Tweeny 4.x: Multi-value tweens return tuples (use structured bindings)

auto tween = tweeny::from(0, 0).to(100, 200).during(100U).build();
auto [x, y] = tween.step(10);

Direction Changes

Tweeny 3.x: Used forward() and backward() to control direction

tween.backward();
tween.step(10); // Steps backward
tween.forward();
tween.step(10); // Steps forward

Tweeny 4.x: Use signed integers with step()

tween.step(-10); // Steps backward by 10
tween.step(10); // Steps forward by 10

The peek() Method

Tweeny 4.x introduces peek() to query values without mutating state.

Tweeny 3.x: No direct equivalent; you had to step and track state manually

auto tween = tweeny::from(0).to(100).during(100);
tween.seek(50);
// Get current value by stepping 0 (awkward)
int value = tween.step(0);

Tweeny 4.x: Use peek() for non-mutating queries

auto tween = tweeny::from(0).to(100).during(100U).build();
tween.seek(50U);
int current = tween.peek(); // Get current value without changing state
int preview = tween.peek(75U); // Preview value at frame 75 without seeking

Event System Changes

The callback system has been completely redesigned around an event-based architecture.

Registration

Tweeny 3.x: Used onStep() and onSeek() methods

auto tween = tweeny::from(0, 0).to(100, 200).during(100);
// Step callback accepting values
tween.onStep([](int x, int y) {
printf("Position: (%d, %d)\n", x, y);
return false; // false = keep callback
});
// Step callback accepting tween reference
tween.onStep([](auto& t) {
return false;
});
// Step callback accepting both
tween.onStep([](auto& t, int x, int y) {
return false;
});
// Seek callback
tween.onSeek([](int x, int y) {
return false;
});
A tween represents an animation between keyframes.
Definition tween.h:68

Tweeny 4.x: Use on() with event type tags

auto tween = tweeny::from(0, 0).to(100, 200).during(100U).build();
// Step callback (receives tween reference)
tween.on(tweeny::event::step, [](auto& t) {
auto [x, y] = t.peek();
printf("Position: (%d, %d)\n", x, y);
return tweeny::event::response::ok; // Keep callback
});
// Seek callback
tween.on(tweeny::event::seek, [](auto& t) {
});
// Jump callback (new in v4)
});
auto on(detail::event::step_t, Callback &&cb) -> void
Registers a callback for step() events.
constexpr detail::event::seek_t seek
Event triggered after each seek() call.
Definition event.h:111
constexpr detail::event::jump_t jump
Event triggered after each jump() call.
Definition event.h:139
@ ok
Continue receiving events.
Definition detail/event.h:108
constexpr detail::event::step_t step
Event triggered after each step() call.
Definition event.h:83

Callback Return Values

Tweeny 3.x: Returned bool

return true; // Remove callback (one-shot)
return false; // Keep callback

Tweeny 4.x: Returns event::response enum

return tweeny::event::response::unsubscribe; // Remove callback
return tweeny::event::response::ok; // Keep callback
@ unsubscribe
Unsubscribe after this callback.
Definition detail/event.h:116

New Event Types

Tweeny 4.x introduces several new event types:

// Triggered when interpolation completes (reaches 100%)
tween.on(tweeny::event::complete, [](auto& t) {
printf("Animation finished!\n");
});
// Triggered after any step(), seek(), or jump() (after the specific event, before complete)
tween.on(tweeny::event::update, [](auto& t) {
printf("Tween updated to: %d\n", t.peek());
});
// Triggered when entering a new keyframe segment
tween.on(tweeny::event::keyframeEnter, [](auto& t, auto evt) {
printf("Entering keyframe %zu\n", evt.key_frame);
});
// Triggered when leaving a keyframe segment
tween.on(tweeny::event::keyframeLeave, [](auto& t, auto evt) {
printf("Leaving keyframe %zu\n", evt.key_frame);
});
constexpr detail::event::complete_t complete
Event triggered when the animation is at completion.
Definition event.h:174
constexpr detail::event::update_t update
Event triggered whenever the tween position changes.
Definition event.h:280
constexpr detail::event::keyframeEnter_t keyframeEnter
Event triggered when entering a new keyframe segment.
Definition event.h:210
constexpr detail::event::keyframeLeave_t keyframeLeave
Event triggered when leaving a keyframe segment.
Definition event.h:246

Callback Signature Changes

Tweeny 3.x callbacks could receive interpolated values directly. Tweeny 4.x callbacks always receive a tween reference; use peek() to get values:

Tweeny 3.x:

tween.onStep([](int x, int y) { // Values passed directly
printf("x=%d, y=%d\n", x, y);
return false;
});

Tweeny 4.x:

tween.on(tweeny::event::step, [](auto& t) { // Tween reference only
auto [x, y] = t.peek(); // Explicitly peek values
printf("x=%d, y=%d\n", x, y);
});

Migration Checklist

Use this checklist to migrate your code:

  1. Add .build() calls
    • Find all tweeny::from(...) chains
    • Add .build() at the end to create the tween
  2. Update duration literals
    • Change during(100) to during(100U)
    • Ensure all duration values use uint32_t
  3. Update step() calls
    • Remove percentage-based stepping (convert to frame counts)
    • Use negative values for backward stepping instead of backward()
  4. Update seek() calls
    • Remove percentage-based seeking (calculate frame from percentage manually)
    • Add U suffix to all seek values: seek(500)seek(500U)
  5. Replace array destructuring with tuple destructuring
    • Change std::array<T, N> v = tween.step(...) to auto [v1, v2, ...] = tween.step(...)
  6. Update callbacks
    • Replace onStep(callback) with on(event::step, callback)
    • Replace onSeek(callback) with on(event::seek, callback)
    • Change callback signatures to accept auto& t parameter
    • Use t.peek() to get values inside callbacks
    • Change return true/false to return event::response::unsubscribe/ok
  7. Remove forward()/backward() calls
    • Replace with signed step values
  8. Use peek() for non-mutating queries
    • Replace step(0) patterns with peek()
    • Use peek(frame) to preview values at different positions
  9. Consider new event types

Complete Migration Example

Tweeny 3.x:

#include "tweeny.h"
auto tween = tweeny::from(0, 0, 255)
.to(640, 480, 0)
.during(2000)
tween.onStep([](int x, int y, int alpha) {
draw_sprite(x, y, alpha);
return false;
});
tween.onSeek([](int x, int y, int alpha) {
printf("Seeked to: %d, %d, %d\n", x, y, alpha);
return false;
});
// Animation loop
while (tween.progress() < 1.0f) {
tween.step(delta_time);
render();
}
// Reverse
tween.backward();
while (tween.progress() > 0.0f) {
tween.step(delta_time);
render();
}
auto step(int32_t frames) -> tween_value_t
Advances or rewinds the animation by a frame delta.
auto progress() const -> float
Returns the animation completion percentage.
constexpr detail::backOutEasing backOut
Easing function that overshoots the target before settling back.
Definition easing.h:131

Tweeny 4.x:

#include <tweeny/tweeny.h>
auto tween = tweeny::from(0, 0, 255)
.to(640, 480, 0)
.during(2000U)
.build(); // <-- Must call build()
tween.on(tweeny::event::step, [](auto& t) {
auto [x, y, alpha] = t.peek(); // <-- Use peek() to get values
draw_sprite(x, y, alpha);
return tweeny::event::response::ok; // <-- New return type
});
tween.on(tweeny::event::seek, [](auto& t) {
auto [x, y, alpha] = t.peek();
printf("Seeked to: %d, %d, %d\n", x, y, alpha);
});
// Completion event (new in v4)
printf("Animation complete!\n");
});
// Animation loop
while (tween.progress() < 1.0f) {
tween.step(delta_time); // delta_time is int32_t
render();
}
// Reverse (use negative steps instead of backward())
while (tween.progress() > 0.0f) {
tween.step(-delta_time); // <-- Negative value steps backward
render();
}

Done!

For detailed information on the new API, see the Tweeny Manual.