Annotation of nono/lib/object.h, revision 1.1.1.17

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: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.