You can write images now.

This commit is contained in:
David Given
2022-02-27 00:07:59 +01:00
parent 528454c361
commit 02c7b86f85
5 changed files with 194 additions and 148 deletions

View File

@@ -10,7 +10,7 @@ extern void runOnUiThread(std::function<void()> callback);
extern void runOnWorkerThread(std::function<void()> callback);
template <typename R>
static inline R runOnUiThread(std::function<R()>& callback)
static inline R runOnUiThread(std::function<R()> callback)
{
R retvar;
runOnUiThread(

View File

@@ -135,7 +135,7 @@ MainWindowGen::MainWindowGen( wxWindow* parent, wxWindowID id, const wxString& t
m_panel3->SetSizer( fgSizer9 );
m_panel3->Layout();
fgSizer9->Fit( m_panel3 );
notebook->AddPage( m_panel3, wxT("Proto config"), false );
notebook->AddPage( m_panel3, wxT("Debug info"), false );
fgSizer2->Add( notebook, 1, wxEXPAND | wxALL, 5 );

View File

@@ -1034,7 +1034,7 @@
</object>
<object class="notebookpage" expanded="1">
<property name="bitmap"></property>
<property name="label">Proto config</property>
<property name="label">Debug info</property>
<property name="select">0</property>
<object class="wxPanel" expanded="1">
<property name="BottomDockable">1</property>

View File

@@ -5,6 +5,7 @@
#include "reader.h"
#include "fluxsource/fluxsource.h"
#include "imagereader/imagereader.h"
#include "imagewriter/imagewriter.h"
#include "decoders/decoders.h"
#include "lib/usb/usbfinder.h"
#include "fmt/format.h"
@@ -16,39 +17,40 @@ extern const std::map<std::string, std::string> formats;
MainWindow::MainWindow(): MainWindowGen(nullptr)
{
Logger::setLogger(
[&](std::shared_ptr<const AnyLogMessage> message) {
runOnUiThread(
[message, this]() {
OnLogMessage(message);
}
);
}
);
Logger::setLogger(
[&](std::shared_ptr<const AnyLogMessage> message)
{
runOnUiThread(
[message, this]()
{
OnLogMessage(message);
});
});
for (const auto& it : formats)
{
auto config = std::make_unique<ConfigProto>();
if (!config->ParseFromString(it.second))
continue;
if (config->is_extension())
continue;
for (const auto& it : formats)
{
auto config = std::make_unique<ConfigProto>();
if (!config->ParseFromString(it.second))
continue;
if (config->is_extension())
continue;
formatChoice->Append(it.first);
_formats.push_back(std::move(config));
}
formatChoice->Append(it.first);
_formats.push_back(std::move(config));
}
UpdateDevices();
if (deviceCombo->GetCount() > 0)
deviceCombo->SetValue(deviceCombo->GetString(0));
UpdateDevices();
if (deviceCombo->GetCount() > 0)
deviceCombo->SetValue(deviceCombo->GetString(0));
fluxSourceSinkCombo->SetValue(fluxSourceSinkCombo->GetString(0));
fluxSourceSinkCombo->SetValue(fluxSourceSinkCombo->GetString(0));
readFluxButton->Bind(wxEVT_BUTTON, &MainWindow::OnReadFluxButton, this);
readImageButton->Bind(wxEVT_BUTTON, &MainWindow::OnReadImageButton, this);
stopButton->Bind(wxEVT_BUTTON, &MainWindow::OnStopButton, this);
readFluxButton->Bind(wxEVT_BUTTON, &MainWindow::OnReadFluxButton, this);
readImageButton->Bind(wxEVT_BUTTON, &MainWindow::OnReadImageButton, this);
writeImageButton->Bind(wxEVT_BUTTON, &MainWindow::OnWriteImageButton, this);
stopButton->Bind(wxEVT_BUTTON, &MainWindow::OnStopButton, this);
UpdateState();
UpdateState();
}
void MainWindow::OnExit(wxCommandEvent& event)
@@ -58,131 +60,175 @@ void MainWindow::OnExit(wxCommandEvent& event)
void MainWindow::OnStopButton(wxCommandEvent&)
{
emergencyStop = true;
emergencyStop = true;
}
void MainWindow::OnReadFluxButton(wxCommandEvent&)
{
try
{
ConfigProto config = PrepareConfig();
try
{
ConfigProto config = PrepareConfig();
FluxSource::updateConfigForFilename(config.mutable_flux_source(),
fluxSourceSinkCombo->GetValue().ToStdString());
FluxSource::updateConfigForFilename(config.mutable_flux_source(),
fluxSourceSinkCombo->GetValue().ToStdString());
visualiser->Clear();
_currentDisk = nullptr;
runOnWorkerThread(
[config, this]() {
::config = config;
auto fluxSource = FluxSource::create(config.flux_source());
auto decoder = AbstractDecoder::create(config.decoder());
auto diskflux = readDiskCommand(*fluxSource, *decoder);
runOnUiThread(
[&]() {
visualiser->SetDiskData(diskflux);
}
);
}
);
}
catch (const ErrorException& e)
{
wxMessageBox(e.message, "Error", wxOK | wxICON_ERROR);
}
runOnWorkerThread(
[config, this]()
{
::config = config;
auto fluxSource = FluxSource::create(config.flux_source());
auto decoder = AbstractDecoder::create(config.decoder());
auto diskflux = readDiskCommand(*fluxSource, *decoder);
runOnUiThread(
[&]()
{
visualiser->SetDiskData(diskflux);
});
});
}
catch (const ErrorException& e)
{
wxMessageBox(e.message, "Error", wxOK | wxICON_ERROR);
}
}
void MainWindow::OnReadImageButton(wxCommandEvent&)
{
auto filename = wxFileSelector("Choose a file to open");
if (filename.empty())
return;
try
{
ConfigProto config = PrepareConfig();
if (!config.has_image_reader())
Error() << "This format is read-only.";
try
{
ConfigProto config = PrepareConfig();
if (!config.has_image_reader())
Error() << "This format is read-only.";
auto filename = wxFileSelector(
"Choose a image file to read",
/* default_path= */ wxEmptyString,
/* default_filename= */ config.image_reader().filename(),
/* default_extension= */ wxEmptyString,
/* wildcard= */ wxEmptyString,
/* flags= */ wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (filename.empty())
return;
ImageReader::updateConfigForFilename(
config.mutable_image_reader(), filename.ToStdString());
ImageReader::updateConfigForFilename(
config.mutable_image_reader(), filename.ToStdString());
visualiser->Clear();
_currentDisk = nullptr;
runOnWorkerThread(
[config, this]() {
::config = config;
auto imageReader = ImageReader::create(config.image_reader());
std::unique_ptr<const Image> image = imageReader->readImage();
runOnUiThread(
[&]() {
auto disk = std::make_shared<DiskFlux>();
disk = std::make_shared<DiskFlux>();
disk->image = std::move(image);
_currentDisk = disk;
visualiser->SetDiskData(_currentDisk);
}
);
}
);
}
catch (const ErrorException& e)
{
wxMessageBox(e.message, "Error", wxOK | wxICON_ERROR);
}
runOnWorkerThread(
[config, this]()
{
::config = config;
auto imageReader = ImageReader::create(config.image_reader());
std::unique_ptr<const Image> image = imageReader->readImage();
runOnUiThread(
[&]()
{
auto disk = std::make_shared<DiskFlux>();
disk = std::make_shared<DiskFlux>();
disk->image = std::move(image);
_currentDisk = disk;
visualiser->SetDiskData(_currentDisk);
});
});
}
catch (const ErrorException& e)
{
wxMessageBox(e.message, "Error", wxOK | wxICON_ERROR);
}
}
void MainWindow::OnWriteImageButton(wxCommandEvent&)
{
try
{
ConfigProto config = PrepareConfig();
if (!config.has_image_writer())
Error() << "This format is write-only.";
auto filename = wxFileSelector(
"Choose a image file to write",
/* default_path= */ wxEmptyString,
/* default_filename= */ config.image_writer().filename(),
/* default_extension= */ wxEmptyString,
/* wildcard= */ wxEmptyString,
/* flags= */ wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if (filename.empty())
return;
ImageWriter::updateConfigForFilename(
config.mutable_image_writer(), filename.ToStdString());
auto image = _currentDisk->image;
runOnWorkerThread(
[config, image, this]()
{
::config = config;
auto imageWriter = ImageWriter::create(config.image_writer());
imageWriter->writeImage(*image);
});
}
catch (const ErrorException& e)
{
wxMessageBox(e.message, "Error", wxOK | wxICON_ERROR);
}
}
ConfigProto MainWindow::PrepareConfig()
{
auto formatSelection = formatChoice->GetSelection();
if (formatSelection == wxNOT_FOUND)
Error() << "no format selected";
auto formatSelection = formatChoice->GetSelection();
if (formatSelection == wxNOT_FOUND)
Error() << "no format selected";
ConfigProto config = *_formats[formatChoice->GetSelection()];
ConfigProto config = *_formats[formatChoice->GetSelection()];
auto serial = deviceCombo->GetValue().ToStdString();
if (!serial.empty() && (serial[0] == '/'))
setProtoByString(&config, "usb.greaseweazle.port", serial);
else
setProtoByString(&config, "usb.serial", serial);
auto serial = deviceCombo->GetValue().ToStdString();
if (!serial.empty() && (serial[0] == '/'))
setProtoByString(&config, "usb.greaseweazle.port", serial);
else
setProtoByString(&config, "usb.serial", serial);
ApplyCustomSettings(config);
ApplyCustomSettings(config);
{
std::string s;
google::protobuf::TextFormat::PrintToString(config, &s);
protoConfigEntry->Clear();
protoConfigEntry->AppendText(s);
}
{
std::string s;
google::protobuf::TextFormat::PrintToString(config, &s);
protoConfigEntry->Clear();
protoConfigEntry->AppendText(s);
}
visualiser->Clear();
logEntry->Clear();
_currentDisk = nullptr;
logEntry->Clear();
return config;
return config;
}
void MainWindow::ApplyCustomSettings(ConfigProto& config)
{
for (int i=0; i < additionalSettingsEntry->GetNumberOfLines(); i++)
{
auto setting = additionalSettingsEntry->GetLineText(i).ToStdString();
trimWhitespace(setting);
if (setting.size() == 0)
continue;
for (int i = 0; i < additionalSettingsEntry->GetNumberOfLines(); i++)
{
auto setting = additionalSettingsEntry->GetLineText(i).ToStdString();
trimWhitespace(setting);
if (setting.size() == 0)
continue;
auto equals = setting.find('=');
if (equals != std::string::npos)
{
auto key = setting.substr(0, equals);
auto value = setting.substr(equals+1);
setProtoByString(&config, key, value);
}
else
FlagGroup::parseConfigFile(setting, formats);
}
auto equals = setting.find('=');
if (equals != std::string::npos)
{
auto key = setting.substr(0, equals);
auto value = setting.substr(equals + 1);
setProtoByString(&config, key, value);
}
else
FlagGroup::parseConfigFile(setting, formats);
}
}
void MainWindow::OnLogMessage(std::shared_ptr<const AnyLogMessage> message)
{
logEntry->AppendText(Logger::toString(*message));
notebook->SetSelection(1);
logEntry->AppendText(Logger::toString(*message));
notebook->SetSelection(1);
std::visit(
overloaded{
@@ -191,42 +237,42 @@ void MainWindow::OnLogMessage(std::shared_ptr<const AnyLogMessage> message)
{
},
/* A fatal error. */
[&](const ErrorLogMessage& m)
{
wxMessageBox(m.message, "Error", wxOK | wxICON_ERROR);
},
/* A fatal error. */
[&](const ErrorLogMessage& m)
{
wxMessageBox(m.message, "Error", wxOK | wxICON_ERROR);
},
/* Indicates that we're starting a write operation. */
[&](const BeginWriteOperationLogMessage& m)
{
visualiser->SetMode(m.cylinder, m.head, VISMODE_WRITING);
visualiser->SetMode(m.cylinder, m.head, VISMODE_WRITING);
},
[&](const EndWriteOperationLogMessage& m)
{
visualiser->SetMode(0, 0, VISMODE_NOTHING);
visualiser->SetMode(0, 0, VISMODE_NOTHING);
},
/* Indicates that we're starting a read operation. */
[&](const BeginReadOperationLogMessage& m)
{
visualiser->SetMode(m.cylinder, m.head, VISMODE_READING);
visualiser->SetMode(m.cylinder, m.head, VISMODE_READING);
},
[&](const EndReadOperationLogMessage& m)
{
visualiser->SetMode(0, 0, VISMODE_NOTHING);
visualiser->SetMode(0, 0, VISMODE_NOTHING);
},
[&](const TrackReadLogMessage& m)
{
visualiser->SetTrackData(m.track);
visualiser->SetTrackData(m.track);
},
[&](const DiskReadLogMessage& m)
{
_currentDisk = m.disk;
_currentDisk = m.disk;
},
},
*message);
@@ -234,23 +280,22 @@ void MainWindow::OnLogMessage(std::shared_ptr<const AnyLogMessage> message)
void MainWindow::UpdateState()
{
writeImageButton->Enable(!!_currentDisk);
writeFluxButton->Enable(!!_currentDisk);
stopButton->Enable(wxGetApp().IsWorkerThreadRunning());
readFluxButton->Enable(!wxGetApp().IsWorkerThreadRunning());
readImageButton->Enable(!wxGetApp().IsWorkerThreadRunning());
writeImageButton->Enable(!!_currentDisk);
writeFluxButton->Enable(!!_currentDisk);
stopButton->Enable(wxGetApp().IsWorkerThreadRunning());
readFluxButton->Enable(!wxGetApp().IsWorkerThreadRunning());
readImageButton->Enable(!wxGetApp().IsWorkerThreadRunning());
}
void MainWindow::UpdateDevices()
{
auto candidates = findUsbDevices();
auto candidates = findUsbDevices();
deviceCombo->Clear();
_devices.clear();
for (auto& candidate : candidates)
{
deviceCombo->Append(candidate->serial);
_devices.push_back(std::move(candidate));
}
deviceCombo->Clear();
_devices.clear();
for (auto& candidate : candidates)
{
deviceCombo->Append(candidate->serial);
_devices.push_back(std::move(candidate));
}
}

View File

@@ -18,6 +18,7 @@ private:
void OnStopButton(wxCommandEvent&);
void OnReadFluxButton(wxCommandEvent&);
void OnReadImageButton(wxCommandEvent&);
void OnWriteImageButton(wxCommandEvent&);
void OnLogMessage(std::shared_ptr<const AnyLogMessage> message);
public: