diff options
Diffstat (limited to 'competition/multilog.cpp')
-rw-r--r-- | competition/multilog.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/competition/multilog.cpp b/competition/multilog.cpp new file mode 100644 index 0000000..bf10ec6 --- /dev/null +++ b/competition/multilog.cpp @@ -0,0 +1,57 @@ +#include <iostream> +#include <string> +#include <cassert> +#include "multilog.h" + + +static int uniqid() { + static int i = 0; + return i++; +} + + +MultiLog::Item::Item() + : id(uniqid()) {} + +int MultiLog::add(const string_view prefix) { + lock_guard guard(mut); + + items.emplace_back(); + items.back().line = prefix; + cout << prefix << endl; + return items.back().id; +} + +void MultiLog::append(int id, const string_view text) { + lock_guard guard(mut); + + assert(text.find('\n') == string::npos); + + size_t idx = findId(id); + items[idx].line += text; + redrawLine(idx); +} + +void MultiLog::complete(int id) { + lock_guard guard(mut); + + size_t idx = findId(id); + items[idx].complete = true; + size_t nextIdx; + for (nextIdx = 0; nextIdx < items.size(); nextIdx++) { + if (!items[nextIdx].complete) break; + } + if (nextIdx > 0) items.erase(items.begin(), items.begin() + (nextIdx - 1)); +} + +size_t MultiLog::findId(int id) { + for (int i = 0; i < (int)items.size(); i++) { + if (items[i].id == id) return i; + } + assert(false); +} + +void MultiLog::redrawLine(size_t idx) { + size_t offset = items.size() - idx; + cout << "\r\x1B[" << offset << "A\x1B[K" << items[idx].line << "\r\x1B[" << offset << "B" << flush; +} |