1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-11 08:30:55 +00:00

Switch to a non-macro route for startup declarations.

This commit is contained in:
Thomas Harte 2024-12-07 10:15:38 -06:00
parent a128247ef5
commit b15a083a15
43 changed files with 609 additions and 529 deletions

View File

@ -23,14 +23,16 @@ struct ElectronTarget: public ::Analyser::Static::Target, public Reflection::Str
bool should_shift_restart = false;
std::string loading_command;
ElectronTarget() : Analyser::Static::Target(Machine::Electron) {
if(needs_declare()) {
DeclareField(has_pres_adfs);
DeclareField(has_acorn_adfs);
DeclareField(has_dfs);
DeclareField(has_ap6_rom);
DeclareField(has_sideways_ram);
}
ElectronTarget() : Analyser::Static::Target(Machine::Electron) {}
private:
friend Reflection::StructImpl<ElectronTarget>;
void declare_fields() {
DeclareField(has_pres_adfs);
DeclareField(has_acorn_adfs);
DeclareField(has_dfs);
DeclareField(has_ap6_rom);
DeclareField(has_sideways_ram);
}
};

View File

@ -28,13 +28,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
ChipRAM chip_ram = ChipRAM::FiveHundredAndTwelveKilobytes;
FastRAM fast_ram = FastRAM::EightMegabytes;
Target() : Analyser::Static::Target(Machine::Amiga) {
if(needs_declare()) {
DeclareField(fast_ram);
DeclareField(chip_ram);
AnnounceEnum(FastRAM);
AnnounceEnum(ChipRAM);
}
Target() : Analyser::Static::Target(Machine::Amiga) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(fast_ram);
DeclareField(chip_ram);
AnnounceEnum(FastRAM);
AnnounceEnum(ChipRAM);
}
};

View File

@ -26,13 +26,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
// This is used internally for testing; it therefore isn't exposed reflectively.
bool catch_ssm_codes = false;
Target() : Analyser::Static::Target(Machine::AmstradCPC) {
if(needs_declare()) {
DeclareField(model);
DeclareField(crtc_type);
AnnounceEnum(Model);
AnnounceEnum(CRTCType);
}
Target() : Analyser::Static::Target(Machine::AmstradCPC) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(model);
DeclareField(crtc_type);
AnnounceEnum(Model);
AnnounceEnum(CRTCType);
}
};

View File

@ -36,17 +36,19 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
SCSIController scsi_controller = SCSIController::None;
bool has_mockingboard = true;
Target() : Analyser::Static::Target(Machine::AppleII) {
if(needs_declare()) {
DeclareField(model);
DeclareField(disk_controller);
DeclareField(scsi_controller);
DeclareField(has_mockingboard);
Target() : Analyser::Static::Target(Machine::AppleII) {}
AnnounceEnum(Model);
AnnounceEnum(DiskController);
AnnounceEnum(SCSIController);
}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(model);
DeclareField(disk_controller);
DeclareField(scsi_controller);
DeclareField(has_mockingboard);
AnnounceEnum(Model);
AnnounceEnum(DiskController);
AnnounceEnum(SCSIController);
}
};

View File

@ -29,13 +29,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
Model model = Model::ROM01;
MemoryModel memory_model = MemoryModel::EightMB;
Target() : Analyser::Static::Target(Machine::AppleIIgs) {
if(needs_declare()) {
DeclareField(model);
DeclareField(memory_model);
AnnounceEnum(Model);
AnnounceEnum(MemoryModel);
}
Target() : Analyser::Static::Target(Machine::AppleIIgs) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(model);
DeclareField(memory_model);
AnnounceEnum(Model);
AnnounceEnum(MemoryModel);
}
};

View File

@ -20,11 +20,13 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
FourMegabytes);
MemorySize memory_size = MemorySize::OneMegabyte;
Target() : Analyser::Static::Target(Machine::AtariST) {
if(needs_declare()) {
DeclareField(memory_size);
AnnounceEnum(MemorySize);
}
Target() : Analyser::Static::Target(Machine::AtariST) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(memory_size);
AnnounceEnum(MemorySize);
}
};

View File

