Second itteration of global undo system. Now based on:
authorTon Roosendaal <ton@blender.org>
Sun, 5 Sep 2004 13:43:51 +0000 (13:43 +0000)
committerTon Roosendaal <ton@blender.org>
Sun, 5 Sep 2004 13:43:51 +0000 (13:43 +0000)
- 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.

18 files changed:
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/object.c
source/blender/blenloader/BLO_readfile.h
source/blender/blenloader/BLO_undofile.h [new file with mode: 0644]
source/blender/blenloader/BLO_writefile.h
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_fileglobal_types.h
source/blender/src/editscreen.c
source/blender/src/header_info.c
source/blender/src/interface.c
source/blender/src/oops.c
source/blender/src/toets.c
source/blender/src/usiblender.c

index 3b7c3ae2d9f5464f97bdcaade878e62cb7c4bd22..81805a63f73129b33fdd29a231fc14e8dd5055b2 100644 (file)
@@ -41,11 +41,13 @@ extern "C" {
 #endif
 
 struct ListBase;
+struct MemFile;
 
 #define BLENDER_VERSION                234
 
 int    BKE_read_file(char *dir, void *type_r);
 int BKE_read_file_from_memory(char* filebuf, int filelength, void *type_r);
+int BKE_read_file_from_memfile(struct MemFile *memfile);
 
 void duplicatelist(struct ListBase *list1, struct ListBase *list2);
 void free_blender(void);
index b9c4583484095bae09b9a7e0befb1235c6da37c1..205c417d79c0ad6b801be6e2665b5e60f0ecb0ae 100644 (file)
@@ -202,6 +202,8 @@ typedef struct Global {
 #define G_FILE_LOCK_BIT                 7
 #define G_FILE_SIGN_BIT                 8
 #define G_FILE_PUBLISH_BIT                             9
+#define G_FILE_NO_UI_BIT                               10
+
 
 #define G_AUTOPACK               (1 << G_AUTOPACK_BIT)
 #define G_FILE_COMPRESS          (1 << G_FILE_COMPRESS_BIT)
@@ -213,6 +215,7 @@ typedef struct Global {
 #define G_FILE_LOCK              (1 << G_FILE_LOCK_BIT)
 #define G_FILE_SIGN              (1 << G_FILE_SIGN_BIT)
 #define G_FILE_PUBLISH                  (1 << G_FILE_PUBLISH_BIT)
+#define G_FILE_NO_UI                    (1 << G_FILE_NO_UI_BIT)
 
 /* G.windowstate */
 #define G_WINDOWSTATE_USERDEF          0
index 02ad5f0c2fa71a5f58c29c55184a55384288093a..793a8f30c608829bf6fa883cdcb9cda795d82567 100644 (file)
@@ -81,6 +81,7 @@
 
 #include "BLI_editVert.h"
 
+#include "BLO_undofile.h"
 #include "BLO_readfile.h" /* for BLO_read_file */
 
 #include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
@@ -223,7 +224,8 @@ void initglobals(void)
 
 /***/
 
-static void clear_global(void) {
+static void clear_global(void) 
+{
        extern short winqueue_break;    /* screen.c */
 
        freeAllRad();
@@ -261,8 +263,36 @@ static void clear_global(void) {
        G.f &= ~(G_WEIGHTPAINT + G_VERTEXPAINT + G_FACESELECT);
 }
 
-static void setup_app_data(BlendFileData *bfd, char *filename) {
+static void setup_app_data(BlendFileData *bfd, char *filename) 
+{
        Object *ob;
+       bScreen *curscreen= NULL;
+       Scene *curscene= NULL;
+       char mode;
+       
+       /* 'u' = undo save, 'n' = no UI load */
+       if(bfd->main->screen.first==NULL) mode= 'u';
+       else if(G.fileflags & G_FILE_NO_UI) mode= 'n';
+       else mode= 0;
+       
+       /* no load screens? */
+       if(mode) {
+               /* comes from readfile.c */
+               extern void lib_link_screen_restore(Main *, char, Scene *);
+               
+               SWAP(ListBase, G.main->screen, bfd->main->screen);
+               
+               /* we re-use current screen */
+               curscreen= G.curscreen;
+               /* but use new Scene pointer */
+               curscene= bfd->curscene;
+               if(curscene==NULL) curscene= bfd->main->scene.first;
+               /* and we enforce curscene to be in current screen */
+               curscreen->scene= curscene;
+
+               /* clear_global will free G.main, here we can still restore pointers */
+               lib_link_screen_restore(bfd->main, mode, curscene);
+       }
        
        clear_global();
        
@@ -286,11 +316,19 @@ static void setup_app_data(BlendFileData *bfd, char *filename) {
                if(U.mixbufsize==0) U.mixbufsize= 2048;
        }
        
-       R.winpos= bfd->winpos;
-       R.displaymode= bfd->displaymode;
-       G.curscreen= bfd->curscreen;
-       G.fileflags= bfd->fileflags;
-
+       /* case G_FILE_NO_UI or no screens in file */
+       if(mode) {
+               G.curscreen= curscreen;
+               G.scene= curscene;
+       }
+       else {
+               R.winpos= bfd->winpos;
+               R.displaymode= bfd->displaymode;
+               G.fileflags= bfd->fileflags;
+               G.curscreen= bfd->curscreen;
+               G.scene= G.curscreen->scene;
+       }
+       
        /* special cases, override loaded flags: */
        if (G.f & G_DEBUG) bfd->globalf |= G_DEBUG;
        else bfd->globalf &= ~G_DEBUG;
@@ -298,7 +336,6 @@ static void setup_app_data(BlendFileData *bfd, char *filename) {
        else bfd->globalf &= ~G_SCENESCRIPT;
 
        G.f= bfd->globalf;
-       G.scene= G.curscreen->scene;
        
                /* few DispLists, but do text_to_curve */
        // this should be removed!!! But first a better displist system (ton)
@@ -330,7 +367,8 @@ static void setup_app_data(BlendFileData *bfd, char *filename) {
        MEM_freeN(bfd);
 }
 
-int BKE_read_file(char *dir, void *type_r) {
+int BKE_read_file(char *dir, void *type_r) 
+{
        BlendReadError bre;
        BlendFileData *bfd;
        
@@ -376,3 +414,25 @@ int BKE_read_file_from_memory(char* filebuf, int filelength, void *type_r)
        
        return (bfd?1:0);
 }
+
+int BKE_read_file_from_memfile(MemFile *memfile)
+{
+       BlendReadError bre;
+       BlendFileData *bfd;
+       
+       if (!G.background)
+               waitcursor(1);
+               
+       bfd= BLO_read_from_memfile(memfile, &bre);
+       if (bfd) {
+               setup_app_data(bfd, "<memory>");
+       } else {
+               error("Loading failed: %s", BLO_bre_as_string(bre));
+       }
+       
+       if (!G.background)
+               waitcursor(0);
+       
+       return (bfd?1:0);
+}
+
index 5b271daefdd24dc06c56ee9b7c313737b5c2cf66..bd7cb626182b8ea237162f8504be4fd8bc72af06 100644 (file)
@@ -59,6 +59,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
+#include "DNA_oops_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
@@ -323,6 +324,19 @@ void unlink_object(Object *ob)
                                                if(v3d->localvd->persp>1) v3d->localvd->persp= 1;
                                        }
                                }
+                               else if(sl->spacetype==SPACE_IPO) {
+                                       SpaceIpo *sipo= (SpaceIpo *)sl;
+                                       if(sipo->from == (ID *)ob) sipo->from= NULL;
+                               }
+                               else if(sl->spacetype==SPACE_OOPS) {
+                                       SpaceOops *so= (SpaceOops *)sl;
+                                       Oops *oops;
+                                       oops= so->oops.first;
+                                       while(oops) {
+                                               if(oops->id==(ID *)ob) oops->id= NULL;
+                                               oops= oops->next;
+                                       }
+                               }
                        }
 
                        sa= sa->next;
index 3093160139b82a9630eafcafc02d81c1d4509df9..2c216f122ccf0680d67f219b81817120816fa850 100644 (file)
@@ -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 (file)
index 0000000..225b6bc
--- /dev/null
@@ -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
+
index 1bbbf7ea4c9de2c69b5c998a5d7f6222825d98dd..cfa2fd7b0f62d7959e29cc93d1ac7d55b92151e0 100644 (file)
 #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
 
index a008142be66c760d0f682dd1c973ff000524857d..fe39effdc01101170ed2f47c1ea95cf1b2f1b163 100644 (file)
@@ -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";
index d72921f1c03915dc853cfdba1229ec1279ea314b..498b84abb2ceb35163cc115362d7d517258d682b 100644 (file)
 #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;
index a052b940c7c276922c7231a56cb20c69348a89eb..e198752f130f06ebf8ccb94b012d6d50659885ff 100644 (file)
@@ -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
 
index ddab7f2b26dfd1a177e8247149bca4e318d9d035..6d84c120422598eca90be59ad1a9cdc007df692b 100644 (file)
@@ -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";
index 40bf5e2a68fdc24986309259b34a86acce6b970a..b06f3f3e3721bba2b9808d1b746fe80166169229 100644 (file)
@@ -40,6 +40,7 @@
  */
 typedef struct FileGlobal {
        void *curscreen;
+       void *curscene;
        short displaymode, winpos;
        int fileflags;
        int globalf;
index b8f26bddbeff8f92f1922ffc7204c4c10a03bdc2..b9aed992686cc7bb62a15b89312e297dc9d183b2 100644 (file)
@@ -554,11 +554,14 @@ void markdirty_all()
        ScrArea *sa;
 
        for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
-               scrarea_queue_winredraw(sa);
-               sa->win_swap &= ~WIN_FRONT_OK;
-               
-               scrarea_queue_headredraw(sa);
-               sa->head_swap &= ~WIN_FRONT_OK;
+               if(sa->win) {
+                       scrarea_queue_winredraw(sa);
+                       sa->win_swap &= ~WIN_FRONT_OK;
+               }
+               if(sa->headwin) {
+                       scrarea_queue_headredraw(sa);
+                       sa->head_swap &= ~WIN_FRONT_OK;
+               }
        }
 }
 
@@ -1870,6 +1873,7 @@ void setscreen(bScreen *sc)
                        sa= sa->next;
                }               
        }
+       else if(G.curscreen) markdirty_all();   /* at least redraw */
 
        if (G.curscreen != sc) {
                mywinset(sc->mainwin);
@@ -1916,7 +1920,7 @@ void setscreen(bScreen *sc)
                
                sa->cursor= CURSOR_STD;
        }
-
+       
        G.scene= sc->scene;
        countall();
        
index 91dc0c29da625b759811712878bac1509f633381..6d22e5a0dae8b1ec7f21d5a8b64cbc324ca6cbc2 100644 (file)
@@ -883,12 +883,16 @@ static void do_info_filemenu(void *arg, int event)
        case 13:
                exit_usiblender();
                break;
+       case 14:
+               G.fileflags ^= G_FILE_NO_UI;
+               break;
        case 31: /* save default settings */
                BIF_write_homefile();
                break;
        }
        allqueue(REDRAWINFO, 0);
 }
+
 static uiBlock *info_filemenu(void *arg_unused)
 {
        uiBlock *block;
@@ -904,6 +908,14 @@ static uiBlock *info_filemenu(void *arg_unused)
 
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
+       if(G.fileflags & G_FILE_NO_UI) {
+               uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Load UI",         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
+       } else {
+               uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Load UI",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
+       }
+
+       uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save|Ctrl W",                            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save As...|F2",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
 
@@ -1290,7 +1302,7 @@ static uiBlock *info_gamemenu(void *arg_unused)
        if(G.fileflags & (1 << G_FILE_ENABLE_ALL_FRAMES_BIT)) {
                uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Enable All Frames",         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_ENABLE_ALL_FRAMES_BIT, "");
        } else {
-                                       uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Enable All Frames",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_ENABLE_ALL_FRAMES_BIT, "");
+               uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Enable All Frames",       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, G_FILE_ENABLE_ALL_FRAMES_BIT, "");
        }
 
        if(G.fileflags & (1 << G_FILE_SHOW_FRAMERATE_BIT)) {
index 29f8a8051533821ebcce21c459b7babc06555f3f..f7fa04982ccfd4ad74faf2445ed414be99819525 100644 (file)
@@ -3091,7 +3091,7 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                                        if(inside || uevent->event!=LEFTMOUSE) {
                                                butevent= ui_do_button(block, but, uevent);
                                                
-                                               if(but->type!=BLOCK) BIF_write_undo(but->str);
+                                               if(but->type!=BLOCK && but->type!=MENU) BIF_write_undo(but->str);
 
                                                if(butevent) addqueue(block->winq, UI_BUT_EVENT, (short)butevent);
 
index 25934fe98a4752539adc947744f1c3f0777a22cf..1646b6c8166a171b4445a5b205de850fa293720e 100644 (file)
@@ -105,6 +105,7 @@ Oops *find_oops(ID *id)
        return oops;
 }
 
+/* never even called! (ton) */
 int test_oops(Oops *oops)
 {
        /* test if own ID block still exists */
index e2ccb8a323903ba2eb623bc8e6d8d9bdfee53d69..81270c9f846eb346dd19b74ded04ec526c964f30 100644 (file)
@@ -888,7 +888,7 @@ int blenderqread(unsigned short event, short val)
                }
                else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
                        int a;
-                       int event= pupmenu("10 Timer%t|draw|draw+swap|displist");
+                       int event= pupmenu("10 Timer%t|draw|draw+swap|displist|undo");
                        if(event>0) {
                                double stime= PIL_check_seconds_timer();
                                char tmpstr[128];
@@ -907,6 +907,10 @@ int blenderqread(unsigned short event, short val)
                                                        makeDispList(OBACT);
                                                }
                                        }
+                                       else if(event==4) {
+                                               extern void BIF_write_undo(char *name);
+                                               BIF_write_undo("10 timer");
+                                       }
                                }
                        
                                time= (PIL_check_seconds_timer()-stime)*1000;
@@ -914,6 +918,7 @@ int blenderqread(unsigned short event, short val)
                                if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time);
                                if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time);
                                if(event==3) sprintf(tmpstr, "displist %%t|%d ms", time);
