Unravel Engine C++ Reference
Loading...
Searching...
No Matches
profiler.h
Go to the documentation of this file.
1#pragma once
2#include <engine/engine_export.h>
3
4#include <chrono>
5#include <cstdint>
6#include <map>
7#include <array>
8#include <type_traits>
9#include <concepts>
10#include <hpp/string_view.hpp>
11
12namespace unravel
13{
14
17template<typename T>
18concept string_literal = std::is_array_v<std::remove_reference_t<T>> &&
19 std::is_same_v<std::remove_extent_t<std::remove_reference_t<T>>, const char>;
20
22{
23public:
25 {
26 float time = 0.0f;
27 uint32_t samples = 0;
28
29 per_frame_data() = default;
30 per_frame_data(float t) : time(t)
31 {
32 }
33
34 operator float() const
35 {
36 return time;
37 }
38 auto operator+=(float t) -> per_frame_data&
39 {
40 time += t;
41 return *this;
42 }
43 };
44
45 using record_data_t = std::map<hpp::string_view, per_frame_data>;
46
51 template<typename T>
52 void add_record(T&& name, float time)
53 {
54 static_assert(string_literal<T>,
55 "ERROR: add_record() only accepts string literals for memory safety. "
56 "Use: add_record(\"literal_name\", time) instead of add_record(variable_name, time)");
57 add_record_internal(name, time);
58 }
59
60 void swap()
61 {
62 current_ = get_next_index();
64 }
65
67 {
68 return per_frame_data_[get_next_index()];
69 }
70
72 {
73 return per_frame_data_[current_];
74 }
75
76private:
79 void add_record_internal(const char* name, float time)
80 {
81 auto& per_frame = get_per_frame_data_write();
82
83 auto& data = per_frame[name];
84 data.time += time;
85 data.samples++;
86 }
87
88 auto get_next_index() const -> int
89 {
90 return (current_ + 1) % per_frame_data_.size();
91 }
92
93 std::array<record_data_t, 2> per_frame_data_;
94 int current_{0};
95
96 // Allow scope_perf_timer to access the internal add_record method
97 friend class scope_perf_timer;
98};
99
101{
102public:
103 using clock_t = std::chrono::high_resolution_clock;
104 using timepoint_t = clock_t::time_point;
105 using duration_t = std::chrono::duration<float, std::milli>;
106
111 template<typename T>
113 : name_(name), profiler_(profiler)
114 {
115 static_assert(string_literal<T>,
116 "ERROR: scope_perf_timer only accepts string literals for memory safety. "
117 "Use: scope_perf_timer(\"literal_name\", profiler) instead of scope_perf_timer(variable_name, profiler)");
118 }
119
121 {
122 auto end = clock_t::now();
123 auto time = std::chrono::duration_cast<duration_t>(end - start_);
124
125 profiler_->add_record_internal(name_, time.count());
126 }
127
128private:
129
130 const char* name_;
131 performance_profiler* profiler_{};
132 timepoint_t start_ = clock_t::now();
133};
134
135auto get_app_profiler() -> performance_profiler*;
136
137// Helper macros to concatenate tokens
138#define APP_SCOPE_PERF_CONCATENATE_DETAIL(x, y) x##y
139#define APP_SCOPE_PERF_CONCATENATE(x, y) APP_SCOPE_PERF_CONCATENATE_DETAIL(x, y)
140
141// Macro to create a unique variable name
142#define APP_SCOPE_PERF_UNIQUE_VAR(prefix) APP_SCOPE_PERF_CONCATENATE(prefix, __LINE__)
143
160#define APP_SCOPE_PERF(name) const scope_perf_timer APP_SCOPE_PERF_UNIQUE_VAR(timer)(name, get_app_profiler())
161
162} // namespace unravel
auto get_per_frame_data_read() const -> const record_data_t &
Definition profiler.h:66
void add_record(T &&name, float time)
Add performance record using string literal only.
Definition profiler.h:52
std::map< hpp::string_view, per_frame_data > record_data_t
Definition profiler.h:45
auto get_per_frame_data_write() -> record_data_t &
Definition profiler.h:71
std::chrono::high_resolution_clock clock_t
Definition profiler.h:103
scope_perf_timer(T &&name, performance_profiler *profiler)
Constructor that only accepts string literals for safety.
Definition profiler.h:112
std::chrono::duration< float, std::milli > duration_t
Definition profiler.h:105
clock_t::time_point timepoint_t
Definition profiler.h:104
Concept to ensure only string literals are accepted.
Definition profiler.h:18
std::string name
Definition hub.cpp:27
auto get_app_profiler() -> performance_profiler *
Definition profiler.cpp:6
auto operator+=(float t) -> per_frame_data &
Definition profiler.h:38