feat(engine,app): effect chain facade + app effect stack wiring
facade (oakengine/oaknode, API only extended): - oaknode_node_get_effect_input / oaknode_node_get_flags module exports - oakengine_clip_as_node, oakengine_node_effect_count/at/insert/remove/ move/set_enabled, oakengine_node_identity/is_enabled/get_type_id, oakengine_node_factory_id_at — chain edits wrap disconnect/reconnect into single undo groups; insert/move/remove validated against the factory and the host's effect input - it_node covers enumeration/insert/remove/move/toggle/undo-redo and the NULL/illegal-input matrix app: - RealEngine binds the selected clip's effect chain to the inspector's effect stack (cards, enable, reorder, remove, expansion state), all edits undoable through the facade - AppEngine gains set_selected_clips / addable_effects / add_effect (default no-ops keep the mock untouched); the timeline selection drives the stack target; the inspector gets a small add-effect menu - known module gap (documented): ClipBlockBehavior sets no effect_input yet, so timeline clips cannot host effects until oaknode grows tex_in
This commit is contained in:
@@ -1016,6 +1016,40 @@ pub mod node {
|
||||
})
|
||||
}
|
||||
|
||||
/// `oaknode_node_get_effect_input` (two-stage; `Node::GetEffectInputID()`).
|
||||
///
|
||||
/// The id of the input the effect chain attaches to (empty when the node
|
||||
/// cannot host effects — the C++ contract: "If this is empty, effects
|
||||
/// cannot attach to this node").
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oaknode_node_get_effect_input(
|
||||
node: CHandle,
|
||||
buf: *mut c_char,
|
||||
buf_size: c_int,
|
||||
) -> c_int {
|
||||
let n = match unsafe { node_ref(&node) } {
|
||||
Ok(n) => n,
|
||||
Err(_) => return crate::error::OAKNODE_E_INVALID,
|
||||
};
|
||||
let effect_input = with_graph_read(&n.project, |g| {
|
||||
g.get(n.id).map(|e| e.core.effect_input.clone())
|
||||
});
|
||||
match effect_input {
|
||||
Some(id) => copy_string_out(&id, buf, buf_size),
|
||||
None => crate::error::OAKNODE_E_NOT_FOUND,
|
||||
}
|
||||
}
|
||||
|
||||
/// `oaknode_node_get_flags` — the node's flags bitmask (`Node::flags_`).
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn oaknode_node_get_flags(node: CHandle) -> u64 {
|
||||
let n = match unsafe { node_ref(&node) } {
|
||||
Ok(n) => n,
|
||||
Err(_) => return 0,
|
||||
};
|
||||
with_graph_read(&n.project, |g| g.get(n.id).map(|e| e.core.flags)).unwrap_or(0)
|
||||
}
|
||||
|
||||
// ---- Input introspection ------------------------------------------
|
||||
|
||||
/// `oaknode_node_input_count`.
|
||||
|
||||
Reference in New Issue
Block a user