+                               if(event==4) sprintf(tmpstr, "undo %%t|%d ms", time);
                        
                                waitcursor(0);
                                pupmenu(tmpstr);
index b484d2d7d689dbe4fa55a76a54db68aae29f4c47..50e599b1427aa7d77999690653a8bdb0a29bb0c2 100644 (file)
 
 #include "PIL_time.h"
 
+// temporal, will go to include file
+void BIF_reset_undo(void);
+void BIF_write_undo(char *);   
+
+
 /***/
 
 void BIF_read_file(char *name)
 {
        extern short winqueue_break; /* editscreen.c */
-       void BIF_reset_undo(void);
-       void BIF_write_undo(char *);    
-
-       BIF_reset_undo();
 
        //here?
        //sound_end_all_sounds();
@@ -149,6 +150,7 @@ void BIF_read_file(char *name)
 
        winqueue_break= 1;      /* leave queues everywhere */
 
+       BIF_reset_undo();
        BIF_write_undo("original");     /* save current state */
 }
 
@@ -232,6 +234,8 @@ int BIF_read_homefile(void)
                space_set_commmandline_options();
 
                if (U.undosteps==0) U.undosteps=32;
+               BIF_reset_undo();
+               BIF_write_undo("original");     /* save current state */
 
                reset_autosave();
 
