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>2008-12-22 15:57:53 +0300
committerTon Roosendaal <ton@blender.org>2008-12-22 15:57:53 +0300
commit9e38e6aeb03e29d053679141134875edbff23d4a (patch)
tree2b52f73663939e9ce2ed166536d416132024f6d0 /source/blender/windowmanager
parent5e443fd45dcd753868e7578b08692c158e8ad657 (diff)
2.5
Better implementation of own window timers, not using ghost. That makes blender's WM nice in control, and gives callers of timers the opportunitie to evaluate time passed since previous step. This system also only generates one timer event per main loop (events - handlers - notifiers - draw) Small fix: allow keymap modifier to give KM_ANY to ignore modifier keys, this to have TIMER keymap work.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/WM_api.h7
-rw-r--r--source/blender/windowmanager/WM_types.h13
-rw-r--r--source/blender/windowmanager/intern/wm.c3
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c13
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c38
-rw-r--r--source/blender/windowmanager/intern/wm_window.c95
-rw-r--r--source/blender/windowmanager/wm_window.h2
7 files changed, 118 insertions, 53 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index cca9794f79e..6a91e3c538b 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -99,9 +99,10 @@ void WM_event_add_notifier(struct bContext *C, int type, int value, void *data)
void wm_event_add (wmWindow *win, struct wmEvent *event_to_add); /* XXX only for warning */
- /* one-shot timer, returns wmTimerData.handle */
-struct wmTimerHandle *WM_event_add_window_timer(wmWindow *win, int delay_ms, int interval_ms);
-void WM_event_remove_window_timer(wmWindow *wm, struct wmTimerHandle *handle);
+ /* at maximum, every timestep seconds it triggers TIMER events */
+struct wmTimer *WM_event_add_window_timer(wmWindow *win, double timestep);
+void WM_event_remove_window_timer(wmWindow *win, struct wmTimer *timer);
+void WM_event_window_timer_sleep(wmWindow *win, struct wmTimer *timer, int dosleep);
/* operator api, default callbacks */
/* confirm menu + exec */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index bccbcc178ba..8944429ecb2 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -163,8 +163,17 @@ typedef struct wmTabletData {
float Ytilt; /* as above */
} wmTabletData;
-struct wmTimerHandle;
-typedef struct wmTimerHandle wmTimerHandle;
+typedef struct wmTimer {
+ struct wmTimer *next, *prev;
+ double timestep; /* set by timer user */
+
+ double duration; /* total running time in seconds */
+ double delta; /* time since previous step in seconds */
+
+ double ltime; /* internal, last time timer was activated */
+ int sleep; /* internal, put timers to sleep when needed */
+} wmTimer;
+
/* ****************** Messages ********************* */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 5e89ad11de2..32d55fe6273 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -184,8 +184,7 @@ void WM_main(bContext *C)
while(1) {
/* get events from ghost, handle window events, add to window queues */
- /* WM_init has assigned to ghost the bContext already */
- wm_window_process_events(1);
+ wm_window_process_events(C);
/* per window, all events to the window, screen, area and region handlers */
wm_event_do_handlers(C);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index abd562a73cd..d1047ca4e63 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -441,11 +441,14 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
if(kmi->val!=KM_ANY)
if(winevent->val!=kmi->val) return 0;
-
- if(winevent->shift!=kmi->shift) return 0;
- if(winevent->ctrl!=kmi->ctrl) return 0;
- if(winevent->alt!=kmi->alt) return 0;
- if(winevent->oskey!=kmi->oskey) return 0;
+ if(kmi->shift!=KM_ANY)
+ if(winevent->shift!=kmi->shift) return 0;
+ if(kmi->ctrl!=KM_ANY)
+ if(winevent->ctrl!=kmi->ctrl) return 0;
+ if(kmi->alt!=KM_ANY)
+ if(winevent->alt!=kmi->alt) return 0;
+ if(kmi->oskey!=KM_ANY)
+ if(winevent->oskey!=kmi->oskey) return 0;
if(kmi->keymodifier)
if(winevent->keymodifier!=kmi->keymodifier) return 0;
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index a7ce67aeeba..dc53bff290d 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -57,22 +57,28 @@ static void keymap_event_set(wmKeymapItem *kmi, short type, short val, int modif
kmi->val= val;
kmi->keymodifier= keymodifier;
- if(modifier & KM_SHIFT)
- kmi->shift= 1;
- else if(modifier & KM_SHIFT2)
- kmi->shift= 2;
- if(modifier & KM_CTRL)
- kmi->ctrl= 1;
- else if(modifier & KM_CTRL2)
- kmi->ctrl= 2;
- if(modifier & KM_ALT)
- kmi->alt= 1;
- else if(modifier & KM_ALT2)
- kmi->alt= 2;
- if(modifier & KM_OSKEY)
- kmi->oskey= 1;
- else if(modifier & KM_OSKEY2)
- kmi->oskey= 2;
+ if(modifier == KM_ANY) {
+ kmi->shift= kmi->ctrl= kmi->alt= kmi->oskey= KM_ANY;
+ }
+ else {
+
+ if(modifier & KM_SHIFT)
+ kmi->shift= 1;
+ else if(modifier & KM_SHIFT2)
+ kmi->shift= 2;
+ if(modifier & KM_CTRL)
+ kmi->ctrl= 1;
+ else if(modifier & KM_CTRL2)
+ kmi->ctrl= 2;
+ if(modifier & KM_ALT)
+ kmi->alt= 1;
+ else if(modifier & KM_ALT2)
+ kmi->alt= 2;
+ if(modifier & KM_OSKEY)
+ kmi->oskey= 1;
+ else if(modifier & KM_OSKEY2)
+ kmi->oskey= 2;
+ }
}
static void keymap_properties_set(wmKeymapItem *kmi)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 7fba9a6115a..5773fd847c7 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -55,6 +55,8 @@
#include "ED_screen.h"
+#include "PIL_time.h"
+
#include "GPU_draw.h"
/* the global to talk to ghost */
@@ -102,7 +104,8 @@ void wm_window_free(bContext *C, wmWindow *win)
}
if(win->eventstate) MEM_freeN(win->eventstate);
-
+ BLI_freelistN(&win->timers);
+
wm_event_free_all(win);
wm_subwindows_free(win);
@@ -496,23 +499,49 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
return 1;
}
-void wm_window_process_events(int wait_for_event)
+
+/* This timer system only gives maximum 1 timer event per redraw cycle,
+ to prevent queues to get overloaded.
+ Timer handlers should check for delta to decide if they just
+ update, or follow real time
+*/
+static int wm_window_timer(const bContext *C)
{
- int handled= 0;
+ wmWindowManager *wm= CTX_wm_manager(C);
+ wmWindow *win;
+ double time= PIL_check_seconds_timer();
+ int retval= 0;
- /* ghost only processes 1 (timer?) event a time... we want to accumulate all */
- while(1) {
- if(GHOST_ProcessEvents(g_system, 0)) {
- GHOST_DispatchEvents(g_system);
- handled= 1;
+ for(win= wm->windows.first; win; win= win->next) {
+ wmTimer *wt;
+ for(wt= win->timers.first; wt; wt= wt->next) {
+ if(wt->sleep==0) {
+ if(wt->timestep < time - wt->ltime) {
+ wt->delta= time - wt->ltime;
+ wt->duration += wt->delta;
+ wt->ltime= time;
+
+ wm_event_add_ghostevent(win, GHOST_kEventTimer, wt);
+ retval= 1;
+ }
+ }
}
- else
- break;
}
- if(handled==0 && wait_for_event) {
- GHOST_ProcessEvents(g_system, wait_for_event);
+ return retval;
+}
+
+void wm_window_process_events(const bContext *C)
+{
+ int hasevent= GHOST_ProcessEvents(g_system, 0); /* 0 is no wait */
+
+ if(hasevent)
GHOST_DispatchEvents(g_system);
- }
+
+ hasevent |= wm_window_timer(C);
+
+ /* no event, we sleep 5 milliseconds */
+ if(hasevent==0)
+ PIL_sleep_ms(5);
}
/* **************** init ********************** */
@@ -529,24 +558,42 @@ void wm_ghost_init(bContext *C)
/* **************** timer ********************** */
-static void window_event_timer_proc(GHOST_TimerTaskHandle timer, GHOST_TUns64 time)
+/* to (de)activate running timers temporary */
+void WM_event_window_timer_sleep(wmWindow *win, wmTimer *timer, int dosleep)
{
- wmWindow *window;
-
- window= GHOST_GetTimerTaskUserData(timer);
-
- wm_event_add_ghostevent(window, GHOST_kEventTimer, (wmTimerHandle*)timer);
+ wmTimer *wt;
+
+ for(wt= win->timers.first; wt; wt= wt->next)
+ if(wt==timer)
+ break;
+ if(wt) {
+ wt->sleep= dosleep;
+ }
}
-wmTimerHandle *WM_event_add_window_timer(wmWindow *win, int delay_ms, int interval_ms)
+wmTimer *WM_event_add_window_timer(wmWindow *win, double timestep)
{
- return (wmTimerHandle*)GHOST_InstallTimer(g_system, delay_ms, interval_ms,
- window_event_timer_proc, win);
+ wmTimer *wt= MEM_callocN(sizeof(wmTimer), "window timer");
+
+ wt->ltime= PIL_check_seconds_timer();
+ wt->timestep= timestep;
+
+ BLI_addtail(&win->timers, wt);
+
+ return wt;
}
-void WM_event_remove_window_timer(wmWindow *wm, wmTimerHandle *handle)
+void WM_event_remove_window_timer(wmWindow *win, wmTimer *timer)
{
- GHOST_RemoveTimer(g_system, (GHOST_TimerTaskHandle)handle);
+ wmTimer *wt;
+
+ for(wt= win->timers.first; wt; wt= wt->next)
+ if(wt==timer)
+ break;
+ if(wt) {
+ BLI_remlink(&win->timers, wt);
+ MEM_freeN(wt);
+ }
}
/* ************************************ */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index b02a16304cb..03f2060e706 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -37,7 +37,7 @@ void wm_ghost_init (bContext *C);
wmWindow *wm_window_new (bContext *C);
void wm_window_free (bContext *C, wmWindow *win);
void wm_window_add_ghostwindows (wmWindowManager *wm);
-void wm_window_process_events (int wait_for_event);
+void wm_window_process_events (const bContext *C);
void wm_window_make_drawable(bContext *C, wmWindow *win);