class FrameCounter {
+public:
+ template<class T>
+ struct Frame {
+ T handle = T(0);
+ T update = T(0);
+ T render = T(0);
+ T running = T(0);
+ T waiting = T(0);
+ T total = T(0);
+ };
+
+
public:
void EnterFrame() noexcept;
void EnterHandle() noexcept;
void ExitRender() noexcept;
void ExitFrame() noexcept;
- float AvgHandle() const noexcept { return avg.handle; }
- float AvgUpdate() const noexcept { return avg.update; }
- float AvgRender() const noexcept { return avg.render; }
- float AvgFrame() const noexcept { return avg.total; }
- float AvgRunning() const noexcept { return avg.handle + avg.update + avg.render; }
- float AvgWaiting() const noexcept { return avg.total - AvgRunning(); }
+ const Frame<int> &Peak() const noexcept { return peak; }
+ const Frame<float> &Average() const noexcept { return avg; }
bool Changed() const noexcept { return changed; }
- void Print(std::ostream &) const;
-
private:
int Tick() noexcept;
+ void Accumulate() noexcept;
+ void Push() noexcept;
+
private:
static constexpr int NUM_FRAMES = 32;
static constexpr float factor = 1.0f / float(NUM_FRAMES);
- template<class T>
- struct Frame {
- T handle = T(0);
- T update = T(0);
- T render = T(0);
- T total = T(0);
- };
-
Uint32 last_enter = 0;
Uint32 last_tick = 0;
int cur_frame = 0;
- Frame<int> running = Frame<int>{};
+ Frame<int> current = Frame<int>{};
+ Frame<int> sum = Frame<int>{};
+ Frame<int> max = Frame<int>{};
+
+ Frame<int> peak = Frame<int>{};
Frame<float> avg = Frame<float>{};
+
bool changed = false;
};
}
void FrameCounter::ExitHandle() noexcept {
- running.handle += Tick();
+ current.handle = Tick();
}
void FrameCounter::EnterUpdate() noexcept {
}
void FrameCounter::ExitUpdate() noexcept {
- running.update += Tick();
+ current.update = Tick();
}
void FrameCounter::EnterRender() noexcept {
}
void FrameCounter::ExitRender() noexcept {
- running.render += Tick();
+ current.render = Tick();
}
void FrameCounter::ExitFrame() noexcept {
Uint32 now = SDL_GetTicks();
- running.total += now - last_enter;
+ current.total = now - last_enter;
+ current.running = current.handle + current.update + current.render;
+ current.waiting = current.total - current.running;
+ Accumulate();
+
++cur_frame;
if (cur_frame >= NUM_FRAMES) {
- avg.handle = running.handle * factor;
- avg.update = running.update * factor;
- avg.render = running.render * factor;
- avg.total = running.total * factor;
- running = Frame<int>{};
+ Push();
cur_frame = 0;
changed = true;
} else {
return delta;
}
-void FrameCounter::Print(std::ostream &out) const {
- out << "frame: " << AvgFrame() << std::endl;
- out << " handle: " << AvgHandle() << std::endl;
- out << " update: " << AvgUpdate() << std::endl;
- out << " render: " << AvgRender() << std::endl;
- out << " running: " << AvgRunning() << std::endl;
- out << " waiting: " << AvgWaiting() << std::endl;
- out << std::endl;
+void FrameCounter::Accumulate() noexcept {
+ sum.handle += current.handle;
+ sum.update += current.update;
+ sum.render += current.render;
+ sum.running += current.running;
+ sum.waiting += current.waiting;
+ sum.total += current.total;
+
+ max.handle = std::max(current.handle, max.handle);
+ max.update = std::max(current.update, max.update);
+ max.render = std::max(current.render, max.render);
+ max.running = std::max(current.running, max.running);
+ max.waiting = std::max(current.waiting, max.waiting);
+ max.total = std::max(current.total, max.total);
+
+ current = Frame<int>();
+}
+
+void FrameCounter::Push() noexcept {
+ peak = max;
+ avg.handle = sum.handle * factor;
+ avg.update = sum.update * factor;
+ avg.render = sum.render * factor;
+ avg.running = sum.running * factor;
+ avg.waiting = sum.waiting * factor;
+ avg.total = sum.total * factor;
+
+ sum = Frame<int>();
+ max = Frame<int>();
}
}