Overhaul the log stuff to actually work again (better).

This commit is contained in:
David Given
2024-10-13 23:26:12 +02:00
parent c5373480ba
commit a006e0bf6f
13 changed files with 174 additions and 74 deletions

View File

@@ -160,6 +160,16 @@ static const std::vector<ImageConstructor> imageConstructors = {
{".xdf", IMAGETYPE_IMG, MODE_RW},
};
struct OptionLogMessage
{
std::string message;
};
void renderLogMessage(LogRenderer& r, std::shared_ptr<const OptionLogMessage> m)
{
r.newline().add("OPTION:").add(m->message).newline();
}
Config& globalConfig()
{
return config;
@@ -442,8 +452,8 @@ bool Config::isOptionValid(std::string option)
void Config::applyOption(const OptionProto& option)
{
log("OPTION: {}",
option.has_message() ? option.message() : option.comment());
log(OptionLogMessage{
option.has_message() ? option.message() : option.comment()});
_appliedOptions.insert(option.name());
}

View File

@@ -7,7 +7,8 @@ static bool indented = false;
static std::function<void(const AnyLogMessage&)> loggerImpl =
[](const auto& message)
{
std::cout << Logger::toString(message) << std::flush;
static auto r = LogRenderer::create(std::cout);
r->add(message);
};
void log(const char* m)
@@ -42,24 +43,14 @@ void renderLogMessage(LogRenderer& r, std::shared_ptr<const std::string> msg)
r.newline().add(*msg).newline();
}
std::string Logger::toString(const AnyLogMessage& message)
LogRenderer& LogRenderer::add(const AnyLogMessage& message)
{
std::stringstream stream;
auto indent = [&]()
{
if (!indented)
stream << " ";
indented = false;
};
auto r = LogRenderer::create();
std::visit(
[&](const auto& arg)
{
renderLogMessage(*r, arg);
renderLogMessage(*this, arg);
},
message);
return stream.str();
return *this;
}

View File

@@ -8,19 +8,7 @@ class DiskFlux;
class TrackDataFlux;
class TrackFlux;
class Sector;
class LogRenderer
{
public:
static std::unique_ptr<LogRenderer> create();
public:
virtual LogRenderer& add(std::string m) = 0;
virtual LogRenderer& newsection() = 0;
virtual LogRenderer& newline() = 0;
virtual void renderTo(std::ostream& stream) = 0;
};
class LogRenderer;
struct ErrorLogMessage;
struct EmergencyStopMessage;
@@ -35,6 +23,7 @@ struct EndWriteOperationLogMessage;
struct BeginOperationLogMessage;
struct EndOperationLogMessage;
struct OperationProgressLogMessage;
struct OptionLogMessage;
struct ErrorLogMessage
{
@@ -71,6 +60,8 @@ extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const EndOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const OperationProgressLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const OptionLogMessage> m);
typedef std::variant<std::shared_ptr<const std::string>,
std::shared_ptr<const ErrorLogMessage>,
@@ -85,7 +76,8 @@ typedef std::variant<std::shared_ptr<const std::string>,
std::shared_ptr<const EndWriteOperationLogMessage>,
std::shared_ptr<const BeginOperationLogMessage>,
std::shared_ptr<const EndOperationLogMessage>,
std::shared_ptr<const OperationProgressLogMessage>>
std::shared_ptr<const OperationProgressLogMessage>,
std::shared_ptr<const OptionLogMessage>>
AnyLogMessage;
extern void log(const char* ptr);
@@ -103,11 +95,24 @@ inline void log(fmt::string_view fstr, const Args&... args)
log(fmt::format(fstr, args...));
}
class LogRenderer
{
public:
static std::unique_ptr<LogRenderer> create(std::ostream& stream);
public:
LogRenderer& add(const AnyLogMessage& message);
public:
virtual LogRenderer& add(const std::string& m) = 0;
virtual LogRenderer& comma() = 0;
virtual LogRenderer& header(const std::string& h) = 0;
virtual LogRenderer& newline() = 0;
};
namespace Logger
{
extern void setLogger(std::function<void(const AnyLogMessage&)> cb);
extern std::string toString(const AnyLogMessage&);
}
#endif

View File

