blob: 2d9f3d669e529b3fe1620a0e9afe962dc897d99c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
#include <iostream>
#include <string>
#include <cassert>
#include "multilog.h"
static int uniqid() {
static int i = 0;
return i++;
}
MultiLog::Item::Item()
: id{uniqid()} {}
MultiLog::MultiLog(bool fancy)
: fancy{fancy} {}
int MultiLog::add(const string_view prefix) {
lock_guard guard(mut);
assert(prefix.find('\n') == string::npos);
items.emplace_back();
items.back().line = prefix;
if (fancy) {
cout << prefix << endl;
} else {
cout << "[" << items.back().id << "] " << 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;
if (fancy) {
redrawLine(idx);
} else {
cout << "[" << items[idx].id << "]... " << text << endl;
}
}
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;
}
|