| 296 | } // namespace |
| 297 | |
| 298 | void PyMenuRegistry::register_menu(nb::object menu_class) { |
| 299 | if (!menu_class.is_valid()) { |
| 300 | LOG_ERROR("register_menu: invalid menu_class"); |
| 301 | return; |
| 302 | } |
| 303 | |
| 304 | const std::string idname = nb::cast<std::string>(menu_class.attr("__module__")) + "." + |
| 305 | nb::cast<std::string>(menu_class.attr("__qualname__")); |
| 306 | |
| 307 | std::string label; |
| 308 | MenuLocation location = MenuLocation::File; |
| 309 | int order = 100; |
| 310 | |
| 311 | try { |
| 312 | if (nb::hasattr(menu_class, "label")) |
| 313 | label = nb::cast<std::string>(menu_class.attr("label")); |
| 314 | if (nb::hasattr(menu_class, "location")) |
| 315 | location = parse_menu_location(nb::cast<std::string>(menu_class.attr("location"))); |
| 316 | if (nb::hasattr(menu_class, "order")) |
| 317 | order = nb::cast<int>(menu_class.attr("order")); |
| 318 | } catch (const std::exception& e) { |
| 319 | LOG_ERROR("register_menu: failed to extract attributes: {}", e.what()); |
| 320 | return; |
| 321 | } |
| 322 | |
| 323 | nb::object instance; |
| 324 | try { |
| 325 | instance = menu_class(); |
| 326 | } catch (const std::exception& e) { |
| 327 | LOG_ERROR("register_menu: failed to create instance for '{}': {}", idname, e.what()); |
| 328 | return; |
| 329 | } |
| 330 | |
| 331 | std::lock_guard lock(mutex_); |
| 332 | |
| 333 | auto it = std::find_if(menu_classes_.begin(), menu_classes_.end(), |
| 334 | [&idname](const PyMenuClassInfo& mc) { return mc.idname == idname; }); |
| 335 | |
| 336 | if (it != menu_classes_.end()) { |
| 337 | it->label = label; |
| 338 | it->location = location; |
| 339 | it->order = order; |
| 340 | it->menu_class = menu_class; |
| 341 | it->menu_instance = instance; |
| 342 | } else { |
| 343 | menu_classes_.push_back({idname, label, location, order, menu_class, instance}); |
| 344 | } |
| 345 | |
| 346 | sort_by_order(menu_classes_); |
| 347 | } |
| 348 | |
| 349 | void PyMenuRegistry::unregister_menu(nb::object menu_class) { |
| 350 | const std::string idname = nb::cast<std::string>(menu_class.attr("__module__")) + "." + |
no test coverage detected