diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 54 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/undo_system.c | 24 |
2 files changed, 58 insertions, 20 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index cabc80d4024..cb41a4728ef 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -57,6 +57,8 @@ #include "RNA_access.h" #include "RNA_types.h" +#include "atomic_ops.h" + #define OVERRIDE_AUTO_CHECK_DELAY 0.2 /* 200ms between auto-override checks. */ //#define DEBUG_OVERRIDE_TIMEIT @@ -982,6 +984,23 @@ IDOverrideLibraryProperty *BKE_lib_override_library_property_get(IDOverrideLibra return op; } +/** + * Get the RNA-property matching the \a library_prop override property. Used for UI to query + * additional data about the overriden property (e.g. UI name). + * + * \param idpoin: Pointer to the override ID. + * \param library_prop: The library override property to find the matching RNA property for. + */ +bool BKE_lib_override_rna_property_find(PointerRNA *idpoin, + const IDOverrideLibraryProperty *library_prop, + PointerRNA *r_override_poin, + PropertyRNA **r_override_prop) +{ + BLI_assert(RNA_struct_is_ID(idpoin->type) && ID_IS_OVERRIDE_LIBRARY(idpoin->data)); + return RNA_path_resolve_property( + idpoin, library_prop->rna_path, r_override_poin, r_override_prop); +} + void lib_override_library_property_copy(IDOverrideLibraryProperty *op_dst, IDOverrideLibraryProperty *op_src) { @@ -1370,19 +1389,20 @@ bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local) * since it has to go over all properties in depth (all overridable ones at least). * Generating differential values and applying overrides are much cheaper. * - * \return true if a new overriding op was created, or some local data was reset. */ + * \return true if any library operation was created. + */ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local) { BLI_assert(local->override_library != NULL); const bool is_template = (local->override_library->reference == NULL); - bool ret = false; + bool created = false; if (!is_template) { /* Do not attempt to generate overriding rules from an empty place-holder generated by link * code when it cannot find the actual library/ID. Much better to keep the local data-block as * is in the file in that case, until broken lib is fixed. */ if (ID_MISSING(local->override_library->reference)) { - return ret; + return created; } if (GS(local->name) == ID_OB) { @@ -1412,14 +1432,16 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local) local->override_library, RNA_OVERRIDE_COMPARE_CREATE | RNA_OVERRIDE_COMPARE_RESTORE, &report_flags); + if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) { - ret = true; + created = true; } + #ifndef NDEBUG if (report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORED) { printf("We did restore some properties of %s from its reference.\n", local->name); } - if (ret) { + if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) { printf("We did generate library override rules for %s\n", local->name); } else { @@ -1427,19 +1449,28 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local) } #endif } - return ret; + return created; } +struct LibOverrideOpCreateData { + Main *bmain; + bool changed; +}; + static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, void *taskdata) { - Main *bmain = BLI_task_pool_user_data(pool); + struct LibOverrideOpCreateData *create_data = BLI_task_pool_user_data(pool); ID *id = taskdata; - BKE_lib_override_library_operations_create(bmain, id); + if (BKE_lib_override_library_operations_create(create_data->bmain, id)) { + /* Technically no need for atomic, all jobs write the same value and we only care if one did + * it. But play safe and avoid implicit assumptions. */ + atomic_fetch_and_or_uint8((uint8_t *)&create_data->changed, true); + } } /** Check all overrides from given \a bmain and create/update overriding operations as needed. */ -void BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto) +bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto) { ID *id; @@ -1464,7 +1495,8 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for } } - TaskPool *task_pool = BLI_task_pool_create(bmain, TASK_PRIORITY_HIGH); + struct LibOverrideOpCreateData create_pool_data = {.bmain = bmain, .changed = false}; + TaskPool *task_pool = BLI_task_pool_create(&create_pool_data, TASK_PRIORITY_HIGH); FOREACH_MAIN_ID_BEGIN (bmain, id) { if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && @@ -1503,6 +1535,8 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for #ifdef DEBUG_OVERRIDE_TIMEIT TIMEIT_END_AVERAGED(BKE_lib_override_library_main_operations_create); #endif + + return create_pool_data.changed; } static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root) diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index b687254fd69..078c93532d9 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -342,9 +342,10 @@ static bool undosys_stack_push_main(UndoStack *ustack, const char *name, struct CLOG_INFO(&LOG, 1, "'%s'", name); bContext *C_temp = CTX_create(); CTX_data_main_set(C_temp, bmain); - bool ok = BKE_undosys_step_push_with_type(ustack, C_temp, name, BKE_UNDOSYS_TYPE_MEMFILE); + UndoPushReturn ret = BKE_undosys_step_push_with_type( + ustack, C_temp, name, BKE_UNDOSYS_TYPE_MEMFILE); CTX_free(C_temp); - return ok; + return (ret & UNDO_PUSH_RET_SUCCESS); } void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain) @@ -495,18 +496,21 @@ UndoStep *BKE_undosys_step_push_init(UndoStack *ustack, bContext *C, const char /** * \param C: Can be NULL from some callers if their encoding function doesn't need it */ -bool BKE_undosys_step_push_with_type(UndoStack *ustack, - bContext *C, - const char *name, - const UndoType *ut) +UndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, + bContext *C, + const char *name, + const UndoType *ut) { UNDO_NESTED_ASSERT(false); undosys_stack_validate(ustack, false); bool is_not_empty = ustack->step_active != NULL; + UndoPushReturn retval = UNDO_PUSH_RET_FAILURE; /* Might not be final place for this to be called - probably only want to call it from some * undo handlers, not all of them? */ - BKE_lib_override_library_main_operations_create(G_MAIN, false); + if (BKE_lib_override_library_main_operations_create(G_MAIN, false)) { + retval |= UNDO_PUSH_RET_OVERRIDE_CHANGED; + } /* Remove all undos after (also when 'ustack->step_active == NULL'). */ while (ustack->steps.last != ustack->step_active) { @@ -558,7 +562,7 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, if (!undosys_step_encode(C, G_MAIN, ustack, us)) { MEM_freeN(us); undosys_stack_validate(ustack, true); - return false; + return retval; } ustack->step_active = us; BLI_addtail(&ustack->steps, us); @@ -589,10 +593,10 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, } undosys_stack_validate(ustack, true); - return true; + return (retval | UNDO_PUSH_RET_SUCCESS); } -bool BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char *name) +UndoPushReturn BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char *name) { UNDO_NESTED_ASSERT(false); const UndoType *ut = ustack->step_init ? ustack->step_init->type : |