diff --git a/src/command.cpp b/src/command.cpp index 62d270d131..0a2d7fc803 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -1218,9 +1218,9 @@ CommandCost &CommandCost::operator=(const CommandCost &other) this->expense_type = other.expense_type; this->flags = other.flags; this->message = other.message; - this->extra_message = other.extra_message; + this->inl = other.inl; if (other.aux_data) { - this->aux_data.reset(new CommandCostAuxliaryData(*other.aux_data)); + this->aux_data.reset(new CommandCostAuxiliaryData(*other.aux_data)); } return *this; } @@ -1249,7 +1249,7 @@ void CommandCost::UseTextRefStack(const GRFFile *grffile, uint num_registers) extern TemporaryStorageArray _temp_store; if (!this->aux_data) { - this->aux_data.reset(new CommandCostAuxliaryData()); + this->AllocAuxData(); } assert(num_registers < lengthof(this->aux_data->textref_stack)); @@ -1292,12 +1292,53 @@ int CommandCost::WriteSummaryMessage(char *buf, char *last, StringID cmd_msg) co } } +void CommandCost::AllocAuxData() +{ + this->aux_data.reset(new CommandCostAuxiliaryData()); + if (this->flags & CCIF_INLINE_EXTRA_MSG) { + this->aux_data->extra_message = this->inl.extra_message; + this->flags &= ~CCIF_INLINE_EXTRA_MSG; + } else if (this->flags & CCIF_INLINE_TILE) { + this->aux_data->tile = this->inl.tile; + this->flags &= ~CCIF_INLINE_TILE; + } else if (this->flags & CCIF_INLINE_RESULT) { + this->aux_data->result = this->inl.result; + this->flags &= ~CCIF_INLINE_RESULT; + } +} + +bool CommandCost::AddInlineData(CommandCostIntlFlags inline_flag) +{ + if (this->aux_data) return true; + if (this->flags & inline_flag) { + return false; + } + if (this->flags & ~CCIF_SUCCESS) { + this->AllocAuxData(); + return true; + } + this->flags |= inline_flag; + return false; +} + void CommandCost::SetTile(TileIndex tile) { if (tile == this->GetTile()) return; - if (!this->aux_data) { - this->aux_data.reset(new CommandCostAuxliaryData()); + if (this->AddInlineData(CCIF_INLINE_TILE)) { + this->aux_data->tile = tile; + } else { + this->inl.tile = tile; + } +} + +void CommandCost::SetResultData(uint32 result) +{ + if (result == this->GetResultData()) return; + + if (this->AddInlineData(CCIF_INLINE_RESULT)) { + this->aux_data->result = result; + } else { + this->inl.result = result; } - this->aux_data->tile = tile; } diff --git a/src/command_type.h b/src/command_type.h index af041b461c..12b44b1bbb 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -20,6 +20,9 @@ struct GRFFile; enum CommandCostIntlFlags : uint8 { CCIF_NONE = 0, CCIF_SUCCESS = 1 << 0, + CCIF_INLINE_EXTRA_MSG = 1 << 1, + CCIF_INLINE_TILE = 1 << 2, + CCIF_INLINE_RESULT = 1 << 3, }; DECLARE_ENUM_AS_BIT_SET(CommandCostIntlFlags) @@ -32,15 +35,24 @@ class CommandCost { ExpensesType expense_type; ///< the type of expence as shown on the finances view CommandCostIntlFlags flags; ///< Flags: see CommandCostIntlFlags StringID message; ///< Warning message for when success is unset - StringID extra_message = INVALID_STRING_ID; ///< Additional warning message for when success is unset + union { + uint32 result = 0; + StringID extra_message; ///< Additional warning message for when success is unset + TileIndex tile; + } inl; - struct CommandCostAuxliaryData { + struct CommandCostAuxiliaryData { uint32 textref_stack[16] = {}; const GRFFile *textref_stack_grffile = nullptr; ///< NewGRF providing the #TextRefStack content. uint textref_stack_size = 0; ///< Number of uint32 values to put on the #TextRefStack for the error message. + StringID extra_message = INVALID_STRING_ID; ///< Additional warning message for when success is unset TileIndex tile = INVALID_TILE; + uint32 result = 0; }; - std::unique_ptr aux_data; + std::unique_ptr aux_data; + + void AllocAuxData(); + bool AddInlineData(CommandCostIntlFlags inline_flag); public: /** @@ -64,7 +76,8 @@ public: static CommandCost DualErrorMessage(StringID msg, StringID extra_msg) { CommandCost cc(msg); - cc.extra_message = extra_msg; + cc.flags |= CCIF_INLINE_EXTRA_MSG; + cc.inl.extra_message = extra_msg; return cc; } @@ -124,12 +137,12 @@ public: * Makes this #CommandCost behave like an error command. * @param message The error message. */ - void MakeError(StringID message, StringID extra_message = INVALID_STRING_ID) + void MakeError(StringID message) { assert(message != INVALID_STRING_ID); - this->flags &= ~CCIF_SUCCESS; + this->flags &= ~(CCIF_SUCCESS | CCIF_INLINE_EXTRA_MSG); this->message = message; - this->extra_message = extra_message; + if (this->aux_data) this->aux_data->extra_message = INVALID_STRING_ID; } void UseTextRefStack(const GRFFile *grffile, uint num_registers); @@ -178,7 +191,8 @@ public: StringID GetExtraErrorMessage() const { if (this->Succeeded()) return INVALID_STRING_ID; - return this->extra_message; + if (this->flags & CCIF_INLINE_EXTRA_MSG) return this->inl.extra_message; + return this->aux_data != nullptr ? this->aux_data->extra_message : INVALID_STRING_ID; } /** @@ -235,10 +249,19 @@ public: TileIndex GetTile() const { + if (this->flags & CCIF_INLINE_TILE) return this->inl.tile; return this->aux_data != nullptr ? this->aux_data->tile : INVALID_TILE; } void SetTile(TileIndex tile); + + uint32 GetResultData() const + { + if (this->flags & CCIF_INLINE_RESULT) return this->inl.result; + return this->aux_data != nullptr ? this->aux_data->result : 0; + } + + void SetResultData(uint32 result); }; /**