From a942687050203b5032d89c509ef4b9bfe786bc36 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 23 Jan 2013 10:41:28 -0800 Subject: [PATCH] Use a circular buffer to store only the last 250 log messages --- aegisub/libaegisub/common/log.cpp | 31 ++++++++------------- aegisub/libaegisub/include/libaegisub/log.h | 25 ++++------------- aegisub/src/dialog_log.cpp | 8 +++--- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/aegisub/libaegisub/common/log.cpp b/aegisub/libaegisub/common/log.cpp index 7bb434f4c..cd7d04407 100644 --- a/aegisub/libaegisub/common/log.cpp +++ b/aegisub/libaegisub/common/log.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include namespace agi { @@ -43,30 +42,17 @@ LogSink *log; /// Keep this ordered the same as Severity const char *Severity_ID = "EAWID"; -SinkMessage::SinkMessage(const char *section, Severity severity, const char *file, const char *func, int line, timeval tv) -: section(section) -, severity(severity) -, file(file) -, func(func) -, line(line) -, tv(tv) -{ -} - -/// @todo The log files need to be trimmed after N amount. LogSink::~LogSink() { // The destructor for emitters may try to log messages, so disable all the // emitters before destructing any std::vector emitters_temp; swap(emitters_temp, emitters); util::delete_clear(emitters_temp); - - util::delete_clear(sink); } -void LogSink::log(SinkMessage *sm) { - sink.push_back(sm); - boost::for_each(emitters, [=](Emitter *em) { em->log(sm); }); +void LogSink::Log(SinkMessage const& sm) { + messages.push_back(sm); + boost::for_each(emitters, [=](Emitter *em) { em->log(&messages.back()); }); } void LogSink::Subscribe(Emitter *em) { @@ -83,12 +69,17 @@ void LogSink::Unsubscribe(Emitter *em) { Message::Message(const char *section, Severity severity, const char *file, const char *func, int line) : msg(nullptr, 1024) { - sm = new SinkMessage(section, severity, file, func, line, util::time_log()); + sm.section = section; + sm.severity = severity; + sm.file = file; + sm.func = func; + sm.line = line; + sm.tv = util::time_log(); } Message::~Message() { - sm->message = std::string(msg.str(), (std::string::size_type)msg.pcount()); - agi::log::log->log(sm); + sm.message = std::string(msg.str(), (std::string::size_type)msg.pcount()); + agi::log::log->Log(sm); msg.freeze(false); } diff --git a/aegisub/libaegisub/include/libaegisub/log.h b/aegisub/libaegisub/include/libaegisub/log.h index 447f20063..2c0c6d0b6 100644 --- a/aegisub/libaegisub/include/libaegisub/log.h +++ b/aegisub/libaegisub/include/libaegisub/log.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include @@ -68,15 +68,6 @@ extern LogSink *log; /// Container to hold a single message struct SinkMessage { - /// @brief Constructor - /// @param section Section info - /// @param severity Severity - /// @param file File name - /// @param func Function name - /// @param line Source line - /// @param tv Log time - SinkMessage(const char *section, Severity severity, const char *file, const char *func, int line, timeval tv); - const char *section; ///< Section info eg "video/open" "video/seek" etc Severity severity; ///< Severity const char *file; ///< Source file @@ -88,23 +79,19 @@ struct SinkMessage { class Emitter; -/// Message sink for holding all messages -typedef std::deque Sink; - /// Log sink, single destination for all messages class LogSink { - /// Log sink - Sink sink; + boost::circular_buffer messages; /// List of pointers to emitters std::vector emitters; public: - /// Destructor + LogSink() : messages(250) { } ~LogSink(); /// Insert a message into the sink. - void log(SinkMessage *sm); + void Log(SinkMessage const& sm); /// @brief Subscribe an emitter /// @param em Emitter to add @@ -118,7 +105,7 @@ public: /// @brief @get the complete (current) log. /// @return Const pointer to internal sink. - const Sink* GetSink() const { return &sink; } + decltype(messages) const& GetSink() const { return messages; } }; /// An emitter to produce human readable output for a log sink. @@ -150,7 +137,7 @@ public: /// Generates a message and submits it to the log sink. class Message { std::ostrstream msg; - SinkMessage *sm; + SinkMessage sm; public: Message(const char *section, Severity severity, const char *file, const char *func, int line); diff --git a/aegisub/src/dialog_log.cpp b/aegisub/src/dialog_log.cpp index 8c87375f4..8c258645e 100644 --- a/aegisub/src/dialog_log.cpp +++ b/aegisub/src/dialog_log.cpp @@ -57,15 +57,15 @@ public: EmitLog(wxTextCtrl *t) : text_ctrl(t) { - const agi::log::Sink *sink = agi::log::log->GetSink(); - for_each(sink->begin(), sink->end(), std::bind(&EmitLog::log, this, std::placeholders::_1)); + for (auto sm : agi::log::log->GetSink()) + log(&sm); } void log(agi::log::SinkMessage *sm) { #ifndef _WIN32 tm tmtime; localtime_r(&sm->tv.tv_sec, &tmtime); - wxString log = wxString::Format("%c %02d:%02d:%02d %-6ld <%-25s> [%s:%s:%d] %s\n", + auto log = wxString::Format("%c %02d:%02d:%02d %-6ld <%-25s> [%s:%s:%d] %s\n", agi::log::Severity_ID[sm->severity], (int)tmtime.tm_hour, (int)tmtime.tm_min, @@ -77,7 +77,7 @@ public: sm->line, to_wx(sm->message)); #else - wxString log = wxString::Format("%c %-6ld <%-25s> [%s:%s:%d] %s\n", + auto log = wxString::Format("%c %-6ld <%-25s> [%s:%s:%d] %s\n", agi::log::Severity_ID[sm->severity], sm->tv.tv_usec, sm->section,