Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2020-04-03 14:34:12 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-04-07 14:19:52 +0300
commit0aac74f18f2d4de1cdde6ca9bf4f8b9a97085d28 (patch)
tree1508569e7e189414be9ead7d7c09de82922735ff /source/blender/blenloader
parentc4def7992b589aaf9f45aca04b5dcb0b760ad36e (diff)
Cleanup: split off direct_link_id() function
Differential Revision: https://developer.blender.org/D7324
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r--source/blender/blenloader/intern/readfile.c365
1 files changed, 187 insertions, 178 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 07cd39e2559..3c5908efa3f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -470,8 +470,9 @@ static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *l
return NULL;
}
-static void oldnewmap_free_unused(OldNewMap *onm)
+static void oldnewmap_clear(OldNewMap *onm)
{
+ /* Free unused data. */
for (int i = 0; i < onm->nentries; i++) {
OldNew *entry = &onm->entries[i];
if (entry->nr == 0) {
@@ -479,10 +480,7 @@ static void oldnewmap_free_unused(OldNewMap *onm)
entry->newp = NULL;
}
}
-}
-static void oldnewmap_clear(OldNewMap *onm)
-{
onm->capacity_exp = DEFAULT_SIZE_EXP;
oldnewmap_clear_map(onm);
onm->nentries = 0;
@@ -2768,7 +2766,7 @@ static void direct_link_id_override_property_cb(FileData *fd, void *data)
link_list_ex(fd, &op->operations, direct_link_id_override_property_operation_cb);
}
-static void direct_link_id(FileData *fd, ID *id, ID *id_old);
+static void direct_link_id_common(FileData *fd, ID *id, ID *id_old, const int tag);
static void direct_link_nodetree(FileData *fd, bNodeTree *ntree);
static void direct_link_collection(FileData *fd, Collection *collection);
@@ -2778,7 +2776,8 @@ static void direct_link_id_private_id(FileData *fd, ID *id, ID *id_old)
bNodeTree **nodetree = BKE_ntree_ptr_from_id(id);
if (nodetree != NULL && *nodetree != NULL) {
*nodetree = newdataadr(fd, *nodetree);
- direct_link_id(fd, (ID *)*nodetree, id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL);
+ direct_link_id_common(
+ fd, (ID *)*nodetree, id_old != NULL ? (ID *)ntreeFromID(id_old) : NULL, 0);
direct_link_nodetree(fd, *nodetree);
}
@@ -2786,15 +2785,16 @@ static void direct_link_id_private_id(FileData *fd, ID *id, ID *id_old)
Scene *scene = (Scene *)id;
if (scene->master_collection != NULL) {
scene->master_collection = newdataadr(fd, scene->master_collection);
- direct_link_id(fd,
- &scene->master_collection->id,
- id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL);
+ direct_link_id_common(fd,
+ &scene->master_collection->id,
+ id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL,
+ 0);
direct_link_collection(fd, scene->master_collection);
}
}
}
-static void direct_link_id(FileData *fd, ID *id, ID *id_old)
+static void direct_link_id_common(FileData *fd, ID *id, ID *id_old, const int tag)
{
/*link direct data of ID properties*/
if (id->properties) {
@@ -2804,10 +2804,8 @@ static void direct_link_id(FileData *fd, ID *id, ID *id_old)
}
id->py_instance = NULL;
- /* That way data-lock reading not going through main read_libblock()
- * function are still in a clear tag state.
- * (glowering at certain nodetree fake data-lock here...). */
- id->tag = 0;
+ /* Initialize with provided tag. */
+ id->tag = tag;
id->flag &= ~LIB_INDIRECT_WEAK_LINK;
/* NOTE: It is important to not clear the recalc flags for undo/redo.
@@ -8378,7 +8376,7 @@ void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions)
static bool direct_link_screen(FileData *fd, bScreen *screen)
{
- bool wrong_id = false;
+ bool success = true;
screen->regionbase.first = screen->regionbase.last = NULL;
screen->context = NULL;
@@ -8388,10 +8386,10 @@ static bool direct_link_screen(FileData *fd, bScreen *screen)
if (!direct_link_area_map(fd, AREAMAP_FROM_SCREEN(screen))) {
printf("Error reading Screen %s... removing it.\n", screen->id.name + 2);
- wrong_id = true;
+ success = false;
}
- return wrong_id;
+ return success;
}
/** \} */
@@ -9227,6 +9225,158 @@ static const char *dataname(short id_code)
return "Data from Lib Block";
}
+static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *id_old)
+{
+ if (fd->memfile == NULL) {
+ /* When actually reading a file , we do want to reset/re-generate session uuids.
+ * In undo case, we want to re-use existing ones. */
+ id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
+ }
+
+ BKE_lib_libblock_session_uuid_ensure(id);
+
+ id->lib = main->curlib;
+ id->us = ID_FAKE_USERS(id);
+ id->icon_id = 0;
+ id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
+ id->orig_id = NULL;
+
+ if (tag & LIB_TAG_ID_LINK_PLACEHOLDER) {
+ /* For placeholder we only need to set the tag, no further data to read. */
+ id->tag = tag;
+ return true;
+ }
+
+ /* Read part of datablock that is common between real and embedded datablocks. */
+ direct_link_id_common(fd, id, id_old, tag);
+
+ /* XXX Very weakly handled currently, see comment in read_libblock() before trying to
+ * use it for anything new. */
+ bool success = true;
+
+ switch (GS(id->name)) {
+ case ID_WM:
+ direct_link_windowmanager(fd, (wmWindowManager *)id);
+ break;
+ case ID_SCR:
+ success = direct_link_screen(fd, (bScreen *)id);
+ break;
+ case ID_SCE:
+ direct_link_scene(fd, (Scene *)id);
+ break;
+ case ID_OB:
+ direct_link_object(fd, (Object *)id);
+ break;
+ case ID_ME:
+ direct_link_mesh(fd, (Mesh *)id);
+ break;
+ case ID_CU:
+ direct_link_curve(fd, (Curve *)id);
+ break;
+ case ID_MB:
+ direct_link_mball(fd, (MetaBall *)id);
+ break;
+ case ID_MA:
+ direct_link_material(fd, (Material *)id);
+ break;
+ case ID_TE:
+ direct_link_texture(fd, (Tex *)id);
+ break;
+ case ID_IM:
+ direct_link_image(fd, (Image *)id);
+ break;
+ case ID_LA:
+ direct_link_light(fd, (Light *)id);
+ break;
+ case ID_VF:
+ direct_link_vfont(fd, (VFont *)id);
+ break;
+ case ID_TXT:
+ direct_link_text(fd, (Text *)id);
+ break;
+ case ID_IP:
+ direct_link_ipo(fd, (Ipo *)id);
+ break;
+ case ID_KE:
+ direct_link_key(fd, (Key *)id);
+ break;
+ case ID_LT:
+ direct_link_latt(fd, (Lattice *)id);
+ break;
+ case ID_WO:
+ direct_link_world(fd, (World *)id);
+ break;
+ case ID_LI:
+ direct_link_library(fd, (Library *)id, main);
+ break;
+ case ID_CA:
+ direct_link_camera(fd, (Camera *)id);
+ break;
+ case ID_SPK:
+ direct_link_speaker(fd, (Speaker *)id);
+ break;
+ case ID_SO:
+ direct_link_sound(fd, (bSound *)id);
+ break;
+ case ID_LP:
+ direct_link_lightprobe(fd, (LightProbe *)id);
+ break;
+ case ID_GR:
+ direct_link_collection(fd, (Collection *)id);
+ break;
+ case ID_AR:
+ direct_link_armature(fd, (bArmature *)id);
+ break;
+ case ID_AC:
+ direct_link_action(fd, (bAction *)id);
+ break;
+ case ID_NT:
+ direct_link_nodetree(fd, (bNodeTree *)id);
+ break;
+ case ID_BR:
+ direct_link_brush(fd, (Brush *)id);
+ break;
+ case ID_PA:
+ direct_link_particlesettings(fd, (ParticleSettings *)id);
+ break;
+ case ID_GD:
+ direct_link_gpencil(fd, (bGPdata *)id);
+ break;
+ case ID_MC:
+ direct_link_movieclip(fd, (MovieClip *)id);
+ break;
+ case ID_MSK:
+ direct_link_mask(fd, (Mask *)id);
+ break;
+ case ID_LS:
+ direct_link_linestyle(fd, (FreestyleLineStyle *)id);
+ break;
+ case ID_PAL:
+ direct_link_palette(fd, (Palette *)id);
+ break;
+ case ID_PC:
+ direct_link_paint_curve(fd, (PaintCurve *)id);
+ break;
+ case ID_CF:
+ direct_link_cachefile(fd, (CacheFile *)id);
+ break;
+ case ID_WS:
+ direct_link_workspace(fd, (WorkSpace *)id, main);
+ break;
+ case ID_HA:
+ direct_link_hair(fd, (Hair *)id);
+ break;
+ case ID_PT:
+ direct_link_pointcloud(fd, (PointCloud *)id);
+ break;
+ case ID_VO:
+ direct_link_volume(fd, (Volume *)id);
+ break;
+ }
+
+ return success;
+}
+
static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *allocname)
{
bhead = blo_bhead_next(fd, bhead);
@@ -9261,15 +9411,8 @@ static BHead *read_libblock(FileData *fd,
const bool placeholder_set_indirect_extern,
ID **r_id)
{
- /* this routine reads a libblock and its direct data. Use link functions to connect it all
- */
- ID *id;
- ListBase *lb;
- const char *allocname;
-
- /* XXX Very weakly handled currently, see comment at the end of this function before trying to
- * use it for anything new. */
- bool wrong_id = false;
+ /* This routine reads a libblock and its direct data. Lib link functions will
+ * set points between datablocks. */
/* In undo case, most libs and linked data should be kept as is from previous state
* (see BLO_read_from_memfile).
@@ -9314,7 +9457,8 @@ static BHead *read_libblock(FileData *fd,
DEBUG_PRINTF("... in %s (%s): ",
main->curlib ? main->curlib->id.name : "<NULL>",
main->curlib ? main->curlib->name : "<NULL>");
- if ((id = BKE_libblock_find_name(main, GS(idname), idname + 2))) {
+ ID *id = BKE_libblock_find_name(main, GS(idname), idname + 2);
+ if (id != NULL) {
DEBUG_PRINTF("FOUND!\n");
/* Even though we found our linked ID,
* there is no guarantee its address is still the same. */
@@ -9335,7 +9479,7 @@ static BHead *read_libblock(FileData *fd,
/* read libblock */
fd->are_memchunks_identical = true;
- id = read_struct(fd, bhead, "lib block");
+ ID *id = read_struct(fd, bhead, "lib block");
const short idcode = id != NULL ? GS(id->name) : 0;
BHead *id_bhead = bhead;
@@ -9348,7 +9492,7 @@ static BHead *read_libblock(FileData *fd,
if (id_bhead->code != ID_LINK_PLACEHOLDER) {
/* need a name for the mallocN, just for debugging and sane prints on leaks */
- allocname = dataname(idcode);
+ const char *allocname = dataname(idcode);
/* read all data into fd->datamap */
/* TODO: instead of building oldnewmap here we could just quickly check the bheads... could
@@ -9442,7 +9586,6 @@ static BHead *read_libblock(FileData *fd,
}
MEM_freeN(id);
- oldnewmap_free_unused(fd->datamap);
oldnewmap_clear(fd->datamap);
return bhead;
@@ -9451,7 +9594,7 @@ static BHead *read_libblock(FileData *fd,
}
/* do after read_struct, for dna reconstruct */
- lb = which_libbase(main, idcode);
+ ListBase *lb = which_libbase(main, idcode);
if (lb) {
/* Some re-used old IDs might also use newly read ones, so we have to check for old memory
* addresses for those as well. */
@@ -9487,14 +9630,6 @@ static BHead *read_libblock(FileData *fd,
oldnewmap_insert(fd->libmap, id_old, id_target, id_bhead->code);
BLI_addtail(lb, id);
-
- if (fd->memfile == NULL) {
- /* When actually reading a file , we do want to reset/re-generate session uuids.
- * In unod case, we want to re-use existing ones. */
- id->session_uuid = MAIN_ID_SESSION_UUID_UNSET;
- }
-
- BKE_lib_libblock_session_uuid_ensure(id);
}
else {
/* unknown ID type */
@@ -9511,160 +9646,35 @@ static BHead *read_libblock(FileData *fd,
return blo_bhead_next(fd, id_bhead);
}
- id->lib = main->curlib;
- id->us = ID_FAKE_USERS(id);
- id->icon_id = 0;
- id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
- id->orig_id = NULL;
+ /* Set tag for new datablock to indicate lib linking and versioning needs
+ * to be done still. */
+ int id_tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW;
- /* this case cannot be direct_linked: it's just the ID part */
if (id_bhead->code == ID_LINK_PLACEHOLDER) {
- /* That way, we know which data-lock needs do_versions (required currently for linking). */
- id->tag = tag | LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_NEED_LINK | LIB_TAG_NEW;
+ /* Tag to get replaced by the actual linked datablock. */
+ id_tag |= LIB_TAG_ID_LINK_PLACEHOLDER;
if (placeholder_set_indirect_extern) {
if (id->flag & LIB_INDIRECT_WEAK_LINK) {
- id->tag |= LIB_TAG_INDIRECT;
+ id_tag |= LIB_TAG_INDIRECT;
}
else {
- id->tag |= LIB_TAG_EXTERN;
+ id_tag |= LIB_TAG_EXTERN;
}
}
-
- return blo_bhead_next(fd, id_bhead);
}
- /* init pointers direct data */
- direct_link_id(fd, id, id_old);
+ /* Read datablock contents. */
+ const bool success = direct_link_id(fd, main, id_tag, id, id_old);
- /* That way, we know which data-lock needs do_versions (required currently for linking). */
- /* Note: doing this after direct_link_id(), which resets that field. */
- id->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW;
-
- switch (idcode) {
- case ID_WM:
- direct_link_windowmanager(fd, (wmWindowManager *)id);
- break;
- case ID_SCR:
- wrong_id = direct_link_screen(fd, (bScreen *)id);
- break;
- case ID_SCE:
- direct_link_scene(fd, (Scene *)id);
- break;
- case ID_OB:
- direct_link_object(fd, (Object *)id);
- break;
- case ID_ME:
- direct_link_mesh(fd, (Mesh *)id);
- break;
- case ID_CU:
- direct_link_curve(fd, (Curve *)id);
- break;
- case ID_MB:
- direct_link_mball(fd, (MetaBall *)id);
- break;
- case ID_MA:
- direct_link_material(fd, (Material *)id);
- break;
- case ID_TE:
- direct_link_texture(fd, (Tex *)id);
- break;
- case ID_IM:
- direct_link_image(fd, (Image *)id);
- break;
- case ID_LA:
- direct_link_light(fd, (Light *)id);
- break;
- case ID_VF:
- direct_link_vfont(fd, (VFont *)id);
- break;
- case ID_TXT:
- direct_link_text(fd, (Text *)id);
- break;
- case ID_IP:
- direct_link_ipo(fd, (Ipo *)id);
- break;
- case ID_KE:
- direct_link_key(fd, (Key *)id);
- break;
- case ID_LT:
- direct_link_latt(fd, (Lattice *)id);
- break;
- case ID_WO:
- direct_link_world(fd, (World *)id);
- break;
- case ID_LI:
- direct_link_library(fd, (Library *)id, main);
- break;
- case ID_CA:
- direct_link_camera(fd, (Camera *)id);
- break;
- case ID_SPK:
- direct_link_speaker(fd, (Speaker *)id);
- break;
- case ID_SO:
- direct_link_sound(fd, (bSound *)id);
- break;
- case ID_LP:
- direct_link_lightprobe(fd, (LightProbe *)id);
- break;
- case ID_GR:
- direct_link_collection(fd, (Collection *)id);
- break;
- case ID_AR:
- direct_link_armature(fd, (bArmature *)id);
- break;
- case ID_AC:
- direct_link_action(fd, (bAction *)id);
- break;
- case ID_NT:
- direct_link_nodetree(fd, (bNodeTree *)id);
- break;
- case ID_BR:
- direct_link_brush(fd, (Brush *)id);
- break;
- case ID_PA:
- direct_link_particlesettings(fd, (ParticleSettings *)id);
- break;
- case ID_GD:
- direct_link_gpencil(fd, (bGPdata *)id);
- break;
- case ID_MC:
- direct_link_movieclip(fd, (MovieClip *)id);
- break;
- case ID_MSK:
- direct_link_mask(fd, (Mask *)id);
- break;
- case ID_LS:
- direct_link_linestyle(fd, (FreestyleLineStyle *)id);
- break;
- case ID_PAL:
- direct_link_palette(fd, (Palette *)id);
- break;
- case ID_PC:
- direct_link_paint_curve(fd, (PaintCurve *)id);
- break;
- case ID_CF:
- direct_link_cachefile(fd, (CacheFile *)id);
- break;
- case ID_WS:
- direct_link_workspace(fd, (WorkSpace *)id, main);
- break;
- case ID_HA:
- direct_link_hair(fd, (Hair *)id);
- break;
- case ID_PT:
- direct_link_pointcloud(fd, (PointCloud *)id);
- break;
- case ID_VO:
- direct_link_volume(fd, (Volume *)id);
- break;
+ /* For placeholders we are done here. */
+ if (id_bhead->code == ID_LINK_PLACEHOLDER) {
+ return blo_bhead_next(fd, id_bhead);
}
- oldnewmap_free_unused(fd->datamap);
oldnewmap_clear(fd->datamap);
- if (wrong_id) {
+ if (!success) {
/* XXX This is probably working OK currently given the very limited scope of that flag.
* However, it is absolutely **not** handled correctly: it is freeing an ID pointer that has
* been added to the fd->libmap mapping, which in theory could lead to nice crashes...
@@ -10151,7 +10161,6 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
user->edit_studio_light = 0;
/* free fd->datamap again */
- oldnewmap_free_unused(fd->datamap);
oldnewmap_clear(fd->datamap);
return bhead;