refactor(undo): switch oakundo to refcounted value handles, migrate consumers
- OakUndoCommand/OakUndoStack become neutral by-value handles
{ctx, addref, release, abi_version}; a handle is a shared_ptr
equivalent at the ABI level, internals untouched (box owns/observes
flag; containers adopt, boxes created by factories own)
- oaknode command factories and undoable variants return/write value
handles; timeline command classes hold value handles; task import
take_command returns a value handle
- tests updated everywhere; suites green: oakundo 22, oaktimeline 117,
oaktask 106, oaknode 96, oakrender 44, oakcodec 18, oakcommon 193,
oakaudio 36
This commit is contained in:
@@ -238,24 +238,20 @@ OakNodeNode *oaknode_folder_as_node(OakNodeFolder *folder)
|
||||
return reinterpret_cast<OakNodeNode *>(folder);
|
||||
}
|
||||
|
||||
OakUndoCommand *oaknode_command_create_folder_add_child(
|
||||
OakUndoCommand oaknode_command_create_folder_add_child(
|
||||
OakNodeFolder *folder, OakNodeNode *child)
|
||||
{
|
||||
if (!folder || !child) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle =
|
||||
new (std::nothrow) OakUndoCommand{ nullptr, true };
|
||||
if (!handle) {
|
||||
return NULL;
|
||||
}
|
||||
handle->command = new olive::FolderAddChild(
|
||||
reinterpret_cast<olive::Folder *>(folder),
|
||||
reinterpret_cast<olive::Node *>(child));
|
||||
return handle;
|
||||
return oakundo_capi::make_command_handle(
|
||||
new olive::FolderAddChild(
|
||||
reinterpret_cast<olive::Folder *>(folder),
|
||||
reinterpret_cast<olive::Node *>(child)),
|
||||
true);
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,18 +111,18 @@ int oaknode_group_add_input_passthrough_undoable(OakNodeGroup *group,
|
||||
OakNodeNode *node,
|
||||
const char *input_id,
|
||||
int element,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!group || !node || !input_id || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeGroupAddInputPassthrough(
|
||||
to_group(group),
|
||||
olive::NodeInput(to_node(node), input_id, element)));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -246,17 +246,17 @@ int oaknode_group_set_output_passthrough(OakNodeGroup *group,
|
||||
}
|
||||
|
||||
int oaknode_group_set_output_passthrough_undoable(
|
||||
OakNodeGroup *group, OakNodeNode *node, OakUndoCommand **out_command)
|
||||
OakNodeGroup *group, OakNodeNode *node, OakUndoCommand *out_command)
|
||||
{
|
||||
if (!group || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeGroupSetOutputPassthrough(to_group(group),
|
||||
to_node(node)));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
|
||||
+15
-15
@@ -213,19 +213,19 @@ int oaknode_keyframe_set_time(OakNodeKeyframe *keyframe, int64_t time_num,
|
||||
|
||||
int oaknode_keyframe_set_time_undoable(OakNodeKeyframe *keyframe,
|
||||
int64_t time_num, int64_t time_den,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!keyframe || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeParamSetKeyframeTimeCommand(
|
||||
to_key(keyframe),
|
||||
olive::core::Rational(static_cast<int>(time_num),
|
||||
static_cast<int>(time_den))));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -316,7 +316,7 @@ int oaknode_keyframe_set_value(OakNodeKeyframe *keyframe,
|
||||
|
||||
int oaknode_keyframe_set_value_undoable(OakNodeKeyframe *keyframe,
|
||||
const oaknode_value *v,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!keyframe || !v || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -328,10 +328,10 @@ int oaknode_keyframe_set_value_undoable(OakNodeKeyframe *keyframe,
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeParamSetKeyframeValueCommand(to_key(keyframe),
|
||||
variant));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -373,17 +373,17 @@ int oaknode_keyframe_set_value_string(OakNodeKeyframe *keyframe,
|
||||
|
||||
int oaknode_keyframe_set_value_string_undoable(OakNodeKeyframe *keyframe,
|
||||
const char *value,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!keyframe || !value || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeParamSetKeyframeValueCommand(
|
||||
to_key(keyframe), olive::Variant(value)));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -426,7 +426,7 @@ int oaknode_keyframe_set_type(OakNodeKeyframe *keyframe, int type)
|
||||
}
|
||||
|
||||
int oaknode_keyframe_set_type_undoable(OakNodeKeyframe *keyframe, int type,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!keyframe || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -438,9 +438,9 @@ int oaknode_keyframe_set_type_undoable(OakNodeKeyframe *keyframe, int type,
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new KeyframeSetTypeCommand(to_key(keyframe), keyframe_type));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -498,7 +498,7 @@ int oaknode_keyframe_set_bezier_control(OakNodeKeyframe *keyframe, int handle,
|
||||
|
||||
int oaknode_keyframe_set_bezier_control_undoable(OakNodeKeyframe *keyframe,
|
||||
int handle, double x, double y,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!keyframe || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -514,10 +514,10 @@ int oaknode_keyframe_set_bezier_control_undoable(OakNodeKeyframe *keyframe,
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
OakUndoCommand *handle_ptr = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle_ptr = oaknode_c_api::wrap_command(
|
||||
new KeyframeSetBezierControlCommand(to_key(keyframe), bezier_handle,
|
||||
olive::PointF(x, y)));
|
||||
if (!handle_ptr) {
|
||||
if (!handle_ptr.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle_ptr;
|
||||
|
||||
+38
-38
@@ -167,16 +167,16 @@ int oaknode_node_set_label(OakNodeNode *node, const char *label)
|
||||
}
|
||||
|
||||
int oaknode_node_set_label_undoable(OakNodeNode *node, const char *label,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!node || !label || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeRenameCommand(to_node(node), label));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -215,16 +215,16 @@ int oaknode_node_set_override_color(OakNodeNode *node, int index)
|
||||
}
|
||||
|
||||
int oaknode_node_set_override_color_undoable(OakNodeNode *node, int index,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!node || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeOverrideColorCommand(to_node(node), index));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -268,7 +268,7 @@ int oaknode_node_set_enabled(OakNodeNode *node, int enabled)
|
||||
}
|
||||
|
||||
int oaknode_node_set_enabled_undoable(OakNodeNode *node, int enabled,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!node || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -279,9 +279,9 @@ int oaknode_node_set_enabled_undoable(OakNodeNode *node, int enabled,
|
||||
olive::SplitValue split =
|
||||
olive::NodeValue::split_normal_value_into_track_values(
|
||||
olive::NodeValue::k_boolean, olive::Variant(enabled != 0));
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeParamSetSplitStandardValueCommand(ref, split));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -464,7 +464,7 @@ int oaknode_node_set_input(OakNodeNode *node, const char *input_id,
|
||||
|
||||
int oaknode_node_set_input_undoable(OakNodeNode *node, const char *input_id,
|
||||
const oaknode_value *v,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!node || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -485,9 +485,9 @@ int oaknode_node_set_input_undoable(OakNodeNode *node, const char *input_id,
|
||||
olive::SplitValue split =
|
||||
olive::NodeValue::split_normal_value_into_track_values(type, variant);
|
||||
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeParamSetSplitStandardValueCommand(ref, split));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -545,7 +545,7 @@ int oaknode_node_set_input_string(OakNodeNode *node, const char *input_id,
|
||||
int oaknode_node_set_input_string_undoable(OakNodeNode *node,
|
||||
const char *input_id,
|
||||
const char *value,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!node || !value || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -566,9 +566,9 @@ int oaknode_node_set_input_string_undoable(OakNodeNode *node,
|
||||
to_node(node)->get_input_data_type(input_id),
|
||||
olive::Variant(value));
|
||||
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeParamSetSplitStandardValueCommand(ref, split));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -610,7 +610,7 @@ int oaknode_node_connect(OakNodeNode *output_node, OakNodeNode *input_node,
|
||||
int oaknode_node_connect_undoable(OakNodeNode *output_node,
|
||||
OakNodeNode *input_node,
|
||||
const char *input_id,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!output_node || !input_node || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -624,11 +624,11 @@ int oaknode_node_connect_undoable(OakNodeNode *output_node,
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeEdgeAddCommand(
|
||||
to_node(output_node),
|
||||
olive::NodeInput(to_node(input_node), input_id)));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -663,7 +663,7 @@ int oaknode_node_disconnect(OakNodeNode *input_node, const char *input_id)
|
||||
|
||||
int oaknode_node_disconnect_undoable(OakNodeNode *input_node,
|
||||
const char *input_id,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!input_node || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -678,10 +678,10 @@ int oaknode_node_disconnect_undoable(OakNodeNode *input_node,
|
||||
return OAKNODE_E_NOT_FOUND;
|
||||
}
|
||||
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeEdgeRemoveCommand(
|
||||
output, olive::NodeInput(to_node(input_node), input_id)));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -804,16 +804,16 @@ int oaknode_node_unlink(OakNodeNode *a, OakNodeNode *b, int *out_unlinked)
|
||||
}
|
||||
|
||||
int oaknode_node_link_undoable(OakNodeNode *a, OakNodeNode *b, int link,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!a || !b || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeLinkCommand(to_node(a), to_node(b), link != 0));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -964,7 +964,7 @@ int oaknode_node_set_context_position(OakNodeNode *node, OakNodeNode *context,
|
||||
int oaknode_node_set_context_position_undoable(OakNodeNode *node,
|
||||
OakNodeNode *context, double x,
|
||||
double y, int expanded,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!node || !context || !out_command) {
|
||||
return OAKNODE_E_INVALID;
|
||||
@@ -977,10 +977,10 @@ int oaknode_node_set_context_position_undoable(OakNodeNode *node,
|
||||
// position map lives on the positioned node keyed by the context,
|
||||
// so the command's (node, context) arguments are swapped relative
|
||||
// to this function's signature.
|
||||
OakUndoCommand *handle = oaknode_c_api::wrap_command(
|
||||
OakUndoCommand handle = oaknode_c_api::wrap_command(
|
||||
new olive::NodeSetPositionCommand(to_node(context), to_node(node),
|
||||
position));
|
||||
if (!handle) {
|
||||
if (!handle.ctx) {
|
||||
return OAKNODE_E_NOMEM;
|
||||
}
|
||||
*out_command = handle;
|
||||
@@ -1039,7 +1039,7 @@ void oaknode_node_free(OakNodeNode *node)
|
||||
}
|
||||
|
||||
OakNodeNode *oaknode_node_copy_in_graph(OakNodeNode *node,
|
||||
OakUndoCommand **out_command)
|
||||
OakUndoCommand *out_command)
|
||||
{
|
||||
if (!node || !out_command) {
|
||||
return NULL;
|
||||
@@ -1054,7 +1054,7 @@ OakNodeNode *oaknode_node_copy_in_graph(OakNodeNode *node,
|
||||
return NULL;
|
||||
}
|
||||
*out_command = oaknode_c_api::wrap_command(command);
|
||||
if (!*out_command) {
|
||||
if (!out_command->ctx) {
|
||||
delete command;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1065,10 +1065,10 @@ OakNodeNode *oaknode_node_copy_in_graph(OakNodeNode *node,
|
||||
}
|
||||
}
|
||||
|
||||
OakUndoCommand *oaknode_command_create_remove_node(OakNodeNode *node)
|
||||
OakUndoCommand oaknode_command_create_remove_node(OakNodeNode *node)
|
||||
{
|
||||
if (!node) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -1076,7 +1076,7 @@ OakUndoCommand *oaknode_command_create_remove_node(OakNodeNode *node)
|
||||
new olive::NodeRemoveWithExclusiveDependenciesAndDisconnect(
|
||||
to_node(node)));
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1171,11 +1171,11 @@ int oaknode_node_disconnect_element(OakNodeNode *input_node,
|
||||
}
|
||||
}
|
||||
|
||||
OakUndoCommand *oaknode_command_create_add_node(OakNodeProject *graph,
|
||||
OakUndoCommand oaknode_command_create_add_node(OakNodeProject *graph,
|
||||
OakNodeNode *node)
|
||||
{
|
||||
if (!graph || !node) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -1183,15 +1183,15 @@ OakUndoCommand *oaknode_command_create_add_node(OakNodeProject *graph,
|
||||
new olive::NodeAddCommand(
|
||||
reinterpret_cast<olive::Project *>(graph), to_node(node)));
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
}
|
||||
|
||||
OakUndoCommand *oaknode_command_create_set_position_recursive(
|
||||
OakUndoCommand oaknode_command_create_set_position_recursive(
|
||||
OakNodeNode *node, OakNodeNode *context, double x, double y)
|
||||
{
|
||||
if (!node || !context) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -1200,7 +1200,7 @@ OakUndoCommand *oaknode_command_create_set_position_recursive(
|
||||
to_node(node), to_node(context),
|
||||
olive::Node::Position(olive::PointF(x, y))));
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -250,22 +250,15 @@ inline int value_from_variant(olive::NodeValue::Type type, const olive::Variant
|
||||
|
||||
/**
|
||||
* @brief Wrap a freshly created olive::UndoCommand in an owned
|
||||
* OakUndoCommand handle. Returns NULL on allocation failure.
|
||||
* OakUndoCommand handle (reference count 1). Returns an empty handle
|
||||
* (ctx == NULL) on allocation failure.
|
||||
*/
|
||||
inline OakUndoCommand *wrap_command(olive::UndoCommand *command)
|
||||
inline OakUndoCommand wrap_command(olive::UndoCommand *command)
|
||||
{
|
||||
if (!command) {
|
||||
return NULL;
|
||||
return OakUndoCommand{};
|
||||
}
|
||||
|
||||
OakUndoCommand *handle = new (std::nothrow) OakUndoCommand();
|
||||
if (!handle) {
|
||||
delete command;
|
||||
return NULL;
|
||||
}
|
||||
handle->command = command;
|
||||
handle->owned = true;
|
||||
return handle;
|
||||
return oakundo_capi::make_command_handle(command, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user