@@ -464,124 +468,6 @@ static void delete_autosave(void)
        }
 }
 
-/***/
-
-#define MAXUNDONAME    64
-typedef struct UndoElem {
-       struct UndoElem *next, *prev;
-       char str[FILE_MAXDIR+FILE_MAXFILE];
-       char name[MAXUNDONAME];
-} UndoElem;
-
-#define MAXUNDO         32
-static ListBase undobase={NULL, NULL};
-static UndoElem *curundo= NULL;
-
-static void get_undosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE], int num)
-{
-       char numstr[32];
-       
-       sprintf(numstr, "%d.blend", num);
-       BLI_make_file_string("/", buf, U.tempdir, numstr);
-
-}
-
-static int read_undosave(char *tstr)
-{
-       char scestr[FILE_MAXDIR+FILE_MAXFILE];
-       int success;
-       
-       strcpy(scestr, G.sce);  /* temporal store */
-       
-       success= BKE_read_file(tstr, NULL);
-       strcpy(G.sce, scestr);
-
-       return success;
-}
-
-/* name can be a dynamic string */
-void BIF_write_undo(char *name)
-{
-       static int counter= 0;
-       int nr;
-       char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
-       UndoElem *uel;
-       
-       if( (U.uiflag & USER_GLOBALUNDO==0)) return;
-       
-       /* calculate current filename */
-       counter++;
-       counter= counter % MAXUNDO;     
-       get_undosave_location(tstr, counter);
-       
-       if(BLO_write_file(tstr, G.fileflags, &err)) {
-
-               /* remove all undos after (also when curundo==NULL) */
-               while(undobase.last != curundo) {
-                       uel= undobase.last;
-                       BLI_remlink(&undobase, uel);
-                       MEM_freeN(uel);
-               }
-               
-               /* make new */
-               curundo= uel= MEM_mallocN(sizeof(UndoElem), "undo file");
-               strcpy(uel->str, tstr);
-               strncpy(uel->name, name, MAXUNDONAME-1);
-               BLI_addtail(&undobase, uel);
-               
-               /* and limit amount to the maximum */
-               nr= 0;
-               uel= undobase.last;
-               while(uel) {
-                       nr++;
-                       if(nr==MAXUNDO) break;
-                       uel= uel->prev;
-               }
-               if(uel) {
-                       while(undobase.first!=uel) {
-                               UndoElem *first= undobase.first;
-                               BLI_remlink(&undobase, first);
-                               MEM_freeN(first);
-                       }
-               }
-       }
-       
-}
-
-/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
-void BIF_undo_step(int step)
-{
-       
-       if(step==1) {
-               /* curundo should never be NULL, after restart or load file it should call undo_save */
-               if(curundo==NULL || curundo->prev==NULL) error("No undo available");
-               else {
-                       printf("undo %s\n", curundo->name);
-                       curundo= curundo->prev;
-                       read_undosave(curundo->str);
-               }
-       }
-       else {
-               
-               /* curundo has to remain current situation! */
-               
-               if(curundo==NULL || curundo->next==NULL) error("No redo available");
-               else {
-                       read_undosave(curundo->next->str);
-                       curundo= curundo->next;
-                       printf("redo %s\n", curundo->name);
-               }
-       }
-}
-
-void BIF_reset_undo(void)
-{
-       
-       BLI_freelistN(&undobase);
-       curundo= NULL;
-}
-
-
 /***/
 
 static void initbuttons(void)