mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Use traits to define BaseSet parameters.
parent
6914d99778
commit
3375dc3095
|
@ -38,21 +38,25 @@ struct MD5File {
|
|||
ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const;
|
||||
};
|
||||
|
||||
/** Defines the traits of a BaseSet type. */
|
||||
template <class T> struct BaseSetTraits;
|
||||
|
||||
/**
|
||||
* Information about a single base set.
|
||||
* @tparam T the real class we're going to be
|
||||
* @tparam Tnum_files the number of files in the set
|
||||
* @tparam Tsearch_in_tars whether to search in the tars or not
|
||||
*/
|
||||
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
|
||||
template <class T>
|
||||
struct BaseSet {
|
||||
typedef std::unordered_map<std::string, std::string> TranslatedStrings;
|
||||
|
||||
/** Number of files in this set */
|
||||
static const size_t NUM_FILES = Tnum_files;
|
||||
static constexpr size_t NUM_FILES = BaseSetTraits<T>::num_files;
|
||||
|
||||
/** Whether to search in the tars or not. */
|
||||
static const bool SEARCH_IN_TARS = Tsearch_in_tars;
|
||||
static constexpr bool SEARCH_IN_TARS = BaseSetTraits<T>::search_in_tars;
|
||||
|
||||
/** BaseSet type name. */
|
||||
static constexpr std::string_view SET_TYPE = BaseSetTraits<T>::set_type;
|
||||
|
||||
/** Internal names of the files in this set. */
|
||||
static const char * const *file_names;
|
||||
|
@ -64,7 +68,7 @@ struct BaseSet {
|
|||
uint32_t version; ///< The version of this base set
|
||||
bool fallback; ///< This set is a fallback set, i.e. it should be used only as last resort
|
||||
|
||||
MD5File files[NUM_FILES]; ///< All files part of this set
|
||||
MD5File files[BaseSet<T>::NUM_FILES]; ///< All files part of this set
|
||||
uint found_files; ///< Number of the files that could be found
|
||||
uint valid_files; ///< Number of the files that could be found and are valid
|
||||
|
||||
|
@ -82,7 +86,7 @@ struct BaseSet {
|
|||
*/
|
||||
int GetNumMissing() const
|
||||
{
|
||||
return Tnum_files - this->found_files;
|
||||
return BaseSet<T>::NUM_FILES - this->found_files;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,7 +96,7 @@ struct BaseSet {
|
|||
*/
|
||||
int GetNumInvalid() const
|
||||
{
|
||||
return Tnum_files - this->valid_files;
|
||||
return BaseSet<T>::NUM_FILES - this->valid_files;
|
||||
}
|
||||
|
||||
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
/**
|
||||
* @file base_media_func.h Generic function implementations for base data (graphics, sounds).
|
||||
* @note You should _never_ include this file due to the SET_TYPE define.
|
||||
*/
|
||||
|
||||
#include "base_media_base.h"
|
||||
|
@ -25,7 +24,7 @@ extern void CheckExternalFiles();
|
|||
#define fetch_metadata(name) \
|
||||
item = metadata->GetItem(name); \
|
||||
if (item == nullptr || !item->value.has_value() || item->value->empty()) { \
|
||||
Debug(grf, 0, "Base " SET_TYPE "set detail loading: {} field missing.", name); \
|
||||
Debug(grf, 0, "Base {}set detail loading: {} field missing.", BaseSet::SET_TYPE, name); \
|
||||
Debug(grf, 0, " Is {} readable for the user running OpenTTD?", full_filename); \
|
||||
return false; \
|
||||
}
|
||||
|
@ -38,12 +37,12 @@ extern void CheckExternalFiles();
|
|||
* @param allow_empty_filename empty filenames are valid
|
||||
* @return true if loading was successful.
|
||||
*/
|
||||
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
|
||||
bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename)
|
||||
template <class T>
|
||||
bool BaseSet<T>::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename)
|
||||
{
|
||||
const IniGroup *metadata = ini.GetGroup("metadata");
|
||||
if (metadata == nullptr) {
|
||||
Debug(grf, 0, "Base " SET_TYPE "set detail loading: metadata missing.");
|
||||
Debug(grf, 0, "Base {}set detail loading: metadata missing.", BaseSet<T>::SET_TYPE);
|
||||
Debug(grf, 0, " Is {} readable for the user running OpenTTD?", full_filename);
|
||||
return false;
|
||||
}
|
||||
|
@ -80,12 +79,12 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(const IniFile &ini,
|
|||
const IniGroup *files = ini.GetGroup("files");
|
||||
const IniGroup *md5s = ini.GetGroup("md5s");
|
||||
const IniGroup *origin = ini.GetGroup("origin");
|
||||
for (uint i = 0; i < Tnum_files; i++) {
|
||||
for (uint i = 0; i < BaseSet<T>::NUM_FILES; i++) {
|
||||
MD5File *file = &this->files[i];
|
||||
/* Find the filename first. */
|
||||
item = files != nullptr ? files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i]) : nullptr;
|
||||
item = files != nullptr ? files->GetItem(BaseSet<T>::file_names[i]) : nullptr;
|
||||
if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
|
||||
Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
|
||||
Debug(grf, 0, "No {} file for: {} (in {})", BaseSet<T>::SET_TYPE, BaseSet<T>::file_names[i], full_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -164,7 +163,7 @@ template <class Tbase_set>
|
|||
bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_length, const std::string &)
|
||||
{
|
||||
bool ret = false;
|
||||
Debug(grf, 1, "Checking {} for base " SET_TYPE " set", filename);
|
||||
Debug(grf, 1, "Checking {} for base {} set", filename, BaseSet<Tbase_set>::SET_TYPE);
|
||||
|
||||
Tbase_set *set = new Tbase_set();
|
||||
IniFile ini{};
|
||||
|
@ -190,7 +189,8 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
|||
/* The more complete set takes precedence over the version number. */
|
||||
if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
|
||||
duplicate->valid_files > set->valid_files) {
|
||||
Debug(grf, 1, "Not adding {} ({}) as base " SET_TYPE " set (duplicate, {})", set->name, set->version,
|
||||
Debug(grf, 1, "Not adding {} ({}) as base {} set (duplicate, {})", set->name, set->version,
|
||||
BaseSet<Tbase_set>::SET_TYPE,
|
||||
duplicate->valid_files > set->valid_files ? "less valid files" : "lower version");
|
||||
set->next = BaseMedia<Tbase_set>::duplicate_sets;
|
||||
BaseMedia<Tbase_set>::duplicate_sets = set;
|
||||
|
@ -209,7 +209,8 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
|||
* version number until a new game is started which isn't a big problem */
|
||||
if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set;
|
||||
|
||||
Debug(grf, 1, "Removing {} ({}) as base " SET_TYPE " set (duplicate, {})", duplicate->name, duplicate->version,
|
||||
Debug(grf, 1, "Removing {} ({}) as base {} set (duplicate, {})", duplicate->name, duplicate->version,
|
||||
BaseSet<Tbase_set>::SET_TYPE,
|
||||
duplicate->valid_files < set->valid_files ? "less valid files" : "lower version");
|
||||
duplicate->next = BaseMedia<Tbase_set>::duplicate_sets;
|
||||
BaseMedia<Tbase_set>::duplicate_sets = duplicate;
|
||||
|
@ -223,7 +224,7 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
|||
ret = true;
|
||||
}
|
||||
if (ret) {
|
||||
Debug(grf, 1, "Adding {} ({}) as base " SET_TYPE " set", set->name, set->version);
|
||||
Debug(grf, 1, "Adding {} ({}) as base {} set", set->name, set->version, BaseSet<Tbase_set>::SET_TYPE);
|
||||
}
|
||||
} else {
|
||||
delete set;
|
||||
|
@ -296,7 +297,7 @@ template <class Tbase_set>
|
|||
template <class Tbase_set>
|
||||
/* static */ void BaseMedia<Tbase_set>::GetSetsList(std::back_insert_iterator<std::string> &output_iterator)
|
||||
{
|
||||
fmt::format_to(output_iterator, "List of " SET_TYPE " sets:\n");
|
||||
fmt::format_to(output_iterator, "List of {} sets:\n", BaseSet<Tbase_set>::SET_TYPE);
|
||||
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
|
||||
fmt::format_to(output_iterator, "{:>18}: {}", s->name, s->GetDescription({}));
|
||||
int invalid = s->GetNumInvalid();
|
||||
|
@ -383,7 +384,7 @@ template <class Tbase_set>
|
|||
if (index == 0) return s;
|
||||
index--;
|
||||
}
|
||||
FatalError("Base" SET_TYPE "::GetSet(): index {} out of range", index);
|
||||
FatalError("Base{}::GetSet(): index {} out of range", BaseSet<Tbase_set>::SET_TYPE, index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,13 +31,19 @@ enum BlitterType : uint8_t {
|
|||
|
||||
struct GRFConfig;
|
||||
|
||||
template <> struct BaseSetTraits<struct GraphicsSet> {
|
||||
static constexpr size_t num_files = MAX_GFT;
|
||||
static constexpr bool search_in_tars = true;
|
||||
static constexpr std::string_view set_type = "graphics";
|
||||
};
|
||||
|
||||
/** All data of a graphics set. */
|
||||
struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, true> {
|
||||
struct GraphicsSet : BaseSet<GraphicsSet> {
|
||||
private:
|
||||
mutable std::unique_ptr<GRFConfig> extra_cfg; ///< Parameters for extra GRF
|
||||
mutable std::unique_ptr<GRFConfig> extra_cfg = nullptr; ///< Parameters for extra GRF
|
||||
public:
|
||||
PaletteType palette; ///< Palette of this graphics set
|
||||
BlitterType blitter; ///< Blitter of this graphics set
|
||||
PaletteType palette{}; ///< Palette of this graphics set
|
||||
BlitterType blitter{}; ///< Blitter of this graphics set
|
||||
|
||||
GraphicsSet();
|
||||
~GraphicsSet();
|
||||
|
|
|
@ -43,12 +43,18 @@ struct MusicSongInfo {
|
|||
int override_end; ///< MIDI tick to end the song at (0 if no override)
|
||||
};
|
||||
|
||||
template <> struct BaseSetTraits<struct MusicSet> {
|
||||
static constexpr size_t num_files = NUM_SONGS_AVAILABLE;
|
||||
static constexpr bool search_in_tars = false;
|
||||
static constexpr std::string_view set_type = "music";
|
||||
};
|
||||
|
||||
/** All data of a music set. */
|
||||
struct MusicSet : BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false> {
|
||||
struct MusicSet : BaseSet<MusicSet> {
|
||||
/** Data about individual songs in set. */
|
||||
MusicSongInfo songinfo[NUM_SONGS_AVAILABLE];
|
||||
/** Number of valid songs in set. */
|
||||
uint8_t num_available;
|
||||
uint8_t num_available = 0;
|
||||
|
||||
bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename);
|
||||
};
|
||||
|
|
|
@ -12,16 +12,20 @@
|
|||
|
||||
#include "base_media_base.h"
|
||||
|
||||
/** All data of a sounds set. */
|
||||
struct SoundsSet : BaseSet<SoundsSet, 1, true> {
|
||||
template <> struct BaseSetTraits<struct SoundsSet> {
|
||||
static constexpr size_t num_files = 1;
|
||||
static constexpr bool search_in_tars = true;
|
||||
static constexpr std::string_view set_type = "sounds";
|
||||
};
|
||||
|
||||
/** All data of a sounds set. */
|
||||
struct SoundsSet : BaseSet<SoundsSet> {};
|
||||
|
||||
/** All data/functions related with replacing the base sounds */
|
||||
class BaseSounds : public BaseMedia<SoundsSet> {
|
||||
public:
|
||||
/** The set as saved in the config file. */
|
||||
static inline std::string ini_set;
|
||||
|
||||
};
|
||||
|
||||
#endif /* BASE_MEDIA_SOUNDS_H */
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
#include "video/video_driver.hpp"
|
||||
#include "window_func.h"
|
||||
#include "palette_func.h"
|
||||
|
||||
/* The type of set we're replacing */
|
||||
#define SET_TYPE "graphics"
|
||||
#include "base_media_func.h"
|
||||
#include "base_media_graphics.h"
|
||||
#include "base_media_sounds.h"
|
||||
|
@ -350,7 +347,6 @@ void GfxLoadSprites()
|
|||
}
|
||||
|
||||
GraphicsSet::GraphicsSet()
|
||||
: BaseSet<GraphicsSet, MAX_GFT, true>{}, palette{}, blitter{}
|
||||
{
|
||||
// instantiate here, because unique_ptr needs a complete type
|
||||
}
|
||||
|
@ -362,7 +358,7 @@ GraphicsSet::~GraphicsSet()
|
|||
|
||||
bool GraphicsSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename)
|
||||
{
|
||||
bool ret = this->BaseSet<GraphicsSet, MAX_GFT, true>::FillSetDetails(ini, path, full_filename, false);
|
||||
bool ret = this->BaseSet<GraphicsSet>::FillSetDetails(ini, path, full_filename, false);
|
||||
if (ret) {
|
||||
const IniGroup *metadata = ini.GetGroup("metadata");
|
||||
assert(metadata != nullptr); /* ret can't be true if metadata isn't present. */
|
||||
|
@ -474,8 +470,8 @@ MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir, size_t max_size)
|
|||
static const char * const _graphics_file_names[] = { "base", "logos", "arctic", "tropical", "toyland", "extra" };
|
||||
|
||||
/** Implementation */
|
||||
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
|
||||
/* static */ const char * const *BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names = _graphics_file_names;
|
||||
template <class T>
|
||||
/* static */ const char * const *BaseSet<T>::file_names = _graphics_file_names;
|
||||
|
||||
template <class Tbase_set>
|
||||
/* static */ bool BaseMedia<Tbase_set>::DetermineBestSet()
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include "string_func.h"
|
||||
|
||||
|
||||
/** The type of set we're replacing */
|
||||
#define SET_TYPE "music"
|
||||
#include "base_media_func.h"
|
||||
#include "base_media_music.h"
|
||||
#include "random_access_file_type.h"
|
||||
|
@ -82,8 +78,8 @@ static const char * const _music_file_names[] = {
|
|||
/** Make sure we aren't messing things up. */
|
||||
static_assert(lengthof(_music_file_names) == NUM_SONGS_AVAILABLE);
|
||||
|
||||
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
|
||||
/* static */ const char * const *BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names = _music_file_names;
|
||||
template <class T>
|
||||
/* static */ const char * const *BaseSet<T>::file_names = _music_file_names;
|
||||
|
||||
template <class Tbase_set>
|
||||
/* static */ const char *BaseMedia<Tbase_set>::GetExtension()
|
||||
|
@ -115,7 +111,7 @@ template <class Tbase_set>
|
|||
|
||||
bool MusicSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename)
|
||||
{
|
||||
bool ret = this->BaseSet<MusicSet, NUM_SONGS_AVAILABLE, false>::FillSetDetails(ini, path, full_filename);
|
||||
bool ret = this->BaseSet<MusicSet>::FillSetDetails(ini, path, full_filename);
|
||||
if (ret) {
|
||||
this->num_available = 0;
|
||||
const IniGroup *names = ini.GetGroup("names");
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
#include "window_func.h"
|
||||
#include "window_gui.h"
|
||||
#include "vehicle_base.h"
|
||||
|
||||
/* The type of set we're replacing */
|
||||
#define SET_TYPE "sounds"
|
||||
#include "base_media_func.h"
|
||||
#include "base_media_sounds.h"
|
||||
|
||||
|
@ -256,8 +253,8 @@ INSTANTIATE_BASE_MEDIA_METHODS(BaseMedia<SoundsSet>, SoundsSet)
|
|||
static const char * const _sound_file_names[] = { "samples" };
|
||||
|
||||
|
||||
template <class T, size_t Tnum_files, bool Tsearch_in_tars>
|
||||
/* static */ const char * const *BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names = _sound_file_names;
|
||||
template <class T>
|
||||
/* static */ const char * const *BaseSet<T>::file_names = _sound_file_names;
|
||||
|
||||
template <class Tbase_set>
|
||||
/* static */ const char *BaseMedia<Tbase_set>::GetExtension()
|
||||
|
|
Loading…
Reference in New Issue