diff options
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 14 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_genfile.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_sdna_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesdna/intern/dna_genfile.c | 20 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_define.c | 2 |
6 files changed, 36 insertions, 11 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b09ea45469c..0dd099df79b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -918,7 +918,7 @@ static int read_file_dna(FileData *fd) if (bhead->code == DNA1) { const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0; - fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap); + fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap, true); if (fd->filesdna) { fd->compflags = DNA_struct_get_compareflags(fd->filesdna, fd->memsdna); /* used to retrieve ID names from (bhead+1) */ @@ -1078,7 +1078,7 @@ static FileData *filedata_new(void) * but it keeps us re-entrant, remove once we have * a lib that provides a nice lock. - zr */ - fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false); + fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false); fd->datamap = oldnewmap_new(); fd->globmap = oldnewmap_new(); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index bbbe04dd24e..77df7ae0431 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -325,7 +325,7 @@ static WriteData *writedata_new(WriteWrap *ww) { WriteData *wd = MEM_callocN(sizeof(*wd), "writedata"); - wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false); + wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false); wd->ww = ww; @@ -4013,6 +4013,10 @@ static bool write_file_handle( write_thumb(wd, thumb); write_global(wd, write_flags, mainvar); + /* The windowmanager and screen often change, + * avoid thumbnail detecting changes because of this. */ + mywrite(wd, MYWRITE_FLUSH, 0); + write_windowmanagers(wd, &mainvar->wm); write_screens(wd, &mainvar->screen); write_movieclips(wd, &mainvar->movieclip); @@ -4046,11 +4050,17 @@ static bool write_file_handle( write_linestyles(wd, &mainvar->linestyle); write_libraries(wd, mainvar->next); + /* So changes above don't cause a 'DNA1' to be detected as changed on undo. */ + mywrite(wd, MYWRITE_FLUSH, 0); + if (write_flags & G_FILE_USERPREFS) { write_userdef(wd); } - /* dna as last, because (to be implemented) test for which structs are written */ + /* Write DNA last, because (to be implemented) test for which structs are written. + * + * Note that we *borrow* the pointer to 'DNAstr', + * so writing each time uses the same address and doesn't cause unnecessary undo overhead. */ writedata(wd, DNA1, wd->sdna->datalen, wd->sdna->data); #ifdef USE_NODE_COMPAT_CUSTOMNODES diff --git a/source/blender/makesdna/DNA_genfile.h b/source/blender/makesdna/DNA_genfile.h index d62369803d6..77877f7bada 100644 --- a/source/blender/makesdna/DNA_genfile.h +++ b/source/blender/makesdna/DNA_genfile.h @@ -74,7 +74,9 @@ enum eSDNA_StructCompare { SDNA_CMP_NOT_EQUAL = 2, }; -struct SDNA *DNA_sdna_from_data(const void *data, const int datalen, bool do_endian_swap); +struct SDNA *DNA_sdna_from_data( + const void *data, const int datalen, + bool do_endian_swap, bool data_alloc); void DNA_sdna_free(struct SDNA *sdna); int DNA_struct_find_nr(struct SDNA *sdna, const char *str); diff --git a/source/blender/makesdna/DNA_sdna_types.h b/source/blender/makesdna/DNA_sdna_types.h index cb7a371c7c5..791aca77558 100644 --- a/source/blender/makesdna/DNA_sdna_types.h +++ b/source/blender/makesdna/DNA_sdna_types.h @@ -35,8 +35,9 @@ # # typedef struct SDNA { - char *data; /* full copy of 'encoded' data */ + const char *data; /* full copy of 'encoded' data */ int datalen; /* length of data */ + bool data_alloc; int nr_names; /* total number of struct members */ const char **names; /* struct member names */ diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index 99ab29fbdcc..9135d7bab7d 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -196,7 +196,10 @@ int DNA_elem_array_size(const char *str) void DNA_sdna_free(SDNA *sdna) { - MEM_freeN(sdna->data); + if (sdna->data_alloc) { + MEM_freeN((void *)sdna->data); + } + MEM_freeN((void *)sdna->names); MEM_freeN(sdna->types); MEM_freeN(sdna->structs); @@ -549,15 +552,24 @@ static void init_structDNA(SDNA *sdna, bool do_endian_swap) /** * Constructs and returns a decoded SDNA structure from the given encoded SDNA data block. */ -SDNA *DNA_sdna_from_data(const void *data, const int datalen, bool do_endian_swap) +SDNA *DNA_sdna_from_data( + const void *data, const int datalen, + bool do_endian_swap, bool data_alloc) { SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna"); sdna->lastfind = 0; sdna->datalen = datalen; - sdna->data = MEM_mallocN(datalen, "sdna_data"); - memcpy(sdna->data, data, datalen); + if (data_alloc) { + char *data_copy = MEM_mallocN(datalen, "sdna_data"); + memcpy(data_copy, data, datalen); + sdna->data = data_copy; + } + else { + sdna->data = data; + } + sdna->data_alloc = data_alloc; init_structDNA(sdna, do_endian_swap); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 36e2b9b0572..bf2b091576e 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -532,7 +532,7 @@ BlenderRNA *RNA_create(void) brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA"); - DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false); + DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false); BLI_listbase_clear(&DefRNA.structs); DefRNA.error = 0; DefRNA.preprocess = 1; |