Config no longer depends on Flux/Image/Encode/Decode, breaking a circular

dependency.
This commit is contained in:
David Given
2024-10-12 01:49:13 +02:00
parent c6cbae4bc4
commit 7e80e255a4
30 changed files with 241 additions and 161 deletions

View File

@@ -186,7 +186,6 @@ def libraryimpl(
name=f"{self.localname}_hdr",
ins=ins,
outs=outs,
deps=deps,
commands=cs,
label="CHEADERS",
)

View File

@@ -3,12 +3,6 @@
#include "lib/proto.h"
#include "lib/logger.h"
#include "lib/core/utils.h"
#include "lib/imagewriter/imagewriter.h"
#include "lib/imagereader/imagereader.h"
#include "lib/fluxsink/fluxsink.h"
#include "lib/fluxsource/fluxsource.h"
#include "lib/encoders/encoders.h"
#include "lib/decoders/decoders.h"
#include <fstream>
#include <google/protobuf/text_format.h>
@@ -211,24 +205,10 @@ ConfigProto* Config::combined()
_combinedConfig.MergeFrom(_overridesConfig);
/* At this point the config is mostly valid. We're about to make calls
* that will want to call combined() reentrantly, so to prevent infinite
* loop we mark the config as valid now. */
/* At this point the config is valid, although when fluxsources or
* imagereaders are loaded it may be adjusted again. */
_configValid = true;
/* We should now be more or less done, but we still need to add in any
* config contributed by the flux source and image readers. This will
* open the files. */
if (hasFluxSource())
_combinedConfig.MergeFrom(getFluxSource()->getExtraConfig());
if (hasImageReader())
_combinedConfig.MergeFrom(getImageReader()->getExtraConfig());
/* Merge in the overrides once again. */
_combinedConfig.MergeFrom(_overridesConfig);
}
return &_combinedConfig;
}
@@ -244,11 +224,6 @@ void Config::clear()
_baseConfig.Clear();
_overridesConfig.Clear();
_combinedConfig.Clear();
_fluxSource.reset();
_verificationFluxSource.reset();
_imageReader.reset();
_encoder.reset();
_decoder.reset();
_appliedOptions.clear();
}
@@ -581,115 +556,36 @@ bool Config::hasFluxSource()
return (*this)->flux_source().type() != FLUXTYPE_NOT_SET;
}
std::shared_ptr<FluxSource>& Config::getFluxSource()
{
if (!_fluxSource)
{
if (!hasFluxSource())
error("no flux source configured");
_fluxSource =
std::shared_ptr(FluxSource::create((*this)->flux_source()));
}
return _fluxSource;
}
bool Config::hasVerificationFluxSource() const
{
return _verificationFluxSourceProto.type() != FLUXTYPE_NOT_SET;
}
std::shared_ptr<FluxSource>& Config::getVerificationFluxSource()
{
if (!_verificationFluxSource)
{
if (!hasVerificationFluxSource())
error("no verification flux source configured");
_verificationFluxSource =
std::shared_ptr(FluxSource::create(_verificationFluxSourceProto));
}
return _verificationFluxSource;
}
bool Config::hasImageReader()
{
return (*this)->image_reader().type() != IMAGETYPE_NOT_SET;
}
std::shared_ptr<ImageReader>& Config::getImageReader()
{
if (!_imageReader)
{
if (!hasImageReader())
error("no image reader configured");
_imageReader =
std::shared_ptr(ImageReader::create((*this)->image_reader()));
}
return _imageReader;
}
bool Config::hasFluxSink()
{
return (*this)->flux_sink().type() != FLUXTYPE_NOT_SET;
}
std::unique_ptr<FluxSink> Config::getFluxSink()
{
if (!hasFluxSink())
error("no flux sink configured");
return FluxSink::create((*this)->flux_sink());
}
bool Config::hasImageWriter()
{
return (*this)->image_writer().type() != IMAGETYPE_NOT_SET;
}
std::unique_ptr<ImageWriter> Config::getImageWriter()
{
if (!hasImageWriter())
error("no image writer configured");
return ImageWriter::create((*this)->image_writer());
}
bool Config::hasEncoder()
{
return (*this)->has_encoder();
}
std::shared_ptr<Encoder>& Config::getEncoder()
{
if (!_encoder)
{
if (!hasEncoder())
error("no encoder configured");
_encoder = Encoder::create((*this)->encoder());
}
return _encoder;
}
bool Config::hasDecoder()
{
return _combinedConfig.has_decoder();
}
std::shared_ptr<Decoder>& Config::getDecoder()
{
if (!_decoder)
{
if (!hasDecoder())
error("no decoder configured");
_decoder = Decoder::create((*this)->decoder());
}
return _decoder;
}
const std::vector<FluxConstructor>& Config::getFluxFormats()
{
return fluxConstructors;

View File

@@ -141,28 +141,21 @@ public:
void setImageReader(std::string value);
void setImageWriter(std::string value);
/* Fetch the sources, opening them if necessary. */
/* Query useful things about the config. */
bool hasFluxSource();
std::shared_ptr<FluxSource>& getFluxSource();
bool hasImageReader();
std::shared_ptr<ImageReader>& getImageReader();
bool hasVerificationFluxSource() const;
std::shared_ptr<FluxSource>& getVerificationFluxSource();
/* Fetch the encoder and decoder, creating them if necessary. */
const FluxSourceProto& getVerificationFluxSourceProto() const
{
return _verificationFluxSourceProto;
}
bool hasEncoder();
std::shared_ptr<Encoder>& getEncoder();
bool hasDecoder();
std::shared_ptr<Decoder>& getDecoder();
/* Create the sinks: these are not cached. */
bool hasFluxSink();
std::unique_ptr<FluxSink> getFluxSink();
bool hasImageWriter();
std::unique_ptr<ImageWriter> getImageWriter();
public:
static const std::vector<FluxConstructor>& getFluxFormats();
@@ -175,11 +168,6 @@ private:
std::set<std::string> _appliedOptions;
bool _configValid;
std::shared_ptr<FluxSource> _fluxSource;
std::shared_ptr<ImageReader> _imageReader;
std::shared_ptr<FluxSource> _verificationFluxSource;
std::shared_ptr<Encoder> _encoder;
std::shared_ptr<Decoder> _decoder;
FluxSourceProto _verificationFluxSourceProto;
};

