[refactor](trx-backend): implement plugin compatibility adapter shim

Replace legacy global BackendRegistry with bootstrap context adapter that
maintains backward compatibility while delegating to explicit context.

Changes:
- Create BOOTSTRAP_CONTEXT: OnceLock<Arc<Mutex<RegistrationContext>>>
- register_backend(): delegates to bootstrap context
- is_backend_registered(): reads from bootstrap context
- registered_backends(): reads from bootstrap context
- build_rig(): reads from bootstrap context

Result: Plugins continue calling global functions, but all operations
now route through the bootstrap context instead of a separate global
registry. This completes the de-globalization while maintaining full
backward compatibility with existing plugins.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
2026-02-12 20:56:11 +01:00
parent ab9604dee9
commit d7f5dc83f8
+19 -36
View File
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: BSD-2-Clause // SPDX-License-Identifier: BSD-2-Clause
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{Mutex, OnceLock}; use std::sync::{Arc, Mutex, OnceLock};
use trx_core::rig::RigCat; use trx_core::rig::RigCat;
use trx_core::DynResult; use trx_core::DynResult;
@@ -73,24 +73,6 @@ impl Default for RegistrationContext {
} }
} }
// Legacy global registry for plugin compatibility
struct BackendRegistry {
factories: HashMap<String, BackendFactory>,
}
impl BackendRegistry {
fn new() -> Self {
Self {
factories: HashMap::new(),
}
}
}
fn registry() -> &'static Mutex<BackendRegistry> {
static REGISTRY: OnceLock<Mutex<BackendRegistry>> = OnceLock::new();
REGISTRY.get_or_init(|| Mutex::new(BackendRegistry::new()))
}
fn normalize_name(name: &str) -> String { fn normalize_name(name: &str) -> String {
name.to_ascii_lowercase() name.to_ascii_lowercase()
.chars() .chars()
@@ -98,11 +80,17 @@ fn normalize_name(name: &str) -> String {
.collect() .collect()
} }
/// Phase 3D: Plugin compatibility adapter - delegates to bootstrap context.
fn bootstrap_context() -> &'static Arc<Mutex<RegistrationContext>> {
static BOOTSTRAP_CONTEXT: OnceLock<Arc<Mutex<RegistrationContext>>> = OnceLock::new();
BOOTSTRAP_CONTEXT.get_or_init(|| Arc::new(Mutex::new(RegistrationContext::new())))
}
/// Register a backend factory under a stable name (e.g. "ft817"). /// Register a backend factory under a stable name (e.g. "ft817").
/// Plugin compatibility: delegates to bootstrap context.
pub fn register_backend(name: &str, factory: BackendFactory) { pub fn register_backend(name: &str, factory: BackendFactory) {
let key = normalize_name(name); let mut ctx = bootstrap_context().lock().expect("backend context mutex poisoned");
let mut reg = registry().lock().expect("backend registry mutex poisoned"); ctx.register_backend(name, factory);
reg.factories.insert(key, factory);
} }
/// Register all built-in backends enabled by features on a context. /// Register all built-in backends enabled by features on a context.
@@ -128,29 +116,24 @@ fn dummy_factory(_access: RigAccess) -> DynResult<Box<dyn RigCat>> {
} }
/// Check whether a backend name is registered. /// Check whether a backend name is registered.
/// Plugin compatibility: reads from bootstrap context.
pub fn is_backend_registered(name: &str) -> bool { pub fn is_backend_registered(name: &str) -> bool {
let key = normalize_name(name); let ctx = bootstrap_context().lock().expect("backend context mutex poisoned");
let reg = registry().lock().expect("backend registry mutex poisoned"); ctx.is_backend_registered(name)
reg.factories.contains_key(&key)
} }
/// List registered backend names. /// List registered backend names.
/// Plugin compatibility: reads from bootstrap context.
pub fn registered_backends() -> Vec<String> { pub fn registered_backends() -> Vec<String> {
let reg = registry().lock().expect("backend registry mutex poisoned"); let ctx = bootstrap_context().lock().expect("backend context mutex poisoned");
let mut names: Vec<String> = reg.factories.keys().cloned().collect(); ctx.registered_backends()
names.sort();
names
} }
/// Instantiate a rig backend based on the selected name and access method. /// Instantiate a rig backend based on the selected name and access method.
/// Plugin compatibility: reads from bootstrap context.
pub fn build_rig(name: &str, access: RigAccess) -> DynResult<Box<dyn RigCat>> { pub fn build_rig(name: &str, access: RigAccess) -> DynResult<Box<dyn RigCat>> {
let key = normalize_name(name); let ctx = bootstrap_context().lock().expect("backend context mutex poisoned");
let reg = registry().lock().expect("backend registry mutex poisoned"); ctx.build_rig(name, access)
let factory = reg
.factories
.get(&key)
.ok_or_else(|| format!("Unknown rig backend: {}", name))?;
factory(access)
} }
#[cfg(feature = "ft817")] #[cfg(feature = "ft817")]