1
0
Fork 0

Compare commits

...

4 Commits

Author SHA1 Message Date
Peter Nelson 7bd019df90 Codechange: Use std::array for TemporaryStorageArray.
This removes the need for initialisation with memset().
2023-09-09 15:26:03 +01:00
Peter Nelson 9040d7813d Codechange: Use std::array and std::unique_ptr for PersistentStorageArrays.
This (mostly) avoids the need for manual memory management and copying.
2023-09-09 15:26:03 +01:00
Patric Stout c3918838f6
Fix: crash when opening a damaged base-graphics (#11275) 2023-09-09 14:06:00 +00:00
PeterN afc1ea8135
Codechange: Using alias and std::array for company expense storage. (#11273)
This simplifies passing yearly expenses to functions and use of std algorithms.
2023-09-09 13:15:53 +00:00
10 changed files with 33 additions and 52 deletions

View File

@ -92,7 +92,7 @@ struct CompanyProperties {
*/
bool is_ai;
Money yearly_expenses[3][EXPENSES_END]; ///< Expenses of the company for the last three years, in every #ExpensesType category.
std::array<Expenses, 3> yearly_expenses{}; ///< Expenses of the company for the last three years.
CompanyEconomyEntry cur_economy; ///< Economic data of the company of this quarter.
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters.
byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.

View File

@ -750,8 +750,9 @@ static IntervalTimer<TimerGameCalendar> _companies_yearly({TimerGameCalendar::YE
{
/* Copy statistics */
for (Company *c : Company::Iterate()) {
memmove(&c->yearly_expenses[1], &c->yearly_expenses[0], sizeof(c->yearly_expenses) - sizeof(c->yearly_expenses[0]));
memset(&c->yearly_expenses[0], 0, sizeof(c->yearly_expenses[0]));
/* Move expenses to previous years. */
std::rotate(std::rbegin(c->yearly_expenses), std::rbegin(c->yearly_expenses) + 1, std::rend(c->yearly_expenses));
c->yearly_expenses[0] = {};
SetWindowDirty(WC_FINANCES, c->index);
}

View File

@ -229,7 +229,7 @@ static void DrawPrice(Money amount, int left, int right, int top, TextColour col
* Draw a category of expenses/revenues in the year column.
* @return The income sum of the category.
*/
static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, const Money(&tbl)[EXPENSES_END])
static Money DrawYearCategory(const Rect &r, int start_y, ExpensesList list, const Expenses &tbl)
{
int y = start_y;
ExpensesType et;
@ -260,7 +260,7 @@ static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, co
* @param tbl Reference to table of amounts for \a year.
* @note The environment must provide padding at the left and right of \a r.
*/
static void DrawYearColumn(const Rect &r, TimerGameCalendar::Year year, const Money (&tbl)[EXPENSES_END])
static void DrawYearColumn(const Rect &r, TimerGameCalendar::Year year, const Expenses &tbl)
{
int y = r.top;
Money sum;

View File

@ -172,6 +172,11 @@ enum ExpensesType : byte {
INVALID_EXPENSES = 0xFF, ///< Invalid expense type.
};
/**
* Data type for storage of Money for each #ExpensesType category.
*/
using Expenses = std::array<Money, EXPENSES_END>;
/**
* Categories of a price bases.
*/

View File

@ -383,10 +383,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy()
{
for (const Company *company : Company::Iterate()) {
/* Get the income. */
Money income = 0;
for (uint i = 0; i < lengthof(company->yearly_expenses[0]); i++) {
income -= company->yearly_expenses[0][i];
}
Money income = -std::reduce(std::begin(company->yearly_expenses[0]), std::end(company->yearly_expenses[0]));
Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_ECONOMY);

View File

@ -65,26 +65,10 @@ private:
*/
template <typename TYPE, uint SIZE>
struct PersistentStorageArray : BasePersistentStorageArray {
TYPE storage[SIZE]; ///< Memory to for the storage array
TYPE *prev_storage; ///< Memory to store "old" states so we can revert them on the performance of test cases for commands etc.
using StorageType = std::array<TYPE, SIZE>;
/** Simply construct the array */
PersistentStorageArray() : prev_storage(nullptr)
{
memset(this->storage, 0, sizeof(this->storage));
}
/** And free all data related to it */
~PersistentStorageArray()
{
free(this->prev_storage);
}
/** Resets all values to zero. */
void ResetToZero()
{
memset(this->storage, 0, sizeof(this->storage));
}
StorageType storage{}; ///< Memory for the storage array
std::unique_ptr<StorageType> prev_storage{}; ///< Temporary memory to store previous state so it can be reverted, e.g. for command tests.
/**
* Stores some value at a given position.
@ -104,10 +88,9 @@ struct PersistentStorageArray : BasePersistentStorageArray {
/* We do not have made a backup; lets do so */
if (AreChangesPersistent()) {
assert(this->prev_storage == nullptr);
} else if (this->prev_storage == nullptr) {
this->prev_storage = MallocT<TYPE>(SIZE);
memcpy(this->prev_storage, this->storage, sizeof(this->storage));
assert(!this->prev_storage);
} else if (!this->prev_storage) {
this->prev_storage = std::make_unique<StorageType>(this->storage);
/* We only need to register ourselves when we made the backup
* as that is the only time something will have changed */
@ -132,10 +115,9 @@ struct PersistentStorageArray : BasePersistentStorageArray {
void ClearChanges()
{
if (this->prev_storage != nullptr) {
memcpy(this->storage, this->prev_storage, sizeof(this->storage));
free(this->prev_storage);
this->prev_storage = nullptr;
if (this->prev_storage) {
this->storage = *this->prev_storage;
this->prev_storage.reset();
}
}
};
@ -149,17 +131,12 @@ struct PersistentStorageArray : BasePersistentStorageArray {
*/
template <typename TYPE, uint SIZE>
struct TemporaryStorageArray {
TYPE storage[SIZE]; ///< Memory to for the storage array
uint16_t init[SIZE]; ///< Storage has been assigned, if this equals 'init_key'.
uint16_t init_key; ///< Magic key to 'init'.
using StorageType = std::array<TYPE, SIZE>;
using StorageInitType = std::array<uint16_t, SIZE>;
/** Simply construct the array */
TemporaryStorageArray()
{
memset(this->storage, 0, sizeof(this->storage)); // not exactly needed, but makes code analysers happy
memset(this->init, 0, sizeof(this->init));
this->init_key = 1;
}
StorageType storage{}; ///< Memory for the storage array
StorageInitType init{}; ///< Storage has been assigned, if this equals 'init_key'.
uint16_t init_key{1}; ///< Magic key to 'init'.
/**
* Stores some value at a given position.
@ -199,7 +176,7 @@ struct TemporaryStorageArray {
this->init_key++;
if (this->init_key == 0) {
/* When init_key wraps around, we need to reset everything */
memset(this->init, 0, sizeof(this->init));
this->init = {};
this->init_key = 1;
}
}

View File

@ -146,9 +146,10 @@ void RandomAccessFile::ReadBlock(void *ptr, size_t size)
* Skip \a n bytes ahead in the file.
* @param n Number of bytes to skip reading.
*/
void RandomAccessFile::SkipBytes(int n)
void RandomAccessFile::SkipBytes(size_t n)
{
int remaining = this->buffer_end - this->buffer;
assert(this->buffer_end >= this->buffer);
size_t remaining = this->buffer_end - this->buffer;
if (n <= remaining) {
this->buffer += n;
} else {

View File

@ -51,7 +51,7 @@ public:
uint32_t ReadDword();
void ReadBlock(void *ptr, size_t size);
void SkipBytes(int n);
void SkipBytes(size_t n);
};
#endif /* RANDOM_ACCESS_FILE_TYPE_H */

View File

@ -246,7 +246,7 @@ struct INDYChunkHandler : ChunkHandler {
/* Store the old persistent storage. The GRFID will be added later. */
assert(PersistentStorage::CanAllocateItem());
i->psa = new PersistentStorage(0, 0, 0);
memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(_old_ind_persistent_storage.storage));
std::copy(std::begin(_old_ind_persistent_storage.storage), std::end(_old_ind_persistent_storage.storage), std::begin(i->psa->storage));
}
if (IsSavegameVersionBefore(SLV_INDUSTRY_CARGO_REORGANISE)) LoadMoveAcceptsProduced(i);
Industry::IncIndustryTypeCount(i->type);

View File

@ -426,7 +426,7 @@ public:
/* Store the old persistent storage. The GRFID will be added later. */
assert(PersistentStorage::CanAllocateItem());
st->airport.psa = new PersistentStorage(0, 0, 0);
memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(_old_st_persistent_storage.storage));
std::copy(std::begin(_old_st_persistent_storage.storage), std::end(_old_st_persistent_storage.storage), std::begin(st->airport.psa->storage));
}
size_t num_cargo = this->GetNumCargo();