mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-11 08:23:43 +00:00
Factors out and slightly generalises textual descriptions of ROM::Descriptions.
This commit is contained in:
parent
4494320238
commit
76335e5cf2
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace ROM;
|
using namespace ROM;
|
||||||
|
|
||||||
@ -198,6 +200,73 @@ std::optional<Description> Description::from_crc(uint32_t crc32) {
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Description::description(int flags) const {
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
// Print the file name(s) and the descriptive name.
|
||||||
|
if(flags & DescriptionFlag::Filename) {
|
||||||
|
flags &= ~DescriptionFlag::Filename;
|
||||||
|
|
||||||
|
output << machine_name << '/';
|
||||||
|
if(file_names.size() == 1) {
|
||||||
|
output << file_names[0];
|
||||||
|
} else {
|
||||||
|
output << "{";
|
||||||
|
bool is_first = true;
|
||||||
|
for(const auto &file_name: file_names) {
|
||||||
|
if(!is_first) output << " or ";
|
||||||
|
output << file_name;
|
||||||
|
is_first = false;
|
||||||
|
}
|
||||||
|
output << "}";
|
||||||
|
}
|
||||||
|
output << " (" << descriptive_name;
|
||||||
|
if(!flags) {
|
||||||
|
output << ")";
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
output << "; ";
|
||||||
|
} else {
|
||||||
|
output << descriptive_name;
|
||||||
|
if(!flags) {
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
output << " (";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the size.
|
||||||
|
if(flags & DescriptionFlag::Size) {
|
||||||
|
flags &= ~DescriptionFlag::Size;
|
||||||
|
output << size << " bytes";
|
||||||
|
|
||||||
|
if(!flags) {
|
||||||
|
output << ")";
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
output << "; ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the CRC(s).
|
||||||
|
if(flags & DescriptionFlag::CRC) {
|
||||||
|
flags &= ~DescriptionFlag::CRC;
|
||||||
|
|
||||||
|
output << ((crc32s.size() > 1) ? "usual crc32s: " : "usual crc32: ");
|
||||||
|
bool is_first = true;
|
||||||
|
for(const auto crc32: crc32s) {
|
||||||
|
if(!is_first) output << ", ";
|
||||||
|
is_first = false;
|
||||||
|
output << std::hex << std::setfill('0') << std::setw(8) << crc32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!flags) {
|
||||||
|
output << ")";
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
|
||||||
Description::Description(Name name) {
|
Description::Description(Name name) {
|
||||||
switch(name) {
|
switch(name) {
|
||||||
default: assert(false); break;
|
default: assert(false); break;
|
||||||
|
@ -141,9 +141,19 @@ struct Description {
|
|||||||
/// Constructs the @c Description that correlates to @c name.
|
/// Constructs the @c Description that correlates to @c name.
|
||||||
Description(Name name);
|
Description(Name name);
|
||||||
|
|
||||||
/// Constructs the @c Description that correlates to @c crc32.
|
/// Constructs the @c Description that correlates to @c crc32, if any.
|
||||||
static std::optional<Description> from_crc(uint32_t crc32);
|
static std::optional<Description> from_crc(uint32_t crc32);
|
||||||
|
|
||||||
|
enum DescriptionFlag {
|
||||||
|
Size = 1 << 0,
|
||||||
|
CRC = 1 << 1,
|
||||||
|
Filename = 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Provides a single-line of text describing this ROM, including the usual base text
|
||||||
|
/// plus all the fields provided as @c flags .
|
||||||
|
std::string description(int flags) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename FileNameT, typename CRC32T> Description(
|
template <typename FileNameT, typename CRC32T> Description(
|
||||||
Name name, std::string machine_name, std::string descriptive_name, FileNameT file_names, size_t size, CRC32T crc32s = uint32_t(0)
|
Name name, std::string machine_name, std::string descriptive_name, FileNameT file_names, size_t size, CRC32T crc32s = uint32_t(0)
|
||||||
@ -157,13 +167,18 @@ struct Description {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @returns a vector of all possible instances of ROM::Description — i.e. descriptions of every ROM
|
||||||
|
/// currently known to the ROM catalogue.
|
||||||
std::vector<Description> all_descriptions();
|
std::vector<Description> all_descriptions();
|
||||||
|
|
||||||
struct Request {
|
struct Request {
|
||||||
Request(Name name, bool optional = false);
|
Request(Name name, bool optional = false);
|
||||||
Request() {}
|
Request() {}
|
||||||
|
|
||||||
|
/// Forms the request that would be satisfied by @c this plus the right-hand side.
|
||||||
Request operator &&(const Request &);
|
Request operator &&(const Request &);
|
||||||
|
|
||||||
|
/// Forms the request that would be satisfied by either @c this or the right-hand side.
|
||||||
Request operator ||(const Request &);
|
Request operator ||(const Request &);
|
||||||
|
|
||||||
/// Inspects the ROMMap to ensure that it satisfies this @c Request.
|
/// Inspects the ROMMap to ensure that it satisfies this @c Request.
|
||||||
@ -172,8 +187,16 @@ struct Request {
|
|||||||
/// All ROMs in the map will be resized to their idiomatic sizes.
|
/// All ROMs in the map will be resized to their idiomatic sizes.
|
||||||
bool validate(Map &) const;
|
bool validate(Map &) const;
|
||||||
|
|
||||||
|
/// Returns a flattened array of all @c ROM::Descriptions that relate to anything
|
||||||
|
/// anywhere in this ROM request.
|
||||||
std::vector<Description> all_descriptions() const;
|
std::vector<Description> all_descriptions() const;
|
||||||
|
|
||||||
|
/// @returns @c true if this request is empty, i.e. would be satisfied with no ROMs; @c false otherwise.
|
||||||
|
bool empty();
|
||||||
|
|
||||||
|
/// @returns what remains of this ROM request given that everything in @c map has been found.
|
||||||
|
Request subtract(const ROM::Map &map) const;
|
||||||
|
|
||||||
enum class ListType {
|
enum class ListType {
|
||||||
Any, All, Single
|
Any, All, Single
|
||||||
};
|
};
|
||||||
@ -183,9 +206,6 @@ struct Request {
|
|||||||
const std::function<void(ROM::Request::ListType type, const ROM::Description &, bool is_optional, size_t remaining)> &add_item
|
const std::function<void(ROM::Request::ListType type, const ROM::Description &, bool is_optional, size_t remaining)> &add_item
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
Request subtract(const ROM::Map &map) const;
|
|
||||||
bool empty();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Node {
|
struct Node {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
|
@ -113,6 +113,7 @@ struct ActivityObserver: public Activity::Observer {
|
|||||||
ROM::Request missing_roms;
|
ROM::Request missing_roms;
|
||||||
_machine.reset(Machine::MachineForTargets(_analyser.targets, CSROMFetcher(&missing_roms), error));
|
_machine.reset(Machine::MachineForTargets(_analyser.targets, CSROMFetcher(&missing_roms), error));
|
||||||
if(!_machine) {
|
if(!_machine) {
|
||||||
|
// TODO.
|
||||||
[missingROMs appendFormat:@"Who told you?"];
|
[missingROMs appendFormat:@"Who told you?"];
|
||||||
/* for(const auto &missing_rom : missing_roms) {
|
/* for(const auto &missing_rom : missing_roms) {
|
||||||
CSMissingROM *rom = [[CSMissingROM alloc] init];
|
CSMissingROM *rom = [[CSMissingROM alloc] init];
|
||||||
|
@ -798,25 +798,9 @@ int main(int argc, char *argv[]) {
|
|||||||
}, [&indentation_level, indent] (ROM::Request::ListType type, const ROM::Description &rom, bool is_optional, size_t remaining) {
|
}, [&indentation_level, indent] (ROM::Request::ListType type, const ROM::Description &rom, bool is_optional, size_t remaining) {
|
||||||
indent();
|
indent();
|
||||||
if(is_optional) std::cerr << "optionally, ";
|
if(is_optional) std::cerr << "optionally, ";
|
||||||
std::cerr << rom.machine_name << '/' << rom.file_names[0];
|
|
||||||
|
|
||||||
if(!rom.descriptive_name.empty() || !rom.crc32s.empty()) {
|
using DescriptionFlag = ROM::Description::DescriptionFlag;
|
||||||
std::cerr << " (";
|
std::cerr << rom.description(DescriptionFlag::Filename | DescriptionFlag::CRC);
|
||||||
if(!rom.descriptive_name.empty()) {
|
|
||||||
std::cerr << rom.descriptive_name;
|
|
||||||
if(!rom.crc32s.empty()) std::cerr << "; ";
|
|
||||||
}
|
|
||||||
if(!rom.crc32s.empty()) {
|
|
||||||
std::cerr << ((rom.crc32s.size() > 1) ? "usual crc32s: " : "usual crc32: ");
|
|
||||||
bool is_first = true;
|
|
||||||
for(const auto crc32: rom.crc32s) {
|
|
||||||
if(!is_first) std::cerr << ", ";
|
|
||||||
is_first = false;
|
|
||||||
std::cerr << std::hex << std::setfill('0') << std::setw(8) << crc32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cerr << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(remaining) {
|
if(remaining) {
|
||||||
std::cerr << ";";
|
std::cerr << ";";
|
||||||
|
Loading…
Reference in New Issue
Block a user