feat: built-in effect params, clip click-select, effect drag-and-drop, project load with plugins
- serializer resolves node types through the factory's dynamic (runtime-registered OpenFX) entries, so a project carrying plugin nodes loads again (was: "unknown node type"); covered by a new CI-gated round-trip test driving the real fixture plugin - built-in effect nodes expose their inputs as inspector parameters like the C++ parameter editor: localized input names from the behavior, combo option tables via the new NodeBehavior::input_combo_strings (16 nodes, string-for-string from the C++ set_combo_box_strings), connection/data inputs excluded - effect library: live drag-and-drop — onto the inspector's effect stack (lands at the indicator position) and onto the node editor canvas (creates the node at the drop point); double-click still appends to the selected clip - inspector parameter controls are no longer recreated per render (gpui stack view caches them per effect), so sliders drag and checkboxes click; the view observes the engine and silently re-syncs values (undo/redo land on the widgets) - timeline: left-press selects clips (plain/keep-multi/Ctrl-Cmd toggle); clip moves clamp the shared delta so no clip of a linked group lands before frame 0 instead of failing with "invalid move target" - oakplugin: createInstance-rejected instances skip the destroyInstance notification (the plugin never owned them); vendor-suite fetchSuite misses moved behind OAK_OFX_TRACE; the worker logs the discovered/ registered plugin counts - CI: the OFX probe step also runs the serialization round-trip test - gpui submodule: params view caching, clip click-select, library drag payload, graph_position_at
This commit is contained in:
@@ -158,9 +158,10 @@ unsafe extern "C" fn host_fetch_suite(
|
||||
p
|
||||
}
|
||||
Ok(None) => {
|
||||
// 诊断:插件请求的 suite 宿主没有(describe 常因此返回
|
||||
// kOfxStatErrMissingHostFeature)。
|
||||
if !name.is_null() {
|
||||
// 诊断:插件请求的 suite 宿主没有。厂商套件(Nuke/Vegas/
|
||||
// Foundry)的探测是插件的正常行为,不打正式日志——需要
|
||||
// 排查时用 OAK_OFX_TRACE 打开。
|
||||
if std::env::var_os("OAK_OFX_TRACE").is_some() && !name.is_null() {
|
||||
if let Ok(n) = unsafe { CStr::from_ptr(name) }.to_str() {
|
||||
eprintln!("[ofx] fetchSuite miss: {n} v{version}");
|
||||
}
|
||||
@@ -1222,6 +1223,12 @@ impl Host {
|
||||
.call_action(ACTION_CREATE_INSTANCE, inst_handle, &empty, &empty)
|
||||
};
|
||||
if stat != status::OK && stat != status::REPLY_DEFAULT {
|
||||
// 插件拒绝了 createInstance——它从没认领这个实例;把
|
||||
// destroyed 门置位,让随后的 drop 跳过 destroyInstance 通知
|
||||
// (否则插件对一个它没创建的实例回 BadIndex 之类的错误)。
|
||||
arc.value
|
||||
.destroyed
|
||||
.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
return Err(crate::error::Error::Failed(format!(
|
||||
"createInstance 失败:{stat}"
|
||||
)));
|
||||
|
||||
Reference in New Issue
Block a user