Add debug summary mechanism to command auxiliary data for command log

This commit is contained in:
Jonathan G Rennison 2024-08-30 19:19:34 +01:00
parent c90d8267d5
commit 282f13cab0
6 changed files with 39 additions and 13 deletions

View File

@ -711,11 +711,8 @@ static void DumpSubCommandLogEntry(char *&buffer, const char *last, const Comman
}
buffer += seprintf(buffer, last, "cmd: 0x%08X (%s)", entry.cmd, GetCommandName(entry.cmd));
switch (entry.cmd & CMD_ID_MASK) {
case CMD_CHANGE_SETTING:
case CMD_CHANGE_COMPANY_SETTING:
buffer += seprintf(buffer, last, " [%s]", entry.text.c_str());
break;
if (!entry.text.empty()) {
buffer += seprintf(buffer, last, " [%s]", entry.text.c_str());
}
}
@ -921,7 +918,7 @@ static void DebugLogCommandLogEntry(const CommandLogEntry &entry)
debug_print("command", 0, buffer);
}
static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32_t p1, uint32_t p2, uint64_t p3, uint32_t cmd, CommandLogEntryFlag log_flags, const char *text)
static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32_t p1, uint32_t p2, uint64_t p3, uint32_t cmd, CommandLogEntryFlag log_flags, const char *text, const CommandAuxiliaryBase *aux_data)
{
if (res.Failed()) log_flags |= CLEF_CMD_FAILED;
if (_generating_world) log_flags |= CLEF_GENERATING_WORLD;
@ -938,6 +935,7 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32
current.current_company == _current_company && current.local_company == _local_company) {
current.log_flags |= log_flags | CLEF_TWICE;
current.log_flags &= ~CLEF_ONLY_SENDING;
if (current.text.empty() && aux_data != nullptr) current.text = aux_data->GetDebugSummary();
DebugLogCommandLogEntry(current);
return;
}
@ -950,6 +948,7 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32
if (text != nullptr) str.assign(text);
break;
}
if (str.empty() && aux_data != nullptr) str = aux_data->GetDebugSummary();
cmd_log.log[cmd_log.next] = CommandLogEntry(tile, p1, p2, p3, cmd, log_flags, std::move(str));
DebugLogCommandLogEntry(cmd_log.log[cmd_log.next]);
@ -1021,7 +1020,7 @@ bool DoCommandPEx(TileIndex tile, uint32_t p1, uint32_t p2, uint64_t p3, uint32_
if (aux_data != nullptr) log_flags |= CLEF_AUX_DATA;
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
if (order_backup_update_counter != OrderBackup::GetUpdateCounter()) log_flags |= CLEF_ORDER_BACKUP;
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text, aux_data);
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;
@ -1070,7 +1069,7 @@ CommandCost DoCommandPScript(TileIndex tile, uint32_t p1, uint32_t p2, uint64_t
if (aux_data != nullptr) log_flags |= CLEF_AUX_DATA;
if (!random_state.Check()) log_flags |= CLEF_RANDOM;
if (order_backup_update_counter != OrderBackup::GetUpdateCounter()) log_flags |= CLEF_ORDER_BACKUP;
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text);
AppendCommandLogEntry(res, tile, p1, p2, p3, cmd, log_flags, text, aux_data);
if (unlikely(HasChickenBit(DCBF_DESYNC_CHECK_POST_COMMAND)) && !(GetCommandFlags(cmd) & CMD_LOG_AUX)) {
CheckCachesFlags flags = CHECK_CACHE_ALL | CHECK_CACHE_EMIT_LOG;

View File

@ -55,20 +55,26 @@ struct CommandSerialisationBuffer : public BufferSerialisationHelper<CommandSeri
struct CommandAuxiliarySerialised : public CommandAuxiliaryBase {
std::vector<uint8_t> serialised_data;
mutable std::string debug_summary;
CommandAuxiliaryBase *Clone() const override
{
return new CommandAuxiliarySerialised(*this);
}
virtual std::optional<std::span<const uint8_t>> GetDeserialisationSrc() const override { return std::span<const uint8_t>(this->serialised_data.data(), this->serialised_data.size()); }
virtual std::optional<CommandAuxiliaryDeserialisationSrc> GetDeserialisationSrc() const override
{
return CommandAuxiliaryDeserialisationSrc{ std::span<const uint8_t>(this->serialised_data.data(), this->serialised_data.size()), this->debug_summary };
}
virtual void Serialise(CommandSerialisationBuffer &buffer) const override { buffer.Send_binary(this->serialised_data.data(), this->serialised_data.size()); }
virtual std::string GetDebugSummary() const override { return std::move(this->debug_summary); }
};
template <typename T>
struct CommandAuxiliarySerialisable : public CommandAuxiliaryBase {
virtual std::optional<std::span<const uint8_t>> GetDeserialisationSrc() const override { return {}; }
virtual std::optional<CommandAuxiliaryDeserialisationSrc> GetDeserialisationSrc() const override { return {}; }
CommandAuxiliaryBase *Clone() const override
{
@ -86,10 +92,10 @@ public:
inline CommandCost Load(const CommandAuxiliaryBase *base)
{
if (base == nullptr) return CMD_ERROR;
std::optional<std::span<const uint8_t>> deserialise_from = base->GetDeserialisationSrc();
std::optional<CommandAuxiliaryDeserialisationSrc> deserialise_from = base->GetDeserialisationSrc();
if (deserialise_from.has_value()) {
this->store = T();
CommandDeserialisationBuffer buffer(deserialise_from->data(), deserialise_from->size());
CommandDeserialisationBuffer buffer(deserialise_from->src.data(), deserialise_from->src.size());
CommandCost res = this->store->Deserialise(buffer);
if (res.Failed()) return res;
if (buffer.error || buffer.pos != buffer.size) {
@ -97,6 +103,7 @@ public:
return CMD_ERROR;
}
this->data = &(*(this->store));
deserialise_from->debug_summary = this->data->GetDebugSummary();
return res;
} else {
this->data = dynamic_cast<const T*>(base);

View File

@ -730,14 +730,21 @@ typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32_t
struct CommandSerialisationBuffer;
struct CommandAuxiliaryDeserialisationSrc {
std::span<const uint8_t> src;
std::string &debug_summary;
};
struct CommandAuxiliaryBase {
virtual ~CommandAuxiliaryBase() {}
virtual CommandAuxiliaryBase *Clone() const = 0;
virtual std::optional<std::span<const uint8_t>> GetDeserialisationSrc() const = 0;
virtual std::optional<CommandAuxiliaryDeserialisationSrc> GetDeserialisationSrc() const = 0;
virtual void Serialise(CommandSerialisationBuffer &buffer) const = 0;
virtual std::string GetDebugSummary() const { return {}; }
};
struct CommandAuxiliaryPtr : public std::unique_ptr<CommandAuxiliaryBase>

View File

@ -18,6 +18,7 @@
#include "window_func.h"
#include "core/pool_func.hpp"
#include "company_base.h"
#include "core/format.hpp"
#include "safeguards.h"
@ -217,3 +218,8 @@ CommandCost CmdRemoveLeagueTableElement(TileIndex tile, DoCommandFlag flags, uin
{
return CmdRemoveLeagueTableElement(flags, p1);
}
std::string LeagueTableElementCmdData::GetDebugSummary() const
{
return fmt::format("t: {}, r: {}, c: {}, type: {}, targ: {}", this->table, this->rating, this->company, this->link_type, this->link_target);
}

View File

@ -64,6 +64,8 @@ struct LeagueTableElementCmdData : public CommandAuxiliarySerialisable<LeagueTab
buffer.Recv_string(this->score, SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK);
return CommandCost();
}
std::string GetDebugSummary() const override;
};
#endif /* LEAGUE_CMD_H */

View File

@ -58,6 +58,11 @@ struct PlanLineCmdData : public CommandAuxiliarySerialisable<PlanLineCmdData> {
}
return CommandCost();
}
std::string GetDebugSummary() const override
{
return stdstr_fmt("%u tiles", (uint32_t)this->tiles.size());
}
};
bool AddPlanLine(PlanID plan, TileVector tiles)