|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2025 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // ログ
9: //
10:
11: #pragma once
12:
13: #include "thread.h"
14: #include <condition_variable>
15: #include <deque>
16: #include <mutex>
17: #include <thread>
18:
19: class TextScreen;
20:
1.1.1.3 ! root 21: // ログメッセージ構造
! 22: class LogMsg
! 23: {
! 24: public:
! 25: enum Type {
! 26: Log,
! 27: Stdout,
! 28: };
! 29:
! 30: public:
! 31: LogMsg() {
! 32: }
! 33: LogMsg(Type type_, const std::string& text_) {
! 34: type = type_;
! 35: text = text_;
! 36: }
! 37:
! 38: Type type {};
! 39: std::string text {};
! 40: };
! 41:
1.1 root 42: // ログは世界が出来る前から(全部終わった最後まで)機能していてほしいため、
43: // ThreadDevice からの継承はしない。
44: // ログウィンドウ用のモニタを持つために Object を継承しているが、
45: // ログは出力できない。
46: class Logger : public Object, public ThreadBase
47: {
48: using inherited = Object;
49:
50: // ログの最大行数。modulo するので 2 のべき乗推奨。
1.1.1.3 ! root 51: static const uint maxlines = 1024;
1.1 root 52:
53: static constexpr uint32 REQ_QUEUE = 0x00000001;
54: static constexpr uint32 REQ_TERMINATE = 0x80000000;
55:
56: public:
57: Logger();
58: ~Logger() override;
59:
60: // スレッドを開始する。
61: bool StartThread();
62:
63: // UTF-8 -> Shift_JIS 変換関数を登録する。
64: void SetConverter(std::string (*)(const std::string&));
65:
66: // スレッドに終了を要求し、その終了を待つ。
67: void TerminateThread();
68:
69: // 標準出力にも出すかどうか
1.1.1.3 ! root 70: void UseStdout(bool val);
1.1 root 71:
72: // ログの表示桁数を変更する。
73: bool ResizeCol(int);
74:
75: // ログ書き込み。
1.1.1.3 ! root 76: void WriteLog(const char *);
! 77:
! 78: // 標準出力への出力。
! 79: void WriteStdout(const char *);
1.1 root 80:
81: // 表示バッファの有効な行数を返す。
82: int GetDispLines() const { return displines; }
83:
84: Monitor *GetMonitor() const { return monitor; }
85:
86: private:
1.1.1.2 root 87: void OnStart();
1.1 root 88: void Terminate();
89: void ThreadRun();
1.1.1.3 ! root 90: void DoStdout(const std::string&);
1.1 root 91: void DoLog(const std::string&);
92: void AddLog(const std::string&);
93: void AddDisplay(const std::string&);
94:
1.1.1.3 ! root 95: DECLARE_MONITOR_SCREEN(MonitorScreen);
1.1 root 96:
1.1.1.3 ! root 97: // ログ・標準出力受け付けキュー。
! 98: std::deque<LogMsg> queue {};
1.1 root 99:
100: // ログ受け付けキューの条件変数。
101: uint32 request {};
102: std::mutex queue_mtx {};
103: std::condition_variable cv {};
104:
1.1.1.3 ! root 105: // 標準出力にも出すかどうか。
1.1 root 106: bool use_stdout {};
107:
108: // バックログの実体。
109: std::deque<std::string> logs {};
110:
111: // 表示用に構成した中間バッファ。
112: // 横が col 桁 * 高さ maxlines 行の固定長。
113: // 行単位のリングバッファとして使う。
114: // そのまま表示用になるので、空いてるところは ' '(空白) で埋める。
115: std::vector<uint8> dispbuf {};
116:
117: // 表示バッファの桁数。
118: uint col {};
119:
120: // 次に書き込む行 (== 最古の行)。dispbuf の先頭を 0行目と数える。
121: int current {};
122:
123: // 表示バッファの有効な行数。
124: int displines {};
125:
126: // UTF-8 -> Shift_JIS 変換関数。(GUI が登録する)
1.1.1.3 ! root 127: std::string (*utf8_to_sjis_converter)(const std::string&) {};
1.1 root 128:
129: Monitor *monitor {};
130:
131: // バックログのロック。
132: std::mutex backend_mtx {};
133:
134: // スレッド。
135: std::unique_ptr<std::thread> thread {};
136:
137: // スレッド開始同期用
138: std::mutex thread_starter {};
139: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.