Fix #27328: Undoing an operation while baking fluids freezes Blender
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 29 Nov 2011 15:26:46 +0000 (15:26 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 29 Nov 2011 15:26:46 +0000 (15:26 +0000)
Prevent Undo be run if there are any jobs are currently running.
This also makes sense with such jobs as multires baker, for example.

source/blender/editors/util/undo.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_jobs.c

index 527537b5efb00a93b7f6dde553d2cdcfb75a6ea9..f0055bd600851b9fe813b4df10594491cdc51bc0 100644 (file)
@@ -125,6 +125,12 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
        Object *obact= CTX_data_active_object(C);
        ScrArea *sa= CTX_wm_area(C);
 
+       /* undo during jobs are running can easily lead to freeing data using by jobs,
+           or they can just lead to freezing job in some other cases */
+       if(WM_jobs_has_running(CTX_wm_manager(C))) {
+               return OPERATOR_CANCELLED;
+       }
+
        /* grease pencil can be can be used in plenty of spaces, so check it first */
        if(ED_gpencil_session_active()) {
                return ED_undo_gpencil_step(C, step, undoname);
index fcdb6d25083036ccd638a0c8ec1bc09a094e7af1..1d8161086b049f47bc4b60191ad69f246531ce37 100644 (file)
@@ -316,6 +316,8 @@ void                WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob);
 void           WM_jobs_kill(struct wmWindowManager *wm, void *owner, void (*)(void *, short int *, short int *, float *));
 void           WM_jobs_stop_all(struct wmWindowManager *wm);
 
+int                    WM_jobs_has_running(struct wmWindowManager *wm);
+
                        /* clipboard */
 char           *WM_clipboard_text_get(int selection);
 void           WM_clipboard_text_set(char *buf, int selection);
index 16691ac5ab01d9e7e76126e64f8a0562900d7508..2d0d0f92a442da0b6f4aadf81432b413fb64d35a 100644 (file)
@@ -505,3 +505,13 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
        }
 }
 
+int WM_jobs_has_running(wmWindowManager *wm)
+{
+       wmJob *steve;
+
+       for(steve= wm->jobs.first; steve; steve= steve->next)
+               if(steve->running)
+                       return 1;
+
+       return 0;
+}