View File

@@ -233,4 +233,3 @@ int findLowestSetBit(uint64_t value)
}
return bit;
}

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/flags.h"
#include "lib/fluxmap.h"
#include "lib/config.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "arch/agat/agat.h"
@@ -32,6 +33,13 @@
#include "lib/layout.h"
#include <numeric>
std::unique_ptr<Decoder> Decoder::create(Config& config)
{
if (!config.hasDecoder())
error("no decoder configured");
return create(config->decoder());
}
std::unique_ptr<Decoder> Decoder::create(const DecoderProto& config)
{
static const std::map<int,

View File

@@ -12,6 +12,7 @@ class FluxMatcher;
class FluxmapReader;
class RawBits;
class DecoderProto;
class Config;
#include "lib/flux.h"
@@ -39,6 +40,7 @@ public:
virtual ~Decoder() {}
static std::unique_ptr<Decoder> create(Config& config);
static std::unique_ptr<Decoder> create(const DecoderProto& config);
public:

View File

@@ -21,6 +21,13 @@
#include "lib/image.h"
#include "protocol.h"
std::unique_ptr<Encoder> Encoder::create(Config& config)
{
if (!config.hasEncoder())
error("no encoder configured");
return create(config->encoder());
}
std::unique_ptr<Encoder> Encoder::create(const EncoderProto& config)
{
static const std::map<int,

View File

@@ -7,6 +7,7 @@ class Image;
class Layout;
class Sector;
class TrackInfo;
class Config;
class Encoder
{
@@ -14,6 +15,7 @@ public:
Encoder(const EncoderProto& config) {}
virtual ~Encoder() {}
static std::unique_ptr<Encoder> create(Config& config);
static std::unique_ptr<Encoder> create(const EncoderProto& config);
public:

View File

@@ -1,11 +1,19 @@
#include "lib/core/globals.h"
#include "lib/flags.h"
#include "lib/config.h"
#include "lib/fluxsink/fluxsink.h"
#include "lib/config.pb.h"
#include "lib/proto.h"
#include "lib/core/utils.h"
#include <regex>
std::unique_ptr<FluxSink> FluxSink::create(Config& config)
{
if (!config.hasFluxSink())
error("no flux sink configured");
return create(config->flux_sink());
}
std::unique_ptr<FluxSink> FluxSink::create(const FluxSinkProto& config)
{
switch (config.type())

View File

@@ -12,6 +12,7 @@ class A2RFluxSinkProto;
class VcdFluxSinkProto;
class ScpFluxSinkProto;
class Fl2FluxSinkProto;
class Config;
class FluxSink
{
@@ -34,6 +35,7 @@ public:
static std::unique_ptr<FluxSink> createFl2FluxSink(
const std::string& filename);
static std::unique_ptr<FluxSink> create(Config& config);
static std::unique_ptr<FluxSink> create(const FluxSinkProto& config);
public:

View File

@@ -1,4 +1,5 @@
#include "lib/core/globals.h"
#include "lib/config.h"
#include "lib/flags.h"
#include "lib/fluxsource/fluxsource.h"
#include "lib/fluxmap.h"
@@ -6,6 +7,13 @@
#include "lib/proto.h"
#include "lib/core/utils.h"
std::unique_ptr<FluxSource> FluxSource::create(Config& config)
{
if (!config.hasFluxSource())
error("no flux source configured");
return create(config->flux_source());
}
std::unique_ptr<FluxSource> FluxSource::create(const FluxSourceProto& config)
{
switch (config.type())

View File

@@ -17,6 +17,7 @@ class KryofluxFluxSourceProto;
class ScpFluxSourceProto;
class TestPatternFluxSourceProto;
class FlxFluxSourceProto;
class Config;
class FluxSourceIterator
{
@@ -58,6 +59,7 @@ public:
static std::unique_ptr<FluxSource> createMemoryFluxSource(
const DiskFlux& flux);
static std::unique_ptr<FluxSource> create(Config& config);
static std::unique_ptr<FluxSource> create(const FluxSourceProto& spec);
public:

View File

@@ -1,4 +1,5 @@
#include "lib/core/globals.h"
#include "lib/config.h"
#include "lib/flags.h"
#include "lib/sector.h"
#include "lib/imagereader/imagereader.h"
@@ -11,6 +12,13 @@
#include <algorithm>
#include <ctype.h>
std::unique_ptr<ImageReader> ImageReader::create(Config& config)
{
if (!config.hasImageReader())
error("no image reader configured");
return create(config->image_reader());
}
std::unique_ptr<ImageReader> ImageReader::create(const ImageReaderProto& config)
{
switch (config.type())

View File

@@ -7,6 +7,7 @@
class ImageSpec;
class ImageReaderProto;
class ConfigProto;
class Config;
class ImageReader
{
@@ -15,6 +16,7 @@ public:
virtual ~ImageReader(){};
public:
static std::unique_ptr<ImageReader> create(Config& config);
static std::unique_ptr<ImageReader> create(const ImageReaderProto& config);
public:

View File

@@ -1,4 +1,5 @@
#include "lib/core/globals.h"
#include "lib/config.h"
#include "lib/flags.h"
#include "lib/sector.h"
#include "lib/imagewriter/imagewriter.h"
@@ -11,6 +12,13 @@
#include <iostream>
#include <fstream>
std::unique_ptr<ImageWriter> ImageWriter::create(Config& config)
{
if (!config.hasImageWriter())
error("no image writer configured");
return create(config->image_writer());
}
std::unique_ptr<ImageWriter> ImageWriter::create(const ImageWriterProto& config)
{
switch (config.type())

View File

@@ -3,6 +3,7 @@
class ImageWriterProto;
class Image;
class Config;
class ImageWriter
{
@@ -11,6 +12,7 @@ public:
virtual ~ImageWriter(){};
public:
static std::unique_ptr<ImageWriter> create(Config& config);
static std::unique_ptr<ImageWriter> create(const ImageWriterProto& config);
static std::unique_ptr<ImageWriter> createD64ImageWriter(

View File

@@ -243,13 +243,13 @@ std::unique_ptr<Filesystem> Filesystem::createFilesystemFromConfig()
std::shared_ptr<Encoder> encoder;
if (globalConfig().hasFluxSource())
{
fluxSource = globalConfig().getFluxSource();
decoder = globalConfig().getDecoder();
fluxSource = FluxSource::create(globalConfig());
decoder = Decoder::create(globalConfig());
}
if (globalConfig()->flux_sink().type() == FLUXTYPE_DRIVE)
{
fluxSink = globalConfig().getFluxSink();
encoder = globalConfig().getEncoder();
fluxSink = FluxSink::create(globalConfig());
encoder = Encoder::create(globalConfig());
}
sectorInterface = SectorInterface::createFluxSectorInterface(
fluxSource, fluxSink, encoder, decoder);
@@ -260,9 +260,9 @@ std::unique_ptr<Filesystem> Filesystem::createFilesystemFromConfig()
std::shared_ptr<ImageWriter> writer;
if (globalConfig().hasImageReader() &&
doesFileExist(globalConfig()->image_reader().filename()))
reader = globalConfig().getImageReader();
reader = ImageReader::create(globalConfig());
if (globalConfig().hasImageWriter())
writer = globalConfig().getImageWriter();
writer = ImageWriter::create(globalConfig());
sectorInterface =
SectorInterface::createImageSectorInterface(reader, writer);

View File

@@ -135,7 +135,7 @@ int mainInspect(int argc, const char* argv[])
globalConfig().overrides()->mutable_flux_source()->set_type(FLUXTYPE_DRIVE);
flags.parseFlagsWithConfigFiles(argc, argv, {});
auto& fluxSource = globalConfig().getFluxSource();
auto fluxSource = FluxSource::create(globalConfig());
const auto fluxmap = fluxSource->readFlux(trackFlag, headFlag)->next();
std::cout << fmt::format("0x{:x} bytes of data in {:.3f}ms\n",

View File

@@ -60,9 +60,8 @@ int mainRawRead(int argc, const char* argv[])
if (globalConfig()->flux_sink().type() == FLUXTYPE_DRIVE)
error("you can't use rawread to write to hardware");
std::shared_ptr<FluxSource> fluxSource = globalConfig().getFluxSource();
std::unique_ptr<FluxSink> fluxSink(
FluxSink::create(globalConfig()->flux_sink()));
auto fluxSource = FluxSource::create(globalConfig());
auto fluxSink = FluxSink::create(globalConfig());
rawReadDiskCommand(*fluxSource, *fluxSink);

View File

@@ -66,9 +66,8 @@ int mainRawWrite(int argc, const char* argv[])
if (globalConfig()->flux_source().type() == FLUXTYPE_DRIVE)
error("you can't use rawwrite to read from hardware");
auto& fluxSource = globalConfig().getFluxSource();
std::unique_ptr<FluxSink> fluxSink(
FluxSink::create(globalConfig()->flux_sink()));
auto fluxSource = FluxSource::create(globalConfig());
auto fluxSink = FluxSink::create(globalConfig());
writeRawDiskCommand(*fluxSource, *fluxSink);
return 0;

View File

@@ -65,9 +65,9 @@ int mainRead(int argc, const char* argv[])
if (globalConfig()->decoder().copy_flux_to().type() == FLUXTYPE_DRIVE)
error("you cannot copy flux to a hardware device");
auto& fluxSource = globalConfig().getFluxSource();
auto& decoder = globalConfig().getDecoder();
auto writer = globalConfig().getImageWriter();
auto fluxSource = FluxSource::create(globalConfig());
auto decoder = Decoder::create(globalConfig());
auto writer = ImageWriter::create(globalConfig());
readDiskCommand(*fluxSource, *decoder, *writer);

View File

@@ -68,18 +68,19 @@ int mainWrite(int argc, const char* argv[])
flags.parseFlagsWithConfigFiles(argc, argv, formats);
auto& reader = globalConfig().getImageReader();
auto reader = ImageReader::create(globalConfig());
std::shared_ptr<Image> image = reader->readMappedImage();
auto encoder = globalConfig().getEncoder();
auto fluxSink = globalConfig().getFluxSink();
auto encoder = Encoder::create(globalConfig());
auto fluxSink = FluxSink::create(globalConfig());
std::shared_ptr<Decoder> decoder;
std::shared_ptr<FluxSource> verificationFluxSource;
if (globalConfig().hasDecoder() && fluxSink->isHardware() && verify)
{
decoder = globalConfig().getDecoder();
verificationFluxSource = globalConfig().getVerificationFluxSource();
decoder = Decoder::create(globalConfig());
verificationFluxSource =
FluxSource::create(globalConfig().getVerificationFluxSourceProto());
}
writeDiskCommand(*image,

View File

@@ -32,6 +32,8 @@ cxxprogram(
name="gui",
srcs=[
"./browserpanel.cc",
"./context.cc",
"./context.h",
"./customstatusbar.cc",
"./explorerpanel.cc",
"./filesystemmodel.cc",

95
src/gui/context.cc Normal file
View File

@@ -0,0 +1,95 @@
#include <lib/core/globals.h>
#include <lib/fluxsource/fluxsource.h>
#include <lib/fluxsink/fluxsink.h>
#include <lib/imagereader/imagereader.h>
#include <lib/imagewriter/imagewriter.h>
#include <lib/decoders/decoders.h>
#include <lib/encoders/encoders.h>
#include <lib/config.h>
#include "context.h"
#include "gui.h"
namespace
{
class ContextImpl : public Context
{
public:
FluxSource* GetFluxSource() override
{
if (!_fluxSource)
{
_fluxSource = FluxSource::create(globalConfig());
}
return _fluxSource.get();
}
FluxSource* GetVerificationFluxSource() override
{
if (!_verificationFluxSource)
{
_verificationFluxSource = FluxSource::create(
globalConfig().getVerificationFluxSourceProto());
}
return _verificationFluxSource.get();
}
FluxSink* GetFluxSink() override
{
if (!_fluxSink)
{
_fluxSink = FluxSink::create(globalConfig());
}
return _fluxSink.get();
}
ImageReader* GetImageReader() override
{
if (!_imageReader)
{
_imageReader = ImageReader::create(globalConfig());
}
return _imageReader.get();
}
ImageWriter* GetImageWriter() override
{
if (!_imageWriter)
{
_imageWriter = ImageWriter::create(globalConfig());
}
return _imageWriter.get();
}
Encoder* GetEncoder() override
{
if (!_encoder)
{
_encoder = Encoder::create(globalConfig());
}
return _encoder.get();
}
Decoder* GetDecoder() override
{
if (!_decoder)
{
_decoder = Decoder::create(globalConfig());
}
return _decoder.get();
}
private:
std::unique_ptr<FluxSource> _fluxSource;
std::unique_ptr<FluxSource> _verificationFluxSource;
std::unique_ptr<FluxSink> _fluxSink;
std::unique_ptr<ImageReader> _imageReader;
std::unique_ptr<ImageWriter> _imageWriter;
std::unique_ptr<Encoder> _encoder;
std::unique_ptr<Decoder> _decoder;
};
}
std::unique_ptr<Context> Context::Create()
{
return std::make_unique<ContextImpl>();
}

25
src/gui/context.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
class FluxSource;
class FluxSink;
class ImageReader;
class ImageWriter;
class Encoder;
class Decoder;
class Context
{
public:
virtual ~Context() {}
public:
virtual FluxSource* GetFluxSource() = 0;
virtual FluxSource* GetVerificationFluxSource() = 0;
virtual FluxSink* GetFluxSink() = 0;
virtual ImageReader* GetImageReader() = 0;
virtual ImageWriter* GetImageWriter() = 0;
virtual Encoder* GetEncoder() = 0;
virtual Decoder* GetDecoder() = 0;
static std::unique_ptr<Context> Create();
};

View File

@@ -7,6 +7,7 @@
#include "gui.h"
#include "layout.h"
#include "jobqueue.h"
#include "context.h"
static Bytes fakeBits(const std::vector<bool>& bits)
{
@@ -158,8 +159,8 @@ private:
if (!_explorerFluxmap || (desiredTrack != _explorerTrack) ||
(desiredSide != _explorerSide))
{
_explorerFluxmap = globalConfig()
.getFluxSource()
_explorerFluxmap = GetContext()
.GetFluxSource()
->readFlux(desiredTrack, desiredSide)
->next();
_explorerTrack = desiredTrack;

View File

@@ -8,6 +8,7 @@ class ExecEvent;
class DiskFlux;
class TrackFlux;
class wxSimplebook;
class Context;
extern void postToUiThread(std::function<void()> callback);
extern void runOnUiThread(std::function<void()> callback);
@@ -87,6 +88,7 @@ public:
virtual void SetPage(int page) = 0;
virtual void PrepareConfig() = 0;
virtual void ClearLog() = 0;
virtual Context& GetContext() = 0;
};
class PanelComponent
@@ -147,6 +149,11 @@ public:
_mainWindow->StartExploring();
}
Context& GetContext()
{
return _mainWindow->GetContext();
}
private:
MainWindow* _mainWindow;
};

View File

@@ -13,6 +13,7 @@
#include "lib/layout.h"
#include "texteditorwindow.h"
#include "iconbutton.h"
#include "context.h"
#include <wx/config.h>
#include <wx/mstream.h>
#include <wx/image.h>
@@ -794,7 +795,6 @@ private:
private:
wxConfig _config;
wxImageList _imageList;
ConfigProto _configProto;
std::vector<std::string> _formatNames;
std::vector<std::shared_ptr<const CandidateDevice>> _devices;
int _selectedSource;

View File

@@ -13,6 +13,7 @@
#include "lib/layout.h"
#include "fluxviewerwindow.h"
#include "jobqueue.h"
#include "context.h"
class ImagerPanelImpl : public ImagerPanelGen, public ImagerPanel, JobQueue
{
@@ -93,8 +94,8 @@ public:
QueueJob(
[this]()
{
auto& fluxSource = globalConfig().getFluxSource();
auto& decoder = globalConfig().getDecoder();
auto* fluxSource = GetContext().GetFluxSource();
auto* decoder = GetContext().GetDecoder();
auto diskflux = readDiskCommand(*fluxSource, *decoder);
runOnUiThread(
@@ -141,24 +142,24 @@ public:
[this]()
{
auto image =
globalConfig().getImageReader()->readMappedImage();
auto encoder = globalConfig().getEncoder();
auto fluxSink = globalConfig().getFluxSink();
GetContext().GetImageReader()->readMappedImage();
auto* encoder = GetContext().GetEncoder();
auto* fluxSink = GetContext().GetFluxSink();
std::shared_ptr<Decoder> decoder;
std::shared_ptr<FluxSource> verificationFluxSource;
Decoder* decoder = nullptr;
FluxSource* verificationFluxSource;
if (globalConfig().hasDecoder() && fluxSink->isHardware())
{
decoder = globalConfig().getDecoder();
decoder = GetContext().GetDecoder();
verificationFluxSource =
globalConfig().getVerificationFluxSource();
GetContext().GetVerificationFluxSource();
}
writeDiskCommand(*image,
*encoder,
*fluxSink,
decoder.get(),
verificationFluxSource.get());
decoder,
verificationFluxSource);
});
}
catch (const ErrorException& e)
@@ -259,7 +260,7 @@ public:
QueueJob(
[image, this]()
{
globalConfig().getImageWriter()->writeMappedImage(*image);
GetContext().GetImageWriter()->writeMappedImage(*image);
});
}
catch (const ErrorException& e)

View File

@@ -17,6 +17,7 @@
#include "texteditorwindow.h"
#include "filesystemmodel.h"
#include "customstatusbar.h"
#include "context.h"
#include "lib/vfs/vfs.h"
#include "lib/layout.h"
#include <google/protobuf/text_format.h>
@@ -179,6 +180,12 @@ public:
/* This sets the *global* config object. That's safe provided the worker
* thread isn't running, otherwise you'll get a race. */
public:
Context& GetContext()
{
assert(_context);
return *_context;
}
void ShowConfig()
{
std::string s;
@@ -189,6 +196,7 @@ public:
void PrepareConfig() override
{
_context = Context::Create();
_idlePanel->PrepareConfig();
ShowConfig();
}
@@ -369,6 +377,7 @@ private:
wxTimer _exitTimer;
std::unique_ptr<TextViewerWindow> _logWindow;
std::unique_ptr<TextViewerWindow> _configWindow;
std::unique_ptr<Context> _context;
};
wxWindow* FluxEngineApp::CreateMainWindow()