@ -171,8 +171,8 @@ private:
std::vector<File> Analyser::Static::Commodore::GetFiles(const std::shared_ptr<Storage::Disk::Disk> &disk) {
std::vector<File> files;
CommodoreGCRParser parser;
parser.set_disk(disk);
auto parser = std::make_unique<CommodoreGCRParser>();
parser->set_disk(disk);
// Assemble directory.
std::vector<uint8_t> directory;
@ -180,7 +180,7 @@ std::vector<File> Analyser::Static::Commodore::GetFiles(const std::shared_ptr<St
uint8_t next_sector = 1;
directory.reserve(20 * 1024); // Probably more than plenty.
while(true) {
auto sector = parser.sector(next_track, next_sector);
auto sector = parser->sector(next_track, next_sector);
if(!sector) break;
directory.insert(directory.end(), sector->data.begin(), sector->data.end());
next_track = sector->data[0];
@ -222,7 +222,7 @@ std::vector<File> Analyser::Static::Commodore::GetFiles(const std::shared_ptr<St
bool is_first_sector = true;
while(next_track) {
auto sector = parser.sector(next_track, next_sector);
auto sector = parser->sector(next_track, next_sector);
if(!sector) break;
next_track = sector->data[0];

View File

@ -57,7 +57,8 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
Target() : Analyser::Static::Target(Machine::Vic20) {}
private:
BEGIN_DECLARATIONS
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(enabled_ram.bank0);
DeclareField(enabled_ram.bank1);
DeclareField(enabled_ram.bank2);
@ -66,7 +67,7 @@ private:
DeclareField(region);
DeclareField(has_c1540);
AnnounceEnum(Region);
END_DECLARATIONS
}
};
}

View File

@ -30,20 +30,22 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
Speed speed = Speed::FourMHz;
std::string loading_command;
Target() : Analyser::Static::Target(Machine::Enterprise) {
if(needs_declare()) {
AnnounceEnum(Model);
AnnounceEnum(EXOSVersion);
AnnounceEnum(BASICVersion);
AnnounceEnum(DOS);
AnnounceEnum(Speed);
Target() : Analyser::Static::Target(Machine::Enterprise) {}
DeclareField(model);
DeclareField(exos_version);
DeclareField(basic_version);
DeclareField(dos);
DeclareField(speed);
}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
AnnounceEnum(Model);
AnnounceEnum(EXOSVersion);
AnnounceEnum(BASICVersion);
AnnounceEnum(DOS);
AnnounceEnum(Speed);
DeclareField(model);
DeclareField(exos_version);
DeclareField(basic_version);
DeclareField(dos);
DeclareField(speed);
}
};

View File

@ -33,15 +33,17 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl<
);
Region region = Region::USA;
Target(): Analyser::Static::Target(Machine::MSX) {
if(needs_declare()) {
DeclareField(has_disk_drive);
DeclareField(has_msx_music);
DeclareField(region);
AnnounceEnum(Region);
DeclareField(model);
AnnounceEnum(Model);
}
Target(): Analyser::Static::Target(Machine::MSX) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(has_disk_drive);
DeclareField(has_msx_music);
DeclareField(region);
AnnounceEnum(Region);
DeclareField(model);
AnnounceEnum(Model);
}
};

View File

@ -18,12 +18,13 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
ReflectableEnum(Model, Mac128k, Mac512k, Mac512ke, MacPlus);
Model model = Model::MacPlus;
Target() : Analyser::Static::Target(Machine::Macintosh) {
// Boilerplate for declaring fields and potential values.
if(needs_declare()) {
DeclareField(model);
AnnounceEnum(Model);
}
Target() : Analyser::Static::Target(Machine::Macintosh) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(model);
AnnounceEnum(Model);
}
};

View File

@ -41,15 +41,17 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
std::string loading_command;
bool should_start_jasmin = false;
Target(): Analyser::Static::Target(Machine::Oric) {
if(needs_declare()) {
DeclareField(rom);
DeclareField(disk_interface);
DeclareField(processor);
AnnounceEnum(ROM);
AnnounceEnum(DiskInterface);
AnnounceEnum(Processor);
}
Target(): Analyser::Static::Target(Machine::Oric) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(rom);
DeclareField(disk_interface);
DeclareField(processor);
AnnounceEnum(ROM);
AnnounceEnum(DiskInterface);
AnnounceEnum(Processor);
}
};

