|
|
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"
1.1.1.9 root 14: #include "object_id.h"
1.1.1.6 root 15: #include <functional>
1.1 root 16: #include <vector>
17:
1.1.1.8 root 18: class Logger;
19:
1.1.1.9 root 20: // オブジェクト ID
1.1.1.10! root 21: static constexpr int OBJ_BANKRAM(int n) { return OBJ_BANKRAM0 + n; }
! 22: static constexpr int OBJ_ETHERNET(int n) { return OBJ_ETHERNET0 + n; }
1.1.1.9 root 23: static constexpr int OBJ_FDD(int n) { return OBJ_FDD0 + n; }
1.1.1.10! root 24: static constexpr int OBJ_HOSTNET(int n) { return OBJ_HOSTNET0 + n; }
1.1.1.9 root 25: static constexpr int OBJ_M88200(int n) { return OBJ_M88200_0 + n; }
26: static constexpr int OBJ_MPU_MEMDUMP(int n) { return OBJ_MPU_MEMDUMP0 + n; }
1.1.1.10! root 27: static constexpr int OBJ_NEREID_BOARD(int n) { return OBJ_NEREID_BOARD0 + n; }
1.1.1.9 root 28: static constexpr int OBJ_XP_MEMDUMP(int n) { return OBJ_XP_MEMDUMP0 + n; }
29:
1.1.1.6 root 30: // ログ表示に指定するラムダ式の便利マクロ。
31: // fmt 内では __func__ が使えないので代わりに lam_func を使うこと。
32: // lstr("%s value=%d", lam_func, value) のようになる。
33: // 他のキャプチャ指定子が必要になったらまた考える。
34: #define lstr(fmt...) \
35: [&, lam_func = __func__] { (void)lam_func; return string_format(fmt); }
36:
1.1 root 37: // 基本オブジェクト
1.1.1.7 root 38: class Object
1.1 root 39: {
40: public:
1.1.1.9 root 41: // 引数はオブジェクト ID。
42: // ID と紐付けされたオブジェクト名は、ログ表示名で、ログに前置される。
1.1.1.7 root 43: // またコンストラクタ指定の場合はエイリアスにも登録する。
44: // これは表示名と指示名が同じことが多いための便宜措置。
45: // 指示名に表示名を使いたくない場合は ClearAlias() してから
46: // AddAlias() すること。
1.1.1.9 root 47: Object(int objid_);
1.1.1.7 root 48:
49: virtual ~Object();
50:
1.1.1.9 root 51: // ID を返す
52: int GetId() const { return objid; }
53: const char *GetIdStr() const;
54:
55: // ID を文字列で返す
56: static const char *GetIdStr(int target_id);
57:
1.1.1.7 root 58: // オブジェクト名(ログ表示名)を取得する
59: const std::string& GetName() const { return objname; }
60:
61: // エイリアスリストを返す
62: const std::vector<std::string>& GetAliases() const { return log_aliases; }
63:
1.1.1.9 root 64: // 指定の id を持つオブジェクトを返す。
65: // 実体は gMainApp.GetObjects() を呼んでいる。
66: // 隣のデバイスを参照したい人が全員 mainapp.h を include しなくて済む
67: // ようにするための便宜上のもの。
68: static Object *GetObject(int target_id);
69:
70: // 指定の id を持つオブジェクトを型 T* にして返す版。
71: template <typename T>
72: static T *GetObject(int target_id) {
73: auto dev = dynamic_cast<T *>(GetObject(target_id));
74: assert(dev);
75: return dev;
76: }
77:
1.1.1.7 root 78: protected:
79: // オブジェクト名を newname に設定(更新)する。
80: // 通常、オブジェクト名はコンストラクタで指定するが、コンストラクタ時点
81: // ではまだ名前が決まらないような場合にだけ使う。
82: // こちらはエイリアスには関与しない。
83: void SetName(const std::string& newname) {
84: objname = newname;
85: }
86:
87: // エイリアスをクリアする。
88: // エイリアスは初期値として、コンストラクタで設定したオブジェクト名が
89: // 1つ入っているが、これを削除したい時に使う。
90: void ClearAlias() {
91: log_aliases.clear();
92: }
93:
94: // エイリアスを追加する。
95: void AddAlias(const std::string& alias) {
96: log_aliases.emplace_back(alias);
97: }
98:
99: private:
1.1.1.9 root 100: int objid {};
101:
1.1.1.7 root 102: // オブジェクト名。
103: // こちらはログの先頭に追加される。
104: std::string objname {};
105:
106: // エイリアスのリスト。
107: // こちらはログ名を指定する時に使う。
108: std::vector<std::string> log_aliases {};
1.1 root 109:
1.1.1.9 root 110: // オブジェクト ID からオブジェクト名(ログ名)変換テーブル
111: static const std::vector<const char *> idname;
112:
113: // オブジェクト ID を文字列にしたもの
114: static const std::vector<const char *> idtext;
115:
1.1.1.7 root 116: public:
1.1 root 117: //
118: // ログ
119: //
120:
1.1.1.8 root 121: // ログレベルを設定する
122: virtual void SetLogLevel(int loglevel_);
1.1 root 123:
124: // メッセージ出力
1.1.1.6 root 125: // メッセージは仮想時刻も現在の PC も表示しない。Init() など VM 実行前や
1.1 root 126: // 仮想マシン(特に仮想時刻、PC) に関係ないあたりはこちらを使用。
127:
1.1.1.6 root 128: // レベル指定なし、フォーマット版。(レベルを評価した後で使う)
129: void putmsgn(const char *fmt, ...) const __printflike(2, 3);
130:
131: // レベル指定あり、フォーマット版。
132: #define putmsg(lv, fmt...) do { \
133: if (__predict_false(loglevel >= (lv))) { \
134: putmsgn(fmt); \
135: } \
136: } while (0)
137:
138: // レベル指定あり、ラムダ式版。
139: void putmsgf(int lv, std::function<std::string()> msgf) const {
140: if (__predict_false(loglevel >= lv)) {
141: putmsgn("%s", msgf().c_str());
1.1 root 142: }
143: }
144:
145: // ログ出力
1.1.1.6 root 146: // ログは仮想時刻と現在の PC も表示する。VM 実行中は基本的にこれで表示。
147:
148: // レベル指定なし、フォーマット版。(レベルを評価した後で使う)
1.1.1.8 root 149: virtual void putlogn(const char *fmt, ...) const __printflike(2, 3);
1.1 root 150:
1.1.1.6 root 151: // レベル指定あり、フォーマット版。
152: #define putlog(lv, fmt...) do { \
153: if (__predict_false(loglevel >= (lv))) { \
154: putlogn(fmt); \
155: } \
156: } while (0)
157:
158: // レベル指定あり、ラムダ式版。
159: void putlogf(int lv, std::function<std::string()> msgf) const {
160: if (__predict_false(loglevel >= lv)) {
161: putlogn("%s", msgf().c_str());
1.1 root 162: }
163: }
164:
1.1.1.8 root 165: // オブジェクト登録時に代入される
166: Logger *logger {};
167:
168: // ログレベルの目安
169: // 0: 未実装動作などのデバッグログではない情報
170: // 1: 大雑把なデバッグログ
171: // 2: 詳細なデバッグログ
172: // 3: うるさいデバッグログ
173: int loglevel {};
174:
175: protected:
176: // ログ直接出力
177: void WriteLog(const char *) const;
178: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.