diff options
author | Matt Ebb <matt@mke3.net> | 2010-05-27 12:22:16 +0400 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2010-05-27 12:22:16 +0400 |
commit | 6e92ddf8b37dbfae733a9738a20777917610b4a0 (patch) | |
tree | 4f92654d234a24a85918f5ec37ad1a9e4d819e63 /source/blender/windowmanager/intern/wm_jobs.c | |
parent | ec70356424d687cb1cdb8cb80095a5593937e03a (diff) |
Progress indicators for threaded jobs
Now, rather than the bit-too-alarming stop sign, threaded wmJobs
display a progress indicator in the header. This is an optional feature
for each job type and still uses the same hardcoded ui template
(could use further work here...).
Currently implemented for:
Render - parts completed, then nodes comped
Compositor - nodes comped
Fluid Sim - frames simulated
Texture Bake - faces baked
Example: http://mke3.net/blender/devel/2.5/progress.mov
Diffstat (limited to 'source/blender/windowmanager/intern/wm_jobs.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_jobs.c | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 30c0c9a7aec..a92a3d746ad 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -26,6 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include <string.h> + #include "DNA_windowmanager_types.h" #include "MEM_guardedalloc.h" @@ -89,7 +91,7 @@ struct wmJob { /* to prevent cpu overhead, use this one which only gets called when job really starts, not in thread */ void (*initjob)(void *); /* this runs inside thread, and does full job */ - void (*startjob)(void *, short *stop, short *do_update); + void (*startjob)(void *, short *stop, short *do_update, float *progress); /* update gets called if thread defines so, and max once per timerstep */ /* it runs outside thread, blocking blender, no drawing! */ void (*update)(void *); @@ -109,6 +111,10 @@ struct wmJob { void *owner; int flag; short suspended, running, ready, do_update, stop; + float progress; + + /* for display in header, identification */ + char name[128]; /* once running, we store this separately */ void *run_customdata; @@ -119,18 +125,32 @@ struct wmJob { }; +/* finds: + * 1st priority: job with same owner and name + * 2nd priority: job with same owner + */ +static wmJob *wm_job_find(wmWindowManager *wm, void *owner, char *name) +{ + wmJob *steve, *found=NULL; + + for(steve= wm->jobs.first; steve; steve= steve->next) + if(steve->owner==owner) { + found= steve; + if (name && strcmp(steve->name, name)==0) + return steve; + } + + return found; +} + /* ******************* public API ***************** */ /* returns current or adds new job, but doesnt run it */ /* every owner only gets a single job, adding a new one will stop running stop and when stopped it starts the new one */ -wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, int flag) +wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, char *name, int flag) { - wmJob *steve; - - for(steve= wm->jobs.first; steve; steve= steve->next) - if(steve->owner==owner) - break; + wmJob *steve= wm_job_find(wm, owner, name); if(steve==NULL) { steve= MEM_callocN(sizeof(wmJob), "new job"); @@ -139,6 +159,7 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, int flag) steve->win= win; steve->owner= owner; steve->flag= flag; + BLI_strncpy(steve->name, name, sizeof(steve->name)); } return steve; @@ -156,6 +177,26 @@ int WM_jobs_test(wmWindowManager *wm, void *owner) return 0; } +float WM_jobs_progress(wmWindowManager *wm, void *owner) +{ + wmJob *steve= wm_job_find(wm, owner, NULL); + + if (steve && steve->flag & WM_JOB_PROGRESS) + return steve->progress; + + return 0.0; +} + +char *WM_jobs_name(wmWindowManager *wm, void *owner) +{ + wmJob *steve= wm_job_find(wm, owner, NULL); + + if (steve) + return steve->name; + + return NULL; +} + void WM_jobs_customdata(wmJob *steve, void *customdata, void (*free)(void *)) { /* pending job? just free */ @@ -179,7 +220,7 @@ void WM_jobs_timer(wmJob *steve, double timestep, unsigned int note, unsigned in } void WM_jobs_callbacks(wmJob *steve, - void (*startjob)(void *, short *, short *), + void (*startjob)(void *, short *, short *, float *), void (*initjob)(void *), void (*update)(void *), void (*endjob)(void *)) @@ -194,7 +235,7 @@ static void *do_job_thread(void *job_v) { wmJob *steve= job_v; - steve->startjob(steve->run_customdata, &steve->stop, &steve->do_update); + steve->startjob(steve->run_customdata, &steve->stop, &steve->do_update, &steve->progress); steve->ready= 1; return NULL; @@ -248,6 +289,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve) steve->stop= 0; steve->ready= 0; + steve->progress= 0.0; BLI_init_threads(&steve->threads, do_job_thread, 1); BLI_insert_thread(&steve->threads, steve); @@ -354,6 +396,9 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) steve->update(steve->run_customdata); if(steve->note) WM_event_add_notifier(C, steve->note, NULL); + + if (steve->flag & WM_JOB_PROGRESS) + WM_event_add_notifier(C, NC_WM|ND_JOB, NULL); steve->do_update= 0; } @@ -375,6 +420,8 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt) if(steve->endnote) WM_event_add_notifier(C, steve->endnote, NULL); + WM_event_add_notifier(C, NC_WM|ND_JOB, NULL); + /* new job added for steve? */ if(steve->customdata) { WM_jobs_start(wm, steve); |