Skip to content

Commit

Permalink
Move the routines which render log messages out of logger.cc; this br…
Browse files Browse the repository at this point in the history
…eaks the

dependency which required logger.cc to have access to the entire rest of the
system. Although we still need to forward declare all the log messages.
  • Loading branch information
davidgiven committed Oct 13, 2024
1 parent 7e80e25 commit 6339cd6
Show file tree
Hide file tree
Showing 8 changed files with 380 additions and 229 deletions.
1 change: 1 addition & 0 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"./lib/layout.cc",
"./lib/ldbs.cc",
"./lib/logger.cc",
"./lib/logrenderer.cc",
"./lib/proto.cc",
"./lib/readerwriter.cc",
"./lib/sector.cc",
Expand Down
161 changes: 32 additions & 129 deletions lib/logger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,44 @@

static bool indented = false;

static std::function<void(std::shared_ptr<const AnyLogMessage>)> loggerImpl =
[](auto message)
static std::function<void(const AnyLogMessage&)> loggerImpl =
[](const auto& message)
{
std::cout << Logger::toString(*message) << std::flush;
std::cout << Logger::toString(message) << std::flush;
};

void log(std::shared_ptr<const AnyLogMessage> message)
void log(const char* m)
{
log(std::string(m));
}

void log(const AnyLogMessage& message)
{
loggerImpl(message);
}

void Logger::setLogger(
std::function<void(std::shared_ptr<const AnyLogMessage>)> cb)
void Logger::setLogger(std::function<void(const AnyLogMessage&)> cb)
{
loggerImpl = cb;
}

void renderLogMessage(
LogRenderer& r, std::shared_ptr<const ErrorLogMessage> msg)
{
r.newline().add("Error:").add(msg->message).newline();
}

void renderLogMessage(
LogRenderer& r, std::shared_ptr<const EmergencyStopMessage> msg)
{
r.newline().add("Stop!").newline();
}

void renderLogMessage(LogRenderer& r, std::shared_ptr<const std::string> msg)
{
r.newline().add(*msg).newline();
}

std::string Logger::toString(const AnyLogMessage& message)
{
std::stringstream stream;
Expand All @@ -35,131 +56,13 @@ std::string Logger::toString(const AnyLogMessage& message)
indented = false;
};

auto r = LogRenderer::create();
std::visit(
overloaded{
/* Fallback --- do nothing */
[&](const auto& m)
{
},

/* Start measuring the rotational speed */
[&](const BeginSpeedOperationLogMessage& m)
{
indent();
stream << "Measuring rotational speed...\n";
},

/* Finish measuring the rotational speed */
[&](const EndSpeedOperationLogMessage& m)
{
indent();
stream << fmt::format(
"Rotational period is {:.1f}ms ({:.1f}rpm)\n",
m.rotationalPeriod / 1e6,
60e9 / m.rotationalPeriod);
},

/* Indicates that we're starting a write operation. */
[&](const BeginWriteOperationLogMessage& m)
{
stream << fmt::format("{:2}.{}: ", m.track, m.head);
indented = true;
},

/* Indicates that we're starting a read operation. */
[&](const BeginReadOperationLogMessage& m)
{
stream << fmt::format("{:2}.{}: ", m.track, m.head);
indented = true;
},

/* We've just read a track (we might reread it if there are errors)
*/
[&](const TrackReadLogMessage& m)
{
const auto& track = *m.track;

std::set<std::shared_ptr<const Sector>> rawSectors;
std::set<std::shared_ptr<const Record>> rawRecords;
for (const auto& trackDataFlux : track.trackDatas)
{
rawSectors.insert(trackDataFlux->sectors.begin(),
trackDataFlux->sectors.end());
rawRecords.insert(trackDataFlux->records.begin(),
trackDataFlux->records.end());
}

nanoseconds_t clock = 0;
for (const auto& sector : rawSectors)
clock += sector->clock;
if (!rawSectors.empty())
clock /= rawSectors.size();

indent();
stream << fmt::format("{} raw records, {} raw sectors",
rawRecords.size(),
rawSectors.size());
if (clock != 0)
{
stream << fmt::format("; {:.2f}us clock ({:.0f}kHz)",
clock / 1000.0,
1000000.0 / clock);
}

stream << '\n';

indent();
stream << "sectors:";

std::vector<std::shared_ptr<const Sector>> sectors(
track.sectors.begin(), track.sectors.end());
std::sort(
sectors.begin(), sectors.end(), sectorPointerSortPredicate);

for (const auto& sector : sectors)
stream << fmt::format(" {}.{}.{}{}",
sector->logicalTrack,
sector->logicalSide,
sector->logicalSector,
Sector::statusToChar(sector->status));

stream << '\n';

int size = 0;
std::set<std::pair<int, int>> track_ids;
for (const auto& sector : m.track->sectors)
{
track_ids.insert(std::make_pair(
sector->logicalTrack, sector->logicalSide));
size += sector->data.size();
}

indent();
stream << fmt::format("{} bytes decoded\n", size);
},

/* Large-scale operation start. */
[&](const BeginOperationLogMessage& m)
{
},

/* Large-scale operation end. */
[&](const EndOperationLogMessage& m)
{
},

/* Large-scale operation progress. */
[&](const OperationProgressLogMessage& m)
{
},

/* Generic text message */
[&](const std::string& s)
{
indent();
stream << s << '\n';
},
[&](const auto& arg)
{
renderLogMessage(*r, arg);
},
message);

return stream.str();
}
143 changes: 70 additions & 73 deletions lib/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,103 +2,101 @@
#define LOGGER_H

