4#ifndef DASMIG_EXT_STATS_OBSERVER_HPP
5#define DASMIG_EXT_STATS_OBSERVER_HPP
7#include "../entitygen.hpp"
30 using clock = std::chrono::steady_clock;
31 using duration = std::chrono::steady_clock::duration;
72 std::numeric_limits<std::size_t>::max()};
83 std::map<std::wstring,
106 return duration::zero();
107 return it->second / ct->second;
122 std::size_t total{0};
124 return static_cast<double>(total)
143 [[nodiscard]] std::wstring
report() const
145 std::wostringstream o;
146 o << std::fixed << std::setprecision(2);
149 return std::chrono::duration_cast<
150 std::chrono::microseconds>(d).count();
154 o << L
"=== Entity Summary ===\n"
165 o << L
"\n=== Entity Timing ===\n"
176 o << L
"\n=== Components per Entity ===\n";
186 o << L
" (no entities generated)\n";
190 o << L
"\n=== Component Summary ===\n"
203 std::map<std::wstring, int> all_keys;
209 if (!all_keys.empty())
211 o << L
"\n=== Per-Component Breakdown ===\n";
213 for (
const auto& [key, _] : all_keys)
215 o << L
"\n [" << key << L
"]\n";
217 auto count_or = [](
const auto& m,
const std::wstring& k)
220 return it != m.end() ? it->second : 0;
228 o << L
" Generated : " << gen_n << L
'\n'
229 << L
" Skipped : " << skip_n << L
'\n'
230 << L
" Retries : " << ret_n << L
'\n'
231 << L
" Failures : " << fail_n << L
'\n';
236 o << L
" Time total: " << us(it->second) << L
" us\n"
244 o << L
" Time min : " << us(it->second) << L
" us\n";
250 o << L
" Time max : " << us(it->second) << L
" us\n";
258 o << L
"\n=== Value Distribution ===\n";
262 o << L
"\n [" << key << L
"] ("
263 << dist.size() << L
" distinct values)\n";
266 std::vector<std::pair<std::wstring, std::size_t>> sorted(
267 dist.begin(), dist.end());
268 std::ranges::sort(sorted, [](
const auto& a,
const auto& b) {
269 return a.second > b.second;
272 auto total_n = count_for(key);
273 for (
const auto& [val, n] : sorted)
275 const double pct = total_n > 0
276 ?
static_cast<double>(n)
277 /
static_cast<double>(total_n) * 100.0
279 o << L
" " << val << L
" : " << n
280 << L
" (" << pct << L
" %)\n";
329 _entity_start = clock::now();
330 _current_entity_components = 0;
337 auto elapsed = clock::now() - _entity_start;
349 _component_start[key] = clock::now();
353 const std::any& value)
override
357 ++_current_entity_components;
359 auto it = _component_start.find(key);
360 if (it != _component_start.end())
362 auto elapsed = clock::now() - it->second;
374 if (elapsed < mn) mn = elapsed;
375 if (elapsed > mx) mx = elapsed;
387 void on_skip(
const std::wstring& key)
override
395 const std::any& )
override
418 clock::time_point _entity_start;
419 std::map<std::wstring, clock::time_point> _component_start;
420 std::size_t _current_entity_components{0};
423 static std::wstring display_for(
const std::any& value)
425 if (
const auto* ws = std::any_cast<std::wstring>(&value))
427 if (
const auto* i = std::any_cast<int>(&value))
428 return std::to_wstring(*i);
429 if (
const auto* d = std::any_cast<double>(&value))
430 return std::to_wstring(*d);
431 if (
const auto* f = std::any_cast<float>(&value))
432 return std::to_wstring(*f);
433 if (
const auto* l = std::any_cast<long>(&value))
434 return std::to_wstring(*l);
435 if (
const auto* b = std::any_cast<bool>(&value))
436 return *b ? L
"true" : L
"false";
441 [[nodiscard]] std::size_t count_for(
const std::wstring& key)
const
452 return os << stats.
report();
A generated entity holding component values in registration order.
Observer that collects comprehensive generation statistics.
std::map< std::wstring, std::size_t > component_retries
Total retries per key.
std::map< std::wstring, std::size_t > component_counts
Successful generations per key.
void on_skip(const std::wstring &key) override
Called when a component is skipped (weight roll or conditional exclusion).
double component_retry_rate() const
Retry rate: total retries / total component generations.
std::map< std::wstring, std::size_t > component_skip_counts
Skips per key.
std::size_t entities_generated
Total entities successfully generated.
std::chrono::steady_clock clock
Clock type used for timing.
std::chrono::steady_clock::duration duration
Duration type.
duration min_entity_time
Fastest entity generation.
void on_after_entity_retry(std::size_t) override
Called after an entity validation retry.
std::map< std::wstring, std::map< std::wstring, std::size_t > > value_distribution
Per-component key, counts how many times each display string appeared.
std::map< std::wstring, std::size_t > component_failure_counts
Failures per key.
std::size_t entity_retries
Total entity-level validation retries.
void reset()
Zero all counters, timers, and distributions.
std::map< std::wstring, duration > component_max_times
Slowest per key.
duration avg_component_time(const std::wstring &key) const
Average generation time per component key.
void on_before_component(const std::wstring &key) override
Called before a component is generated.
void on_entity_fail() override
Called when entity validation is exhausted (precedes exception).
std::size_t total_components_in_entities
Sum for computing the average.
double entity_retry_rate() const
Entity retry rate: entity retries / entities generated.
std::size_t min_components_per_entity
Fewest components in any entity.
void on_after_retry(const std::wstring &key, std::size_t, const std::any &) override
Called after a component validation retry.
std::size_t max_components_per_entity
Most components in any entity.
std::wstring report() const
Produce a human-readable wide-string report of all collected stats.
duration max_entity_time
Slowest entity generation.
duration total_generation_time
Wall-clock time summed across all entities.
std::size_t entity_failures
Total entity-level validation failures.
std::size_t components_skipped
Total components skipped (weight or conditional).
void on_component_fail(const std::wstring &key) override
Called when component validation is exhausted (precedes exception).
void on_after_generate(const entity &) override
Called after an entity is successfully generated.
double avg_components_per_entity() const
Average components produced per entity (0.0 if none generated).
duration avg_entity_time() const
Average generation time per entity (zero if none generated).
std::size_t components_generated
Total components successfully generated.
std::map< std::wstring, duration > component_times
Total generation time per key.
void on_before_generate() override
Called before an entity is generated.
std::size_t component_failures
Total component validation failures.
void on_after_component(const std::wstring &key, const std::any &value) override
Called after a component is successfully generated.
std::map< std::wstring, duration > component_min_times
Fastest per key.
Observer interface for hooking into generation lifecycle events.
std::wostream & operator<<(std::wostream &os, const stats_observer &stats)
Stream operator for one-liner report output.