diff options
author | Bastien Montagne <bastien@blender.org> | 2020-07-06 17:21:41 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-07-06 17:55:38 +0300 |
commit | ee3eba902a0b5d5f44b1cb2ff52a3a42cc9e9670 (patch) | |
tree | 8e6e50a808e6e29a6bb3f44b953912764e1452e6 /source | |
parent | bfc644dcfb52b873ad7c356cf4b05208fba17bba (diff) |
Runtime cache preservation during undo: add support for nodes and embedded IDs.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_idtype.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/idtype.c | 33 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 28 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readblenentry.c | 12 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 29 |
5 files changed, 74 insertions, 36 deletions
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h index 6cbb7571f41..0377d8ae741 100644 --- a/source/blender/blenkernel/BKE_idtype.h +++ b/source/blender/blenkernel/BKE_idtype.h @@ -235,6 +235,14 @@ short BKE_idtype_idcode_from_index(const int index); short BKE_idtype_idcode_iter_step(int *index); +/* Some helpers/wrappers around callbacks defined in IDTypeInfo, dealing e.g. with embedded IDs... + * XXX Ideally those would rather belong to BKE_lib_id, but using callback fonction pointers makes + * this hard to do properly if we want to avoid headers includes in headers... */ + +void BKE_idtype_id_foreach_cache(struct ID *id, + IDTypeForeachCacheFunctionCallback function_callback, + void *user_data); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c index 2684e964eb1..1166ad9ad2f 100644 --- a/source/blender/blenkernel/intern/idtype.c +++ b/source/blender/blenkernel/intern/idtype.c @@ -36,8 +36,11 @@ #include "BLT_translation.h" #include "DNA_ID.h" +#include "DNA_node_types.h" +#include "DNA_scene_types.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_idtype.h" @@ -470,3 +473,33 @@ short BKE_idtype_idcode_iter_step(int *index) { return (*index < ARRAY_SIZE(id_types)) ? BKE_idtype_idcode_from_index((*index)++) : 0; } + +/** Wrapper around IDTypeInfo foreach_cache that also handles embedded IDs. */ +void BKE_idtype_id_foreach_cache(struct ID *id, + IDTypeForeachCacheFunctionCallback function_callback, + void *user_data) +{ + const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id); + if (type_info->foreach_cache != NULL) { + type_info->foreach_cache(id, function_callback, user_data); + } + + /* Handle 'private IDs'. */ + bNodeTree *nodetree = ntreeFromID(id); + if (nodetree != NULL) { + type_info = BKE_idtype_get_info_from_id(&nodetree->id); + if (type_info->foreach_cache != NULL) { + type_info->foreach_cache(&nodetree->id, function_callback, user_data); + } + } + + if (GS(id->name) == ID_SCE) { + Scene *scene = (Scene *)id; + if (scene->master_collection != NULL) { + type_info = BKE_idtype_get_info_from_id(&scene->master_collection->id); + if (type_info->foreach_cache != NULL) { + type_info->foreach_cache(&scene->master_collection->id, function_callback, user_data); + } + } + } +} diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index b73f957535c..52f0d259058 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -315,6 +315,33 @@ static void node_foreach_id(ID *id, LibraryForeachIDData *data) } } +static void node_foreach_cache(ID *id, + IDTypeForeachCacheFunctionCallback function_callback, + void *user_data) +{ + bNodeTree *nodetree = (bNodeTree *)id; + IDCacheKey key = { + .id_session_uuid = id->session_uuid, + .offset_in_ID = offsetof(bNodeTree, previews), + .cache_v = nodetree->previews, + }; + + /* TODO, see also `direct_link_nodetree()` in readfile.c. */ +#if 0 + function_callback(id, &key, (void **)&nodetree->previews, 0, user_data); +#endif + + if (nodetree->type == NTREE_COMPOSIT) { + for (bNode *node = nodetree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_MOVIEDISTORTION) { + key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(node->name); + key.cache_v = node->storage; + function_callback(id, &key, (void **)&node->storage, 0, user_data); + } + } + } +} + IDTypeInfo IDType_ID_NT = { .id_code = ID_NT, .id_filter = FILTER_ID_NT, @@ -330,6 +357,7 @@ IDTypeInfo IDType_ID_NT = { .free_data = ntree_free_data, .make_local = NULL, .foreach_id = node_foreach_id, + .foreach_cache = node_foreach_cache, }; static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype) diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index e4129282a68..cb2094d050f 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -390,12 +390,6 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, blo_make_old_idmap_from_main(fd, old_mainlist.first); } - /* TODO: Move handling of nodetree caches to new system as well... */ - /* makes lookup of existing images in old main */ - blo_make_image_pointer_map(fd, oldmain); - /* makes lookup of existing video clips in old main */ - blo_make_movieclip_pointer_map(fd, oldmain); - /* removed packed data from this trick - it's internal data that needs saves */ /* Store all existing ID caches pointers into a mapping, to allow restoring them into newly @@ -407,12 +401,6 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, /* Ensure relinked caches are not freed together with their old IDs. */ blo_cache_storage_old_bmain_clear(fd, oldmain); - /* TODO: Move handling of nodetree caches to new system as well... */ - /* ensures relinked images are not freed */ - blo_end_image_pointer_map(fd, oldmain); - /* ensures relinked movie clips are not freed */ - blo_end_movieclip_pointer_map(fd, oldmain); - /* Still in-use libraries have already been moved from oldmain to new mainlist, * but oldmain itself shall *never* be 'transferred' to new mainlist! */ BLI_assert(old_mainlist.first == oldmain); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 441421c8736..b8ded36b4eb 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2349,7 +2349,7 @@ void blo_cache_storage_init(FileData *fd, Main *bmain) if (ID_IS_LINKED(id)) { continue; } - type_info->foreach_cache(id, blo_cache_storage_entry_register, fd->cache_storage); + BKE_idtype_id_foreach_cache(id, blo_cache_storage_entry_register, fd->cache_storage); } FOREACH_MAIN_LISTBASE_ID_END; } @@ -2379,7 +2379,7 @@ void blo_cache_storage_old_bmain_clear(FileData *fd, Main *bmain_old) if (ID_IS_LINKED(id)) { continue; } - type_info->foreach_cache(id, blo_cache_storage_entry_clear_in_old, fd->cache_storage); + BKE_idtype_id_foreach_cache(id, blo_cache_storage_entry_clear_in_old, fd->cache_storage); } FOREACH_MAIN_LISTBASE_ID_END; } @@ -3851,28 +3851,8 @@ static void direct_link_nodetree(BlendDataReader *reader, bNodeTree *ntree) BLO_read_data_address(reader, &link->tosock); } -#if 0 - if (ntree->previews) { - bNodeInstanceHash* new_previews = BKE_node_instance_hash_new("node previews"); - bNodeInstanceHashIterator iter; - - NODE_INSTANCE_HASH_ITER(iter, ntree->previews) { - bNodePreview* preview = BKE_node_instance_hash_iterator_get_value(&iter); - if (preview) { - bNodePreview* new_preview = newimaadr(fd, preview); - if (new_preview) { - bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter); - BKE_node_instance_hash_insert(new_previews, key, new_preview); - } - } - } - BKE_node_instance_hash_free(ntree->previews, NULL); - ntree->previews = new_previews; - } -#else - /* XXX TODO */ + /* TODO, should be dealt by new generic cache handling of IDs... */ ntree->previews = NULL; -#endif /* type verification is in lib-link */ } @@ -9242,7 +9222,8 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID * /* try to restore (when undoing) or clear ID's cache pointers. */ if (id_type->foreach_cache != NULL) { - id_type->foreach_cache(id, blo_cache_storage_entry_restore_in_new, reader.fd->cache_storage); + BKE_idtype_id_foreach_cache( + id, blo_cache_storage_entry_restore_in_new, reader.fd->cache_storage); } return success; |