mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-21 02:37:44 +00:00
Split interface, make const
.
This commit is contained in:
parent
c39d0ce2f7
commit
4b19a3f4ed
@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#include "MultiMediaTarget.hpp"
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace Analyser::Dynamic;
|
||||
|
||||
@ -27,3 +28,29 @@ bool MultiMediaTarget::insert_media(const Analyser::Static::Media &media) {
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
|
||||
MultiMediaChangeObserver::MultiMediaChangeObserver(const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &machines) {
|
||||
for(const auto &machine: machines) {
|
||||
auto media_change_observer = machine->media_change_observer();
|
||||
if(media_change_observer) targets_.push_back(media_change_observer);
|
||||
}
|
||||
}
|
||||
|
||||
using ChangeEffect = MachineTypes::MediaChangeObserver::ChangeEffect;
|
||||
|
||||
ChangeEffect MultiMediaChangeObserver::effect_for_file_did_change(const std::string &name) const {
|
||||
if(targets_.empty()) {
|
||||
return ChangeEffect::None;
|
||||
}
|
||||
|
||||
std::unordered_set<ChangeEffect> effects;
|
||||
for(const auto &target: targets_) {
|
||||
effects.insert(target->effect_for_file_did_change(name));
|
||||
}
|
||||
|
||||
// No agreement => restart.
|
||||
if(effects.size() > 1) {
|
||||
return ChangeEffect::RestartMachine;
|
||||
}
|
||||
return *effects.begin();
|
||||
}
|
||||
|
@ -33,4 +33,15 @@ private:
|
||||
std::vector<MachineTypes::MediaTarget *> targets_;
|
||||
};
|
||||
|
||||
struct MultiMediaChangeObserver: public MachineTypes::MediaChangeObserver {
|
||||
public:
|
||||
MultiMediaChangeObserver(const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &);
|
||||
|
||||
// Below is the standard MediaTarget::Machine interface; see there for documentation.
|
||||
ChangeEffect effect_for_file_did_change(const std::string &) const final;
|
||||
|
||||
private:
|
||||
std::vector<MachineTypes::MediaChangeObserver *> targets_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ MultiMachine::MultiMachine(std::vector<std::unique_ptr<DynamicMachine>> &&machin
|
||||
audio_producer_(machines_, machines_mutex_),
|
||||
joystick_machine_(machines_),
|
||||
keyboard_machine_(machines_),
|
||||
media_target_(machines_)
|
||||
media_target_(machines_),
|
||||
media_change_observer_(machines_)
|
||||
{
|
||||
timed_machine_.set_delegate(this);
|
||||
}
|
||||
@ -52,6 +53,7 @@ Provider(MachineTypes::AudioProducer, audio_producer, audio_producer_)
|
||||
Provider(MachineTypes::JoystickMachine, joystick_machine, joystick_machine_)
|
||||
Provider(MachineTypes::KeyboardMachine, keyboard_machine, keyboard_machine_)
|
||||
Provider(MachineTypes::MediaTarget, media_target, media_target_)
|
||||
Provider(MachineTypes::MediaChangeObserver, media_change_observer, media_change_observer_)
|
||||
|
||||
MachineTypes::MouseMachine *MultiMachine::mouse_machine() {
|
||||
// TODO.
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
MachineTypes::KeyboardMachine *keyboard_machine() final;
|
||||
MachineTypes::MouseMachine *mouse_machine() final;
|
||||
MachineTypes::MediaTarget *media_target() final;
|
||||
MachineTypes::MediaChangeObserver *media_change_observer() final;
|
||||
void *raw_pointer() final;
|
||||
|
||||
private:
|
||||
@ -73,6 +74,7 @@ private:
|
||||
MultiJoystickMachine joystick_machine_;
|
||||
MultiKeyboardMachine keyboard_machine_;
|
||||
MultiMediaTarget media_target_;
|
||||
MultiMediaChangeObserver media_change_observer_;
|
||||
|
||||
void pick_first();
|
||||
bool has_picked_ = false;
|
||||
|
@ -31,6 +31,7 @@ struct DynamicMachine {
|
||||
virtual MachineTypes::KeyboardMachine *keyboard_machine() = 0;
|
||||
virtual MachineTypes::MouseMachine *mouse_machine() = 0;
|
||||
virtual MachineTypes::MediaTarget *media_target() = 0;
|
||||
virtual MachineTypes::MediaChangeObserver *media_change_observer() = 0;
|
||||
|
||||
/*!
|
||||
Provides a raw pointer to the underlying machine if and only if this dynamic machine really is
|
||||
@ -65,6 +66,7 @@ SpecialisedGet(MachineTypes::JoystickMachine, joystick_machine)
|
||||
SpecialisedGet(MachineTypes::KeyboardMachine, keyboard_machine)
|
||||
SpecialisedGet(MachineTypes::MouseMachine, mouse_machine)
|
||||
SpecialisedGet(MachineTypes::MediaTarget, media_target)
|
||||
SpecialisedGet(MachineTypes::MediaChangeObserver, media_change_observer)
|
||||
|
||||
#undef SpecialisedGet
|
||||
|
||||
|
@ -30,7 +30,9 @@ struct MediaTarget {
|
||||
// inserted, ejected and ignored. That'll allow the owner to know which media is actually
|
||||
// being consumed, so it knows what to monitor (if available on the host system) and hence
|
||||
// if/when to call effect_for_file_did_change.
|
||||
};
|
||||
|
||||
struct MediaChangeObserver {
|
||||
enum class ChangeEffect {
|
||||
None,
|
||||
ReinsertMedia,
|
||||
@ -58,7 +60,7 @@ struct MediaTarget {
|
||||
might be appropriate depending on whether it is more likely that execution will continue correctly
|
||||
with a simple media swap or whether this implies that previous state should be completely discarded.
|
||||
*/
|
||||
virtual ChangeEffect effect_for_file_did_change([[maybe_unused]] const std::string &file_name) {
|
||||
virtual ChangeEffect effect_for_file_did_change([[maybe_unused]] const std::string &file_name) const {
|
||||
return ChangeEffect::None;
|
||||
}
|
||||
};
|
||||
|
@ -126,6 +126,7 @@ template<Model model> class ConcreteMachine:
|
||||
public MachineTypes::AudioProducer,
|
||||
public MachineTypes::JoystickMachine,
|
||||
public MachineTypes::MappedKeyboardMachine,
|
||||
public MachineTypes::MediaChangeObserver,
|
||||
public MachineTypes::MediaTarget,
|
||||
public MachineTypes::ScanProducer,
|
||||
public MachineTypes::TimedMachine,
|
||||
@ -696,7 +697,7 @@ template<Model model> class ConcreteMachine:
|
||||
return !media.tapes.empty() || (!media.disks.empty() && model == Model::Plus3);
|
||||
}
|
||||
|
||||
ChangeEffect effect_for_file_did_change(const std::string &file_name) override {
|
||||
ChangeEffect effect_for_file_did_change(const std::string &file_name) const override {
|
||||
const auto disk = fdc_->disk();
|
||||
return disk && disk->represents(file_name) && disk->has_written() ?
|
||||
ChangeEffect::None : ChangeEffect::RestartMachine;
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
Provide(MachineTypes::KeyboardMachine, keyboard_machine)
|
||||
Provide(MachineTypes::MouseMachine, mouse_machine)
|
||||
Provide(MachineTypes::MediaTarget, media_target)
|
||||
Provide(MachineTypes::MediaChangeObserver, media_change_observer)
|
||||
|
||||
#undef Provide
|
||||
|
||||
|
@ -373,12 +373,12 @@ struct ActivityObserver: public Activity::Observer {
|
||||
|
||||
- (CSMachineChangeEffect)effectForFileAtURLDidChange:(nonnull NSURL *)url {
|
||||
@synchronized(self) {
|
||||
const auto mediaTarget = _machine->media_target();
|
||||
if(!mediaTarget) {
|
||||
const auto mediaChangeObserver = _machine->media_change_observer();
|
||||
if(!mediaChangeObserver) {
|
||||
return CSMachineChangeEffectNone;
|
||||
}
|
||||
const auto effect = mediaTarget->effect_for_file_did_change([url fileSystemRepresentation]);
|
||||
using ChangeEffect = MachineTypes::MediaTarget::ChangeEffect;
|
||||
const auto effect = mediaChangeObserver->effect_for_file_did_change([url fileSystemRepresentation]);
|
||||
using ChangeEffect = MachineTypes::MediaChangeObserver::ChangeEffect;
|
||||
switch(effect) {
|
||||
case ChangeEffect::None:
|
||||
return CSMachineChangeEffectNone;
|
||||
|
Loading…
x
Reference in New Issue
Block a user