--- nono/lib/monitor.cpp 2026/04/29 17:05:15 1.1.1.3 +++ nono/lib/monitor.cpp 2026/04/29 17:05:52 1.1.1.7 @@ -20,47 +20,24 @@ 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(0 <= id_ && id_ < ID_SUBWIN_MAX); - - // ポカ避けのため assert を入れたいが Bt45x は後から関数を決める方式 - //assert(func); - - id = id_; - assert(gMonitorManager); - gMonitorManager->Regist(this); -} - -// このモニタが登録されていれば削除する -void -Monitor::Unregist() -{ - assert(gMonitorManager); - gMonitorManager->Unregist(this); } // ID を表示用文字列にして返す /*static*/ const char * -Monitor::GetIdText(int target_id) +Monitor::GetIdText(uint target_id) { for (const auto& p : idtext) { - int id = p.first; + uint id = p.first; const char *text = p.second; if (id == target_id) { @@ -89,24 +66,34 @@ MonitorManager::~MonitorManager() gMonitorManager = NULL; } -// 登録 -void -MonitorManager::Regist(Monitor *mon) +// 登録(というか初期化というか確保というか)。 +// 成功すればモニターを返す。通常失敗しない。 +// 失敗すればいずれのケースも assert で終了する。 +Monitor * +MonitorManager::Regist(uint id_, Object *parent_) { - assert(fixed == false); + assert(id_ < ID_SUBWIN_MAX); - // 二重登録防止 - assert(Find(mon->GetId()) == NULL); + // 追加が遅すぎる。 + assert(fixed == false); - // 登録 - list.emplace_back(mon); + // 二重登録防止。 + assertmsg((bool)monitors[id_] == false, + "%s already registered", Monitor::GetIdText(id_)); + + // 生成。 + 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) { // ソートして.. @@ -117,19 +104,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(); } @@ -140,19 +124,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]; @@ -161,11 +183,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++) { @@ -174,7 +195,7 @@ MonitorManager::MakeListString(std::vect } str += ')'; } - str += '\n'; + rv.push_back(str); } - return str; + return rv; }