View File

@ -24,13 +24,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
Fast);
Speed speed = Speed::Fast;
Target() : Analyser::Static::Target(Machine::PCCompatible) {
if(needs_declare()) {
AnnounceEnum(VideoAdaptor);
AnnounceEnum(Speed);
DeclareField(adaptor);
DeclareField(speed);
}
Target() : Analyser::Static::Target(Machine::PCCompatible) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
AnnounceEnum(VideoAdaptor);
AnnounceEnum(Speed);
DeclareField(adaptor);
DeclareField(speed);
}
};

View File

@ -37,11 +37,13 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
Region region = Region::Japan;
PagingScheme paging_scheme = PagingScheme::Sega;
Target() : Analyser::Static::Target(Machine::MasterSystem) {
if(needs_declare()) {
DeclareField(region);
AnnounceEnum(Region);
}
Target() : Analyser::Static::Target(Machine::MasterSystem) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(region);
AnnounceEnum(Region);
}
};

View File

@ -27,13 +27,15 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl<
bool ZX80_uses_ZX81_ROM = false;
std::string loading_command;
Target(): Analyser::Static::Target(Machine::ZX8081) {
if(needs_declare()) {
DeclareField(memory_model);
DeclareField(is_ZX81);
DeclareField(ZX80_uses_ZX81_ROM);
AnnounceEnum(MemoryModel);
}
Target(): Analyser::Static::Target(Machine::ZX8081) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(memory_model);
DeclareField(is_ZX81);
DeclareField(ZX80_uses_ZX81_ROM);
AnnounceEnum(MemoryModel);
}
};

View File

@ -27,11 +27,13 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl<
Model model = Model::Plus2;
bool should_hold_enter = false;
Target(): Analyser::Static::Target(Machine::ZXSpectrum) {
if(needs_declare()) {
DeclareField(model);
AnnounceEnum(Model);
}
Target(): Analyser::Static::Target(Machine::ZXSpectrum) {}
private:
friend Reflection::StructImpl<Target>;
void declare_fields() {
DeclareField(model);
AnnounceEnum(Model);
}
};

View File

@ -223,13 +223,6 @@ struct State: public Reflection::StructImpl<State> {
// TODO: all audio-production thread state.
State() {
if(needs_declare()) {
DeclareField(registers);
DeclareField(selected_register);
}
}
template <typename AY> void apply(AY &target) {
// Establish emulator-thread state
for(uint8_t c = 0; c < 16; c++) {
@ -238,6 +231,13 @@ struct State: public Reflection::StructImpl<State> {
}
target.select_register(selected_register);
}
private:
friend Reflection::StructImpl<State>;
void declare_fields() {
DeclareField(registers);
DeclareField(selected_register);
}
};
}

View File

@ -17,24 +17,25 @@
namespace Archimedes {
class Machine {
public:
virtual ~Machine() = default;
static std::unique_ptr<Machine> Archimedes(
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> Archimedes(
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
if(needs_declare()) {
declare_quickload_option();
}
}
};
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_quickload_option();
}
};
};
}

View File

