diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_lib_override.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 186 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_tools.c | 126 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ID.h | 22 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ID.c | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rna.c | 64 |
6 files changed, 325 insertions, 77 deletions
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index ba8f2eb3399..6a05f0c22b6 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -119,6 +119,9 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct bool BKE_lib_override_library_operations_create(struct Main *bmain, struct ID *local); void BKE_lib_override_library_main_operations_create(struct Main *bmain, const bool force_auto); +void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root); +void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, struct ID *id_root); + void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property, const short tag, const bool do_set); diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 8e662892d30..421a53b8e8d 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -155,8 +155,8 @@ void BKE_lib_override_library_clear(IDOverrideLibrary *override, const bool do_i { BLI_assert(override != NULL); - if (override->runtime != NULL) { - BLI_ghash_clear(override->runtime, NULL, NULL); + if (!ELEM(NULL, override->runtime, override->runtime->rna_path_to_override_properties)) { + BLI_ghash_clear(override->runtime->rna_path_to_override_properties, NULL, NULL); } LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &override->properties) { @@ -176,8 +176,10 @@ void BKE_lib_override_library_free(struct IDOverrideLibrary **override, const bo BLI_assert(*override != NULL); if ((*override)->runtime != NULL) { - BLI_ghash_free((*override)->runtime, NULL, NULL); - (*override)->runtime = NULL; + if ((*override)->runtime->rna_path_to_override_properties != NULL) { + BLI_ghash_free((*override)->runtime->rna_path_to_override_properties, NULL, NULL); + } + MEM_SAFE_FREE((*override)->runtime); } BKE_lib_override_library_clear(*override, do_id_user); @@ -362,7 +364,11 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain) static bool lib_override_hierarchy_recursive_tag(Main *bmain, ID *id, const uint tag) { - MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id); + void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id); + if (entry_vp == NULL) { + /* Already processed. */ + return (id->tag & tag) != 0; + } /* This way we won't process again that ID should we encounter it again through another * relationship hierarchy. @@ -370,7 +376,12 @@ static bool lib_override_hierarchy_recursive_tag(Main *bmain, ID *id, const uint */ BKE_main_relations_ID_remove(bmain, id); - for (; entry != NULL; entry = entry->next) { + for (MainIDRelationsEntry *entry = *entry_vp; entry != NULL; entry = entry->next) { + if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) { + /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as + * actual dependencies. */ + continue; + } /* We only consider IDs from the same library. */ if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) { if (lib_override_hierarchy_recursive_tag(bmain, *entry->id_pointer, tag)) { @@ -606,19 +617,28 @@ bool BKE_lib_override_library_create( return success; } -/* We only build override GHash on request. */ -BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure( +BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_runtime_ensure( IDOverrideLibrary *override) { if (override->runtime == NULL) { - override->runtime = BLI_ghash_new( + override->runtime = MEM_callocN(sizeof(*override->runtime), __func__); + } + return override->runtime; +} + +/* We only build override GHash on request. */ +BLI_INLINE GHash *override_library_rna_path_mapping_ensure(IDOverrideLibrary *override) +{ + IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure(override); + if (override_runtime->rna_path_to_override_properties == NULL) { + override_runtime->rna_path_to_override_properties = BLI_ghash_new( BLI_ghashutil_strhash_p_murmur, BLI_ghashutil_strcmp, __func__); for (IDOverrideLibraryProperty *op = override->properties.first; op != NULL; op = op->next) { - BLI_ghash_insert(override->runtime, op->rna_path, op); + BLI_ghash_insert(override_runtime->rna_path_to_override_properties, op->rna_path, op); } } - return override->runtime; + return override_runtime->rna_path_to_override_properties; } /** @@ -627,7 +647,7 @@ BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure( IDOverrideLibraryProperty *BKE_lib_override_library_property_find(IDOverrideLibrary *override, const char *rna_path) { - IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(override); + GHash *override_runtime = override_library_rna_path_mapping_ensure(override); return BLI_ghash_lookup(override_runtime, rna_path); } @@ -645,8 +665,7 @@ IDOverrideLibraryProperty *BKE_lib_override_library_property_get(IDOverrideLibra op->rna_path = BLI_strdup(rna_path); BLI_addtail(&override->properties, op); - IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure( - override); + GHash *override_runtime = override_library_rna_path_mapping_ensure(override); BLI_ghash_insert(override_runtime, op->rna_path, op); if (r_created) { @@ -692,8 +711,11 @@ void lib_override_library_property_clear(IDOverrideLibraryProperty *op) void BKE_lib_override_library_property_delete(IDOverrideLibrary *override, IDOverrideLibraryProperty *override_property) { - if (override->runtime != NULL) { - BLI_ghash_remove(override->runtime, override_property->rna_path, NULL, NULL); + if (!ELEM(NULL, override->runtime, override->runtime->rna_path_to_override_properties)) { + BLI_ghash_remove(override->runtime->rna_path_to_override_properties, + override_property->rna_path, + NULL, + NULL); } lib_override_library_property_clear(override_property); BLI_freelinkN(&override->properties, override_property); @@ -1143,6 +1165,137 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for #endif } +static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root) +{ + bool was_property_deleted = false; + + LISTBASE_FOREACH_MUTABLE ( + IDOverrideLibraryProperty *, op, &id_root->override_library->properties) { + bool do_op_delete = true; + const bool is_collection = op->rna_prop_type == PROP_COLLECTION; + if (is_collection || op->rna_prop_type == PROP_POINTER) { + PointerRNA ptr_root, ptr_root_lib, ptr, ptr_lib; + PropertyRNA *prop, *prop_lib; + + RNA_pointer_create(id_root, &RNA_ID, id_root, &ptr_root); + RNA_pointer_create(id_root->override_library->reference, + &RNA_ID, + id_root->override_library->reference, + &ptr_root_lib); + + bool prop_exists = RNA_path_resolve_property(&ptr_root, op->rna_path, &ptr, &prop); + BLI_assert(prop_exists); + prop_exists = RNA_path_resolve_property(&ptr_root_lib, op->rna_path, &ptr_lib, &prop_lib); + + if (prop_exists) { + BLI_assert(ELEM(RNA_property_type(prop), PROP_POINTER, PROP_COLLECTION)); + BLI_assert(RNA_property_type(prop) == RNA_property_type(prop_lib)); + if (is_collection) { + ptr.type = RNA_property_pointer_type(&ptr, prop); + ptr_lib.type = RNA_property_pointer_type(&ptr_lib, prop_lib); + } + else { + ptr = RNA_property_pointer_get(&ptr, prop); + ptr_lib = RNA_property_pointer_get(&ptr_lib, prop_lib); + } + if (ptr.owner_id != NULL && ptr_lib.owner_id != NULL) { + BLI_assert(ptr.type == ptr_lib.type); + do_op_delete = !(RNA_struct_is_ID(ptr.type) && ptr.owner_id->override_library != NULL && + ptr.owner_id->override_library->reference == ptr_lib.owner_id); + } + } + } + + if (do_op_delete) { + BKE_lib_override_library_property_delete(id_root->override_library, op); + was_property_deleted = true; + } + } + + if (was_property_deleted) { + DEG_id_tag_update_ex(bmain, id_root, ID_RECALC_COPY_ON_WRITE); + IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure( + id_root->override_library); + override_runtime->tag |= IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD; + } + + return was_property_deleted; +} + +/** Reset all overrides in given \a id_root, while preserving ID relations. */ +void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root) +{ + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { + return; + } + + if (lib_override_library_id_reset_do(bmain, id_root)) { + if (id_root->override_library->runtime != NULL && + (id_root->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) != + 0) { + BKE_lib_override_library_update(bmain, id_root); + id_root->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD; + } + } +} + +static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *id_root) +{ + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { + return; + } + + void **entry_pp = BLI_ghash_lookup(bmain->relations->id_user_to_used, id_root); + if (entry_pp == NULL) { + /* Already processed. */ + return; + } + + lib_override_library_id_reset_do(bmain, id_root); + + /* This way we won't process again that ID should we encounter it again through another + * relationship hierarchy. + * Note that this does not free any memory from relations, so we can still use the entries. + */ + BKE_main_relations_ID_remove(bmain, id_root); + + for (MainIDRelationsEntry *entry = *entry_pp; entry != NULL; entry = entry->next) { + if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) { + /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as + * actual dependencies. */ + continue; + } + /* We only consider IDs from the same library. */ + if (entry->id_pointer != NULL) { + ID *id_entry = *entry->id_pointer; + if (id_entry->override_library != NULL) { + lib_override_library_id_hierarchy_recursive_reset(bmain, id_entry); + } + } + } +} + +/** Reset all overrides in given \a id_root and its dependencies, while preserving ID relations. */ +void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, ID *id_root) +{ + BKE_main_relations_create(bmain, 0); + + lib_override_library_id_hierarchy_recursive_reset(bmain, id_root); + + BKE_main_relations_free(bmain); + + ID *id; + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || id->override_library->runtime == NULL || + (id->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) == 0) { + continue; + } + BKE_lib_override_library_update(bmain, id); + id->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD; + } + FOREACH_MAIN_ID_END; +} + /** Set or clear given tag in all operations as unused in that override property data. */ void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property, const short tag, @@ -1320,6 +1473,7 @@ void BKE_lib_override_library_update(Main *bmain, ID *local) /* Full rebuild of Depsgraph! */ /* Note: this is really brute force, in theory updates from RNA should have handle this already, * but for now let's play it safe. */ + DEG_id_tag_update_ex(bmain, local, ID_RECALC_ALL); DEG_relations_tag_update(bmain); } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 6b998828c77..7515178e1d1 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -744,22 +744,21 @@ typedef struct OutlinerLibOverrideData { bool do_hierarchy; } OutlinerLibOverrideData; -static void id_override_library_cb(bContext *C, - ReportList *UNUSED(reports), - Scene *UNUSED(scene), - TreeElement *te, - TreeStoreElem *UNUSED(tsep), - TreeStoreElem *tselem, - void *user_data) +static void id_override_library_create_cb(bContext *C, + ReportList *UNUSED(reports), + Scene *UNUSED(scene), + TreeElement *te, + TreeStoreElem *UNUSED(tsep), + TreeStoreElem *tselem, + void *user_data) { BLI_assert(TSE_IS_REAL_ID(tselem)); ID *id_root = tselem->id; + OutlinerLibOverrideData *data = user_data; + const bool do_hierarchy = data->do_hierarchy; - if (ID_IS_LINKED(id_root) && - (BKE_idtype_get_info_from_id(id_root)->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0) { + if (ID_IS_OVERRIDABLE_LIBRARY(id_root) || (ID_IS_LINKED(id_root) && do_hierarchy)) { Main *bmain = CTX_data_main(C); - OutlinerLibOverrideData *data = user_data; - const bool do_hierarchy = data->do_hierarchy; id_root->tag |= LIB_TAG_DOIT; @@ -798,6 +797,34 @@ static void id_override_library_cb(bContext *C, } } +static void id_override_library_reset_cb(bContext *C, + ReportList *UNUSED(reports), + Scene *UNUSED(scene), + TreeElement *UNUSED(te), + TreeStoreElem *UNUSED(tsep), + TreeStoreElem *tselem, + void *user_data) +{ + BLI_assert(TSE_IS_REAL_ID(tselem)); + ID *id_root = tselem->id; + OutlinerLibOverrideData *data = user_data; + const bool do_hierarchy = data->do_hierarchy; + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { + Main *bmain = CTX_data_main(C); + + if (do_hierarchy) { + BKE_lib_override_library_id_hierarchy_reset(bmain, id_root); + } + else { + BKE_lib_override_library_id_reset(bmain, id_root); + } + + WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } +} + static void id_fake_user_set_cb(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), @@ -1546,8 +1573,10 @@ typedef enum eOutlinerIdOpTypes { OUTLINER_IDOP_UNLINK, OUTLINER_IDOP_LOCAL, - OUTLINER_IDOP_OVERRIDE_LIBRARY, - OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY, + OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE, + OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY, + OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET, + OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY, OUTLINER_IDOP_SINGLE, OUTLINER_IDOP_DELETE, OUTLINER_IDOP_REMAP, @@ -1566,16 +1595,6 @@ typedef enum eOutlinerIdOpTypes { static const EnumPropertyItem prop_id_op_types[] = { {OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""}, {OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""}, - {OUTLINER_IDOP_OVERRIDE_LIBRARY, - "OVERRIDE_LIBRARY", - 0, - "Add Library Override", - "Add a local override of this linked data-block"}, - {OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY, - "OVERRIDE_LIBRARY_HIERARCHY", - 0, - "Add Library Override Hierarchy", - "Add a local override of this linked data-block, and its hierarchy of dependencies"}, {OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""}, {OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""}, {OUTLINER_IDOP_REMAP, @@ -1584,6 +1603,27 @@ static const EnumPropertyItem prop_id_op_types[] = { "Remap Users", "Make all users of selected data-blocks to use instead current (clicked) one"}, {0, "", 0, NULL, NULL}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE, + "OVERRIDE_LIBRARY_CREATE", + 0, + "Add Library Override", + "Add a local override of this linked data-block"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY, + "OVERRIDE_LIBRARY_CREATE_HIERARCHY", + 0, + "Add Library Override Hierarchy", + "Add a local override of this linked data-block, and its hierarchy of dependencies"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET, + "OVERRIDE_LIBRARY_RESET", + 0, + "Reset Library Override", + "Reset this local override to its linked values"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY, + "OVERRIDE_LIBRARY_RESET_HIERARCHY", + 0, + "Reset Library Override Hierarchy", + "Reset this local override to its linked values, as well as its hierarchy of dependencies"}, + {0, "", 0, NULL, NULL}, {OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""}, {OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""}, {0, "", 0, NULL, NULL}, @@ -1607,7 +1647,11 @@ static bool outliner_id_operation_item_poll(bContext *C, SpaceOutliner *soops = CTX_wm_space_outliner(C); switch (enum_value) { - case OUTLINER_IDOP_OVERRIDE_LIBRARY: + case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE: + case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: + return true; + case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: + case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY: return true; case OUTLINER_IDOP_SINGLE: if (!soops || ELEM(soops->outlinevis, SO_SCENES, SO_VIEW_LAYER)) { @@ -1721,28 +1765,52 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Localized Data"); break; } - case OUTLINER_IDOP_OVERRIDE_LIBRARY: { + case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE: { /* make local */ outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, - id_override_library_cb, + id_override_library_create_cb, &(OutlinerLibOverrideData){.do_hierarchy = false}); ED_undo_push(C, "Overridden Data"); break; } - case OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY: { + case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: { /* make local */ outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, - id_override_library_cb, + id_override_library_create_cb, &(OutlinerLibOverrideData){.do_hierarchy = true}); - ED_undo_push(C, "Overridden Data"); + ED_undo_push(C, "Overridden Data Hierarchy"); + break; + } + case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: { + /* make local */ + outliner_do_libdata_operation(C, + op->reports, + scene, + soops, + &soops->tree, + id_override_library_reset_cb, + &(OutlinerLibOverrideData){.do_hierarchy = false}); + ED_undo_push(C, "Reset Overridden Data"); + break; + } + case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY: { + /* make local */ + outliner_do_libdata_operation(C, + op->reports, + scene, + soops, + &soops->tree, + id_override_library_reset_cb, + &(OutlinerLibOverrideData){.do_hierarchy = true}); + ED_undo_push(C, "Reset Overridden Data Hierarchy"); break; } case OUTLINER_IDOP_SINGLE: { diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 60cedfe3c8a..4ec622574cc 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -206,7 +206,10 @@ typedef struct IDOverrideLibraryProperty { /** Runtime, tags are common to both IDOverrideProperty and IDOverridePropertyOperation. */ short tag; - char _pad0[6]; + char _pad[2]; + + /** The property type matching the rna_path. */ + unsigned int rna_prop_type; } IDOverrideLibraryProperty; /* IDOverrideProperty->tag and IDOverridePropertyOperation->tag. */ @@ -215,8 +218,18 @@ enum { IDOVERRIDE_LIBRARY_TAG_UNUSED = 1 << 0, }; -/* We do not need a full struct for that currently, just a GHash. */ -typedef struct GHash IDOverrideLibraryRuntime; +# +# +typedef struct IDOverrideLibraryRuntime { + struct GHash *rna_path_to_override_properties; + uint tag; +} IDOverrideLibraryRuntime; + +/* IDOverrideLibraryRuntime->tag. */ +enum { + /** This override needs to be reloaded. */ + IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD = 1 << 0, +}; /* Main container for all overriding data info of a data-block. */ typedef struct IDOverrideLibrary { @@ -468,7 +481,8 @@ typedef enum ID_Type { /* Note that this is a fairly high-level check, should be used at user interaction level, not in * BKE_library_override typically (especially due to the check on LIB_TAG_EXTERN). */ #define ID_IS_OVERRIDABLE_LIBRARY(_id) \ - (ID_IS_LINKED(_id) && !ID_MISSING(_id) && (((const ID *)(_id))->tag & LIB_TAG_EXTERN) != 0) + (ID_IS_LINKED(_id) && !ID_MISSING(_id) && (((const ID *)(_id))->tag & LIB_TAG_EXTERN) != 0 && \ + (BKE_idtype_get_info_from_id((const ID *)(_id))->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0) #define ID_IS_OVERRIDE_LIBRARY_REAL(_id) \ (((const ID *)(_id))->override_library != NULL && \ diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 8d498ab569b..e9ca0d577ce 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -96,6 +96,7 @@ const EnumPropertyItem rna_enum_id_type_items[] = { # include "BKE_font.h" # include "BKE_global.h" /* XXX, remove me */ # include "BKE_idprop.h" +# include "BKE_idtype.h" # include "BKE_lib_override.h" # include "BKE_lib_query.h" # include "BKE_lib_remap.h" diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index f9f6defb2f1..9f5440be9f8 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -1250,6 +1250,7 @@ static int rna_property_override_diff_propptr(Main *bmain, IDOverrideLibrary *override, const char *rna_path, size_t rna_path_len, + const uint property_type, const char *rna_itemname_a, const char *rna_itemname_b, const int rna_itemindex_a, @@ -1257,6 +1258,8 @@ static int rna_property_override_diff_propptr(Main *bmain, const int flags, bool *r_override_changed) { + BLI_assert(ELEM(property_type, PROP_POINTER, PROP_COLLECTION)); + const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL; @@ -1300,6 +1303,13 @@ static int rna_property_override_diff_propptr(Main *bmain, if (op != NULL) { BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false); + if (created || op->rna_prop_type == 0) { + op->rna_prop_type = property_type; + } + else { + BLI_assert(op->rna_prop_type == property_type); + } + if (created || rna_itemname_a != NULL || rna_itemname_b != NULL || rna_itemindex_a != -1 || rna_itemindex_b != -1) { BKE_lib_override_library_property_operation_get(op, @@ -1464,7 +1474,11 @@ int rna_property_override_diff_default(Main *bmain, PROPOVERRIDE_LIBRARY_INSERTION) && do_create; - switch (RNA_property_type(prop_a->rnaprop)) { + const uint rna_prop_type = RNA_property_type(prop_a->rnaprop); + bool created = false; + IDOverrideLibraryProperty *op = NULL; + + switch (rna_prop_type) { case PROP_BOOLEAN: { if (len_a) { bool array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY]; @@ -1482,9 +1496,7 @@ int rna_property_override_diff_default(Main *bmain, if (do_create && comp != 0) { /* XXX TODO this will have to be refined to handle array items */ - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { BKE_lib_override_library_property_operation_get( @@ -1513,9 +1525,7 @@ int rna_property_override_diff_default(Main *bmain, const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0; if (do_create && comp != 0) { - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( @@ -1547,9 +1557,7 @@ int rna_property_override_diff_default(Main *bmain, if (do_create && comp != 0) { /* XXX TODO this will have to be refined to handle array items */ - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { BKE_lib_override_library_property_operation_get( @@ -1578,9 +1586,7 @@ int rna_property_override_diff_default(Main *bmain, const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0; if (do_create && comp != 0) { - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( @@ -1612,9 +1618,7 @@ int rna_property_override_diff_default(Main *bmain, if (do_create && comp != 0) { /* XXX TODO this will have to be refined to handle array items */ - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { BKE_lib_override_library_property_operation_get( @@ -1643,9 +1647,7 @@ int rna_property_override_diff_default(Main *bmain, const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0; if (do_create && comp != 0) { - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( @@ -1666,9 +1668,7 @@ int rna_property_override_diff_default(Main *bmain, const int comp = value_a != value_b; if (do_create && comp != 0) { - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( @@ -1700,9 +1700,7 @@ int rna_property_override_diff_default(Main *bmain, const int comp = strcmp(value_a, value_b); if (do_create && comp != 0) { - bool created = false; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( @@ -1740,6 +1738,7 @@ int rna_property_override_diff_default(Main *bmain, override, rna_path, rna_path_len, + PROP_POINTER, NULL, NULL, -1, @@ -1848,9 +1847,7 @@ int rna_property_override_diff_default(Main *bmain, * pointers), since they do not support removing, only in *some* cases, insertion. We * also assume then that _a data is the one where things are inserted. */ if (is_valid_for_insertion && use_collection_insertion) { - bool created; - IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get( - override, rna_path, &created); + op = BKE_lib_override_library_property_get(override, rna_path, &created); if (is_first_insert) { /* We need to clean up all possible existing insertion operations, @@ -1883,6 +1880,7 @@ int rna_property_override_diff_default(Main *bmain, prev_propname_a, idx_a - 1); # endif + op = NULL; } else if (is_id || is_valid_for_diffing) { if (equals || do_create) { @@ -1895,6 +1893,7 @@ int rna_property_override_diff_default(Main *bmain, override, rna_path, rna_path_len, + PROP_COLLECTION, propname_a, propname_b, idx_a, @@ -1963,6 +1962,15 @@ int rna_property_override_diff_default(Main *bmain, break; } + if (op != NULL) { + if (created || op->rna_prop_type == 0) { + op->rna_prop_type = rna_prop_type; + } + else { + BLI_assert(op->rna_prop_type == rna_prop_type); + } + } + return 0; } |