Runtime cache preservation during undo: add support for nodes and embedded IDs.
This commit is contained in:
parent
bfc644dcfb
commit
ee3eba902a
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue