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