From 6c685daf9877c88bbb7488b20e5181fb919926a4 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sun, 25 May 2014 18:41:16 -0700 Subject: [PATCH] Ditch boost.circular_buffer It drags in a ton of crap, is kinda slow at runtime due to using std::deque, and doesn't actually make the code much simpler than just using a manual ring buffer. --- libaegisub/common/log.cpp | 36 ++++++++++++++++++---------- libaegisub/include/libaegisub/log.h | 12 +++++----- libaegisub/unix/log.cpp | 22 ++++++++--------- libaegisub/windows/log_win.cpp | 37 ++++++++++------------------- src/dialog_log.cpp | 36 ++++++++++++++-------------- 5 files changed, 71 insertions(+), 72 deletions(-) diff --git a/libaegisub/common/log.cpp b/libaegisub/common/log.cpp index 685d07a5e..2179a9fce 100644 --- a/libaegisub/common/log.cpp +++ b/libaegisub/common/log.cpp @@ -44,9 +44,15 @@ LogSink::~LogSink() { } void LogSink::Log(SinkMessage const& sm) { - queue->Async([=]{ - messages.push_back(sm); - for (auto& em : emitters) em->log(&messages.back()); + queue->Async([=] { + if (messages.size() < 250) + messages.push_back(sm); + else { + messages[next_idx] = sm; + if (++next_idx == 250) + next_idx = 0; + } + for (auto& em : emitters) em->log(sm); }); } @@ -67,7 +73,11 @@ void LogSink::Unsubscribe(Emitter *em) { decltype(LogSink::messages) LogSink::GetMessages() const { decltype(messages) ret; - queue->Sync([&] { ret = messages; }); + queue->Sync([&] { + ret.reserve(messages.size()); + ret.insert(ret.end(), messages.begin() + next_idx, messages.end()); + ret.insert(ret.end(), messages.begin(), messages.begin() + next_idx); + }); return ret; } @@ -93,16 +103,16 @@ JsonEmitter::JsonEmitter(fs::path const& directory) { } -void JsonEmitter::log(SinkMessage *sm) { +void JsonEmitter::log(SinkMessage const& sm) { json::Object entry; - entry["sec"] = sm->time / 1000000000; - entry["usec"] = sm->time % 1000000000; - entry["severity"] = sm->severity; - entry["section"] = sm->section; - entry["file"] = sm->file; - entry["func"] = sm->func; - entry["line"] = sm->line; - entry["message"] = sm->message; + entry["sec"] = sm.time / 1000000000; + entry["usec"] = sm.time % 1000000000; + entry["severity"] = sm.severity; + entry["section"] = sm.section; + entry["file"] = sm.file; + entry["func"] = sm.func; + entry["line"] = sm.line; + entry["message"] = sm.message; json::Writer::Write(entry, *fp); fp->flush(); } diff --git a/libaegisub/include/libaegisub/log.h b/libaegisub/include/libaegisub/log.h index 343d6461c..d980b3b80 100644 --- a/libaegisub/include/libaegisub/log.h +++ b/libaegisub/include/libaegisub/log.h @@ -14,7 +14,6 @@ #include -#include #include #include #include @@ -70,7 +69,8 @@ class Emitter; /// Log sink, single destination for all messages class LogSink { - boost::circular_buffer messages{250}; + std::vector messages; + size_t next_idx = 0; std::unique_ptr queue; /// List of pointers to emitters @@ -93,7 +93,7 @@ public: /// @brief @get the complete (current) log. /// @return Const pointer to internal sink. - decltype(messages) GetMessages() const; + std::vector GetMessages() const; }; /// An emitter to produce human readable output for a log sink. @@ -103,7 +103,7 @@ public: virtual ~Emitter() { } /// Accept a single log entry - virtual void log(SinkMessage *sm)=0; + virtual void log(SinkMessage const& sm)=0; }; /// A simple emitter which writes the log to a file in json format @@ -115,7 +115,7 @@ public: /// @param directory Directory to write the log file in JsonEmitter(fs::path const& directory); - void log(SinkMessage *) override; + void log(SinkMessage const&) override; }; /// Generates a message and submits it to the log sink. @@ -133,7 +133,7 @@ public: /// Emit log entries to stdout. class EmitSTDOUT: public Emitter { public: - void log(SinkMessage *sm) override; + void log(SinkMessage const& sm) override; }; } // namespace log diff --git a/libaegisub/unix/log.cpp b/libaegisub/unix/log.cpp index cdbf7857f..82109dd2b 100644 --- a/libaegisub/unix/log.cpp +++ b/libaegisub/unix/log.cpp @@ -19,23 +19,23 @@ #include namespace agi { namespace log { -void EmitSTDOUT::log(SinkMessage *sm) { - time_t time = sm->time / 1000000000; +void EmitSTDOUT::log(SinkMessage const& sm) { + time_t time = sm.time / 1000000000; tm tmtime; localtime_r(&time, &tmtime); - printf("%c %02d:%02d:%02d %-6ld <%-25s> [%s:%s:%d] %.*s\n", - Severity_ID[sm->severity], + printf("%c %02d:%02d:%02d %-9ld <%-25s> [%s:%s:%d] %.*s\n", + Severity_ID[sm.severity], tmtime.tm_hour, tmtime.tm_min, tmtime.tm_sec, - (long)(sm->time % 1000000000), - sm->section, - sm->file, - sm->func, - sm->line, - (int)sm->message.size(), - sm->message.c_str()); + (long)(sm.time % 1000000000), + sm.section, + sm.file, + sm.func, + sm.line, + (int)sm.message.size(), + sm.message.c_str()); if (!isatty(fileno(stdout))) fflush(stdout); diff --git a/libaegisub/windows/log_win.cpp b/libaegisub/windows/log_win.cpp index d5171e5df..91017a8f5 100644 --- a/libaegisub/windows/log_win.cpp +++ b/libaegisub/windows/log_win.cpp @@ -12,14 +12,6 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -/// @file log.cpp -/// @brief Windows logging -/// @ingroup libaegisub - -#include -#include -#include - #include "libaegisub/log.h" #include "libaegisub/charset_conv_win.h" @@ -28,28 +20,25 @@ #define WIN32_LEAN_AND_MEAN #include -namespace agi { - namespace log { - -void EmitSTDOUT::log(SinkMessage *sm) { +namespace agi { namespace log { +void EmitSTDOUT::log(SinkMessage const& sm) { tm tmtime; - time_t time = sm->tv.tv_sec; + time_t time = sm.time / 1000000000; localtime_s(&tmtime, &time); char buff[65536]; - _snprintf_s(buff, _TRUNCATE, "%s (%d): %c %02d:%02d:%02d %-6ld <%-25s> [%s] %.*s\n", - sm->file, - sm->line, - Severity_ID[sm->severity], + _snprintf_s(buff, _TRUNCATE, "%s (%d): %c %02d:%02d:%02d.%-3ld <%-25s> [%s] %.*s\n", + sm.file, + sm.line, + Severity_ID[sm.severity], tmtime.tm_hour, tmtime.tm_min, tmtime.tm_sec, - sm->tv.tv_usec, - sm->section, - sm->func, - sm->message.size(), - sm->message.c_str()); + (long)(sm.time % 1000000000 / 1000000), + sm.section, + sm.func, + (int)sm.message.size(), + sm.message.c_str()); OutputDebugStringW(charset::ConvertW(buff).c_str()); } - } // namespace log -} // namespace agi +} } diff --git a/src/dialog_log.cpp b/src/dialog_log.cpp index 4e404afad..89489653d 100644 --- a/src/dialog_log.cpp +++ b/src/dialog_log.cpp @@ -48,35 +48,35 @@ public: EmitLog(wxTextCtrl *t) : text_ctrl(t) { - for (auto sm : agi::log::log->GetMessages()) - log(&sm); + for (auto const& sm : agi::log::log->GetMessages()) + log(sm); } - void log(agi::log::SinkMessage *sm) override { - time_t time = sm->time / 1000000000; + void log(agi::log::SinkMessage const& sm) override { + time_t time = sm.time / 1000000000; #ifndef _WIN32 tm tmtime; localtime_r(&time, &tmtime); auto log = wxString::Format("%c %02d:%02d:%02d %-6ld <%-25s> [%s:%s:%d] %s\n", - agi::log::Severity_ID[sm->severity], + agi::log::Severity_ID[sm.severity], (int)tmtime.tm_hour, (int)tmtime.tm_min, (int)tmtime.tm_sec, - (long)(sm->time % 1000000000), - sm->section, - sm->file, - sm->func, - sm->line, - to_wx(sm->message)); + (long)(sm.time % 1000000000), + sm.section, + sm.file, + sm.func, + sm.line, + to_wx(sm.message)); #else auto log = wxString::Format("%c %-6ld <%-25s> [%s:%s:%d] %s\n", - agi::log::Severity_ID[sm->severity], - (long)(sm->time % 1000000000), - sm->section, - sm->file, - sm->func, - sm->line, - to_wx(sm->message)); + agi::log::Severity_ID[sm.severity], + (long)(sm.time % 1000000000), + sm.section, + sm.file, + sm.func, + sm.line, + to_wx(sm.message)); #endif if (wxIsMainThread())