1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Factors out and slightly generalises textual descriptions of ROM::Descriptions.

This commit is contained in:
Thomas Harte 2021-06-06 18:15:00 -04:00
parent 4494320238
commit 76335e5cf2
4 changed files with 96 additions and 22 deletions

View File

@ -10,6 +10,8 @@
#include <algorithm>
#include <cassert>
#include <iomanip>
#include <sstream>
using namespace ROM;
@ -198,6 +200,73 @@ std::optional<Description> Description::from_crc(uint32_t crc32) {
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) {
switch(name) {
default: assert(false); break;

View File

@ -141,9 +141,19 @@ struct Description {
/// Constructs the @c Description that correlates to @c 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);
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:
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)
@ -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();
struct Request {
Request(Name name, bool optional = false);
Request() {}
/// Forms the request that would be satisfied by @c this plus the right-hand side.
Request operator &&(const Request &);
/// Forms the request that would be satisfied by either @c this or the right-hand side.
Request operator ||(const 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.
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;
/// @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 {
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;
Request subtract(const ROM::Map &map) const;
bool empty();
private:
struct Node {
enum class Type {

View File

@ -113,6 +113,7 @@ struct ActivityObserver: public Activity::Observer {
ROM::Request missing_roms;
_machine.reset(Machine::MachineForTargets(_analyser.targets, CSROMFetcher(&missing_roms), error));
if(!_machine) {
// TODO.
[missingROMs appendFormat:@"Who told you?"];
/* for(const auto &missing_rom : missing_roms) {
CSMissingROM *rom = [[CSMissingROM alloc] init];

View File

@ -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) {
indent();
if(is_optional) std::cerr << "optionally, ";
std::cerr << rom.machine_name << '/' << rom.file_names[0];
if(!rom.descriptive_name.empty() || !rom.crc32s.empty()) {
std::cerr << " (";
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 << ")";
}
using DescriptionFlag = ROM::Description::DescriptionFlag;
std::cerr << rom.description(DescriptionFlag::Filename | DescriptionFlag::CRC);
if(remaining) {
std::cerr << ";";