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