@ -23,28 +23,31 @@ namespace Electron {
@discussion An instance of Electron::Machine represents the current state of an
Acorn Electron.
*/
class Machine {
struct Machine {
virtual ~Machine() = default;
/// Creates and returns an Electron.
static std::unique_ptr<Machine> Electron(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
/// Defines the runtime options available for an Electron.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
virtual ~Machine() = default;
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
/// Creates and returns an Electron.
static std::unique_ptr<Machine> Electron(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
/// Defines the runtime options available for an Electron.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
if(needs_declare()) {
declare_display_option();
declare_quickload_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
declare_quickload_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
}
};
};
}

View File

@ -15,12 +15,11 @@
namespace Amiga {
class Machine {
public:
virtual ~Machine() = default;
struct Machine {
virtual ~Machine() = default;
/// Creates and returns an Amiga.
static std::unique_ptr<Machine> Amiga(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
/// Creates and returns an Amiga.
static std::unique_ptr<Machine> Amiga(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
};
}

View File

@ -20,41 +20,44 @@ namespace AmstradCPC {
/*!
Models an Amstrad CPC.
*/
class Machine {
struct Machine {
virtual ~Machine() = default;
/// Creates and returns an Amstrad CPC.
static std::unique_ptr<Machine> AmstradCPC(
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
/// Defines the runtime options available for an Amstrad CPC.
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
{
public:
virtual ~Machine() = default;
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(Configurable::Display::RGB),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
/// Creates and returns an Amstrad CPC.
static std::unique_ptr<Machine> AmstradCPC(
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
private:
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
/// Defines the runtime options available for an Amstrad CPC.
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(Configurable::Display::RGB),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly)
{
if(needs_declare()) {
declare_display_option();
declare_quickload_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
}
};
Options() : Options(Configurable::OptionsType::UserFriendly) {}
struct SSMDelegate {
virtual void perform(uint16_t) = 0;
};
virtual void set_ssm_delegate(SSMDelegate *) = 0;
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
declare_quickload_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
};
struct SSMDelegate {
virtual void perform(uint16_t) = 0;
};
virtual void set_ssm_delegate(SSMDelegate *) = 0;
};
}

View File

@ -17,27 +17,30 @@
namespace Apple::II {
class Machine {
struct Machine {
virtual ~Machine() = default;
/// Creates and returns an AppleII.
static std::unique_ptr<Machine> AppleII(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
/// Defines the runtime options available for an Apple II.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
virtual ~Machine() = default;
bool use_square_pixels = false;
/// Creates and returns an AppleII.
static std::unique_ptr<Machine> AppleII(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
Options(Configurable::OptionsType) :
Configurable::DisplayOption<Options>(Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
/// Defines the runtime options available for an Apple II.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
bool use_square_pixels = false;
Options(Configurable::OptionsType) : Configurable::DisplayOption<Options>(Configurable::Display::CompositeColour) {
if(needs_declare()) {
DeclareField(use_square_pixels);
declare_display_option();
limit_enum(&output, Configurable::Display::CompositeMonochrome, Configurable::Display::CompositeColour, -1);
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
DeclareField(use_square_pixels);
declare_display_option();
limit_enum(&output, Configurable::Display::CompositeMonochrome, Configurable::Display::CompositeColour, -1);
}
};
};
}

View File

@ -17,12 +17,11 @@
namespace Apple::IIgs {
class Machine {
public:
virtual ~Machine() = default;
struct Machine {
virtual ~Machine() = default;
/// Creates and returns an AppleIIgs.
static std::unique_ptr<Machine> AppleIIgs(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
/// Creates and returns an AppleIIgs.
static std::unique_ptr<Machine> AppleIIgs(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
};
}

View File

@ -15,23 +15,25 @@
namespace Apple::Macintosh {
class Machine {
struct Machine {
virtual ~Machine() = default;
/// Creates and returns a Macintosh.
static std::unique_ptr<Machine> Macintosh(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickbootOption<Options> {
friend Configurable::QuickbootOption<Options>;
public:
virtual ~Machine() = default;
Options(Configurable::OptionsType type) :
Configurable::QuickbootOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
/// Creates and returns a Macintosh.
static std::unique_ptr<Machine> Macintosh(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickbootOption<Options> {
friend Configurable::QuickbootOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::QuickbootOption<Options>(type == Configurable::OptionsType::UserFriendly) {
if(needs_declare()) {
declare_quickboot_option();
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_quickboot_option();
}
};
};
}

View File

@ -21,8 +21,7 @@ namespace Atari2600 {
/*!
Models an Atari 2600.
*/
class Machine {
public:
struct Machine {
virtual ~Machine() = default;
/// Creates and returns an Atari 2600 on the heap.

View File

@ -17,23 +17,27 @@
namespace Atari::ST {
class Machine {
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> AtariST(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
virtual ~Machine() = default;
Options(Configurable::OptionsType type) : Configurable::DisplayOption<Options>(
type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
static std::unique_ptr<Machine> AtariST(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType type) : Configurable::DisplayOption<Options>(
type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {
if(needs_declare()) {
declare_display_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
};
};
}

View File

@ -17,22 +17,26 @@
namespace Coleco::Vision {
class Machine {
public:
virtual ~Machine() = default;
static std::unique_ptr<Machine> ColecoVision(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> ColecoVision(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::SVideo : Configurable::Display::CompositeColour) {
if(needs_declare()) {
declare_display_option();
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
}
}
};
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::SVideo : Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
}
};
};
}

View File

@ -15,8 +15,7 @@
namespace Commodore::Plus4 {
class Machine {
public:
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> Plus4(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);

View File

@ -20,26 +20,34 @@ namespace Commodore::Vic20 {
/// @returns The options available for a Vic-20.
std::unique_ptr<Reflection::Struct> get_options();
class Machine {
public:
struct Machine {
virtual ~Machine() = default;
/// Creates and returns a Vic-20.
static std::unique_ptr<Machine> Vic20(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::SVideo : Configurable::Display::CompositeColour),
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::SVideo : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
if(needs_declare()) {
declare_display_option();
declare_quickload_option();
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
}
}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
declare_quickload_option();
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
}
};
};

View File

@ -23,23 +23,26 @@ namespace Enterprise {
@discussion An instance of Enterprise::Machine represents the current state of an
Elan Enterprise.
*/
class Machine {
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> Enterprise(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
/// Defines the runtime options available for an Enterprise.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
virtual ~Machine() = default;
static std::unique_ptr<Machine> Enterprise(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
/// Defines the runtime options available for an Enterprise.
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {
if(needs_declare()) {
declare_display_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
}
}
};
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
}
};
};
};

View File

@ -17,24 +17,31 @@
namespace MSX {
class Machine {
public:
virtual ~Machine() = default;
static std::unique_ptr<Machine> MSX(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> MSX(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
if(needs_declare()) {
declare_display_option();
declare_quickload_option();
}
}
};
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
declare_quickload_option();
}
};
};
}

View File

@ -17,21 +17,25 @@
namespace Sega::MasterSystem {
class Machine {
public:
virtual ~Machine() = default;
static std::unique_ptr<Machine> MasterSystem(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> MasterSystem(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {
if(needs_declare()) {
declare_display_option();
}
}
};
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
}
};
};
}

View File

@ -20,26 +20,32 @@ namespace Oric {
/*!
Models an Oric 1/Atmos with or without a Microdisc.
*/
class Machine {
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> Oric(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
virtual ~Machine() = default;
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
/// Creates and returns an Oric.
static std::unique_ptr<Machine> Oric(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
if(needs_declare()) {
declare_display_option();
declare_quickload_option();
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
declare_quickload_option();
}
};
};
}

View File

@ -18,32 +18,34 @@ namespace PCCompatible {
/*!
Models a PC compatible.
*/
class Machine {
struct Machine {
virtual ~Machine() = default;
/// Creates and returns a PC Compatible.
static std::unique_ptr<Machine> PCCompatible(
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
/// Defines the runtime options [sometimes] available for a PC.
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>
{
friend Configurable::DisplayOption<Options>;
public:
virtual ~Machine() = default;
Options(Configurable::OptionsType) :
Configurable::DisplayOption<Options>(Configurable::Display::RGB) {}
/// Creates and returns a PC Compatible.
static std::unique_ptr<Machine> PCCompatible(
const Analyser::Static::Target *target,
const ROMMachine::ROMFetcher &rom_fetcher
);
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
/// Defines the runtime options [sometimes] available for a PC.
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>
{
friend Configurable::DisplayOption<Options>;
public:
Options(Configurable::OptionsType) :
Configurable::DisplayOption<Options>(Configurable::Display::RGB)
{
if(needs_declare()) {
declare_display_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
declare_display_option();
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
}
};
};
}

View File

@ -18,31 +18,32 @@
namespace Sinclair::ZX8081 {
/// The ZX80/81 machine.
class Machine {
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> ZX8081(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
virtual void set_tape_is_playing(bool is_playing) = 0;
virtual bool get_tape_is_playing() = 0;
/// Defines the runtime options available for a ZX80/81.
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::QuickloadOption<Options>;
public:
virtual ~Machine() = default;
static std::unique_ptr<Machine> ZX8081(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
bool automatic_tape_motor_control = true;
virtual void set_tape_is_playing(bool is_playing) = 0;
virtual bool get_tape_is_playing() = 0;
Options(Configurable::OptionsType type):
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {}
/// Defines the runtime options available for a ZX80/81.
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::QuickloadOption<Options>;
public:
bool automatic_tape_motor_control = true;
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options(Configurable::OptionsType type):
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {
// Declare fields if necessary.
if(needs_declare()) {
DeclareField(automatic_tape_motor_control);
declare_quickload_option();
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
DeclareField(automatic_tape_motor_control);
declare_quickload_option();
}
};
};
}

View File

@ -32,15 +32,15 @@ struct State: public Reflection::StructImpl<State> {
// Meaningful for the +2a and +3 only.
uint8_t last_1ffd = 0;
State() {
if(needs_declare()) {
DeclareField(z80);
DeclareField(video);
DeclareField(ram);
DeclareField(last_7ffd);
DeclareField(last_1ffd);
DeclareField(ay);
}
private:
friend Reflection::StructImpl<State>;
void declare_fields() {
DeclareField(z80);
DeclareField(video);
DeclareField(ram);
DeclareField(last_7ffd);
DeclareField(last_1ffd);
DeclareField(ay);
}
};

View File

@ -455,15 +455,7 @@ struct State: public Reflection::StructImpl<State> {
int flash_counter = 0;
bool is_alternate_line = false;
State() {
if(needs_declare()) {
DeclareField(border_colour);
DeclareField(half_cycles_since_interrupt);
DeclareField(flash);
DeclareField(flash_counter);
DeclareField(is_alternate_line);
}
}
State() {}
template <typename Video> State(const Video &source) : State() {
border_colour = source.border_byte_;
@ -480,6 +472,16 @@ struct State: public Reflection::StructImpl<State> {
target.is_alternate_line_ = is_alternate_line;
target.set_time_since_interrupt(HalfCycles(half_cycles_since_interrupt));
}
private:
friend Reflection::StructImpl<State>;
void declare_fields() {
DeclareField(border_colour);
DeclareField(half_cycles_since_interrupt);
DeclareField(flash);
DeclareField(flash_counter);
DeclareField(is_alternate_line);
}
};
}

View File

@ -17,32 +17,38 @@
namespace Sinclair::ZXSpectrum {
class Machine {
struct Machine {
virtual ~Machine() = default;
static std::unique_ptr<Machine> ZXSpectrum(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
virtual void set_tape_is_playing(bool is_playing) = 0;
virtual bool get_tape_is_playing() = 0;
class Options:
public Reflection::StructImpl<Options>,
public Configurable::DisplayOption<Options>,
public Configurable::QuickloadOption<Options>
{
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
virtual ~Machine() = default;
static std::unique_ptr<Machine> ZXSpectrum(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
bool automatic_tape_motor_control = true;
virtual void set_tape_is_playing(bool is_playing) = 0;
virtual bool get_tape_is_playing() = 0;
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {}
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
friend Configurable::DisplayOption<Options>;
friend Configurable::QuickloadOption<Options>;
public:
bool automatic_tape_motor_control = true;
private:
Options() : Options(Configurable::OptionsType::UserFriendly) {}
Options(Configurable::OptionsType type) :
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly)
{
if(needs_declare()) {
DeclareField(automatic_tape_motor_control);
declare_display_option();
declare_quickload_option();
}
}
};
friend Reflection::StructImpl<Options>;
void declare_fields() {
DeclareField(automatic_tape_motor_control);
declare_display_option();
declare_quickload_option();
}
};
};
}

View File

@ -83,43 +83,35 @@ void State::apply(ProcessorBase &target) {
}
// Boilerplate follows here, to establish 'reflection'.
State::State() {
if(needs_declare()) {
DeclareField(registers);
DeclareField(execution_state);
DeclareField(inputs);
}
void State::declare_fields() {
DeclareField(registers);
DeclareField(execution_state);
DeclareField(inputs);
}
State::Registers::Registers() {
if(needs_declare()) {
DeclareField(program_counter);
DeclareField(stack_pointer);
DeclareField(flags);
DeclareField(a);
DeclareField(x);
DeclareField(y);
}
void State::Registers::declare_fields() {
DeclareField(program_counter);
DeclareField(stack_pointer);
DeclareField(flags);
DeclareField(a);
DeclareField(x);
DeclareField(y);
}
State::ExecutionState::ExecutionState() {
if(needs_declare()) {
AnnounceEnum(Phase);
DeclareField(phase);
DeclareField(micro_program);
DeclareField(micro_program_offset);
DeclareField(operation);
DeclareField(operand);
DeclareField(address);
DeclareField(next_address);
}
void State::ExecutionState::declare_fields() {
AnnounceEnum(Phase);
DeclareField(phase);
DeclareField(micro_program);
DeclareField(micro_program_offset);
DeclareField(operation);
DeclareField(operand);
DeclareField(address);
DeclareField(next_address);
}
State::Inputs::Inputs() {
if(needs_declare()) {
DeclareField(ready);
DeclareField(irq);
DeclareField(nmi);
DeclareField(reset);
}
void State::Inputs::declare_fields() {
DeclareField(ready);
DeclareField(irq);
DeclareField(nmi);
DeclareField(reset);
}

View File

@ -31,7 +31,9 @@ struct State: public Reflection::StructImpl<State> {
uint8_t flags;
uint8_t a, x, y;
Registers();
private:
friend Reflection::StructImpl<Registers>;
void declare_fields();
} registers;
/*!
@ -44,7 +46,9 @@ struct State: public Reflection::StructImpl<State> {
bool nmi;
bool reset;
Inputs();
private:
friend Reflection::StructImpl<Inputs>;
void declare_fields();
} inputs;
/*!
@ -74,17 +78,22 @@ struct State: public Reflection::StructImpl<State> {
uint8_t operation, operand;
uint16_t address, next_address;
ExecutionState();
private:
friend Reflection::StructImpl<ExecutionState>;
void declare_fields();
} execution_state;
/// Default constructor; makes no guarantees as to field values beyond those given above.
State();
State() {}
/// Instantiates a new State based on the processor @c src.
State(const ProcessorBase &src);
State(const ProcessorBase &);
/// Applies this state to @c target.
void apply(ProcessorBase &target);
void apply(ProcessorBase &);
private:
friend Reflection::StructImpl<State>;
void declare_fields();
};
}

View File

@ -164,62 +164,54 @@ void State::apply(ProcessorBase &target) {
}
// Boilerplate follows here, to establish 'reflection'.
State::State() {
if(needs_declare()) {
DeclareField(registers);
DeclareField(execution_state);
DeclareField(inputs);
}
void State::declare_fields() {
DeclareField(registers);
DeclareField(execution_state);
DeclareField(inputs);
}
State::Registers::Registers() {
if(needs_declare()) {
DeclareField(a);
DeclareField(flags);
DeclareField(bc);
DeclareField(de);
DeclareField(hl);
DeclareField(af_dash); // TODO: is there any disadvantage to declaring these for reflective
DeclareField(bc_dash); // purposes as AF', BC', etc?
DeclareField(de_dash);
DeclareField(hl_dash);
DeclareField(ix);
DeclareField(iy);
DeclareField(ir);
DeclareField(program_counter);
DeclareField(stack_pointer);
DeclareField(interrupt_mode);
DeclareField(iff1);
DeclareField(iff2);
DeclareField(memptr);
}
void State::Registers::declare_fields() {
DeclareField(a);
DeclareField(flags);
DeclareField(bc);
DeclareField(de);
DeclareField(hl);
DeclareField(af_dash); // TODO: is there any disadvantage to declaring these for reflective
DeclareField(bc_dash); // purposes as AF', BC', etc?
DeclareField(de_dash);
DeclareField(hl_dash);
DeclareField(ix);
DeclareField(iy);
DeclareField(ir);
DeclareField(program_counter);
DeclareField(stack_pointer);
DeclareField(interrupt_mode);
DeclareField(iff1);
DeclareField(iff2);
DeclareField(memptr);
}
State::ExecutionState::ExecutionState() {
if(needs_declare()) {
DeclareField(is_halted);
DeclareField(requests);
DeclareField(last_requests);
DeclareField(temp8);
DeclareField(operation);
DeclareField(temp16);
DeclareField(flag_adjustment_history);
DeclareField(pc_increment);
DeclareField(refresh_address);
void State::ExecutionState::declare_fields() {
DeclareField(is_halted);
DeclareField(requests);
DeclareField(last_requests);
DeclareField(temp8);
DeclareField(operation);
DeclareField(temp16);
DeclareField(flag_adjustment_history);
DeclareField(pc_increment);
DeclareField(refresh_address);
AnnounceEnum(Phase);
DeclareField(phase);
DeclareField(half_cycles_into_step);
DeclareField(steps_into_phase);
DeclareField(instruction_page);
}
AnnounceEnum(Phase);
DeclareField(phase);
DeclareField(half_cycles_into_step);
DeclareField(steps_into_phase);
DeclareField(instruction_page);
}
State::Inputs::Inputs() {
if(needs_declare()) {
DeclareField(irq);
DeclareField(nmi);
DeclareField(bus_request);
DeclareField(wait);
}
void State::Inputs::declare_fields() {
DeclareField(irq);
DeclareField(nmi);
DeclareField(bus_request);
DeclareField(wait);
}

View File

@ -37,7 +37,9 @@ struct State: public Reflection::StructImpl<State> {
int interrupt_mode;
bool iff1, iff2;
Registers();
private:
friend Reflection::StructImpl<Registers>;
void declare_fields();
} registers;
/*!
@ -50,7 +52,9 @@ struct State: public Reflection::StructImpl<State> {
bool bus_request = false;
bool wait = false;
Inputs();
private:
friend Reflection::StructImpl<Inputs>;
void declare_fields();
} inputs;
/*!
@ -80,17 +84,22 @@ struct State: public Reflection::StructImpl<State> {
int steps_into_phase = 0;
uint16_t instruction_page = 0;
ExecutionState();
private:
friend Reflection::StructImpl<ExecutionState>;
void declare_fields();
} execution_state;
/// Default constructor; makes no guarantees as to field values beyond those given above.
State();
State() {}
/// Instantiates a new State based on the processor @c src.
State(const ProcessorBase &src);
/// Applies this state to @c target.
void apply(ProcessorBase &target);
private:
friend Reflection::StructImpl<State>;
void declare_fields();
};
}

View File

@ -27,12 +27,6 @@ namespace Reflection {
#define DeclareField(Name) declare(&Name, #Name)
#define BEGIN_DECLARATIONS void declare_fields() {
#define END_DECLARATIONS } \
struct Declarer { Declarer() { Target t; t.declare_fields(); } }; \
static Declarer declarer;
struct Struct {
virtual std::vector<std::string> all_keys() const = 0;
virtual const std::type_info *type_of(const std::string &name) const = 0;
@ -248,9 +242,8 @@ protected:
declare_field(&field1, "field1");
declare_field(&field2, "field2");
Fields are registered in class storage. So callers can use needs_declare()
to determine whether a class of this type has already established the
reflective fields.
They should provide a default constructor and implement the method
declare_fields() to perform all declarations.
*/
/*!
@ -303,13 +296,6 @@ protected:
permitted_enum_values_.emplace(name, permitted_values);
}
/*!
@returns @c true if this subclass of @c Struct has not yet declared any fields.
*/
bool needs_declare() const {
return contents_.empty();
}
/*!
Performs a reverse lookup from field to name.
*/
@ -358,6 +344,15 @@ private:
};
static inline std::unordered_map<std::string, Field> contents_;
static inline std::unordered_map<std::string, std::vector<bool>> permitted_enum_values_;
// Ensure fields are declared at startup.
struct Declarer {
Declarer() {
Owner o;
o.declare_fields();
}
};
static Declarer declarer;
};