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:
authorTon Roosendaal <ton@blender.org>2004-09-05 17:43:51 +0400
committerTon Roosendaal <ton@blender.org>2004-09-05 17:43:51 +0400
commitbf83f6ddd87a76d30339057118f23c5651f9eff4 (patch)
treed28c5dbec49a60b2060dda9f17f48d08b404f806 /source/blender/blenloader
parent61e4707bdb6e9f64db0520c47f398d68e9322937 (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.h6
-rw-r--r--source/blender/blenloader/BLO_undofile.h58
-rw-r--r--source/blender/blenloader/BLO_writefile.h7
-rw-r--r--source/blender/blenloader/intern/readblenentry.c59
-rw-r--r--source/blender/blenloader/intern/readfile.c239
-rw-r--r--source/blender/blenloader/intern/readfile.h42
-rw-r--r--source/blender/blenloader/intern/writefile.c136
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";