refactor(node): switch oaknode to refcounted value handles, migrate consumers
- all 15 OakNode* handle types become neutral by-value structs
{ctx, addref, release, abi_version}; shared box in
src/node/c_api/nodehandle.h with owns flag (borrowed accessors
return non-owning boxes; graph insertion flips owns off)
- oaktimeline/oaktask/oakrender call sites and their own public
headers migrated to value handles; identity comparisons in
timeline/task now compare native pointers
- regressions green: oaknode 96, oaktimeline 117, oaktask 106,
oakrender 44, oakcommon 193, oakcodec 18, oakaudio 36
This commit is contained in:
+19
-13
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "../../node/c_api/nodehandle.h"
|
||||
#include "../src/projectcopier.h"
|
||||
|
||||
namespace
|
||||
@@ -50,36 +51,41 @@ void oakrender_project_copier_free(OakRenderProjectCopier *copier)
|
||||
}
|
||||
|
||||
int oakrender_project_copier_set_project(OakRenderProjectCopier *copier,
|
||||
OakNodeProject *project)
|
||||
OakNodeProject project)
|
||||
{
|
||||
if (!copier || !project) {
|
||||
if (!copier || !project.ctx) {
|
||||
return OAKRENDER_E_INVALID;
|
||||
}
|
||||
try {
|
||||
impl(copier)->set_project(
|
||||
reinterpret_cast<olive::Project *>(project));
|
||||
oaknode_c_api::to_native<olive::Project>(project));
|
||||
return OAKRENDER_OK;
|
||||
} catch (...) {
|
||||
return OAKRENDER_E_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
OakNodeNode *oakrender_project_copier_get_copy(
|
||||
OakRenderProjectCopier *copier, OakNodeNode *original)
|
||||
OakNodeNode oakrender_project_copier_get_copy(
|
||||
OakRenderProjectCopier *copier, OakNodeNode original)
|
||||
{
|
||||
if (!copier || !original) {
|
||||
return NULL;
|
||||
if (!copier || !original.ctx) {
|
||||
return OakNodeNode{};
|
||||
}
|
||||
return reinterpret_cast<OakNodeNode *>(
|
||||
impl(copier)->get_copy(reinterpret_cast<olive::Node *>(original)));
|
||||
// Borrowed handle: releasing it only destroys the handle box, never
|
||||
// the copied node (owned by the copier's copied project).
|
||||
return oaknode_c_api::make_handle<OakNodeNode>(
|
||||
impl(copier)->get_copy(oaknode_c_api::to_native<olive::Node>(original)),
|
||||
false, &oaknode_c_api::delete_as<olive::Node>);
|
||||
}
|
||||
|
||||
OakNodeProject *oakrender_project_copier_get_copied_project(
|
||||
OakNodeProject oakrender_project_copier_get_copied_project(
|
||||
OakRenderProjectCopier *copier)
|
||||
{
|
||||
if (!copier) {
|
||||
return NULL;
|
||||
return OakNodeProject{};
|
||||
}
|
||||
return reinterpret_cast<OakNodeProject *>(
|
||||
impl(copier)->get_copied_project());
|
||||
// Borrowed handle: the copied project is owned by the copier.
|
||||
return oaknode_c_api::make_handle<OakNodeProject>(
|
||||
impl(copier)->get_copied_project(), false,
|
||||
&oaknode_c_api::delete_as<olive::Project>);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "alivecount.h"
|
||||
#include "internalhandles.h"
|
||||
|
||||
#include "../../node/c_api/nodehandle.h"
|
||||
|
||||
#include "diskmanager.h"
|
||||
#include "output/viewer/viewer.h"
|
||||
#include "previewautocacher.h"
|
||||
@@ -75,10 +77,10 @@ void oakrender_manager_shutdown(void)
|
||||
}
|
||||
}
|
||||
|
||||
int64_t oakrender_request_frame(OakNodeNode *viewer, int64_t ts,
|
||||
int64_t oakrender_request_frame(OakNodeNode viewer, int64_t ts,
|
||||
oakrender_frame_ready_fn cb, void *userdata)
|
||||
{
|
||||
if (!viewer || !cb) {
|
||||
if (!viewer.ctx || !cb) {
|
||||
return OAKRENDER_E_INVALID;
|
||||
}
|
||||
olive::RenderManager *manager = olive::RenderManager::instance();
|
||||
@@ -86,7 +88,7 @@ int64_t oakrender_request_frame(OakNodeNode *viewer, int64_t ts,
|
||||
return OAKRENDER_E_STATE;
|
||||
}
|
||||
auto *v = dynamic_cast<olive::ViewerOutput *>(
|
||||
reinterpret_cast<olive::Node *>(viewer));
|
||||
oaknode_c_api::to_native<olive::Node>(viewer));
|
||||
if (!v) {
|
||||
return OAKRENDER_E_INVALID;
|
||||
}
|
||||
@@ -157,14 +159,16 @@ int oakrender_cancel_request(int64_t request_id)
|
||||
return OAKRENDER_OK;
|
||||
}
|
||||
|
||||
int oakrender_set_cacher_multicam(OakNodeNode *multicam_or_NULL)
|
||||
int oakrender_set_cacher_multicam(OakNodeNode multicam_or_NULL)
|
||||
{
|
||||
olive::RenderManager *manager = olive::RenderManager::instance();
|
||||
if (!manager) {
|
||||
return OAKRENDER_E_STATE;
|
||||
}
|
||||
manager->get_cacher()->set_multicam_node(
|
||||
reinterpret_cast<olive::MultiCamNode *>(multicam_or_NULL));
|
||||
multicam_or_NULL.ctx ?
|
||||
oaknode_c_api::to_native<olive::MultiCamNode>(multicam_or_NULL) :
|
||||
nullptr);
|
||||
return OAKRENDER_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "../src/framehashcache.h"
|
||||
#include "../src/rendermanager.h"
|
||||
#include "../src/renderticket.h"
|
||||
#include "../../node/c_api/nodehandle.h"
|
||||
#include "internalhandles.h"
|
||||
|
||||
namespace
|
||||
@@ -59,9 +60,9 @@ OakRenderTicket *wrap(olive::RenderTicketWatcher *w,
|
||||
return reinterpret_cast<OakRenderTicket *>(h);
|
||||
}
|
||||
|
||||
olive::Node *to_node(OakNodeNode *n)
|
||||
olive::Node *to_node(OakNodeNode n)
|
||||
{
|
||||
return reinterpret_cast<olive::Node *>(n);
|
||||
return oaknode_c_api::to_native<olive::Node>(n);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -70,7 +71,7 @@ OakRenderTicket *oakrender_ticket_render_frame(
|
||||
const oakrender_video_ticket_params *params,
|
||||
oakrender_ticket_finished_fn cb, void *userdata)
|
||||
{
|
||||
if (!params || !params->output_node) {
|
||||
if (!params || !params->output_node.ctx) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -96,7 +97,10 @@ OakRenderTicket *oakrender_ticket_render_frame(
|
||||
: olive::AudioParams(),
|
||||
olive::core::Rational(int(params->time_num),
|
||||
int(params->time_den)),
|
||||
reinterpret_cast<olive::ColorManager *>(params->color_manager),
|
||||
params->color_manager.ctx ?
|
||||
oaknode_c_api::to_native<olive::ColorManager>(
|
||||
params->color_manager) :
|
||||
nullptr,
|
||||
static_cast<olive::RenderMode::Mode>(params->mode));
|
||||
|
||||
rvp.force_size =
|
||||
@@ -161,11 +165,11 @@ OakRenderTicket *oakrender_ticket_render_frame(
|
||||
}
|
||||
|
||||
OakRenderTicket *oakrender_ticket_render_audio(
|
||||
OakNodeNode *output_node, int64_t in_num, int64_t in_den,
|
||||
OakNodeNode output_node, int64_t in_num, int64_t in_den,
|
||||
int64_t out_num, int64_t out_den, const OakAudioParams *params,
|
||||
int mode, oakrender_ticket_finished_fn cb, void *userdata)
|
||||
{
|
||||
if (!output_node || !params) {
|
||||
if (!output_node.ctx || !params) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,30 +57,31 @@ TEST(OakRenderManagerTest, InitShutdown)
|
||||
TEST(OakRenderManagerTest, RequestFrameRequiresManager)
|
||||
{
|
||||
ASSERT_EQ(oaknode_factory_initialize(), OAKNODE_OK);
|
||||
OakNodeNode *viewer = oaknode_factory_create_from_id(
|
||||
OakNodeNode viewer = oaknode_factory_create_from_id(
|
||||
"org.olivevideoeditor.Olive.vieweroutput");
|
||||
ASSERT_NE(viewer, nullptr);
|
||||
ASSERT_NE(viewer.ctx, nullptr);
|
||||
|
||||
// No oakrender_manager_init() in this process: E_STATE
|
||||
EXPECT_EQ(oakrender_request_frame(viewer, 0, noop_frame_ready, nullptr),
|
||||
int64_t(OAKRENDER_E_STATE));
|
||||
|
||||
oaknode_node_free(viewer);
|
||||
oaknode_node_free(&viewer);
|
||||
oaknode_factory_destroy();
|
||||
}
|
||||
|
||||
TEST(OakRenderManagerTest, RequestFrameInvalidArgs)
|
||||
{
|
||||
EXPECT_EQ(oakrender_request_frame(nullptr, 0, noop_frame_ready, nullptr),
|
||||
EXPECT_EQ(oakrender_request_frame(OakNodeNode{}, 0, noop_frame_ready,
|
||||
nullptr),
|
||||
int64_t(OAKRENDER_E_INVALID));
|
||||
|
||||
ASSERT_EQ(oaknode_factory_initialize(), OAKNODE_OK);
|
||||
OakNodeNode *viewer = oaknode_factory_create_from_id(
|
||||
OakNodeNode viewer = oaknode_factory_create_from_id(
|
||||
"org.olivevideoeditor.Olive.vieweroutput");
|
||||
ASSERT_NE(viewer, nullptr);
|
||||
ASSERT_NE(viewer.ctx, nullptr);
|
||||
EXPECT_EQ(oakrender_request_frame(viewer, 0, nullptr, nullptr),
|
||||
int64_t(OAKRENDER_E_INVALID));
|
||||
oaknode_node_free(viewer);
|
||||
oaknode_node_free(&viewer);
|
||||
oaknode_factory_destroy();
|
||||
}
|
||||
|
||||
@@ -98,7 +99,7 @@ TEST(OakRenderManagerTest, CancelUnknownRequest)
|
||||
|
||||
TEST(OakRenderManagerTest, CacherSettersRequireManager)
|
||||
{
|
||||
EXPECT_EQ(oakrender_set_cacher_multicam(nullptr), OAKRENDER_E_STATE);
|
||||
EXPECT_EQ(oakrender_set_cacher_multicam(OakNodeNode{}), OAKRENDER_E_STATE);
|
||||
EXPECT_EQ(oakrender_set_display_color_processor(nullptr),
|
||||
OAKRENDER_E_STATE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user