Real openfx-misc/CImg/Shadertoy bundles (148 plugins at /Library/OFX/Plugins) all failed to load before; every failure was silent. Root causes found one by one with a probe example + lldb: - property suite rejected propSet on undefined properties and propGetDimension on empty ones, and disallowed the index==size append — OFX semantics are create-on-set and appendable dimensions (this alone failed every plugin's describe) - host property set missed the mandatory OfxPropType/OfxPropAPIVersion and the capability props ofxs' fetchHostDescription reads with throwOnFailure=true (IsBackground, TemporalClipAccess, MaxPages, PageRowColumnCount, host SupportedContexts, ...) — one missing prop aborted the read chain and left a half-initialised host description, which made every temporal plugin refuse to load - MultiThreadSuiteV1 lacked the five mutex functions (the plugin reads past the short table — UB); implemented as a real counting-semaphore registry - the OfxHost struct was a stack local; ofxs keeps the POINTER past setHost, so describe/render-time fetchSuite calls dereferenced a dangling stack address (bus error once plugins actually loaded) — the struct is now a leaked process global - General is a standard OFX context and is no longer filtered out (Roto/AppendClip/STMap declare only it) - every scan/load/describe early-out now logs its reason; suite entry points report non-OK statuses with caller location under OAK_OFX_TRACE - examples/scan_probe.rs: scans the real plugin dirs and prints discovered/registered counts (also usable from CI) Result: 148/148 plugins discovered, 134 registered as node types (the remaining 14 need vendor suites — Vegas stereoscopic etc. — and are logged, not silent)
29 lines
1.1 KiB
Rust
29 lines
1.1 KiB
Rust
//! Throwaway probe: scan the real system OFX directory and print what the
|
|
//! host actually discovers (diagnosing why the effect library is empty).
|
|
|
|
fn main() {
|
|
let host = oakplugin::host::Host::global();
|
|
match host.cache.scan() {
|
|
Ok(()) => println!("scan: ok"),
|
|
Err(e) => println!("scan: FAILED: {e}"),
|
|
}
|
|
println!("plugins discovered: {}", host.cache.count());
|
|
// Direct probe: read the host-level props through the C suite table.
|
|
let suite = oakplugin::suites::property::suite_v1();
|
|
unsafe {
|
|
let handle = &host.props as *const oakplugin::property::PropertySet as *mut std::ffi::c_void;
|
|
let name = std::ffi::CString::new("OfxPropName").unwrap();
|
|
let mut out: *mut std::ffi::c_char = std::ptr::null_mut();
|
|
let stat = (suite.get_string)(handle, name.as_ptr(), 0, &mut out);
|
|
println!("direct propGetString(OfxPropName) -> {stat}");
|
|
if stat == 0 && !out.is_null() {
|
|
println!(" value: {:?}", std::ffi::CStr::from_ptr(out));
|
|
}
|
|
}
|
|
let registered = oakplugin::node_factory::register_plugin_nodes();
|
|
println!("factory node types registered: {}", registered.len());
|
|
for id in ®istered {
|
|
println!(" type_id={id}");
|
|
}
|
|
}
|