|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
1.1.1.6 root 9: #include "mystring.h"
1.1 root 10: #include "textscreen.h"
1.1.1.6 root 11: #include <functional>
1.1 root 12: #include <vector>
13:
1.1.1.6 root 14: // ログ表示に指定するラムダ式の便利マクロ。
15: // fmt 内では __func__ が使えないので代わりに lam_func を使うこと。
16: // lstr("%s value=%d", lam_func, value) のようになる。
17: // 他のキャプチャ指定子が必要になったらまた考える。
18: #define lstr(fmt...) \
19: [&, lam_func = __func__] { (void)lam_func; return string_format(fmt); }
20:
1.1 root 21: //
22: // 基本オブジェクト
23: //
24: // ログ出力機能を持つ。
25: //
1.1.1.7 ! root 26: class Object
1.1 root 27: {
28: public:
1.1.1.7 ! root 29: // 引数はオブジェクト名(ログ表示名)で、これはログに前置される。
! 30: // またコンストラクタ指定の場合はエイリアスにも登録する。
! 31: // これは表示名と指示名が同じことが多いための便宜措置。
! 32: // 指示名に表示名を使いたくない場合は ClearAlias() してから
! 33: // AddAlias() すること。
! 34: Object(const std::string& objname_);
! 35:
! 36: virtual ~Object();
! 37:
! 38: // オブジェクト名(ログ表示名)を取得する
! 39: const std::string& GetName() const { return objname; }
! 40:
! 41: // エイリアスリストを返す
! 42: const std::vector<std::string>& GetAliases() const { return log_aliases; }
! 43:
! 44: protected:
! 45: // オブジェクト名を newname に設定(更新)する。
! 46: // 通常、オブジェクト名はコンストラクタで指定するが、コンストラクタ時点
! 47: // ではまだ名前が決まらないような場合にだけ使う。
! 48: // こちらはエイリアスには関与しない。
! 49: void SetName(const std::string& newname) {
! 50: objname = newname;
! 51: }
! 52:
! 53: // エイリアスをクリアする。
! 54: // エイリアスは初期値として、コンストラクタで設定したオブジェクト名が
! 55: // 1つ入っているが、これを削除したい時に使う。
! 56: void ClearAlias() {
! 57: log_aliases.clear();
! 58: }
! 59:
! 60: // エイリアスを追加する。
! 61: void AddAlias(const std::string& alias) {
! 62: log_aliases.emplace_back(alias);
! 63: }
! 64:
! 65: private:
! 66: // オブジェクト名。
! 67: // こちらはログの先頭に追加される。
! 68: std::string objname {};
! 69:
! 70: // エイリアスのリスト。
! 71: // こちらはログ名を指定する時に使う。
! 72: std::vector<std::string> log_aliases {};
1.1 root 73:
1.1.1.7 ! root 74: public:
1.1 root 75: //
76: // ログ
77: //
78:
79: // ログレベル
80: // 0: 未実装動作などのデバッグログではない情報
81: // 1: 大雑把なデバッグログ
82: // 2: 詳細なデバッグログ
83: // 3: うるさいデバッグログ
1.1.1.5 root 84: int loglevel {};
1.1 root 85:
86: // メッセージ出力
1.1.1.6 root 87: // メッセージは仮想時刻も現在の PC も表示しない。Init() など VM 実行前や
1.1 root 88: // 仮想マシン(特に仮想時刻、PC) に関係ないあたりはこちらを使用。
89:
1.1.1.6 root 90: // レベル指定なし、フォーマット版。(レベルを評価した後で使う)
91: void putmsgn(const char *fmt, ...) const __printflike(2, 3);
92:
93: // レベル指定あり、フォーマット版。
94: #define putmsg(lv, fmt...) do { \
95: if (__predict_false(loglevel >= (lv))) { \
96: putmsgn(fmt); \
97: } \
98: } while (0)
99:
100: // レベル指定あり、ラムダ式版。
101: void putmsgf(int lv, std::function<std::string()> msgf) const {
102: if (__predict_false(loglevel >= lv)) {
103: putmsgn("%s", msgf().c_str());
1.1 root 104: }
105: }
106:
107: // ログ出力
1.1.1.6 root 108: // ログは仮想時刻と現在の PC も表示する。VM 実行中は基本的にこれで表示。
109:
110: // レベル指定なし、フォーマット版。(レベルを評価した後で使う)
111: void putlogn(const char *fmt, ...) const __printflike(2, 3);
1.1 root 112:
1.1.1.6 root 113: // レベル指定あり、フォーマット版。
114: #define putlog(lv, fmt...) do { \
115: if (__predict_false(loglevel >= (lv))) { \
116: putlogn(fmt); \
117: } \
118: } while (0)
119:
120: // レベル指定あり、ラムダ式版。
121: void putlogf(int lv, std::function<std::string()> msgf) const {
122: if (__predict_false(loglevel >= lv)) {
123: putlogn("%s", msgf().c_str());
1.1 root 124: }
125: }
126: };
127:
128: // 全オブジェクトのリスト
129: extern std::vector<Object*> gObjects;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.