diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 29 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ID.h | 5 |
2 files changed, 32 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 4403949274a..9e8d48531d7 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -162,20 +162,38 @@ void id_lib_extern(ID *id) } /* ensure we have a real user */ +/* Note: Now that we have flags, we could get rid of the 'fake_user' special case, flags are enough to ensure + * we always have a real user. + * However, ID_REAL_USERS is used in several places outside of core library.c, so think we can wait later + * to make this change... */ void id_us_ensure_real(ID *id) { if (id) { const int limit = ID_FAKE_USERS(id); + id->tag |= LIB_TAG_EXTRAUSER; if (id->us <= limit) { - if (id->us < limit) { + if (id->us < limit || ((id->us == limit) && (id->tag & LIB_TAG_EXTRAUSER_SET))) { printf("ID user count error: %s (from '%s')\n", id->name, id->lib ? id->lib->filepath : "[Main]"); BLI_assert(0); } id->us = limit + 1; + id->tag |= LIB_TAG_EXTRAUSER_SET; } } } +/* Unused currently... */ +static void UNUSED_FUNCTION(id_us_clear_real)(ID *id) +{ + if (id && (id->tag & LIB_TAG_EXTRAUSER)) { + if (id->tag & LIB_TAG_EXTRAUSER_SET) { + id->us--; + BLI_assert(id->us >= ID_FAKE_USERS(id)); + } + id->tag &= ~(LIB_TAG_EXTRAUSER | LIB_TAG_EXTRAUSER_SET); + } +} + void id_us_plus(ID *id) { if (id) { @@ -190,8 +208,15 @@ void id_us_min(ID *id) { if (id) { const int limit = ID_FAKE_USERS(id); + + if ((id->us == limit) && (id->tag & LIB_TAG_EXTRAUSER) && !(id->tag & LIB_TAG_EXTRAUSER_SET)) { + /* We need an extra user here, but never actually incremented user count for it so far, do it now. */ + id_us_ensure_real(id); + } + if (id->us <= limit) { - printf("ID user decrement error: %s (from '%s')\n", id->name, id->lib ? id->lib->filepath : "[Main]"); + printf("ID user decrement error: %s (from '%s'): %d <= %d\n", + id->name, id->lib ? id->lib->filepath : "[Main]", id->us, limit); /* We cannot assert here, because of how we 'delete' datablocks currently (setting their usercount to zero), * this is weak but it's how it works for now. */ /* BLI_assert(0); */ diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 74a63be8bbc..0bf3c350263 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -313,6 +313,11 @@ enum { /* RESET_NEVER tag datablock as a place-holder (because the real one could not be linked from its library e.g.). */ LIB_TAG_MISSING = 1 << 6, + /* tag datablock has having an extra user. */ + LIB_TAG_EXTRAUSER = 1 << 2, + /* tag datablock has having actually increased usercount for the extra virtual user. */ + LIB_TAG_EXTRAUSER_SET = 1 << 7, + /* RESET_AFTER_USE tag newly duplicated/copied IDs. */ LIB_TAG_NEW = 1 << 8, /* RESET_BEFORE_USE free test flag. |