17#include "3rdparty/fmt/chrono.h"
25std::vector<NewGRFProfiler> _newgrf_profilers;
49 using namespace std::chrono;
52 this->
cur_call.time = (uint32_t)time_point_cast<microseconds>(high_resolution_clock::now()).time_since_epoch().count();
64 using namespace std::chrono;
65 this->
cur_call.time = (uint32_t)time_point_cast<microseconds>(high_resolution_clock::now()).time_since_epoch().count() - this->
cur_call.time;
68 uint32_t operator()(std::monostate)
72 uint32_t operator()(CallbackResult cb_result)
82 return group ==
nullptr ? 0 : group->nfo_line;
86 return group ==
nullptr ? 0 : group->nfo_line;
89 this->
cur_call.result = std::visit(visitor{}, result);
102void NewGRFProfiler::Start()
109uint32_t NewGRFProfiler::Finish()
111 if (!this->
active)
return 0;
113 if (this->
calls.empty()) {
114 IConsolePrint(
CC_DEBUG,
"Finished profile of NewGRF [{:08X}], no events collected, not writing a file.", std::byteswap(this->
grffile->grfid));
121 IConsolePrint(
CC_DEBUG,
"Finished profile of NewGRF [{:08X}], writing {} events to '{}'.", std::byteswap(this->
grffile->grfid), this->calls.size(), filename);
123 uint32_t total_microseconds = 0;
127 if (!f.has_value()) {
130 fmt::print(*f,
"Tick,Sprite,Feature,Item,CallbackID,Microseconds,Depth,Result\n");
132 fmt::print(*f,
"{},{},0x{:X},{},0x{:X},{},{},{}\n", c.tick, c.root_sprite, c.feat, c.item, (uint)c.cb, c.time, c.subs, c.result);
133 total_microseconds += c.time;
138 return total_microseconds;
141void NewGRFProfiler::Abort()
156 uint32_t NewGRFProfiler::FinishAll()
160 uint64_t max_ticks = 0;
161 uint32_t total_microseconds = 0;
164 total_microseconds += pr.Finish();
169 if (total_microseconds > 0 && max_ticks > 0) {
170 IConsolePrint(
CC_DEBUG,
"Total NewGRF callback processing: {} microseconds over {} ticks.", total_microseconds, max_ticks);
173 return total_microseconds;
181 NewGRFProfiler::FinishAll();
constexpr enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
A timeout timer will fire once after the interval.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
@ None
These timers can be executed in any order; the order is not relevant.
void IConsolePrint(TextColour colour_code, const std::string &string)
Handle the printing of text entered into the console or redirected there by any other means.
Console functions used outside of the console code.
static const TextColour CC_DEBUG
Colour for debug output.
static const TextColour CC_ERROR
Colour for error lines.
std::optional< FileHandle > FioFOpenFile(std::string_view filename, std::string_view mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
Functions for standard in/out file operations.
std::string_view FiosGetScreenshotDir()
Get the directory for screenshots.
@ NO_DIRECTORY
A path without any base directory.
static TimeoutTimer< TimerGameTick > _profiling_finish_timeout({ TimerGameTick::Priority::None, 0 }, []() { NewGRFProfiler::FinishAll();})
Check whether profiling is active and should be finished.
Profiling of NewGRF action 2 handling.
std::variant< std::monostate, CallbackResult, const ResultSpriteGroup *, const TileLayoutSpriteGroup *, const IndustryProductionSpriteGroup * > ResolverResult
Result of resolving sprite groups:
A number of safeguards to prevent using unsafe methods.
uint32_t GetSpriteLocalID(SpriteID sprite)
Get the GRF-local sprite id of a given sprite.
Functions to cache sprites in memory.
Definition of base types and functions in a cross-platform compatible way.
Functions related to low-level strings.
Dynamic data of a loaded NewGRF.
Measurement of a single sprite group resolution.
Callback profiler for NewGRF development.
void RecursiveResolve()
Capture a recursive sprite group resolution.
static void StartTimer(uint64_t ticks)
Start the timeout timer that will finish all profiling sessions.
void EndResolve(const ResolverResult &result)
Capture the completion of a sprite group resolution.
~NewGRFProfiler()
Complete profiling session and write data to file.
Call cur_call
Data for current call in progress.
bool active
Is this profiler collecting data.
const GRFFile * grffile
Which GRF is being profiled.
uint64_t start_tick
Tick number this profiler was started on.
static void AbortTimer()
Abort the timeout timer, so the timer callback is never called.
void BeginResolve(const ResolverObject &resolver)
Capture the start of a sprite group resolution.
NewGRFProfiler(const GRFFile *grffile)
Create profiler object and begin profiling session.
std::vector< Call > calls
All calls collected so far.
std::string GetOutputFilename() const
Get name of the file that will be written.
Interface for SpriteGroup-s to access the gamestate.
virtual uint32_t GetDebugID() const
Get an identifier for the item being resolved.
CallbackID callback
Callback being resolved.
virtual GrfSpecFeature GetFeature() const
Get the feature number being resolved for.
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
Definition of Interval and OneShot timers.
Definition of the tick-based game-timer.