1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-27 18:55:48 +00:00

Introduces a multimachine to handle multi-target static analyser outputs.

Non-functional as of yet.
This commit is contained in:
Thomas Harte 2018-01-28 22:22:21 -05:00
parent e025674eb2
commit d493ea4bca
11 changed files with 154 additions and 21 deletions

View File

@ -8,7 +8,7 @@
#include "ConfidenceCounter.hpp"
using namespace DynamicAnalyser;
using namespace Analyser::Dynamic;
float ConfidenceCounter::get_confidence() {
return static_cast<float>(hits_) / static_cast<float>(hits_ + misses_);

View File

@ -11,7 +11,8 @@
#include "ConfidenceSource.hpp"
namespace DynamicAnalyser {
namespace Analyser {
namespace Dynamic {
/*!
Provides a confidence source that calculates its probability by virtual of a history of events.
@ -40,6 +41,7 @@ class ConfidenceCounter: public ConfidenceSource {
int misses_ = 1;
};
}
}
#endif /* ConfidenceCounter_hpp */

View File

@ -9,7 +9,8 @@
#ifndef ConfidenceSource_hpp
#define ConfidenceSource_hpp
namespace DynamicAnalyser {
namespace Analyser {
namespace Dynamic {
/*!
Provides an abstract interface through which objects can declare the probability
@ -21,6 +22,7 @@ struct ConfidenceSource {
virtual float get_confidence() = 0;
};
}
}
#endif /* ConfidenceSource_hpp */

View File

@ -11,7 +11,7 @@
#include <cassert>
#include <numeric>
using namespace DynamicAnalyser;
using namespace Analyser::Dynamic;
ConfidenceSummary::ConfidenceSummary(const std::vector<ConfidenceSource *> &sources, const std::vector<float> &weights) :
sources_(sources), weights_(weights) {

View File

@ -13,7 +13,8 @@
#include <vector>
namespace DynamicAnalyser {
namespace Analyser {
namespace Dynamic {
/*!
Summaries a collection of confidence sources by calculating their weighted sum.
@ -39,6 +40,7 @@ class ConfidenceSummary: public ConfidenceSource {
float weight_sum_;
};
}
}
#endif /* ConfidenceSummary_hpp */

View File

@ -0,0 +1,38 @@
//
// MultiMachine.cpp
// Clock Signal
//
// Created by Thomas Harte on 28/01/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#include "MultiMachine.hpp"
using namespace Analyser::Dynamic;
MultiMachine::MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines) :
machines_(std::move(machines)) {}
ConfigurationTarget::Machine *MultiMachine::configuration_target() {
return nullptr;
}
CRTMachine::Machine *MultiMachine::crt_machine() {
return nullptr;
}
JoystickMachine::Machine *MultiMachine::joystick_machine() {
return nullptr;
}
KeyboardMachine::Machine *MultiMachine::keyboard_machine() {
return nullptr;
}
Configurable::Device *MultiMachine::configurable_device() {
return nullptr;
}
Utility::TypeRecipient *MultiMachine::type_recipient() {
return nullptr;
}

View File

@ -0,0 +1,50 @@
//
// MultiMachine.hpp
// Clock Signal
//
// Created by Thomas Harte on 28/01/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef MultiMachine_hpp
#define MultiMachine_hpp
#include "../../../Machines/Utility/MachineForTarget.hpp"
#include <memory>
#include <vector>
namespace Analyser {
namespace Dynamic {
/*!
Provides the same interface as to a single machine, while multiplexing all
underlying calls to an array of real dynamic machines.
Calls to crt_machine->get_crt will return that for the first machine.
Following each crt_machine->run_for, reorders the supplied machines by
confidence.
If confidence for any machine becomes disproportionately low compared to
the others in the set, that machine is removed from the array.
*/
class MultiMachine: public ::Machine::DynamicMachine {
public:
MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machines);
ConfigurationTarget::Machine *configuration_target() override;
CRTMachine::Machine *crt_machine() override;
JoystickMachine::Machine *joystick_machine() override;
KeyboardMachine::Machine *keyboard_machine() override;
Configurable::Device *configurable_device() override;
Utility::TypeRecipient *type_recipient() override;
private:
std::vector<std::unique_ptr<DynamicMachine>> machines_;
};
}
}
#endif /* MultiMachine_hpp */

View File

@ -70,7 +70,7 @@ class ROMSlotHandler {
}
protected:
DynamicAnalyser::ConfidenceCounter confidence_counter_;
Analyser::Dynamic::ConfidenceCounter confidence_counter_;
};
}

View File

@ -16,24 +16,25 @@
#include "../Oric/Oric.hpp"
#include "../ZX8081/ZX8081.hpp"
#include "../../Analyser/Dynamic/MultiMachine/MultiMachine.hpp"
#include "TypedDynamicMachine.hpp"
::Machine::DynamicMachine *::Machine::MachineForTargets(const std::vector<std::unique_ptr<Analyser::Static::Target>> &targets, const ROMMachine::ROMFetcher &rom_fetcher, Error &error) {
// TODO: deal with target lists containing more than one machine.
namespace {
error = Error::None;
::Machine::DynamicMachine *MachineForTarget(const Analyser::Static::Target &target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error) {
error = Machine::Error::None;
::Machine::DynamicMachine *machine = nullptr;
switch(targets.front()->machine) {
case Analyser::Machine::AmstradCPC: machine = new TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC()); break;
case Analyser::Machine::Atari2600: machine = new TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600()); break;
case Analyser::Machine::Electron: machine = new TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron()); break;
case Analyser::Machine::MSX: machine = new TypedDynamicMachine<MSX::Machine>(MSX::Machine::MSX()); break;
case Analyser::Machine::Oric: machine = new TypedDynamicMachine<Oric::Machine>(Oric::Machine::Oric()); break;
case Analyser::Machine::Vic20: machine = new TypedDynamicMachine<Commodore::Vic20::Machine>(Commodore::Vic20::Machine::Vic20()); break;
case Analyser::Machine::ZX8081: machine = new TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(*targets.front())); break;
switch(target.machine) {
case Analyser::Machine::AmstradCPC: machine = new Machine::TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC()); break;
case Analyser::Machine::Atari2600: machine = new Machine::TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600()); break;
case Analyser::Machine::Electron: machine = new Machine::TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron()); break;
case Analyser::Machine::MSX: machine = new Machine::TypedDynamicMachine<MSX::Machine>(MSX::Machine::MSX()); break;
case Analyser::Machine::Oric: machine = new Machine::TypedDynamicMachine<Oric::Machine>(Oric::Machine::Oric()); break;
case Analyser::Machine::Vic20: machine = new Machine::TypedDynamicMachine<Commodore::Vic20::Machine>(Commodore::Vic20::Machine::Vic20()); break;
case Analyser::Machine::ZX8081: machine = new Machine::TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(target)); break;
default:
error = Error::UnknownMachine;
error = Machine::Error::UnknownMachine;
return nullptr;
}
@ -42,19 +43,42 @@
if(crt_machine) {
if(!machine->crt_machine()->set_rom_fetcher(rom_fetcher)) {
delete machine;
error = Error::MissingROM;
error = Machine::Error::MissingROM;
return nullptr;
}
}
ConfigurationTarget::Machine *configuration_target = machine->configuration_target();
if(configuration_target) {
machine->configuration_target()->configure_as_target(*targets.front());
machine->configuration_target()->configure_as_target(target);
}
return machine;
}
}
::Machine::DynamicMachine *::Machine::MachineForTargets(const std::vector<std::unique_ptr<Analyser::Static::Target>> &targets, const ROMMachine::ROMFetcher &rom_fetcher, Error &error) {
// Zero targets implies no machine.
if(targets.empty()) {
error = Error::NoTargets;
return nullptr;
}
// If there's more than one target, get all the machines and combine them into a multimachine.
if(targets.size() > 1) {
std::vector<std::unique_ptr<Machine::DynamicMachine>> machines;
for(const auto &target: targets) {
machines.emplace_back(MachineForTarget(*target, rom_fetcher, error));
}
return new Analyser::Dynamic::MultiMachine(std::move(machines));
}
// There's definitely exactly one target.
return MachineForTarget(*targets.front(), rom_fetcher, error);
}
std::string Machine::ShortNameForTargetMachine(const Analyser::Machine machine) {
switch(machine) {
case Analyser::Machine::AmstradCPC: return "AmstradCPC";

View File

@ -41,7 +41,8 @@ struct DynamicMachine {
enum class Error {
None,
UnknownMachine,
MissingROM
MissingROM,
NoTargets
};
/*!

View File

@ -161,6 +161,7 @@
4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */; };
4B3BA0D11D318B44005DD7A7 /* TestMachine6502.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */; };
4B3BF5B01F146265005B6C36 /* CSW.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BF5AE1F146264005B6C36 /* CSW.cpp */; };
4B3FCC40201EC24200960631 /* MultiMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FCC3F201EC24200960631 /* MultiMachine.cpp */; };
4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */; };
4B448E811F1C45A00009ABD6 /* TZX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B448E7F1F1C45A00009ABD6 /* TZX.cpp */; };
4B448E841F1C4C480009ABD6 /* PulseQueuedTape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B448E821F1C4C480009ABD6 /* PulseQueuedTape.cpp */; };
@ -749,6 +750,8 @@
4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine6502.mm; sourceTree = "<group>"; };
4B3BF5AE1F146264005B6C36 /* CSW.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSW.cpp; sourceTree = "<group>"; };
4B3BF5AF1F146264005B6C36 /* CSW.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CSW.hpp; sourceTree = "<group>"; };
4B3FCC3E201EC24200960631 /* MultiMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MultiMachine.hpp; sourceTree = "<group>"; };
4B3FCC3F201EC24200960631 /* MultiMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiMachine.cpp; sourceTree = "<group>"; };
4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPM.cpp; path = Parsers/CPM.cpp; sourceTree = "<group>"; };
4B3FE75D1F3CF68B00448EE4 /* CPM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CPM.hpp; path = Parsers/CPM.hpp; sourceTree = "<group>"; };
4B448E7F1F1C45A00009ABD6 /* TZX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TZX.cpp; sourceTree = "<group>"; };
@ -1687,6 +1690,15 @@
path = Bridges;
sourceTree = "<group>";
};
4B3FCC3D201EC24200960631 /* MultiMachine */ = {
isa = PBXGroup;
children = (
4B3FCC3E201EC24200960631 /* MultiMachine.hpp */,
4B3FCC3F201EC24200960631 /* MultiMachine.cpp */,
);
path = MultiMachine;
sourceTree = "<group>";
};
4B3FE75F1F3CF6BA00448EE4 /* Parsers */ = {
isa = PBXGroup;
children = (
@ -2066,6 +2078,7 @@
4B8944E7201967B4007DE474 /* ConfidenceCounter.hpp */,
4B8944E5201967B4007DE474 /* ConfidenceSource.hpp */,
4B8944E4201967B4007DE474 /* ConfidenceSummary.hpp */,
4B3FCC3D201EC24200960631 /* MultiMachine */,
);
path = Dynamic;
sourceTree = "<group>";
@ -3564,6 +3577,7 @@
4B98A05E1FFAD3F600ADF63B /* CSROMFetcher.mm in Sources */,
4B8FE2201DA19D7C0090D3CE /* Atari2600OptionsPanel.swift in Sources */,
4B8805F41DCFD22A003085B1 /* Commodore.cpp in Sources */,
4B3FCC40201EC24200960631 /* MultiMachine.cpp in Sources */,
4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */,
4B9CCDA11DA279CA0098B625 /* Vic20OptionsPanel.swift in Sources */,
4B8805F01DCFC99C003085B1 /* Acorn.cpp in Sources */,