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

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

unix.superglobalmegacorp.com

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