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:
parent
4494320238
commit
76335e5cf2
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
@ -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 << ";";
|
||||
|
Loading…
Reference in New Issue
Block a user