- capi: oakengine_node_output_connection_at/_at_ex returned the source
node as the connection destination; the actual destination is
conn.second.node(). Out-edge enumeration was useless, so the node
view could only draw in-edges and randomly lost whichever edges
needed the out-edge path (random per context build order).
Regression test in oakengine_node_test
- project teardown: Project::clear() pre-notifies node removal while
nodes are fully constructed (observers used to crash on
half-destroyed nodes); childEvent suppresses the removal dance while
clearing; Node::disconnect_all/disconnect_edge get a silent mode for
teardown so no invalidation/events touch dying members
(is_being_cleared); ClipBlock marker disconnect guarded against
dead viewer/markers; ProjectCopier and PreviewAutoCacher drop
project references on Project::destroyed instead of disconnecting
dead objects at shutdown
- preview: add oakengine_preview_request_get_audio_sample_count; the
viewer queried sample count by passing nullptr to get_audio_samples
which rejects it, so all playback audio was silently dropped
- app: fix unterminated input-id memcpy in ResolveGroupInput
(nodeparamviewitem, widgetbridge) that corrupted every parameter id
- app: unsubscribe raw C-API event subscriptions in destructors of
NodeParamViewKeyframeControl, NodeParamViewConnectedLabel and
ExportDialog; playhead events used to fire into dead widgets
(crash when dragging the playhead)
- tests: preview request roundtrip (video frame + audio range) and
free-while-active teardown coverage; env-gated OAK_DEBUG_EDGES /
OAK_DEBUG_INVALID_INPUT diagnostics
- docs: investigation notes in docs/zh/
- app/ no longer includes engine C++ headers nor holds engine C++ types:
engine access goes through the oakengine C ABI plus C++ wrappers
(oakutil/oaknode.h, oakutil/oakvideo.h) and app-local mirror types
(tooltypes, trackreferencehandle, timelinecommonapp, keyframetypes,
subtitleapp, serializedlayoutinfoapp, nodevaluehandle, sliderdisplaytypeapp)
- engine: new C ABI functions for block/track/clip/transition navigation
and predicates, links, caches, waveform/playback, disk folder,
sequence_track_list, node_free, footage_is_valid, block_get_track,
get_brush; loadotio/saveotio ported to the current engine API
- OTIO is now a required dependency: CI and CD build it on every
platform, FindOpenTimelineIO fixed for OTIO 0.16/0.19 (the old deps
include requirement silently disabled OTIO everywhere), runtime
libraries are bundled into packages and copied next to macOS binaries
(oak_copy_otio_runtime)
- fix ProjectViewModel drag&drop mime read/write size mismatch (segfault)
- unify color label naming (k_olive -> "Oak") in the app-side mirror
- docs: OTIO required, FFmpeg minimum corrected to 6.0 (en/zh)
- gtest suite: 1925 passed, 0 failed
Every app module now reaches liboakengine exclusively through
oakengine_* C calls, EngineEventBridge subscriptions and app-side
handle headers (cliphandle/keyframehandle/nodevaluehandle/oakvaluehelper).
Direct C++ command construction, engine signal connect()s, and engine
type usage in MOC-visible signatures are gone: 557 -> 0 undefined
olive:: symbols in oak-editor.
- oakengine_export_render_ex covers the dialog's entire option surface
(formats, codecs, pix fmts, audio params, ranges incl. still frame,
subtitles, scaling, threads, custom OCIO color transform names,
per-codec key/value options) - zero feature reduction
- the dialog's Start now creates a FacadeExportTask that drives
oakengine_export_render_ex instead of constructing ExportTask in the
UI; progress flows through the facade callback and cancel through
oakengine_export_cancel (OAKENGINE_E_CANCELLED preserves the
keep-dialog-open semantics)
- two real fixes: audio sample format 0 no longer means an
AAC-unsupported u8_p (default is f32_p), and image-sequence exports
use the engine's real [#####] placeholder instead of a made-up -%04d
Project items are now represented directly in nodes opening up more versatility and possibilities. This is the first iteration of this and will be buggy. Need to test thoroughly.
The macro defined namespaces confused the hell out of lupdate and more or less broke translations permanently. Looks like the only way we can do it is to have a hardcoded namespace, which goes against my instinct, but honestly how likely is it that we'll change the namespace anyway (I guess forks might want to do it, but that's their problem ;) )
Made various changes and fixes to the task system:
- Tasks are built around QtConcurrent rather than QThread. Reduces
code complexity significantly.
- Task error reporting is now streamlined in both TaskManager and
TaskDialog.
- Moved ProjectImport/Save/LoadManager to the app/task folder