@@ -7,55 +7,89 @@ namespace
class LogRendererImpl : public LogRenderer
{
public:
LogRenderer& add(std::string m) override
LogRendererImpl(std::ostream& stream): _stream(stream) {}
private:
void indent()
{
if (_atNewline && _indented)
_stream << " ";
_lineLen = 7;
_space = true;
}
public:
LogRenderer& add(const std::string& m) override
{
if (_newline && !_header)
indent();
if (!_space)
{
_stream << " ";
_lineLen = 4;
_indented = true;
_stream << ' ';
_lineLen++;
}
if ((m.size() + _lineLen) > 80)
{
_stream << "\n ";
_lineLen = 4;
_indented = true;
}
_newline = false;
_header = false;
_lineLen += m.size();
if (_lineLen >= 80)
{
_stream << '\n';
indent();
}
_stream << m;
_space = !m.empty() && isspace(m[m.size() - 1]);
return *this;
}
LogRenderer& newsection() override
LogRenderer& header(const std::string& m) override
{
newline();
_indented = false;
if (!_newline)
_stream << '\n';
_stream << m;
_lineLen = m.size();
_header = true;
_newline = true;
_space = !m.empty() && isspace(m[m.size() - 1]);
return *this;
}
LogRenderer& comma() override
{
if (!_newline || _header)
{
_stream << ';';
_space = false;
}
return *this;
}
LogRenderer& newline() override
{
if (!_atNewline)
if (!_header)
{
_stream << '\n';
_atNewline = true;
if (!_newline)
_stream << '\n';
_lineLen = 0;
_header = false;
_newline = true;
_space = true;
}
_lineLen = 0;
return *this;
}
void renderTo(std::ostream& stream) override {}
private:
bool _atNewline = false;
bool _indented = false;
bool _header = false;
bool _newline = false;
bool _space = false;
int _lineLen = 0;
std::stringstream _stream;
std::ostream& _stream;
};
}
std::unique_ptr<LogRenderer> LogRenderer::create()
std::unique_ptr<LogRenderer> LogRenderer::create(std::ostream& stream)
{
return std::make_unique<LogRendererImpl>();
return std::make_unique<LogRendererImpl>(stream);
}

View File

