app: migrate all engine access to the C ABI facade (nm U _ZN5olive = 0)
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.
This commit is contained in:
@@ -25,15 +25,20 @@
|
||||
|
||||
#include "common/autoscroll.h"
|
||||
#include "common/range.h"
|
||||
#include "config/config.h"
|
||||
#include "common/configwrapper.h"
|
||||
#include "core.h"
|
||||
#include "engineeventbridge.h"
|
||||
#include "common/current.h"
|
||||
#include "dialog/markerproperties/markerpropertiesdialog.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "oakengine/timeline.h"
|
||||
#include "timeline/timelineundoworkarea.h"
|
||||
#include "oakengine/viewer.h"
|
||||
#include "oakengine/timeline.h"
|
||||
#include "oakengine/undo.h"
|
||||
#include "widget/timeruler/timeruler.h"
|
||||
#include "widget/timelinewidget/cliphandle.h"
|
||||
|
||||
#include "widget/viewer/vieweroutpututils.h"
|
||||
namespace olive
|
||||
{
|
||||
|
||||
@@ -42,6 +47,7 @@ TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible,
|
||||
QWidget *parent)
|
||||
: TimelineScaledWidget(parent)
|
||||
, viewer_node_(nullptr)
|
||||
, bridge_(new EngineEventBridge(this))
|
||||
, auto_max_scrollbar_(false)
|
||||
, toggle_show_all_(false)
|
||||
, auto_set_timebase_(true)
|
||||
@@ -95,33 +101,28 @@ void TimeBasedWidget::connect_viewer_node(ViewerOutput *node)
|
||||
// Set viewer node
|
||||
ViewerOutput *old = viewer_node_.data();
|
||||
viewer_node_ = node;
|
||||
|
||||
// Disconnect old bridge subscriptions and connections
|
||||
disconnect(bridge_, nullptr, this, nullptr);
|
||||
bridge_->unsubscribe_all();
|
||||
|
||||
if (viewer_node_) {
|
||||
oak_video_params vp;
|
||||
oakengine_viewer_get_video_params(
|
||||
reinterpret_cast<OakEngineNode *>(viewer_node_.data()), 0, &vp);
|
||||
// We still need Current class - keep using it for now
|
||||
Current::getInstance().setCurrentVideoParams(
|
||||
viewer_node_->get_video_params());
|
||||
viewer_output_video_params(viewer_node_));
|
||||
Current::getInstance().setCurrentAudioParams(
|
||||
viewer_node_->get_audio_params());
|
||||
viewer_output_audio_params(viewer_node_));
|
||||
} else {
|
||||
Current::getInstance().setCurrentVideoParams(VideoParams());
|
||||
Current::getInstance().setCurrentVideoParams(empty_video_params());
|
||||
Current::getInstance().setCurrentAudioParams(AudioParams());
|
||||
}
|
||||
if (old) {
|
||||
// Call potential derivative functions for disconnecting the viewer node
|
||||
DisconnectNodeEvent(old);
|
||||
|
||||
// Disconnect length changed signal
|
||||
disconnect(old, &ViewerOutput::length_changed, this,
|
||||
&TimeBasedWidget::update_maximum_scroll);
|
||||
disconnect(old, &ViewerOutput::removed_from_graph, this,
|
||||
&TimeBasedWidget::connected_node_removed_from_graph);
|
||||
disconnect(old, &ViewerOutput::playhead_changed, this,
|
||||
&TimeBasedWidget::playhead_time_changed);
|
||||
|
||||
// Disconnect rate change signals if they were connected
|
||||
disconnect(old, &ViewerOutput::frame_rate_changed, this,
|
||||
&TimeBasedWidget::auto_update_timebase);
|
||||
disconnect(old, &ViewerOutput::sample_rate_changed, this,
|
||||
&TimeBasedWidget::auto_update_timebase);
|
||||
|
||||
// Reset timebase to null
|
||||
SetTimebase(Rational());
|
||||
|
||||
@@ -137,13 +138,28 @@ void TimeBasedWidget::connect_viewer_node(ViewerOutput *node)
|
||||
ConnectedNodeChangeEvent(viewer_node_.data());
|
||||
|
||||
if (viewer_node_) {
|
||||
// Connect length changed signal
|
||||
connect(viewer_node_.data(), &ViewerOutput::length_changed, this,
|
||||
&TimeBasedWidget::update_maximum_scroll);
|
||||
connect(viewer_node_.data(), &ViewerOutput::removed_from_graph, this,
|
||||
&TimeBasedWidget::connected_node_removed_from_graph);
|
||||
connect(viewer_node_.data(), &ViewerOutput::playhead_changed, this,
|
||||
&TimeBasedWidget::playhead_time_changed);
|
||||
OakEngineNode *handle =
|
||||
reinterpret_cast<OakEngineNode *>(viewer_node_.data());
|
||||
|
||||
// Subscribe to viewer events via bridge
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_VIEWER_LENGTH_CHANGED);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_VIEWER_PLAYHEAD_CHANGED);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_NODE_REMOVED_FROM_GRAPH);
|
||||
|
||||
connect(bridge_, &EngineEventBridge::viewer_length_changed, this,
|
||||
[this](OakEngineNode *, qint64, qint64) {
|
||||
update_maximum_scroll();
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::viewer_playhead_changed, this,
|
||||
[this](OakEngineNode *, qint64 num, qint64 den) {
|
||||
playhead_time_changed(Rational(num, den));
|
||||
});
|
||||
|
||||
// Node removed from graph - use the bridge signal
|
||||
connect(bridge_, &EngineEventBridge::node_removed_from_graph, this,
|
||||
[this](OakEngineNode *, OakEngineNode *) {
|
||||
connected_node_removed_from_graph();
|
||||
});
|
||||
|
||||
// Connect ruler and scrollbar to timeline points
|
||||
connect_work_area(viewer_node_->get_work_area());
|
||||
@@ -152,10 +168,16 @@ void TimeBasedWidget::connect_viewer_node(ViewerOutput *node)
|
||||
// If we're setting the timebase, set it automatically based on the video and audio parameters
|
||||
if (auto_set_timebase_) {
|
||||
auto_update_timebase();
|
||||
connect(viewer_node_.data(), &ViewerOutput::frame_rate_changed, this,
|
||||
&TimeBasedWidget::auto_update_timebase);
|
||||
connect(viewer_node_.data(), &ViewerOutput::sample_rate_changed, this,
|
||||
&TimeBasedWidget::auto_update_timebase);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_VIEWER_FRAME_RATE_CHANGED);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_VIEWER_SAMPLE_RATE_CHANGED);
|
||||
connect(bridge_, &EngineEventBridge::viewer_frame_rate_changed, this,
|
||||
[this](OakEngineNode *, qint64, qint64) {
|
||||
auto_update_timebase();
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::viewer_sample_rate_changed, this,
|
||||
[this](OakEngineNode *, int) {
|
||||
auto_update_timebase();
|
||||
});
|
||||
}
|
||||
|
||||
// Call derivatives
|
||||
@@ -164,7 +186,8 @@ void TimeBasedWidget::connect_viewer_node(ViewerOutput *node)
|
||||
|
||||
update_maximum_scroll();
|
||||
|
||||
emit connected_node_changed(old, node);
|
||||
emit connected_node_changed(reinterpret_cast<OakEngineNode *>(old),
|
||||
reinterpret_cast<OakEngineNode *>(node));
|
||||
}
|
||||
|
||||
void TimeBasedWidget::connect_work_area(TimelineWorkArea *workarea)
|
||||
@@ -287,13 +310,13 @@ void TimeBasedWidget::auto_update_timebase()
|
||||
return;
|
||||
}
|
||||
Rational video_tb =
|
||||
viewer_node_->get_video_params().frame_rate_as_time_base();
|
||||
viewer_output_video_params(viewer_node_).frame_rate_as_time_base();
|
||||
|
||||
if (!video_tb.isNull()) {
|
||||
SetTimebase(video_tb);
|
||||
} else {
|
||||
Rational audio_tb =
|
||||
viewer_node_->get_audio_params().sample_rate_as_time_base();
|
||||
viewer_output_audio_params(viewer_node_).sample_rate_as_time_base();
|
||||
|
||||
if (!audio_tb.isNull()) {
|
||||
SetTimebase(audio_tb);
|
||||
@@ -489,7 +512,9 @@ void TimeBasedWidget::go_to_prev_cut()
|
||||
closest_cut = qMax(closest_cut, this_track_closest_cut);
|
||||
}
|
||||
|
||||
get_connected_node()->set_playhead(closest_cut);
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(get_connected_node()),
|
||||
closest_cut.numerator(), closest_cut.denominator());
|
||||
}
|
||||
|
||||
void TimeBasedWidget::go_to_next_cut()
|
||||
@@ -521,14 +546,17 @@ void TimeBasedWidget::go_to_next_cut()
|
||||
}
|
||||
|
||||
if (closest_cut < RATIONAL_MAX) {
|
||||
get_connected_node()->set_playhead(closest_cut);
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(get_connected_node()),
|
||||
closest_cut.numerator(), closest_cut.denominator());
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::go_to_start()
|
||||
{
|
||||
if (viewer_node_) {
|
||||
viewer_node_->set_playhead(0);
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(viewer_node_.data()), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +570,12 @@ void TimeBasedWidget::prev_frame()
|
||||
// Catch rounding error, assume this time is snapped and just subtract a timebase
|
||||
proposed_time -= timebase();
|
||||
}
|
||||
viewer_node_->set_playhead(qMax(Rational(0), proposed_time));
|
||||
{
|
||||
Rational _pt = qMax(Rational(0), proposed_time);
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(viewer_node_.data()),
|
||||
_pt.numerator(), _pt.denominator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,14 +589,19 @@ void TimeBasedWidget::next_frame()
|
||||
// Catch rounding error, assume this time is snapped and just add a timebase
|
||||
proposed_time += timebase();
|
||||
}
|
||||
viewer_node_->set_playhead(proposed_time);
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(viewer_node_.data()),
|
||||
proposed_time.numerator(), proposed_time.denominator());
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::go_to_end()
|
||||
{
|
||||
if (viewer_node_) {
|
||||
viewer_node_->set_playhead(viewer_node_->get_length());
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(viewer_node_.data()),
|
||||
viewer_node_->get_length().numerator(),
|
||||
viewer_node_->get_length().denominator());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,13 +625,13 @@ void TimeBasedWidget::set_point(Timeline::MovementMode m, const Rational &time)
|
||||
return;
|
||||
}
|
||||
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
void *command = oakengine_undo_command_create_multi();
|
||||
TimelineWorkArea *points = viewer_node_->get_work_area();
|
||||
|
||||
// Enable workarea if it isn't already enabled
|
||||
if (!points->enabled()) {
|
||||
command->add_child(new WorkareaSetEnabledCommand(
|
||||
viewer_node_->project(), points, true));
|
||||
oakengine_workarea_set_enabled_undoable(
|
||||
reinterpret_cast<OakEngineWorkarea *>(points), 1, command);
|
||||
}
|
||||
|
||||
// Determine our new range
|
||||
@@ -603,7 +641,7 @@ void TimeBasedWidget::set_point(Timeline::MovementMode m, const Rational &time)
|
||||
in_point = time;
|
||||
|
||||
if (!points->enabled() || points->out() < in_point) {
|
||||
out_point = TimelineWorkArea::k_reset_out;
|
||||
out_point = RATIONAL_MAX;
|
||||
} else {
|
||||
out_point = points->out();
|
||||
}
|
||||
@@ -611,17 +649,28 @@ void TimeBasedWidget::set_point(Timeline::MovementMode m, const Rational &time)
|
||||
out_point = time;
|
||||
|
||||
if (!points->enabled() || points->in() > out_point) {
|
||||
in_point = TimelineWorkArea::k_reset_in;
|
||||
in_point = Rational(0, 1);
|
||||
} else {
|
||||
in_point = points->in();
|
||||
}
|
||||
}
|
||||
|
||||
// Set workarea
|
||||
command->add_child(
|
||||
new WorkareaSetRangeCommand(points, TimeRange(in_point, out_point)));
|
||||
{
|
||||
int64_t old_in_num, old_in_den, old_out_num, old_out_den;
|
||||
int old_enabled;
|
||||
oakengine_workarea_get(
|
||||
reinterpret_cast<OakEngineWorkarea *>(points),
|
||||
&old_in_num, &old_in_den, &old_out_num, &old_out_den,
|
||||
&old_enabled);
|
||||
oakengine_workarea_set_range_undoable(
|
||||
reinterpret_cast<OakEngineWorkarea *>(points),
|
||||
in_point.numerator(), in_point.denominator(),
|
||||
out_point.numerator(), out_point.denominator(),
|
||||
old_in_num, old_in_den, old_out_num, old_out_den, command);
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command, tr("Set In/Out Point"));
|
||||
oakengine_undo_push(command, tr("Set In/Out Point").toUtf8().constData());
|
||||
}
|
||||
|
||||
void TimeBasedWidget::reset_point(Timeline::MovementMode m)
|
||||
@@ -639,13 +688,27 @@ void TimeBasedWidget::reset_point(Timeline::MovementMode m)
|
||||
TimeRange r = points->range();
|
||||
|
||||
if (m == Timeline::k_trim_in) {
|
||||
r.set_in(TimelineWorkArea::k_reset_in);
|
||||
r.set_in(Rational(0, 1));
|
||||
} else {
|
||||
r.set_out(TimelineWorkArea::k_reset_out);
|
||||
r.set_out(RATIONAL_MAX);
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(new WorkareaSetRangeCommand(points, r),
|
||||
tr("Reset In/Out Points"));
|
||||
{
|
||||
auto reset_cmd = oakengine_undo_command_create_multi();
|
||||
int64_t old_in_num, old_in_den, old_out_num, old_out_den;
|
||||
int old_enabled;
|
||||
oakengine_workarea_get(
|
||||
reinterpret_cast<OakEngineWorkarea *>(points),
|
||||
&old_in_num, &old_in_den, &old_out_num, &old_out_den,
|
||||
&old_enabled);
|
||||
oakengine_workarea_set_range_undoable(
|
||||
reinterpret_cast<OakEngineWorkarea *>(points),
|
||||
r.in().numerator(), r.in().denominator(),
|
||||
r.out().numerator(), r.out().denominator(),
|
||||
old_in_num, old_in_den, old_out_num, old_out_den, reset_cmd);
|
||||
oakengine_undo_push(reset_cmd,
|
||||
tr("Reset In/Out Points").toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::page_scroll_internal(QScrollBar *bar, int maximum,
|
||||
@@ -717,10 +780,15 @@ void TimeBasedWidget::clear_in_out_points()
|
||||
return;
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(
|
||||
new WorkareaSetEnabledCommand(get_connected_node()->project(),
|
||||
get_connected_node()->get_work_area(), false),
|
||||
tr("Cleared In/Out Points"));
|
||||
{
|
||||
auto clear_cmd = oakengine_undo_command_create_multi();
|
||||
oakengine_workarea_set_enabled_undoable(
|
||||
reinterpret_cast<OakEngineWorkarea *>(
|
||||
get_connected_node()->get_work_area()),
|
||||
0, clear_cmd);
|
||||
oakengine_undo_push(clear_cmd,
|
||||
tr("Cleared In/Out Points").toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::set_marker()
|
||||
@@ -748,16 +816,20 @@ void TimeBasedWidget::set_marker()
|
||||
color = OAK_CONFIG("MarkerColor").toInt();
|
||||
}
|
||||
|
||||
TimelineMarker *marker = new TimelineMarker(
|
||||
color, TimeRange(get_connected_node()->get_playhead(),
|
||||
get_connected_node()->get_playhead()));
|
||||
const Rational playhead = get_connected_node()->get_playhead();
|
||||
OakEngineMarker *marker = oakengine_marker_create(
|
||||
color, playhead.numerator(), playhead.denominator(),
|
||||
playhead.numerator(), playhead.denominator(), "");
|
||||
TimelineMarker *cpp_marker =
|
||||
reinterpret_cast<TimelineMarker *>(marker);
|
||||
|
||||
bool edited_in_dialog = false;
|
||||
if (OAK_CONFIG("SetNameWithMarker").toBool()) {
|
||||
MarkerPropertiesDialog mpd({ marker }, timebase(), this);
|
||||
MarkerPropertiesDialog mpd({ cpp_marker }, timebase(), this);
|
||||
if (mpd.exec() != QDialog::Accepted) {
|
||||
delete marker;
|
||||
oakengine_marker_free(marker);
|
||||
marker = nullptr;
|
||||
cpp_marker = nullptr;
|
||||
} else {
|
||||
edited_in_dialog = true;
|
||||
}
|
||||
@@ -767,19 +839,19 @@ void TimeBasedWidget::set_marker()
|
||||
if (edited_in_dialog) {
|
||||
// The dialog pushed undo commands referencing this exact
|
||||
// marker object, so it must be the one added to the list.
|
||||
Core::instance()->undo_stack()->push(
|
||||
new MarkerAddCommand(markers, marker), tr("Added Marker"));
|
||||
oakengine_marker_list_add_existing(
|
||||
reinterpret_cast<OakEngineMarkerList *>(markers), marker);
|
||||
} else {
|
||||
// Pristine marker: add through the liboakengine C ABI
|
||||
// facade (one undoable command) and drop the temporary.
|
||||
oakengine_sequence_marker_add_ex(
|
||||
reinterpret_cast<OakEngineSequence *>(
|
||||
get_connected_node()),
|
||||
Timecode::time_to_timestamp(marker->time().in(),
|
||||
Timecode::time_to_timestamp(cpp_marker->time().in(),
|
||||
timebase(),
|
||||
Timecode::k_round),
|
||||
"", marker->color());
|
||||
delete marker;
|
||||
"", cpp_marker->color());
|
||||
oakengine_marker_free(marker);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -820,8 +892,10 @@ void TimeBasedWidget::go_to_in()
|
||||
{
|
||||
if (get_connected_node()) {
|
||||
if (get_connected_node()->get_work_area()->enabled()) {
|
||||
get_connected_node()->set_playhead(
|
||||
get_connected_node()->get_work_area()->in());
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(get_connected_node()),
|
||||
get_connected_node()->get_work_area()->in().numerator(),
|
||||
get_connected_node()->get_work_area()->in().denominator());
|
||||
} else {
|
||||
go_to_start();
|
||||
}
|
||||
@@ -832,8 +906,10 @@ void TimeBasedWidget::go_to_out()
|
||||
{
|
||||
if (get_connected_node()) {
|
||||
if (get_connected_node()->get_work_area()->enabled()) {
|
||||
get_connected_node()->set_playhead(
|
||||
get_connected_node()->get_work_area()->out());
|
||||
oakengine_viewer_set_playhead(
|
||||
reinterpret_cast<OakEngineNode *>(get_connected_node()),
|
||||
get_connected_node()->get_work_area()->out().numerator(),
|
||||
get_connected_node()->get_work_area()->out().denominator());
|
||||
} else {
|
||||
go_to_end();
|
||||
}
|
||||
@@ -913,7 +989,7 @@ bool TimeBasedWidget::snap_point(const std::vector<Rational> &start_times,
|
||||
TimelineMarker *marker = *jt;
|
||||
|
||||
TimeRange marker_range =
|
||||
marker->time() + clip->in() - clip->media_in();
|
||||
marker->time() + clip->in() - clip_media_in(clip);
|
||||
|
||||
qreal marker_in_screen =
|
||||
time_to_scene(marker_range.in());
|
||||
|
||||
Reference in New Issue
Block a user