--- nono/lib/monitor.cpp 2026/04/29 17:04:54 1.1.1.1 +++ nono/lib/monitor.cpp 2026/04/29 17:05:56 1.1.1.8 @@ -4,11 +4,13 @@ // Licensed under nono-license.txt // +// +// モニタ管理 +// + #include "monitor.h" #include -MonitorManager gMonitorManager; - // // モニター // @@ -18,35 +20,31 @@ Monitor::Monitor() { } -// コンストラクタ (obj 指定あり) -Monitor::Monitor(Object *obj_) +// コンストラクタ +Monitor::Monitor(uint id_, Object *obj_) { + id = id_; obj = obj_; } // デストラクタ Monitor::~Monitor() { - Unregist(); } -// このモニタを登録する -void -Monitor::Regist(int id_) -{ - assert(obj); - assert(func); - assert(0 <= id_ && id_ < ID_SUBWIN_MAX); - - id = id_; - gMonitorManager.Regist(this); -} +// ID を表示用文字列にして返す +/*static*/ const char * +Monitor::GetIdText(uint target_id) +{ + for (const auto& p : idtext) { + uint id = p.first; + const char *text = p.second; -// このモニタが登録されていれば削除する -void -Monitor::Unregist() -{ - gMonitorManager.Unregist(this); + if (id == target_id) { + return text; + } + } + return "unknownID?"; } @@ -54,25 +52,68 @@ Monitor::Unregist() // モニターマネージャ // -// 登録 -void -MonitorManager::Regist(Monitor *mon) +// グローバル参照用 +MonitorManager *gMonitorManager; + +// コンストラクタ +MonitorManager::MonitorManager() { - assert(fixed == false); +} + +// デストラクタ +MonitorManager::~MonitorManager() +{ + gMonitorManager = NULL; +} + +// モニタを登録。 +Monitor * +MonitorManager::Regist(uint id_, Object *parent_) +{ + return RegistCommon(id_, parent_, NULL); +} - int id = mon->GetId(); - // 二重登録防止 - assert(Find(id) == NULL); +// 呼び出し側で作成したモニタを登録。 +Monitor * +MonitorManager::Regist(Monitor *monitor_) +{ + return RegistCommon(monitor_->GetId(), monitor_->obj, monitor_); +} - // 登録 - list.emplace_back(mon); +// id_, parent_ のモニタを登録。 +// monitor_ は通常 NULL を指定しておけばこちらで標準モニタを作成する。 +// 呼び出し元で派生クラスなどを生成していればそれを指定。 +// 成功すればモニターを返す。通常失敗しない。 +// 失敗すればいずれのケースも assert で終了する。 +Monitor * +MonitorManager::RegistCommon(uint id_, Object *parent_, Monitor *monitor_) +{ + assert(id_ < ID_SUBWIN_MAX); + + // 追加が遅すぎる。 + assert(fixed == false); + + // 二重登録防止。 + assertmsg((bool)monitors[id_] == false, + "%s already registered", Monitor::GetIdText(id_)); + + // 登録、もしくはここで生成。 + if (monitor_) { + monitors[id_].reset(monitor_); + } else { + monitors[id_].reset(new Monitor(id_, parent_)); + assertmsg((bool)monitors[id_], "cannot create new monitor"); + } // 名前が衝突していないことを確認。 // どのケースの衝突も検出できるよう、追加後に全部列挙して.. std::vector names; - for (const auto& m : list) { - const std::vector& aliases = GetAliases(m->GetId()); - names.insert(names.end(), aliases.begin(), aliases.end()); + for (const auto& uptr : monitors) { + if ((bool)uptr) { + const Monitor *m = uptr.get(); + const std::vector& aliases = GetAliases(m->GetId()); + names.insert(names.end(), aliases.begin(), aliases.end()); + } } if (names.size() > 1) { // ソートして.. @@ -83,19 +124,16 @@ MonitorManager::Regist(Monitor *mon) "monitor alias \"%s\" duplicated", names[i].c_str()); } } + + return monitors[id_].get(); } // mon がリストにあれば削除する。なければ何もしない。 void MonitorManager::Unregist(Monitor *mon) { - // 最初に見付かった一つを削除するだけでいい - for (auto it = list.begin(); it != list.end(); ++it) { - if (*it == mon) { - list.erase(it); - break; - } - } + uint id = mon->GetId(); + monitors[id].reset(); } @@ -106,19 +144,57 @@ MonitorManager::Fix() assert(fixed == false); fixed = true; + + // デバッグ用。 + if (0) { + uint i = 0; + for (const auto& uptr : monitors) { + if ((bool)uptr) { + const Monitor *m = uptr.get(); + auto sz = m->GetSize(); + printf("[%2u] %s\t%d,%d\n", i++, m->GetIdText(), + sz.width, sz.height); + } + } + } +} + +// 指定された id を持つモニターを返す。 +// こっちは、なければ assert する。 +Monitor * +MonitorManager::Get(uint id) const +{ + Monitor *mon = Find(id); + assertmsg(mon, "id=%u not found", id); + return mon; +} + +// 現在登録されているモニターの一覧を返す。 +const std::vector +MonitorManager::GetList() const +{ + std::vector list; + + for (auto& uptr : monitors) { + if ((bool)uptr) { + list.push_back(uptr.get()); + } + } + + return list; } -// id リストから一覧表示用の文字列を生成して返す -/*static*/ std::string -MonitorManager::MakeListString(std::vector list) +// id リストから一覧表示用の文字列リストを生成して返す +std::vector +MonitorManager::MakeListString(std::vector list) const { - std::string str; + std::vector rv; // id をモニター情報内の1つ目の名前順にソートする std::sort(list.begin(), list.end(), - [](const auto& a_id, const auto& b_id) { - const auto& a_alias = gMonitorManager.GetAliases(a_id); - const auto& b_alias = gMonitorManager.GetAliases(b_id); + [&](const auto& a_id, const auto& b_id) { + const auto& a_alias = GetAliases(a_id); + const auto& b_alias = GetAliases(b_id); const std::string a_name = a_alias[0]; const std::string b_name = b_alias[0]; @@ -127,11 +203,10 @@ MonitorManager::MakeListString(std::vect ); for (const auto id : list) { - const auto& aliases = gMonitorManager.GetAliases(id); + const auto& aliases = GetAliases(id); assert(aliases.empty() == false); - str += ' '; - str += aliases[0]; + std::string str = aliases[0]; if (aliases.size() > 1) { str += " (alias:"; for (int i = 1, sz = aliases.size(); i < sz; i++) { @@ -140,7 +215,7 @@ MonitorManager::MakeListString(std::vect } str += ')'; } - str += '\n'; + rv.push_back(str); } - return str; + return rv; }