@@ -57,7 +57,7 @@ void renderLogMessage(
void renderLogMessage(
LogRenderer& r, std::shared_ptr<const BeginWriteOperationLogMessage> m)
{
r.newsection().add(fmt::format("{:2}.{}: ", m->track, m->head));
r.header(fmt::format("W{:2}.{}: ", m->track, m->head));
}
/* Indicates that we're finishing a write operation. */
@@ -70,7 +70,7 @@ void renderLogMessage(
void renderLogMessage(
LogRenderer& r, std::shared_ptr<const BeginReadOperationLogMessage> m)
{
r.newsection().add(fmt::format("{:2}.{}: ", m->track, m->head));
r.header(fmt::format("R{:2}.{}: ", m->track, m->head));
}
/* Indicates that we're finishing a read operation. */
@@ -102,13 +102,13 @@ void renderLogMessage(
if (!rawSectors.empty())
clock /= rawSectors.size();
r.add(fmt::format("{} raw records, {} raw sectors",
r.comma().add(fmt::format("{} raw records, {} raw sectors",
rawRecords.size(),
rawSectors.size()));
if (clock != 0)
{
r.add(fmt::format(
"; {:.2f}us clock ({:.0f}kHz)", clock / 1000.0, 1000000.0 / clock));
r.comma().add(fmt::format(
"{:.2f}us clock ({:.0f}kHz)", clock / 1000.0, 1000000.0 / clock));
}
r.newline().add("sectors:");
@@ -118,7 +118,7 @@ void renderLogMessage(
std::sort(sectors.begin(), sectors.end(), sectorPointerSortPredicate);
for (const auto& sector : sectors)
r.add(fmt::format(" {}.{}.{}{}",
r.add(fmt::format("{}.{}.{}{}",
sector->logicalTrack,
sector->logicalSide,
sector->logicalSector,
@@ -349,13 +349,14 @@ ReadResult readGroup(FluxSourceIteratorHolder& fluxSourceIteratorHolder,
for (unsigned offset = 0; offset < trackInfo->groupSize;
offset += Layout::getHeadWidth())
{
log(BeginReadOperationLogMessage{
trackInfo->physicalTrack + offset, trackInfo->physicalSide});
auto& fluxSourceIterator = fluxSourceIteratorHolder.getIterator(
trackInfo->physicalTrack + offset, trackInfo->physicalSide);
if (!fluxSourceIterator.hasNext())
continue;
log(BeginReadOperationLogMessage{
trackInfo->physicalTrack + offset, trackInfo->physicalSide});
std::shared_ptr<const Fluxmap> fluxmap = fluxSourceIterator.next();
// ->rescale(
// 1.0 / globalConfig()->flux_source().rescale());

View File

@@ -43,6 +43,7 @@ cxxprogram(
"dep/stb",
"+lib",
"lib/core",
"lib/data",
"lib/vfs",
"lib/config",
"lib/fluxsource+proto_lib",

View File

@@ -65,6 +65,7 @@ cxxprogram(
"extras+icons",
"+lib",
"lib/core",
"lib/data",
"lib/vfs",
"lib/config",
"lib/fluxsource+proto_lib",

View File

@@ -195,6 +195,7 @@ public:
if (formatSelection == wxNOT_FOUND)
error("no format selected");
ClearLog();
globalConfig().clear();
auto formatName = _formatNames[formatChoice->GetSelection()];
globalConfig().readBaseConfigFile(formatName);
@@ -292,7 +293,6 @@ public:
globalConfig().set("usb.serial", serial);
globalConfig().validateAndThrow();
ClearLog();
}
const wxBitmap GetBitmap() override

View File

@@ -24,13 +24,45 @@
#include <wx/aboutdlg.h>
#include <deque>
class CallbackOstream : public std::streambuf
{
public:
CallbackOstream(std::function<void(const std::string&)> cb): _cb(cb) {}
public:
std::streamsize xsputn(const char* p, std::streamsize n) override
{
_cb(std::string(p, n));
return n;
}
int_type overflow(int_type v) override
{
char c = v;
_cb(std::string(&c, 1));
return 1;
}
private:
std::function<void(const std::string&)> _cb;
};
class MainWindowImpl : public MainWindowGen, public MainWindow
{
private:
class FilesystemOperation;
public:
MainWindowImpl(): MainWindowGen(nullptr)
MainWindowImpl():
MainWindowGen(nullptr),
_logStreamBuf(
[this](const std::string& s)
{
if (_logWindow)
_logWindow->GetTextControl()->AppendText(s);
}),
_logStream(&_logStreamBuf),
_logRenderer(LogRenderer::create(_logStream))
{
Logger::setLogger(
[&](const AnyLogMessage& message)
@@ -203,7 +235,8 @@ public:
void OnLogMessage(const AnyLogMessage& message)
{
_logWindow->GetTextControl()->AppendText(Logger::toString(message));
_logRenderer->add(message);
_logStream.flush();
std::visit(
overloaded{
@@ -376,8 +409,11 @@ private:
CustomStatusBar* _statusBar;
wxTimer _exitTimer;
std::unique_ptr<TextViewerWindow> _logWindow;
CallbackOstream _logStreamBuf;
std::ostream _logStream;
std::unique_ptr<TextViewerWindow> _configWindow;
std::unique_ptr<Context> _context;
std::unique_ptr<LogRenderer> _logRenderer;
};
wxWindow* FluxEngineApp::CreateMainWindow()

View File

@@ -29,6 +29,18 @@ wxTextCtrl* TextViewerWindow::GetTextControl() const
return textControl;
}
std::streamsize TextViewerWindow::xsputn(const char* s, std::streamsize n)
{
textControl->AppendText(std::string(s, n));
return n;
}
int TextViewerWindow::overflow(int c)
{
char b = c;
return xsputn(&b, 1);
}
void TextViewerWindow::OnClose(wxCloseEvent& event)
{
if (_autodestroy)

View File

@@ -3,7 +3,7 @@
#include "layout.h"
class TextViewerWindow : public TextViewerWindowGen
class TextViewerWindow : public TextViewerWindowGen, public std::streambuf
{
public:
TextViewerWindow(wxWindow* parent,
@@ -19,6 +19,10 @@ public:
public:
wxTextCtrl* GetTextControl() const;
public:
std::streamsize xsputn(const char* s, std::streamsize n) override;
int overflow(int c) override;
private:
void OnClose(wxCloseEvent& event) override;

View File

@@ -55,8 +55,6 @@ export(
"+fl2_proto_lib",
"+fmt_lib",
"+lib",
"lib/core",
"lib/fluxsource+proto_lib",
"+protobuf_lib",
"+protocol",
"+z_lib",
@@ -69,6 +67,9 @@ export(
"dep/snowhouse",
"dep/stb",
"lib/config",
"lib/core",
"lib/data",
"lib/fluxsource+proto_lib",
"src/formats",
],
),
@@ -84,11 +85,10 @@ export(
"+fl2_proto_lib",
"+fmt_lib",
"+lib",
"lib/core",
"lib/fluxsource+proto_lib",
"+protobuf_lib",
"+protocol",
"+z_lib",
"arch+proto_lib",
"dep/adflib",
"dep/agg",
"dep/fatfs",
@@ -96,8 +96,10 @@ export(
"dep/libusbp",
"dep/snowhouse",
"dep/stb",
"arch+proto_lib",
"lib/config",
"lib/core",
"lib/data",
"lib/fluxsource+proto_lib",
"src/formats",
]
+ ([".+test_proto_lib"] if n == "options" else [])

View File

@@ -11,6 +11,7 @@ cxxprogram(
deps=[
"+lib",
"lib/core",
"lib/data",
"lib/config+proto_lib",
"lib/fluxsource+proto_lib",
"+fmt_lib",
@@ -25,6 +26,7 @@ cxxprogram(
deps=[
"+lib",
"lib/core",
"lib/data",
"lib/config+proto_lib",
"lib/fluxsource+proto_lib",
"+fmt_lib",
@@ -49,5 +51,6 @@ cxxprogram(
"lib/fluxsource+proto_lib",
"src/formats",
"lib/core",
"lib/data",
],
)