| 449 | } |
| 450 | |
| 451 | bool ensure_python_bridge_ready_locked() { |
| 452 | if (g_python_bridge_ready.load(std::memory_order_acquire)) { |
| 453 | ensure_builtin_ui_ready_locked(); |
| 454 | return true; |
| 455 | } |
| 456 | |
| 457 | add_dll_directories(); |
| 458 | |
| 459 | LOG_INFO("Attempting to import lichtfeld module..."); |
| 460 | PyObject* lf = import_lichtfeld_module("Failed to import lichtfeld", true); |
| 461 | if (!lf) { |
| 462 | return false; |
| 463 | } |
| 464 | LOG_INFO("lichtfeld module imported successfully"); |
| 465 | |
| 466 | ensure_builtin_ui_ready_locked(); |
| 467 | |
| 468 | // Initialize signal bridge after lfs_plugins.ui.state is available |
| 469 | // Note: signals is registered as lichtfeld.ui.signals |
| 470 | PyObject* ui_module = PyObject_GetAttrString(lf, "ui"); |
| 471 | if (ui_module) { |
| 472 | PyObject* signals = PyObject_GetAttrString(ui_module, "signals"); |
| 473 | if (signals) { |
| 474 | PyObject* init_fn = PyObject_GetAttrString(signals, "init"); |
| 475 | if (init_fn) { |
| 476 | PyObject* result = PyObject_CallNoArgs(init_fn); |
| 477 | if (!result) { |
| 478 | PyErr_Print(); |
| 479 | LOG_ERROR("Failed to initialize signal bridge"); |
| 480 | } else { |
| 481 | Py_DECREF(result); |
| 482 | } |
| 483 | Py_DECREF(init_fn); |
| 484 | } else { |
| 485 | LOG_ERROR("signals.init function not found"); |
| 486 | } |
| 487 | Py_DECREF(signals); |
| 488 | } else { |
| 489 | LOG_ERROR("signals submodule not found in lichtfeld.ui"); |
| 490 | } |
| 491 | Py_DECREF(ui_module); |
| 492 | } else { |
| 493 | LOG_ERROR("ui submodule not found in lichtfeld module"); |
| 494 | } |
| 495 | |
| 496 | Py_DECREF(lf); |
| 497 | g_python_bridge_ready.store(true, std::memory_order_release); |
| 498 | return true; |
| 499 | } |
| 500 | |
| 501 | std::vector<std::string> discover_enabled_plugins_locked() { |
| 502 | std::vector<std::string> names; |
no test coverage detected