Arena works better now and I can give a list of sprites to work as fixtures in a scene.
This commit is contained in:
parent
59ba73baa0
commit
71e3c97cf0
8 changed files with 169 additions and 36 deletions
117
tests/animation2.cpp
Normal file
117
tests/animation2.cpp
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <fmt/core.h>
|
||||
#include <string>
|
||||
#include <coroutine>
|
||||
#include <chrono>
|
||||
#include "rand.hpp"
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "components.hpp"
|
||||
#include <iostream>
|
||||
#include "stats.hpp"
|
||||
#include "simplefsm.hpp"
|
||||
#include "textures.hpp"
|
||||
#include "animation.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using components::Animation;
|
||||
using TheClock = std::chrono::steady_clock;
|
||||
using TimeDelta = TheClock::duration;
|
||||
using TimePoint = std::chrono::time_point<TheClock>;
|
||||
const TimeDelta MIN_TICK = 200ms;
|
||||
|
||||
struct AnimationState {
|
||||
Animation anim;
|
||||
TimeDelta wait = 1s;
|
||||
sf::Vector2f scale{1.0, 1.0};
|
||||
sf::Vector2f pos{0.0, 0.0};
|
||||
sf::IntRect rect{{0, 0}, {300, 300}};
|
||||
|
||||
void step() {
|
||||
anim.step(scale, pos, rect);
|
||||
}
|
||||
|
||||
void apply(textures::SpriteTexture& st) {
|
||||
animation::apply(anim, *st.sprite, pos);
|
||||
}
|
||||
};
|
||||
|
||||
struct AnimationQueue {
|
||||
std::vector<AnimationState> active;
|
||||
TimePoint last_tick;
|
||||
TimeDelta wait_for = MIN_TICK;
|
||||
size_t in_queue = 0;
|
||||
size_t chunk = 1000;
|
||||
|
||||
TimeDelta delta() {
|
||||
return TheClock::now() - last_tick;
|
||||
}
|
||||
|
||||
void tick() {
|
||||
last_tick = TheClock::now();
|
||||
}
|
||||
|
||||
size_t add(Animation& anim, int initial_wait) {
|
||||
active.emplace_back(anim, TheClock::duration(initial_wait));
|
||||
return active.size() - 1;
|
||||
}
|
||||
|
||||
AnimationState& get(size_t id) {
|
||||
return active.at(id);
|
||||
}
|
||||
|
||||
void render() {
|
||||
wait_for = MIN_TICK;
|
||||
auto dt = delta();
|
||||
|
||||
for(size_t i = 0; i < chunk; i++) {
|
||||
in_queue++;
|
||||
auto& a = active[in_queue % active.size()];
|
||||
|
||||
if(!a.anim.playing) continue;
|
||||
|
||||
if(a.wait < wait_for) {
|
||||
wait_for = a.wait;
|
||||
}
|
||||
|
||||
if(a.wait < dt) {
|
||||
// fmt::println("play animation: {} total ", active.size());
|
||||
a.step();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("simple coroutine animation test", "[coro]") {
|
||||
AnimationQueue queue;
|
||||
Animation anim;
|
||||
anim.play();
|
||||
|
||||
for(int i = 0; i < 100; i++) {
|
||||
int time = Random::uniform(16, 32);
|
||||
size_t id = queue.add(anim, time);
|
||||
auto& what = queue.get(id);
|
||||
|
||||
REQUIRE(what.wait == TheClock::duration(time));
|
||||
}
|
||||
|
||||
dbc::check(queue.active.size() > 0, "zero size queue after adding is impossible.");
|
||||
queue.tick();
|
||||
Stats stats;
|
||||
|
||||
for(int i = 0; i < 10000; i++) {
|
||||
auto start = stats.time_start();
|
||||
auto delta = queue.delta();
|
||||
|
||||
queue.render();
|
||||
|
||||
if(delta > queue.wait_for) {
|
||||
queue.add(anim, Random::uniform(100, 5000));
|
||||
queue.tick();
|
||||
}
|
||||
|
||||
stats.sample_time(start);
|
||||
}
|
||||
|
||||
fmt::print("stdev: {}, mean: {}\r", stats.stddev(), stats.mean());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue