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:
+64
-39
@@ -21,7 +21,10 @@
|
||||
#ifndef OAK_EDITOR_NODE_SERIALIZER_H
|
||||
#define OAK_EDITOR_NODE_SERIALIZER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "node/error.h"
|
||||
#include "node/node.h"
|
||||
#include "node/project.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -73,17 +76,33 @@ extern "C" {
|
||||
#define OAKNODE_SERIALIZER_NO_DATA 7
|
||||
|
||||
/**
|
||||
* @brief Opaque save descriptor (wraps ProjectSerializer::SaveData).
|
||||
* Owned by the caller; release with oaknode_serializer_savedata_free().
|
||||
* @brief Reference-counted save descriptor (wraps
|
||||
* olive::ProjectSerializer::SaveData).
|
||||
*
|
||||
* oaknode_serializer_savedata_create() returns a handle whose object has
|
||||
* reference count 1; release it with oaknode_serializer_savedata_free().
|
||||
*/
|
||||
typedef struct OakNodeSerializerSaveData OakNodeSerializerSaveData;
|
||||
typedef struct OakNodeSerializerSaveData {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKNODE_ABI_VERSION. */
|
||||
} OakNodeSerializerSaveData;
|
||||
|
||||
/**
|
||||
* @brief Opaque load result (wraps ProjectSerializer::LoadData).
|
||||
* Owned by the caller; release with oaknode_serializer_loaddata_free().
|
||||
* @brief Reference-counted load result (wraps
|
||||
* olive::ProjectSerializer::LoadData).
|
||||
*
|
||||
* The handle returned through oaknode_serializer_load_from_xml() has
|
||||
* reference count 1; release it with oaknode_serializer_loaddata_free().
|
||||
* Node handles obtained from it are borrowed from the target project.
|
||||
*/
|
||||
typedef struct OakNodeSerializerLoadData OakNodeSerializerLoadData;
|
||||
typedef struct OakNodeSerializerLoadData {
|
||||
void *ctx; /**< Opaque pointer to the reference-counted object. */
|
||||
void (*addref)(void *ctx); /**< Atomically increments the count. */
|
||||
void (*release)(void *ctx); /**< Decrements the count, destroys at 0. */
|
||||
uint32_t abi_version; /**< OAKNODE_ABI_VERSION. */
|
||||
} OakNodeSerializerLoadData;
|
||||
|
||||
/**
|
||||
* @brief Register the versioned serializers and initialize the node factory.
|
||||
@@ -104,16 +123,19 @@ void oaknode_serializer_shutdown(void);
|
||||
*
|
||||
* @param load_type One of OAKNODE_SERIALIZER_LOAD_*; use
|
||||
* OAKNODE_SERIALIZER_LOAD_ONLY_NODES for clipboard-style node copies.
|
||||
* @param project Context project (borrowed), may be NULL for load types
|
||||
* that do not require it.
|
||||
* @param project Context project (borrowed), may be an empty handle for
|
||||
* load types that do not require it.
|
||||
*
|
||||
* @return Save-data handle, or NULL on failure.
|
||||
* @return Save-data handle with reference count 1 (release with
|
||||
* oaknode_serializer_savedata_free()); ctx is NULL on failure.
|
||||
*/
|
||||
OakNodeSerializerSaveData *oaknode_serializer_savedata_create(
|
||||
int load_type, OakNodeProject *project);
|
||||
OakNodeSerializerSaveData oaknode_serializer_savedata_create(
|
||||
int load_type, OakNodeProject project);
|
||||
|
||||
/**
|
||||
* @brief Destroy a save descriptor. NULL is a no-op.
|
||||
* @brief Release the caller's reference to the save descriptor and null
|
||||
* out the handle. NULL and empty handles are a no-op; the object is
|
||||
* destroyed when its reference count reaches zero.
|
||||
*/
|
||||
void oaknode_serializer_savedata_free(OakNodeSerializerSaveData *save_data);
|
||||
|
||||
@@ -125,7 +147,7 @@ void oaknode_serializer_savedata_free(OakNodeSerializerSaveData *save_data);
|
||||
* @return OAKNODE_OK or a negative OAKNODE_E_* error code.
|
||||
*/
|
||||
int oaknode_serializer_savedata_set_nodes(
|
||||
OakNodeSerializerSaveData *save_data, OakNodeNode *const *nodes, int count);
|
||||
OakNodeSerializerSaveData save_data, const OakNodeNode *nodes, int count);
|
||||
|
||||
/**
|
||||
* @brief Attach a free-form (key, value) property to a node in the
|
||||
@@ -135,7 +157,7 @@ int oaknode_serializer_savedata_set_nodes(
|
||||
* @return OAKNODE_OK or a negative OAKNODE_E_* error code.
|
||||
*/
|
||||
int oaknode_serializer_savedata_set_property(
|
||||
OakNodeSerializerSaveData *save_data, OakNodeNode *node, const char *key,
|
||||
OakNodeSerializerSaveData save_data, OakNodeNode node, const char *key,
|
||||
const char *value);
|
||||
|
||||
/**
|
||||
@@ -146,21 +168,22 @@ int oaknode_serializer_savedata_set_property(
|
||||
* OAKNODE_E_* error code (OAKNODE_E_STATE if the serializers have
|
||||
* not been initialized).
|
||||
*/
|
||||
int oaknode_serializer_save_to_xml(OakNodeSerializerSaveData *save_data,
|
||||
int oaknode_serializer_save_to_xml(OakNodeSerializerSaveData save_data,
|
||||
char *buf, int buf_size);
|
||||
|
||||
/**
|
||||
* @brief Parse an in-memory XML document into `project` ("paste").
|
||||
*
|
||||
* @param project Target project (borrowed), may be NULL for load types that
|
||||
* do not attach nodes to a project.
|
||||
* @param project Target project (borrowed), may be an empty handle for
|
||||
* load types that do not attach nodes to a project.
|
||||
* @param xml Complete XML document text. Must not be NULL.
|
||||
* @param load_type One of OAKNODE_SERIALIZER_LOAD_*.
|
||||
* @param out_result Receives one of the OAKNODE_SERIALIZER_* result codes.
|
||||
* Must not be NULL.
|
||||
* @param out_load_data Receives the load result on OAKNODE_SERIALIZER_OK
|
||||
* (caller-owned, may be NULL if the caller does not need it;
|
||||
* receives NULL on failure).
|
||||
* (reference count 1, release with oaknode_serializer_loaddata_free();
|
||||
* may be NULL if the caller does not need it; receives an empty
|
||||
* handle on failure).
|
||||
* @param details_buf Optional human-readable error detail buffer
|
||||
* (two-stage convention is NOT used; truncation is silent). May be
|
||||
* NULL.
|
||||
@@ -169,13 +192,14 @@ int oaknode_serializer_save_to_xml(OakNodeSerializerSaveData *save_data,
|
||||
* @return OAKNODE_OK if the call itself succeeded (inspect *out_result for
|
||||
* the serializer outcome), or a negative OAKNODE_E_* error code.
|
||||
*/
|
||||
int oaknode_serializer_load_from_xml(OakNodeProject *project, const char *xml,
|
||||
int oaknode_serializer_load_from_xml(OakNodeProject project, const char *xml,
|
||||
int load_type, int *out_result,
|
||||
OakNodeSerializerLoadData **out_load_data,
|
||||
OakNodeSerializerLoadData *out_load_data,
|
||||
char *details_buf, int details_buf_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a load result. NULL is a no-op.
|
||||
* @brief Release the caller's reference to the load result and null out
|
||||
* the handle. NULL and empty handles are a no-op.
|
||||
*
|
||||
* Does not delete the loaded nodes: they are newly created objects owned by
|
||||
* the CALLER until adopted into a project with oaknode_project_add_node()
|
||||
@@ -185,17 +209,17 @@ void oaknode_serializer_loaddata_free(OakNodeSerializerLoadData *load_data);
|
||||
|
||||
/**
|
||||
* @brief Number of nodes created by the load. Negative OAKNODE_E_* code on
|
||||
* NULL.
|
||||
* an empty handle.
|
||||
*/
|
||||
int oaknode_serializer_loaddata_node_count(
|
||||
const OakNodeSerializerLoadData *load_data);
|
||||
OakNodeSerializerLoadData load_data);
|
||||
|
||||
/**
|
||||
* @brief Borrowed handle of the loaded node at `index`, or NULL when out of
|
||||
* range.
|
||||
* @brief Borrowed handle of the loaded node at `index`, or an empty handle
|
||||
* when out of range.
|
||||
*/
|
||||
OakNodeNode *oaknode_serializer_loaddata_node_at(
|
||||
const OakNodeSerializerLoadData *load_data, int index);
|
||||
OakNodeNode oaknode_serializer_loaddata_node_at(
|
||||
OakNodeSerializerLoadData load_data, int index);
|
||||
|
||||
/**
|
||||
* @brief Look up a serialized property attached to a loaded node.
|
||||
@@ -206,15 +230,15 @@ OakNodeNode *oaknode_serializer_loaddata_node_at(
|
||||
* negative OAKNODE_E_* error code.
|
||||
*/
|
||||
int oaknode_serializer_loaddata_get_property(
|
||||
const OakNodeSerializerLoadData *load_data, OakNodeNode *node,
|
||||
const char *key, char *buf, int buf_size);
|
||||
OakNodeSerializerLoadData load_data, OakNodeNode node, const char *key,
|
||||
char *buf, int buf_size);
|
||||
|
||||
/**
|
||||
* @brief Number of promised (deferred) connections in the load result.
|
||||
* Negative OAKNODE_E_* code on NULL.
|
||||
* Negative OAKNODE_E_* code on an empty handle.
|
||||
*/
|
||||
int oaknode_serializer_loaddata_connection_count(
|
||||
const OakNodeSerializerLoadData *load_data);
|
||||
OakNodeSerializerLoadData load_data);
|
||||
|
||||
/**
|
||||
* @brief Read the promised connection at `index`.
|
||||
@@ -223,8 +247,8 @@ int oaknode_serializer_loaddata_connection_count(
|
||||
* `input_id_buf` follows the two-stage string convention inside a
|
||||
* fixed call: pass NULL/0 to skip copying the id.
|
||||
*
|
||||
* @param out_output_node Receives the output (source) node.
|
||||
* @param out_input_node Receives the input (destination) node.
|
||||
* @param out_output_node Receives the output (source) node (borrowed).
|
||||
* @param out_input_node Receives the input (destination) node (borrowed).
|
||||
* @param input_id_buf Receives the input id string, may be NULL.
|
||||
* @param input_id_buf_size Size of input_id_buf.
|
||||
* @param out_element Receives the input element index.
|
||||
@@ -233,8 +257,8 @@ int oaknode_serializer_loaddata_connection_count(
|
||||
* negative OAKNODE_E_* error code.
|
||||
*/
|
||||
int oaknode_serializer_loaddata_connection_at(
|
||||
const OakNodeSerializerLoadData *load_data, int index,
|
||||
OakNodeNode **out_output_node, OakNodeNode **out_input_node,
|
||||
OakNodeSerializerLoadData load_data, int index,
|
||||
OakNodeNode *out_output_node, OakNodeNode *out_input_node,
|
||||
char *input_id_buf, int input_id_buf_size, int *out_element);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -268,9 +292,10 @@ enum OakNodeSerializerResultCode {
|
||||
* string (e.g. the fallback filename on overwrite errors).
|
||||
* @return OAKNODE_OK when the result code is
|
||||
* OAKNODE_SERIALIZER_RESULT_SUCCESS, OAKNODE_E_FAILED otherwise
|
||||
* (details in out_code/details), OAKNODE_E_INVALID for NULL args.
|
||||
* (details in out_code/details), OAKNODE_E_INVALID for empty
|
||||
* handles/NULL args.
|
||||
*/
|
||||
int oaknode_serializer_save_to_file(OakNodeProject *project,
|
||||
int oaknode_serializer_save_to_file(OakNodeProject project,
|
||||
const char *filename, int use_compression, int *out_code,
|
||||
char *details, int details_size);
|
||||
|
||||
@@ -280,6 +305,6 @@ int oaknode_serializer_save_to_file(OakNodeProject *project,
|
||||
*
|
||||
* Same return/out-param convention as oaknode_serializer_save_to_file().
|
||||
*/
|
||||
int oaknode_serializer_load_from_file(OakNodeProject *project,
|
||||
int oaknode_serializer_load_from_file(OakNodeProject project,
|
||||
const char *filename, int *out_code, char *details,
|
||||
int details_size);
|
||||
|
||||
Reference in New Issue
Block a user