diff options
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_main.h | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 28 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blendfile.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.cc | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/main.c | 3 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 8 |
7 files changed, 67 insertions, 16 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 940dec2fcd5..1f0919bb3e6 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -11,6 +11,9 @@ extern "C" { #endif +#include "BLI_compiler_attrs.h" + +struct Main; struct UserDef; /** @@ -21,6 +24,16 @@ void BKE_blender_free(void); void BKE_blender_globals_init(void); void BKE_blender_globals_clear(void); +/** Replace current global Main by the given one, freeing existing one. */ +void BKE_blender_globals_main_replace(struct Main *bmain); +/** + * Replace current global Main by the given one, returning the old one. + * + * \warning Advanced, risky workaround addressing the issue that current RNA is not able to process + * correectly non-G_MAIN data, use with (a lot of) care. + */ +struct Main *BKE_blender_globals_main_swap(struct Main *new_gmain); + void BKE_blender_userdef_data_swap(struct UserDef *userdef_a, struct UserDef *userdef_b); void BKE_blender_userdef_data_set(struct UserDef *userdef); void BKE_blender_userdef_data_set_and_free(struct UserDef *userdef); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 0048ad4dde5..7c3a64f1cad 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -138,6 +138,14 @@ typedef struct Main { */ bool is_locked_for_linking; + /** + * True if this main is the 'GMAIN' of current Blender. + * + * \note There should always be only one global main, all others generated temporarily for + * various data management process must have this property set to false.. + */ + bool is_global_main; + BlendThumbnail *blen_thumb; struct Library *curlib; @@ -202,6 +210,12 @@ typedef struct Main { struct MainLock *lock; } Main; +/** + * Create a new Main data-base. + * + * \note Always generate a non-global Main, use #BKE_blender_globals_main_replace to put a newly + * created one in `G_MAIN`. + */ struct Main *BKE_main_new(void); void BKE_main_free(struct Main *mainvar); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 947cdc0c8bf..23cf368af01 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -62,8 +62,7 @@ void BKE_blender_free(void) /* Needs to run before main free as wm is still referenced for icons preview jobs. */ BKE_studiolight_free(); - BKE_main_free(G_MAIN); - G_MAIN = NULL; + BKE_blender_globals_clear(); if (G.log.file != NULL) { fclose(G.log.file); @@ -146,7 +145,7 @@ void BKE_blender_globals_init(void) U.savetime = 1; - G_MAIN = BKE_main_new(); + BKE_blender_globals_main_replace(BKE_main_new()); strcpy(G.ima, "//"); @@ -161,11 +160,34 @@ void BKE_blender_globals_init(void) void BKE_blender_globals_clear(void) { + if (G_MAIN == NULL) { + return; + } + BLI_assert(G_MAIN->is_global_main); BKE_main_free(G_MAIN); /* free all lib data */ G_MAIN = NULL; } +void BKE_blender_globals_main_replace(Main *bmain) +{ + BLI_assert(!bmain->is_global_main); + BKE_blender_globals_clear(); + bmain->is_global_main = true; + G_MAIN = bmain; +} + +Main *BKE_blender_globals_main_swap(Main *new_gmain) +{ + Main *old_gmain = G_MAIN; + BLI_assert(old_gmain->is_global_main); + BLI_assert(!new_gmain->is_global_main); + new_gmain->is_global_main = true; + G_MAIN = new_gmain; + old_gmain->is_global_main = false; + return old_gmain; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index ba208f688ee..6546659f6cd 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -287,11 +287,8 @@ static void setup_app_data(bContext *C, } } - /* free G_MAIN Main database */ - // CTX_wm_manager_set(C, NULL); - BKE_blender_globals_clear(); - - bmain = G_MAIN = bfd->main; + BKE_blender_globals_main_replace(bfd->main); + bmain = G_MAIN; bfd->main = NULL; CTX_data_main_set(C, bmain); diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index e2f991a4026..04679b72b2d 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -23,6 +23,7 @@ #include "BKE_anim_data.h" #include "BKE_armature.h" +#include "BKE_blender.h" #include "BKE_collection.h" #include "BKE_fcurve.h" #include "BKE_global.h" @@ -3829,9 +3830,8 @@ void BKE_lib_override_library_main_update(Main *bmain) /* This temporary swap of G_MAIN is rather ugly, * but necessary to avoid asserts checks in some RNA assignment functions, - * since those always use on G_MAIN when they need access to a Main database. */ - Main *orig_gmain = G_MAIN; - G_MAIN = bmain; + * since those always use G_MAIN when they need access to a Main database. */ + Main *orig_gmain = BKE_blender_globals_main_swap(bmain); BLI_assert(BKE_main_namemap_validate(bmain)); @@ -3844,7 +3844,9 @@ void BKE_lib_override_library_main_update(Main *bmain) BLI_assert(BKE_main_namemap_validate(bmain)); - G_MAIN = orig_gmain; + Main *tmp_gmain = BKE_blender_globals_main_swap(orig_gmain); + BLI_assert(tmp_gmain == bmain); + UNUSED_VARS_NDEBUG(tmp_gmain); } bool BKE_lib_override_library_id_is_user_deletable(Main *bmain, ID *id) diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c index 239aacf28d6..3e8ff957d53 100644 --- a/source/blender/blenkernel/intern/main.c +++ b/source/blender/blenkernel/intern/main.c @@ -29,11 +29,12 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -Main *BKE_main_new(void) +Main *BKE_main_new() { Main *bmain = MEM_callocN(sizeof(Main), "new main"); bmain->lock = MEM_mallocN(sizeof(SpinLock), "main lock"); BLI_spin_init((SpinLock *)bmain->lock); + bmain->is_global_main = false; return bmain; } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 3e26516cd69..a9048037513 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -53,6 +53,7 @@ #include "DNA_world_types.h" #include "BKE_animsys.h" +#include "BKE_blender.h" #include "BKE_brush.h" #include "BKE_cloth.h" #include "BKE_collection.h" @@ -1613,12 +1614,13 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) if (me->totface && !me->totpoly) { /* temporarily switch main so that reading from * external CustomData works */ - Main *gmain = G_MAIN; - G_MAIN = bmain; + Main *orig_gmain = BKE_blender_globals_main_swap(bmain); BKE_mesh_do_versions_convert_mfaces_to_mpolys(me); - G_MAIN = gmain; + Main *tmp_gmain = BKE_blender_globals_main_swap(orig_gmain); + BLI_assert(tmp_gmain == bmain); + UNUSED_VARS_NDEBUG(tmp_gmain); } /* Deprecated, only kept for conversion. */ |