diff options
author | Ton Roosendaal <ton@blender.org> | 2004-09-05 17:43:51 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2004-09-05 17:43:51 +0400 |
commit | bf83f6ddd87a76d30339057118f23c5651f9eff4 (patch) | |
tree | d28c5dbec49a60b2060dda9f17f48d08b404f806 /source/blender/blenloader | |
parent | 61e4707bdb6e9f64db0520c47f398d68e9322937 (diff) |
Second itteration of global undo system. Now based on:
- file-to-memory save
- incremental difference steps (compression)
everthing has been tightly coded to use minimum of memcpy or allocs. In
fact this system works with a single full buffer (=file) in memory, and undosteps as differences from it.
Speed gain is factor 4-8 faster. I've added it in CTRL+ALT+T timer menu for
a test. Please note the gain is especially in the undo-storing, not in
retrieving undo.
Also new: file read option to skip UI read (file menu). This now also is
default for the undo system.
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/BLO_readfile.h | 6 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_undofile.h | 58 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_writefile.h | 7 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readblenentry.c | 59 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 239 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.h | 42 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 136 |
7 files changed, 440 insertions, 107 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 3093160139b..2c216f122cc 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -43,6 +43,7 @@ struct Main; struct UserDef; struct bScreen; struct Scene; +struct MemFile; typedef struct BlendHandle BlendHandle; @@ -113,7 +114,7 @@ BlendFileData* BLO_read_from_file (char *file, BlendReadError *error_r); * code indicating the cause of the failure. * @return The data of the file. */ -BlendFileData* BLO_read_from_memory (void *mem, int memsize, BlendReadError *error_r); +BlendFileData* BLO_read_from_memory(void *mem, int memsize, BlendReadError *error_r); /** @@ -124,6 +125,9 @@ BlendFileData* BLO_read_from_memory (void *mem, int memsize, BlendReadError *err * @return A static human readable string representation * of @a error. */ + +BlendFileData *BLO_read_from_memfile(struct MemFile *memfile, BlendReadError *error_r); + char* BLO_bre_as_string( BlendReadError error); diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h new file mode 100644 index 00000000000..225b6bc15f5 --- /dev/null +++ b/source/blender/blenloader/BLO_undofile.h @@ -0,0 +1,58 @@ +/* + * $Id: + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * external writefile function prototypes + */ + +#ifndef BLO_UNDOFILE_H +#define BLO_UNDOFILE_H + +typedef struct { + void *next, *prev; + + char *buf; + unsigned int ident, size; + +} MemFileChunk; + +typedef struct MemFile { + ListBase chunks; + unsigned int size; +} MemFile; + +/* actually only used writefile.c */ +extern void add_memfilechunk(MemFile *compare, MemFile *current, char *buf, unsigned int size); + +/* exports */ +extern void BLO_free_memfile(MemFile *memfile); +extern void BLO_merge_memfile(MemFile *first, MemFile *second); + +#endif + diff --git a/source/blender/blenloader/BLO_writefile.h b/source/blender/blenloader/BLO_writefile.h index 1bbbf7ea4c9..cfa2fd7b0f6 100644 --- a/source/blender/blenloader/BLO_writefile.h +++ b/source/blender/blenloader/BLO_writefile.h @@ -34,8 +34,11 @@ #ifndef BLO_WRITEFILE_H #define BLO_WRITEFILE_H -int BLO_write_file(char *dir, int write_flags, char **error_r); -void BLO_write_runtime(char *file, char *exename); +struct MemFile; + +extern int BLO_write_file(char *dir, int write_flags, char **error_r); +extern int BLO_write_file_mem(struct MemFile *compare, struct MemFile *current, int write_flags, char **error_r); +extern void BLO_write_runtime(char *file, char *exename); #endif diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index a008142be66..fe39effdc01 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -61,6 +61,8 @@ #include "BKE_library.h" // for free_main #include "BLO_readfile.h" +#include "BLO_undofile.h" + #include "readfile.h" #include "BLO_readblenfile.h" @@ -113,7 +115,8 @@ static IDType idtypes[]= { }; static int nidtypes= sizeof(idtypes)/sizeof(idtypes[0]); -static IDType *idtype_from_name(char *str) { +static IDType *idtype_from_name(char *str) +{ int i= nidtypes; while (i--) @@ -122,7 +125,8 @@ static IDType *idtype_from_name(char *str) { return NULL; } -static IDType *idtype_from_code(int code) { +static IDType *idtype_from_code(int code) +{ int i= nidtypes; while (i--) @@ -132,7 +136,8 @@ static IDType *idtype_from_code(int code) { return NULL; } -static int bheadcode_is_idcode(int code) { +static int bheadcode_is_idcode(int code) +{ return idtype_from_code(code)?1:0; } @@ -141,13 +146,15 @@ static int idcode_is_linkable(int code) { return idt?(idt->flags&IDTYPE_FLAGS_ISLINKABLE):0; } -char *BLO_idcode_to_name(int code) { +char *BLO_idcode_to_name(int code) +{ IDType *idt= idtype_from_code(code); return idt?idt->name:NULL; } -int BLO_idcode_from_name(char *name) { +int BLO_idcode_from_name(char *name) +{ IDType *idt= idtype_from_name(name); return idt?idt->code:0; @@ -155,11 +162,13 @@ int BLO_idcode_from_name(char *name) { /* Access routines used by filesel. */ -BlendHandle *BLO_blendhandle_from_file(char *file) { +BlendHandle *BLO_blendhandle_from_file(char *file) +{ return (BlendHandle*) blo_openblenderfile(file); } -void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) { +void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) +{ FileData *fd= (FileData*) bh; BHead *bhead; @@ -188,7 +197,8 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) { fprintf(fp, "]\n"); } -LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype) { +LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype) +{ FileData *fd= (FileData*) bh; LinkNode *names= NULL; BHead *bhead; @@ -205,7 +215,8 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype) return names; } -LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh) { +LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh) +{ FileData *fd= (FileData*) bh; GHash *gathered= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); LinkNode *names= NULL; @@ -239,7 +250,8 @@ void BLO_blendhandle_close(BlendHandle *bh) { /**********/ -BlendFileData *BLO_read_from_file(char *file, BlendReadError *error_r) { +BlendFileData *BLO_read_from_file(char *file, BlendReadError *error_r) +{ BlendFileData *bfd = NULL; FileData *fd; @@ -256,7 +268,8 @@ BlendFileData *BLO_read_from_file(char *file, BlendReadError *error_r) { return bfd; } -BlendFileData *BLO_read_from_memory(void *mem, int memsize, BlendReadError *error_r) { +BlendFileData *BLO_read_from_memory(void *mem, int memsize, BlendReadError *error_r) +{ BlendFileData *bfd = NULL; FileData *fd; @@ -273,7 +286,26 @@ BlendFileData *BLO_read_from_memory(void *mem, int memsize, BlendReadError *erro return bfd; } -void BLO_blendfiledata_free(BlendFileData *bfd) { +BlendFileData *BLO_read_from_memfile(MemFile *memfile, BlendReadError *error_r) +{ + BlendFileData *bfd = NULL; + FileData *fd; + + fd = blo_openblendermemfile(memfile); + if (fd) { + bfd= blo_read_file_internal(fd, error_r); + if (bfd) { + bfd->type= BLENFILETYPE_BLEND; + strcpy(bfd->main->name, ""); + } + blo_freefiledata(fd); + } + + return bfd; +} + +void BLO_blendfiledata_free(BlendFileData *bfd) +{ if (bfd->main) { free_main(bfd->main); } @@ -285,7 +317,8 @@ void BLO_blendfiledata_free(BlendFileData *bfd) { MEM_freeN(bfd); } -char *BLO_bre_as_string(BlendReadError error) { +char *BLO_bre_as_string(BlendReadError error) +{ switch (error) { case BRE_NONE: return "No error"; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d72921f1c03..498b84abb2c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -121,6 +121,7 @@ #include "BIF_butspace.h" // for do_versions, patching event codes #include "BLO_readfile.h" +#include "BLO_undofile.h" #include "readfile.h" #include "genfile.h" @@ -767,6 +768,54 @@ static int fd_read_from_memory(FileData *filedata, void *buffer, int size) return (readsize); } +static int fd_read_from_memfile(FileData *filedata, void *buffer, int size) +{ + static unsigned int seek= 1<<30; /* the current position */ + static unsigned int offset= 0; /* size of previous chunks */ + static MemFileChunk *chunk=NULL; + + if(size==0) return 0; + + if(seek != filedata->seek) { + chunk= filedata->memfile->chunks.first; + seek= 0; + + while(chunk) { + if(seek + chunk->size > filedata->seek) break; + seek+= chunk->size; + chunk= chunk->next; + } + offset= seek; + seek= filedata->seek; + } + + if(chunk) { + /* first check if it's on the end if current chunk */ + if( seek-offset == chunk->size) { + offset+= chunk->size; + chunk= chunk->next; + } + + /* debug, should never happen */ + if(chunk==NULL) { + printf("illegal read, chunk zero\n"); + return 0; + } + else if( (seek-offset)+size > chunk->size) { + size= chunk->size - (seek-offset); + printf("chunk too large, clipped to %d\n", size); + } + + memcpy(buffer, chunk->buf + (seek-offset), size); + filedata->seek += size; + seek+= size; + + return (size); + + } + return 0; +} + static FileData *filedata_new(void) { extern char DNAstr[]; /* DNA.c */ @@ -850,6 +899,34 @@ FileData *blo_openblendermemory(void *mem, int memsize) } } +FileData *blo_openblendermemfile(MemFile *memfile) +{ + if (!memfile) { + return NULL; + } else { + FileData *fd= filedata_new(); + fd->memfile= memfile; + + fd->read= fd_read_from_memfile; + fd->flags|= FD_FLAGS_NOT_MY_BUFFER; + + decode_blender_header(fd); + + if (fd->flags & FD_FLAGS_FILE_OK) { + if (!read_file_dna(fd)) { + blo_freefiledata(fd); + fd= NULL; + } + } else { + blo_freefiledata(fd); + fd= NULL; + } + + return fd; + } +} + + void blo_freefiledata(FileData *fd) { if (fd) { @@ -2437,6 +2514,8 @@ static void direct_link_scene(FileData *fd, Scene *sce) /* ************ READ SCREEN ***************** */ +/* note: file read without screens option G_FILE_NO_UI; + check lib pointers in call below */ static void lib_link_screen(FileData *fd, Main *main) { bScreen *sc; @@ -2478,8 +2557,8 @@ static void lib_link_screen(FileData *fd, Main *main) } else if(sl->spacetype==SPACE_BUTS) { SpaceButs *sbuts= (SpaceButs *)sl; - sbuts->rect= 0; - sbuts->lockpoin= 0; + sbuts->rect= NULL; + sbuts->lockpoin= NULL; if(main->versionfile<132) set_rects_butspace(sbuts); } else if(sl->spacetype==SPACE_FILE) { @@ -2540,6 +2619,130 @@ static void lib_link_screen(FileData *fd, Main *main) } } +static void *restore_pointer_by_name(Main *mainp, ID *id) +{ + ListBase *lb; + ID *idn=NULL; + + if(id) { + lb= wich_libbase(mainp, GS(id->name)); + idn= lb->first; + while(idn) { + if( strcmp(idn->name, id->name)==0) { + if(idn->us==0) idn->us++; + break; + } + idn= idn->next; + } + } + return idn; +} + +/* called from kernel/blender.c */ +void lib_link_screen_restore(Main *newmain, char mode, Scene *curscene) +{ + bScreen *sc; + ScrArea *sa; + + sc= newmain->screen.first; + while(sc) { + + if(mode=='u') sc->scene= restore_pointer_by_name(newmain, (ID *)sc->scene); + if(sc->scene==NULL || mode=='n') sc->scene= curscene; + + sa= sc->areabase.first; + while(sa) { + SpaceLink *sl; + + for (sl= sa->spacedata.first; sl; sl= sl->next) { + if(sl->spacetype==SPACE_VIEW3D) { + View3D *v3d= (View3D*) sl; + + if(mode=='u') v3d->camera= restore_pointer_by_name(newmain, (ID *)v3d->camera); + if(v3d->camera==NULL || mode=='n') v3d->camera= sc->scene->camera; + + if(v3d->scenelock) v3d->lay= sc->scene->lay; + + if(v3d->bgpic) { + v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima); + v3d->bgpic->tex= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->tex); + if(v3d->bgpic->rect) freeN(v3d->bgpic->rect); + v3d->bgpic->rect= NULL; + } + if(v3d->localvd) { + if(mode=='u') v3d->localvd->camera= restore_pointer_by_name(newmain, (ID *)v3d->localvd->camera); + if(v3d->localvd->camera==NULL || mode=='n') v3d->localvd->camera= sc->scene->camera; + } + } + else if(sl->spacetype==SPACE_IPO) { + SpaceIpo *sipo= (SpaceIpo *)sl; + sipo->from= restore_pointer_by_name(newmain, (ID *)sipo->from); + // not free sipo->ipokey, creates dependency with src/ + sipo->ipo= restore_pointer_by_name(newmain, (ID *)sipo->ipo); + if(sipo->editipo) MEM_freeN(sipo->editipo); + sipo->editipo= NULL; + } + else if(sl->spacetype==SPACE_BUTS) { + SpaceButs *sbuts= (SpaceButs *)sl; + sbuts->lockpoin= NULL; + if(sbuts->rect) MEM_freeN(sbuts->rect); + sbuts->rect= NULL; + } + else if(sl->spacetype==SPACE_FILE) { + SpaceFile *sfile= (SpaceFile *)sl; + + } + else if(sl->spacetype==SPACE_IMASEL) { + check_imasel_copy((SpaceImaSel *)sl); + } + else if(sl->spacetype==SPACE_ACTION) { + SpaceAction *saction= (SpaceAction *)sl; + saction->action = restore_pointer_by_name(newmain, (ID *)saction->action); + } + else if(sl->spacetype==SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage *)sl; + + sima->image= restore_pointer_by_name(newmain, (ID *)sima->image); + } + else if(sl->spacetype==SPACE_NLA){ + /* SpaceNla *snla= (SpaceNla *)sl; */ + } + else if(sl->spacetype==SPACE_TEXT) { + SpaceText *st= (SpaceText *)sl; + + st->text= restore_pointer_by_name(newmain, (ID *)st->text); + } + else if(sl->spacetype==SPACE_SCRIPT) { + SpaceScript *sc= (SpaceScript *)sl; + + sc->script = NULL; + } + else if(sl->spacetype==SPACE_OOPS) { + SpaceOops *so= (SpaceOops *)sl; + Oops *oops; + + oops= so->oops.first; + while(oops) { + oops->id= restore_pointer_by_name(newmain, (ID *)oops->id); + oops= oops->next; + } + + so->lockpoin= NULL; + } + else if(sl->spacetype==SPACE_SOUND) { + SpaceSound *ssound= (SpaceSound *)sl; + + ssound->sound= restore_pointer_by_name(newmain, (ID *)ssound->sound); + } + } + sa= sa->next; + } + + sc= sc->id.next; + } + +} + static void direct_link_screen(FileData *fd, bScreen *sc) { ScrArea *sa; @@ -2881,12 +3084,17 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID static void link_global(FileData *fd, BlendFileData *bfd, FileGlobal *fg) { - // this is nonsense... will get rid of it once (ton) + // this is nonsense... make it struct once (ton) bfd->winpos= fg->winpos; bfd->fileflags= fg->fileflags; bfd->displaymode= fg->displaymode; bfd->globalf= fg->globalf; bfd->curscreen= newlibadr(fd, 0, fg->curscreen); + bfd->curscene= newlibadr(fd, 0, fg->curscene); + // this happens in files older than 2.35 + if(bfd->curscene==NULL) { + if(bfd->curscreen) bfd->curscene= bfd->curscreen->scene; + } } static void vcol_to_fcol(Mesh *me) @@ -4344,30 +4552,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) lib_link_all(fd, bfd->main); link_global(fd, bfd, fg); /* as last */ - if (!bfd->curscreen) - bfd->curscreen= bfd->main->screen.first; - - if (bfd->curscreen) { - bfd->curscene= bfd->curscreen->scene; - if (!bfd->curscene) { - bfd->curscene= bfd->main->scene.first; - bfd->curscreen->scene= bfd->curscene; - } - } + /* removed here: check for existance of curscreen/scene, moved to kernel setup_app */ MEM_freeN(fg); - /* require all files to have an active scene - * and screen. (implicitly: require all files - * to have at least one scene and one screen). - */ - if (!bfd->curscreen || !bfd->curscene) { - *error_r= (!bfd->curscreen)?BRE_NO_SCREEN:BRE_NO_SCENE; - - BLO_blendfiledata_free(bfd); - return NULL; - } - return bfd; } @@ -5202,7 +5390,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) /* reading runtime */ -BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r) { +BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r) +{ BlendFileData *bfd = NULL; FileData *fd = filedata_new(); fd->filedes = file; diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index a052b940c7c..e198752f130 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -34,6 +34,7 @@ #define READFILE_H struct OldNewMap; +struct MemFile; typedef struct FileData { // linked list of BHeadN's @@ -45,7 +46,9 @@ typedef struct FileData { int (*read)(struct FileData *filedata, void *buffer, int size); // variables needed for reading from memory / stream - char * buffer; + char *buffer; + // variables needed for reading from memfile (undo) + struct MemFile *memfile; // variables needed for reading from file int filedes; @@ -93,39 +96,18 @@ typedef struct BHeadN { void blo_join_main(ListBase *mainlist); void blo_split_main(ListBase *mainlist); - BlendFileData* -blo_read_file_internal( - FileData *fd, - BlendReadError *error_r); +BlendFileData *blo_read_file_internal( FileData *fd, BlendReadError *error_r); +FileData *blo_openblenderfile( char *name); +FileData *blo_openblendermemory( void *buffer, int buffersize); +FileData *blo_openblendermemfile(struct MemFile *memfile); - FileData* -blo_openblenderfile( - char *name); +void blo_freefiledata( FileData *fd); - FileData* -blo_openblendermemory( - void *buffer, - int buffersize); - void -blo_freefiledata( - FileData *fd); - - - BHead* -blo_firstbhead( - FileData *fd); - - BHead* -blo_nextbhead( - FileData *fd, - BHead *thisblock); - - BHead* -blo_prevbhead( - FileData *fd, - BHead *thisblock); +BHead *blo_firstbhead(FileData *fd); +BHead *blo_nextbhead(FileData *fd, BHead *thisblock); +BHead *blo_prevbhead(FileData *fd, BHead *thisblock); #endif diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ddab7f2b26d..6d84c120422 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -158,17 +158,22 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "BLO_writefile.h" #include "BLO_readfile.h" +#include "BLO_undofile.h" #include "readfile.h" #include "genfile.h" + +/* ********* my write, buffered writing with minimum 50k chunks ************ */ + typedef struct { struct SDNA *sdna; int file; unsigned char *buf; - - int tot, count, error; + MemFile *compare, *current; + + int tot, count, error, memsize; } WriteData; static WriteData *writedata_new(int file) @@ -193,8 +198,16 @@ static WriteData *writedata_new(int file) static void writedata_do_write(WriteData *wd, void *mem, int memlen) { if (wd->error) return; - if (write(wd->file, mem, memlen) != memlen) - wd->error= 1; + + /* memory based save */ + if(wd->current) { + add_memfilechunk(NULL, wd->current, mem, memlen); + } + else { + if (write(wd->file, mem, memlen) != memlen) + wd->error= 1; + + } } static void writedata_free(WriteData *wd) @@ -215,16 +228,23 @@ int mywfile; * @param len Length of new chunk of data * @warning Talks to other functions with global parameters */ - static void -mywrite( - WriteData *wd, - void *adr, - int len) + +#define MYWRITE_FLUSH NULL + +static void mywrite( WriteData *wd, void *adr, int len) { if (wd->error) return; - wd->tot+= len; + if(adr==MYWRITE_FLUSH) { + if(wd->count) { + writedata_do_write(wd, wd->buf, wd->count); + wd->count= 0; + } + return; + } + wd->tot+= len; + if(len>50000) { if(wd->count) { writedata_do_write(wd, wd->buf, wd->count); @@ -239,6 +259,7 @@ mywrite( } memcpy(&wd->buf[wd->count], adr, len); wd->count+= len; + } /** @@ -247,13 +268,15 @@ mywrite( * @param write_flags Write parameters * @warning Talks to other functions with global parameters */ - static WriteData * -bgnwrite( - int file, - int write_flags) +static WriteData *bgnwrite(int file, MemFile *compare, MemFile *current, int write_flags) { WriteData *wd= writedata_new(file); + wd->compare= compare; + wd->current= current; + /* this inits comparing */ + add_memfilechunk(compare, NULL, NULL, 0); + return wd; } @@ -263,9 +286,7 @@ bgnwrite( * @return unknown global variable otherwise * @warning Talks to other functions with global parameters */ - static int -endwrite( - WriteData *wd) +static int endwrite(WriteData *wd) { int err; @@ -273,10 +294,10 @@ endwrite( writedata_do_write(wd, wd->buf, wd->count); wd->count= 0; } - + err= wd->error; writedata_free(wd); - +if(wd->current) printf("undo size %d\n", wd->current->size); return err; } @@ -654,6 +675,9 @@ static void write_objects(WriteData *wd, ListBase *idbase) } ob= ob->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } @@ -709,6 +733,9 @@ static void write_ipos(WriteData *wd, ListBase *idbase) ipo= ipo->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_keys(WriteData *wd, ListBase *idbase) @@ -733,6 +760,8 @@ static void write_keys(WriteData *wd, ListBase *idbase) key= key->id.next; } + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_cameras(WriteData *wd, ListBase *idbase) @@ -816,6 +845,9 @@ static void write_curves(WriteData *wd, ListBase *idbase) } cu= cu->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist) @@ -880,6 +912,8 @@ static void write_images(WriteData *wd, ListBase *idbase) } ima= ima->id.next; } + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_textures(WriteData *wd, ListBase *idbase) @@ -899,6 +933,9 @@ static void write_textures(WriteData *wd, ListBase *idbase) } tex= tex->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_materials(WriteData *wd, ListBase *idbase) @@ -1088,6 +1125,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase) sce= sce->id.next; } + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_screens(WriteData *wd, ListBase *scrbase) @@ -1282,6 +1321,9 @@ static void write_armatures(WriteData *wd, ListBase *idbase) } arm=arm->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_actions(WriteData *wd, ListBase *idbase) @@ -1331,6 +1373,9 @@ static void write_texts(WriteData *wd, ListBase *idbase) } text= text->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_sounds(WriteData *wd, ListBase *idbase) @@ -1377,6 +1422,9 @@ static void write_sounds(WriteData *wd, ListBase *idbase) } sound= sound->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_groups(WriteData *wd, ListBase *idbase) @@ -1423,6 +1471,7 @@ static void write_global(WriteData *wd) FileGlobal fg; fg.curscreen= G.curscreen; + fg.curscene= G.scene; fg.displaymode= R.displaymode; fg.winpos= R.winpos; fg.fileflags= G.fileflags; @@ -1431,8 +1480,10 @@ static void write_global(WriteData *wd) writestruct(wd, GLOB, "FileGlobal", 1, &fg); } -static int write_file_handle(int handle, int write_user_block, int write_flags) +/* if *mem there's filesave to memory */ +static int write_file_handle(int handle, MemFile *compare, MemFile *current, int write_user_block, int write_flags) { + BHead bhead; ListBase mainlist; char buf[13]; WriteData *wd; @@ -1443,21 +1494,18 @@ static int write_file_handle(int handle, int write_user_block, int write_flags) blo_split_main(&mainlist); - wd= bgnwrite(handle, write_flags); - + wd= bgnwrite(handle, compare, current, write_flags); + sprintf(buf, "BLENDER%c%c%.3d", (sizeof(void*)==8)?'-':'_', (G.order==B_ENDIAN)?'V':'v', G.version); mywrite(wd, buf, 12); write_renderinfo(wd); - - write_screens (wd, &G.main->screen); + + if(current==NULL) + write_screens (wd, &G.main->screen); // no UI save write_scenes (wd, &G.main->scene); - write_objects (wd, &G.main->object); - write_meshs (wd, &G.main->mesh); write_curves (wd, &G.main->curve); write_mballs (wd, &G.main->mball); - write_materials(wd, &G.main->mat); - write_textures (wd, &G.main->tex); write_images (wd, &G.main->image); write_cameras (wd, &G.main->camera); write_lamps (wd, &G.main->lamp); @@ -1472,6 +1520,10 @@ static int write_file_handle(int handle, int write_user_block, int write_flags) write_groups (wd, &G.main->group); write_armatures(wd, &G.main->armature); write_actions (wd, &G.main->action); + write_objects (wd, &G.main->object); + write_materials(wd, &G.main->mat); + write_textures (wd, &G.main->tex); + write_meshs (wd, &G.main->mesh); write_libraries(wd, G.main->next); write_global(wd); @@ -1482,11 +1534,10 @@ static int write_file_handle(int handle, int write_user_block, int write_flags) /* dna as last, because (to be implemented) test for which structs are written */ writedata(wd, DNA1, wd->sdna->datalen, wd->sdna->data); - data= ENDB; - mywrite(wd, &data, 4); - - data= 0; - mywrite(wd, &data, 4); + /* end of file */ + memset(&bhead, 0, sizeof(BHead)); + bhead.code= ENDB; + mywrite(wd, &bhead, sizeof(BHead)); blo_join_main(&mainlist); G.main= mainlist.first; @@ -1494,6 +1545,7 @@ static int write_file_handle(int handle, int write_user_block, int write_flags) return endwrite(wd); } +/* return: success (1) */ int BLO_write_file(char *dir, int write_flags, char **error_r) { char userfilename[FILE_MAXDIR+FILE_MAXFILE]; @@ -1515,7 +1567,7 @@ int BLO_write_file(char *dir, int write_flags, char **error_r) write_user_block= BLI_streq(dir, userfilename); - fout= write_file_handle(file, write_user_block, write_flags); + fout= write_file_handle(file, NULL,NULL, write_user_block, write_flags); close(file); if(!fout) { @@ -1533,6 +1585,18 @@ int BLO_write_file(char *dir, int write_flags, char **error_r) return 1; } +/* return: success (1) */ +int BLO_write_file_mem(MemFile *compare, MemFile *current, int write_flags, char **error_r) +{ + int err; + + err= write_file_handle(0, compare, current, 0, write_flags); + + if(err==0) return 1; + return 0; +} + + /* Runtime writing */ #ifdef WIN32 @@ -1632,7 +1696,7 @@ void BLO_write_runtime(char *file, char *exename) { outfd= open(gamename, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0777); if (outfd != -1) { - write_file_handle(outfd, 0, G.fileflags); + write_file_handle(outfd, NULL,NULL, 0, G.fileflags); if (write(outfd, " ", 1) != 1) { cause= "Unable to write to output file"; @@ -1712,7 +1776,7 @@ void BLO_write_runtime(char *file, char *exename) { datastart= lseek(outfd, 0, SEEK_CUR); - write_file_handle(outfd, 0, G.fileflags); + write_file_handle(outfd, NULL,NULL, 0, G.fileflags); if (!handle_write_msb_int(outfd, datastart) || (write(outfd, "BRUNTIME", 8)!=8)) { cause= "Unable to write to output file"; |