|
|
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: ! 21: // ログは世界が出来る前から(全部終わった最後まで)機能していてほしいため、 ! 22: // ThreadDevice からの継承はしない。 ! 23: // ログウィンドウ用のモニタを持つために Object を継承しているが、 ! 24: // ログは出力できない。 ! 25: class Logger : public Object, public ThreadBase ! 26: { ! 27: using inherited = Object; ! 28: ! 29: // ログの最大行数。modulo するので 2 のべき乗推奨。 ! 30: static const uint maxlines = 64; ! 31: ! 32: static constexpr uint32 REQ_QUEUE = 0x00000001; ! 33: static constexpr uint32 REQ_TERMINATE = 0x80000000; ! 34: ! 35: public: ! 36: Logger(); ! 37: ~Logger() override; ! 38: ! 39: // スレッドを開始する。 ! 40: bool StartThread(); ! 41: ! 42: // UTF-8 -> Shift_JIS 変換関数を登録する。 ! 43: void SetConverter(std::string (*)(const std::string&)); ! 44: ! 45: // スレッドに終了を要求し、その終了を待つ。 ! 46: void TerminateThread(); ! 47: ! 48: // 標準出力にも出すかどうか ! 49: void UseStdout(bool val) { use_stdout = val; } ! 50: ! 51: // ログの表示桁数を変更する。 ! 52: bool ResizeCol(int); ! 53: ! 54: // ログ書き込み。 ! 55: void Write(const char *); ! 56: ! 57: // 表示バッファの有効な行数を返す。 ! 58: int GetDispLines() const { return displines; } ! 59: ! 60: Monitor *GetMonitor() const { return monitor; } ! 61: ! 62: private: ! 63: void Terminate(); ! 64: void ThreadRun(); ! 65: void DoLog(const std::string&); ! 66: void AddLog(const std::string&); ! 67: void AddDisplay(const std::string&); ! 68: ! 69: DECLARE_MONITOR_CALLBACK(MonitorUpdate); ! 70: ! 71: // ログ受け付けキュー。 ! 72: std::deque<std::string> queue {}; ! 73: ! 74: // ログ受け付けキューの条件変数。 ! 75: uint32 request {}; ! 76: std::mutex queue_mtx {}; ! 77: std::condition_variable cv {}; ! 78: ! 79: // 標準出力にも出すかどうか ! 80: bool use_stdout {}; ! 81: ! 82: // バックログの実体。 ! 83: std::deque<std::string> logs {}; ! 84: ! 85: // 表示用に構成した中間バッファ。 ! 86: // 横が col 桁 * 高さ maxlines 行の固定長。 ! 87: // 行単位のリングバッファとして使う。 ! 88: // そのまま表示用になるので、空いてるところは ' '(空白) で埋める。 ! 89: std::vector<uint8> dispbuf {}; ! 90: ! 91: // 表示バッファの桁数。 ! 92: uint col {}; ! 93: ! 94: // 次に書き込む行 (== 最古の行)。dispbuf の先頭を 0行目と数える。 ! 95: int current {}; ! 96: ! 97: // 表示バッファの有効な行数。 ! 98: int displines {}; ! 99: ! 100: // UTF-8 -> Shift_JIS 変換関数。(GUI が登録する) ! 101: std::string (*utf8_to_sjis_converter)(const std::string&); ! 102: ! 103: Monitor *monitor {}; ! 104: ! 105: // バックログのロック。 ! 106: std::mutex backend_mtx {}; ! 107: ! 108: // スレッド。 ! 109: std::unique_ptr<std::thread> thread {}; ! 110: ! 111: // スレッド開始同期用 ! 112: std::mutex thread_starter {}; ! 113: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.