#include "fmt/format.h"
#include <type_traits>

class DiskFlux;
class TrackDataFlux;
class TrackFlux;
class Sector;

struct ErrorLogMessage
class LogRenderer
{
std::string message;
};
public:
static std::unique_ptr<LogRenderer> create();

struct EmergencyStopMessage
{
};
public:
virtual LogRenderer& add(std::string m) = 0;
virtual LogRenderer& newsection() = 0;
virtual LogRenderer& newline() = 0;

struct BeginSpeedOperationLogMessage
{
virtual void renderTo(std::ostream& stream) = 0;
};

struct EndSpeedOperationLogMessage
{
nanoseconds_t rotationalPeriod;
};
struct ErrorLogMessage;
struct EmergencyStopMessage;
struct BeginSpeedOperationLogMessage;
struct EndSpeedOperationLogMessage;
struct TrackReadLogMessage;
struct DiskReadLogMessage;
struct BeginReadOperationLogMessage;
struct EndReadOperationLogMessage;
struct BeginWriteOperationLogMessage;
struct EndWriteOperationLogMessage;
struct BeginOperationLogMessage;
struct EndOperationLogMessage;
struct OperationProgressLogMessage;

struct TrackReadLogMessage
{
std::shared_ptr<const TrackFlux> track;
};

struct DiskReadLogMessage
{
std::shared_ptr<const DiskFlux> disk;
};

struct BeginReadOperationLogMessage
{
unsigned track;
unsigned head;
};

struct EndReadOperationLogMessage
{
std::shared_ptr<const TrackDataFlux> trackDataFlux;
std::set<std::shared_ptr<const Sector>> sectors;
};

struct BeginWriteOperationLogMessage
{
unsigned track;
unsigned head;
};

struct EndWriteOperationLogMessage
{
};

struct BeginOperationLogMessage
{
std::string message;
};

struct EndOperationLogMessage
struct ErrorLogMessage
{
std::string message;
};

struct OperationProgressLogMessage
struct EmergencyStopMessage
{
unsigned progress;
};

class TrackFlux;

typedef std::variant<std::string,
ErrorLogMessage,
EmergencyStopMessage,
TrackReadLogMessage,
DiskReadLogMessage,
BeginSpeedOperationLogMessage,
EndSpeedOperationLogMessage,
BeginReadOperationLogMessage,
EndReadOperationLogMessage,
BeginWriteOperationLogMessage,
EndWriteOperationLogMessage,
BeginOperationLogMessage,
EndOperationLogMessage,
OperationProgressLogMessage>
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const ErrorLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const EmergencyStopMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const TrackReadLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const DiskReadLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const BeginSpeedOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const EndSpeedOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const BeginReadOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const EndReadOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const BeginWriteOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const EndWriteOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const BeginOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const EndOperationLogMessage> m);
extern void renderLogMessage(
LogRenderer& r, std::shared_ptr<const OperationProgressLogMessage> m);

typedef std::variant<std::shared_ptr<const std::string>,
std::shared_ptr<const ErrorLogMessage>,
std::shared_ptr<const EmergencyStopMessage>,
std::shared_ptr<const TrackReadLogMessage>,
std::shared_ptr<const DiskReadLogMessage>,
std::shared_ptr<const BeginSpeedOperationLogMessage>,
std::shared_ptr<const EndSpeedOperationLogMessage>,
std::shared_ptr<const BeginReadOperationLogMessage>,
std::shared_ptr<const EndReadOperationLogMessage>,
std::shared_ptr<const BeginWriteOperationLogMessage>,
std::shared_ptr<const EndWriteOperationLogMessage>,
std::shared_ptr<const BeginOperationLogMessage>,
std::shared_ptr<const EndOperationLogMessage>,
std::shared_ptr<const OperationProgressLogMessage>>
AnyLogMessage;

extern void log(const char* ptr);
extern void log(const AnyLogMessage& message);

template <class T>
inline void log(const T& message)
{
log(std::make_shared<const AnyLogMessage>(message));
log(AnyLogMessage(std::make_shared<T>(message)));
}

extern void log(std::shared_ptr<const AnyLogMessage> message);

template <typename... Args>
inline void log(fmt::string_view fstr, const Args&... args)
{
Expand All @@ -107,8 +105,7 @@ inline void log(fmt::string_view fstr, const Args&... args)

namespace Logger
{
extern void setLogger(
std::function<void(std::shared_ptr<const AnyLogMessage>)> cb);
extern void setLogger(std::function<void(const AnyLogMessage&)> cb);

extern std::string toString(const AnyLogMessage&);
}
Expand Down
Loading

0 comments on commit 6339cd6

Please sign in to comment.