forked from bartvdbraak/blender
=BMesh: (personal) Testing Framework=
I've got my testing framework done now. It's based on recording events at the GHOST level. This has issues; a test created on one computer might not pass on another, due to floating point inaccuracies (though I tried to blunt this a bit). This isn't appropriate for general use. I wrote it for personal use, and other devs might find it useful for their personal use as well. However, it lacks the reliability you'd need for a real unit testing framework. This isn't meant to replace lief's work, by any means, which is a real unit testing framework.
This commit is contained in:
parent
bc428e330b
commit
53920b1b83
@ -35,6 +35,7 @@
|
||||
#define GHOST_C_API_H
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -837,6 +838,12 @@ extern GHOST_TUns8* GHOST_getClipboard(int selection);
|
||||
extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection);
|
||||
|
||||
|
||||
extern GHOST_TSuccess GHOST_RecordEvents(GHOST_SystemHandle systemhandle, FILE *file);
|
||||
extern GHOST_TSuccess GHOST_StopRecording(GHOST_SystemHandle systemhandle);
|
||||
extern GHOST_TSuccess GHOST_PlaybackEvents(GHOST_SystemHandle systemhandle, FILE *file);
|
||||
extern int GHOST_PlayingEvents(GHOST_SystemHandle systemhandle);
|
||||
extern int GHOST_RecordingEvents(GHOST_SystemHandle systemhandle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -34,8 +34,8 @@
|
||||
#define _GHOST_IEVENT_H_
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
|
||||
class GHOST_IWindow;
|
||||
#include "GHOST_IWindow.h"
|
||||
#include "intern/GHOST_ModifierKeys.h"
|
||||
|
||||
/**
|
||||
* Interface class for events received from GHOST.
|
||||
@ -71,6 +71,13 @@ public:
|
||||
*/
|
||||
virtual GHOST_TUns64 getTime() = 0;
|
||||
|
||||
virtual void setTime(GHOST_TUns64 t) = 0;
|
||||
|
||||
virtual void setPlaybackModifierKeys(GHOST_ModifierKeys keys) = 0;
|
||||
virtual void getPlaybackModifierKeys(GHOST_ModifierKeys &keys) = 0;
|
||||
virtual void setPlaybackCursor(GHOST_TInt32 x, GHOST_TInt32 y) = 0;
|
||||
virtual void getPlaybackCursor(GHOST_TInt32 &x, GHOST_TInt32 &y) = 0;
|
||||
|
||||
/**
|
||||
* Returns the window this event was generated on,
|
||||
* or NULL if it is a 'system' event.
|
||||
@ -83,6 +90,17 @@ public:
|
||||
* @return The event data.
|
||||
*/
|
||||
virtual GHOST_TEventDataPtr getData() = 0;
|
||||
|
||||
virtual int serialize(char buf[256])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int writeheader(char buf[256])
|
||||
{
|
||||
sprintf(buf, "%lf %d %d", ((double)this->getTime())*0.001, this->getType(), this->getWindow()->getID());
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _GHOST_IEVENT_H_
|
||||
|
@ -275,6 +275,13 @@ public:
|
||||
/***************************************************************************************
|
||||
** Event management functionality
|
||||
***************************************************************************************/
|
||||
|
||||
virtual GHOST_TSuccess beginRecord(FILE *file) = 0;
|
||||
virtual GHOST_TSuccess endRecord() = 0;
|
||||
virtual GHOST_TSuccess playbackEvents(FILE *file) = 0;
|
||||
|
||||
virtual bool playingEvents(bool *hasevent) const = 0;
|
||||
virtual bool recordingEvents() = 0;
|
||||
|
||||
/**
|
||||
* Retrieves events from the system and stores them in the queue.
|
||||
|
@ -65,6 +65,17 @@ public:
|
||||
virtual ~GHOST_IWindow()
|
||||
{
|
||||
}
|
||||
|
||||
GHOST_IWindow()
|
||||
{
|
||||
static int id = 0;
|
||||
m_id = id++;
|
||||
}
|
||||
|
||||
virtual int getID()
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns indication as to whether the window is valid.
|
||||
@ -305,6 +316,8 @@ public:
|
||||
*/
|
||||
virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; };
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
};
|
||||
|
||||
#endif // _GHOST_IWINDOW_H_
|
||||
|
@ -95,6 +95,39 @@ GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle,
|
||||
return (GHOST_TimerTaskHandle) system->installTimer(delay, interval, timerproc, userdata);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_RecordEvents(GHOST_SystemHandle systemhandle, FILE *file)
|
||||
{
|
||||
GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
|
||||
|
||||
return system->beginRecord(file);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_StopRecording(GHOST_SystemHandle systemhandle)
|
||||
{
|
||||
GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
|
||||
|
||||
return system->endRecord();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_PlaybackEvents(GHOST_SystemHandle systemhandle, FILE *file)
|
||||
{
|
||||
GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
|
||||
|
||||
return system->playbackEvents(file);
|
||||
}
|
||||
|
||||
int GHOST_PlayingEvents(GHOST_SystemHandle systemhandle)
|
||||
{
|
||||
GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
|
||||
return system->playingEvents(NULL);
|
||||
}
|
||||
|
||||
int GHOST_RecordingEvents(GHOST_SystemHandle systemhandle)
|
||||
{
|
||||
GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
|
||||
|
||||
return system->recordingEvents();
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
|
||||
|
@ -35,6 +35,14 @@
|
||||
|
||||
#include "GHOST_IEvent.h"
|
||||
|
||||
/* INTEGER CODES */
|
||||
#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__hppa__) || defined (__BIG_ENDIAN__)
|
||||
/* Big Endian */
|
||||
#define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
|
||||
#else
|
||||
/* Little Endian */
|
||||
#define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Base class for events received the operating system.
|
||||
@ -73,6 +81,12 @@ public:
|
||||
return m_time;
|
||||
}
|
||||
|
||||
virtual void setTime(GHOST_TUns64 t)
|
||||
{
|
||||
m_time = t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the window this event was generated on,
|
||||
* or NULL if it is a 'system' event.
|
||||
@ -91,7 +105,29 @@ public:
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
virtual void setPlaybackModifierKeys(GHOST_ModifierKeys keys)
|
||||
{
|
||||
m_playmods = keys;
|
||||
}
|
||||
|
||||
virtual void getPlaybackModifierKeys(GHOST_ModifierKeys &keys)
|
||||
{
|
||||
keys = m_playmods;
|
||||
}
|
||||
|
||||
virtual void setPlaybackCursor(GHOST_TInt32 mx, GHOST_TInt32 my)
|
||||
{
|
||||
x = mx;
|
||||
y = my;
|
||||
}
|
||||
|
||||
virtual void getPlaybackCursor(GHOST_TInt32 &mx, GHOST_TInt32 &my)
|
||||
{
|
||||
mx = x;
|
||||
my = y;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Type of this event. */
|
||||
GHOST_TEventType m_type;
|
||||
@ -101,6 +137,11 @@ protected:
|
||||
GHOST_IWindow* m_window;
|
||||
/** Pointer to the event data. */
|
||||
GHOST_TEventDataPtr m_data;
|
||||
|
||||
/** Modifier key state during event playback **/
|
||||
GHOST_ModifierKeys m_playmods;
|
||||
/** Mouse cursor state during event playback **/
|
||||
GHOST_TInt32 x, y;
|
||||
};
|
||||
|
||||
#endif // _GHOST_EVENT_H_
|
||||
|
@ -58,6 +58,23 @@ public:
|
||||
m_data = &m_buttonEventData;
|
||||
}
|
||||
|
||||
virtual int serialize(char buf[256])
|
||||
{
|
||||
sprintf(buf, "button mask: %d", m_buttonEventData.button);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GHOST_EventButton(GHOST_TUns64 time, GHOST_TEventType type, GHOST_IWindow* window, char buf[256])
|
||||
: GHOST_Event(time, type, window)
|
||||
{
|
||||
int i;
|
||||
sscanf(buf, "button mask: %d", &i);
|
||||
|
||||
m_buttonEventData.button = (GHOST_TButtonMask)i;
|
||||
m_data = &m_buttonEventData;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** The button event data. */
|
||||
GHOST_TEventButtonData m_buttonEventData;
|
||||
|
@ -58,6 +58,24 @@ public:
|
||||
m_data = &m_cursorEventData;
|
||||
}
|
||||
|
||||
GHOST_EventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256])
|
||||
: GHOST_Event(msec, type, window)
|
||||
{
|
||||
int x, y;
|
||||
sscanf(buf, "mousecursor: %d %d", &x, &y);
|
||||
|
||||
m_cursorEventData.x = x;
|
||||
m_cursorEventData.y = y;
|
||||
m_data = &m_cursorEventData;
|
||||
}
|
||||
|
||||
virtual int serialize(char buf[256])
|
||||
{
|
||||
sprintf(buf, "mousecursor: %d %d", m_cursorEventData.x, m_cursorEventData.y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** The x,y-coordinates of the cursor position. */
|
||||
GHOST_TEventCursorData m_cursorEventData;
|
||||
|
@ -71,7 +71,24 @@ public:
|
||||
m_keyEventData.ascii = ascii;
|
||||
m_data = &m_keyEventData;
|
||||
}
|
||||
|
||||
GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256])
|
||||
: GHOST_Event(msec, type, window)
|
||||
{
|
||||
int key, ascii;
|
||||
sscanf(buf, "key: %d %d", &key, &ascii);
|
||||
|
||||
m_keyEventData.key = (GHOST_TKey) key;
|
||||
m_keyEventData.ascii = ascii;
|
||||
m_data = &m_keyEventData;
|
||||
}
|
||||
|
||||
virtual int serialize(char buf[256])
|
||||
{
|
||||
sprintf(buf, "key: %d %d", m_keyEventData.key, m_keyEventData.ascii);
|
||||
|
||||
return 0;
|
||||
}
|
||||
protected:
|
||||
/** The key event data. */
|
||||
GHOST_TEventKeyData m_keyEventData;
|
||||
|
@ -38,9 +38,20 @@
|
||||
#include <algorithm>
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
#include "GHOST_System.h"
|
||||
#include "GHOST_IWindow.h"
|
||||
#include "GHOST_WindowManager.h"
|
||||
#include "GHOST_Event.h"
|
||||
#include "GHOST_EventButton.h"
|
||||
#include "GHOST_EventCursor.h"
|
||||
#include "GHOST_EventKey.h"
|
||||
#include "GHOST_EventWheel.h"
|
||||
#include "GHOST_EventTrackpad.h"
|
||||
|
||||
GHOST_EventManager::GHOST_EventManager()
|
||||
{
|
||||
m_playfile = m_recfile = NULL;
|
||||
m_lasttime = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -87,6 +98,33 @@ GHOST_IEvent* GHOST_EventManager::peekEvent()
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_EventManager::beginRecord(FILE *file)
|
||||
{
|
||||
if (m_playfile || !file)
|
||||
return GHOST_kFailure;
|
||||
|
||||
m_recfile = file;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_EventManager::endRecord()
|
||||
{
|
||||
if (!m_recfile)
|
||||
return GHOST_kFailure;
|
||||
|
||||
m_recfile = NULL;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_EventManager::playbackEvents(FILE *file)
|
||||
{
|
||||
if (m_recfile || !file)
|
||||
return GHOST_kFailure;
|
||||
|
||||
m_playfile = file;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent* event)
|
||||
{
|
||||
@ -95,6 +133,39 @@ GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent* event)
|
||||
if (m_events.size() < m_events.max_size()) {
|
||||
m_events.push_front(event);
|
||||
success = GHOST_kSuccess;
|
||||
if (m_recfile) {
|
||||
GHOST_System *sys;
|
||||
GHOST_ModifierKeys keys;
|
||||
GHOST_TInt32 x, y;
|
||||
char buf[256];
|
||||
|
||||
sys = reinterpret_cast<GHOST_System*>(GHOST_ISystem::getSystem());
|
||||
|
||||
/*write event parent class data*/
|
||||
event->writeheader(buf);
|
||||
fprintf(m_recfile, "%s\n", buf);
|
||||
|
||||
/*write child class data*/
|
||||
event->serialize(buf);
|
||||
fprintf(m_recfile, "%s\n", buf);
|
||||
|
||||
/*write modifier key states*/
|
||||
sys->getModifierKeys(keys);
|
||||
fprintf(m_recfile, "lshift: %d rshift: %d lalt: %d ralt: %d lctrl: %d rctrl: %d command: %d\n",
|
||||
(int)keys.get(GHOST_kModifierKeyLeftShift),
|
||||
(int)keys.get(GHOST_kModifierKeyRightShift),
|
||||
(int)keys.get(GHOST_kModifierKeyLeftAlt),
|
||||
(int)keys.get(GHOST_kModifierKeyRightAlt),
|
||||
(int)keys.get(GHOST_kModifierKeyLeftControl),
|
||||
(int)keys.get(GHOST_kModifierKeyRightControl),
|
||||
(int)keys.get(GHOST_kModifierKeyCommand));
|
||||
fflush(m_recfile);
|
||||
|
||||
sys->getCursorPosition(x, y);
|
||||
|
||||
/*write mouse cursor state*/
|
||||
fprintf(m_recfile, "mcursorstate: %d %d\n", x, y);
|
||||
}
|
||||
}
|
||||
else {
|
||||
success = GHOST_kFailure;
|
||||
@ -121,6 +192,21 @@ bool GHOST_EventManager::dispatchEvent(GHOST_IEvent* event)
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool GHOST_EventManager::playingEvents(bool *hasevent) {
|
||||
if (hasevent && m_events.size()) {
|
||||
GHOST_IEvent *event = m_events[m_events.size()-1];
|
||||
GHOST_System *sys;
|
||||
|
||||
sys = reinterpret_cast<GHOST_System*>(GHOST_ISystem::getSystem());
|
||||
*hasevent = event->getType()==0 || sys->getMilliSeconds()-m_lasttime > event->getTime();
|
||||
|
||||
if (event->getType()==0)
|
||||
popEvent();
|
||||
} else if (hasevent)
|
||||
*hasevent = true;
|
||||
|
||||
return m_playfile != NULL;
|
||||
}
|
||||
|
||||
bool GHOST_EventManager::dispatchEvent()
|
||||
{
|
||||
@ -136,18 +222,200 @@ bool GHOST_EventManager::dispatchEvent()
|
||||
|
||||
bool GHOST_EventManager::dispatchEvents()
|
||||
{
|
||||
bool handled;
|
||||
if (getNumEvents()) {
|
||||
handled = true;
|
||||
while (getNumEvents()) {
|
||||
if (!dispatchEvent()) {
|
||||
handled = false;
|
||||
bool handled = false;
|
||||
|
||||
if (m_recfile && getNumEvents()) {
|
||||
fprintf(m_recfile, "break\n");
|
||||
}
|
||||
|
||||
if (m_playfile) {
|
||||
GHOST_IEvent *event = NULL;
|
||||
GHOST_System *sys;
|
||||
GHOST_WindowManager *wm;
|
||||
GHOST_TInt32 x, y;
|
||||
GHOST_ModifierKeys modkeys;
|
||||
std::vector<GHOST_IWindow *> windows;
|
||||
double lasttime = -1.0;
|
||||
char buf[256], *str;
|
||||
|
||||
sys = reinterpret_cast<GHOST_System*>(GHOST_ISystem::getSystem());
|
||||
wm = sys->getWindowManager();
|
||||
windows = wm->getWindows();
|
||||
|
||||
while (str = fgets(buf, 256, m_playfile)) {
|
||||
GHOST_IWindow *iwin = NULL;
|
||||
GHOST_TEventType type;
|
||||
double time;
|
||||
int winid, i;
|
||||
int ctype;
|
||||
|
||||
event = NULL;
|
||||
|
||||
if (strcmp(str, "break\n")==0) {
|
||||
event = new GHOST_Event(0, GHOST_kEventUnknown, NULL);
|
||||
pushEvent(event);
|
||||
continue;
|
||||
}
|
||||
|
||||
sscanf(str, "%lf %d %d", &time, &ctype, &winid);
|
||||
type = (GHOST_TEventType)(ctype);
|
||||
|
||||
if (lasttime > 0.0) {
|
||||
double t = time;
|
||||
|
||||
time -= lasttime;
|
||||
lasttime = t;
|
||||
} else lasttime = time;
|
||||
|
||||
for (i=0; i<windows.size(); i++) {
|
||||
if (windows[i]->getID() == winid)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == windows.size()) {
|
||||
printf("Eek! Could not find window %d!\n", winid);
|
||||
str = fgets(buf, 256, m_playfile);
|
||||
continue;
|
||||
}
|
||||
|
||||
iwin = windows[i];
|
||||
|
||||
str = fgets(buf, 256, m_playfile);
|
||||
if (!str)
|
||||
break;
|
||||
|
||||
switch (type) {
|
||||
case GHOST_kEventCursorMove:
|
||||
event = new GHOST_EventCursor(time*1000, type, iwin, str);
|
||||
break;
|
||||
case GHOST_kEventButtonDown:
|
||||
event = new GHOST_EventButton(time*1000, type, iwin, str);
|
||||
break;
|
||||
case GHOST_kEventButtonUp:
|
||||
event = new GHOST_EventButton(time*1000, type, iwin, str);
|
||||
break;
|
||||
case GHOST_kEventWheel:
|
||||
event = new GHOST_EventWheel(time*1000, type, iwin, str);
|
||||
break;
|
||||
case GHOST_kEventTrackpad:
|
||||
event = new GHOST_EventTrackpad(time*1000, type, iwin, str);
|
||||
break;
|
||||
|
||||
case GHOST_kEventNDOFMotion:
|
||||
break;
|
||||
case GHOST_kEventNDOFButton:
|
||||
break;
|
||||
|
||||
case GHOST_kEventKeyDown:
|
||||
event = new GHOST_EventKey(time*1000, type, iwin, str);
|
||||
break;
|
||||
case GHOST_kEventKeyUp:
|
||||
event = new GHOST_EventKey(time*1000, type, iwin, str);
|
||||
break;
|
||||
// case GHOST_kEventKeyAuto:
|
||||
|
||||
case GHOST_kEventQuit:
|
||||
break;
|
||||
|
||||
case GHOST_kEventWindowClose:
|
||||
break;
|
||||
case GHOST_kEventWindowActivate:
|
||||
break;
|
||||
case GHOST_kEventWindowDeactivate:
|
||||
break;
|
||||
case GHOST_kEventWindowUpdate:
|
||||
break;
|
||||
case GHOST_kEventWindowSize:
|
||||
break;
|
||||
case GHOST_kEventWindowMove:
|
||||
break;
|
||||
|
||||
case GHOST_kEventDraggingEntered:
|
||||
break;
|
||||
case GHOST_kEventDraggingUpdated:
|
||||
break;
|
||||
case GHOST_kEventDraggingExited:
|
||||
break;
|
||||
case GHOST_kEventDraggingDropDone:
|
||||
break;
|
||||
|
||||
case GHOST_kEventOpenMainFile:
|
||||
break;
|
||||
|
||||
case GHOST_kEventTimer:
|
||||
break;
|
||||
}
|
||||
|
||||
str = fgets(buf, 256, m_playfile);
|
||||
if (str) {
|
||||
int lshift, rshift, lalt, ralt, lctrl, rctrl, command;
|
||||
sscanf(str, "lshift: %d rshift: %d lalt: %d ralt: %d lctrl: %d rctrl: %d command: %d",
|
||||
&lshift, &rshift, &lalt, &ralt, &lctrl, &rctrl, &command);
|
||||
modkeys.set(GHOST_kModifierKeyLeftShift, lshift);
|
||||
modkeys.set(GHOST_kModifierKeyRightShift, rshift);
|
||||
modkeys.set(GHOST_kModifierKeyLeftAlt, lalt);
|
||||
modkeys.set(GHOST_kModifierKeyRightAlt, ralt);
|
||||
modkeys.set(GHOST_kModifierKeyLeftControl, lctrl);
|
||||
modkeys.set(GHOST_kModifierKeyRightControl, rctrl);
|
||||
modkeys.set(GHOST_kModifierKeyCommand, command);
|
||||
}
|
||||
|
||||
str = fgets(buf, 256, m_playfile);
|
||||
if (str) {
|
||||
/*read mouse cursor state*/
|
||||
sscanf(str, "mcursorstate: %d %d", &x, &y);
|
||||
}
|
||||
|
||||
if (event) {
|
||||
event->setPlaybackCursor(x, y);
|
||||
event->setPlaybackModifierKeys(modkeys);
|
||||
pushEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
if (getNumEvents()) {
|
||||
handled = true;
|
||||
while (getNumEvents()) {
|
||||
event = m_events[m_events.size()-1];
|
||||
//event->geTime() stores delay between last event and this one
|
||||
if (event->getType() == 0 || sys->getMilliSeconds()-m_lasttime < event->getTime()) {
|
||||
handled = false;
|
||||
|
||||
if (event->getType() == 0)
|
||||
popEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
//change event->time from delay-since-last-event to
|
||||
//current system timevoid
|
||||
m_lasttime = sys->getMilliSeconds();
|
||||
event->setTime(m_lasttime);
|
||||
|
||||
event->getPlaybackModifierKeys(m_playmods);
|
||||
event->getPlaybackCursor(m_x, m_y);
|
||||
|
||||
if (!dispatchEvent()) {
|
||||
handled = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handled = false;
|
||||
m_playfile = NULL;
|
||||
}
|
||||
} else {
|
||||
if (getNumEvents()) {
|
||||
handled = true;
|
||||
while (getNumEvents()) {
|
||||
if (!dispatchEvent()) {
|
||||
handled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
handled = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
handled = false;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,10 @@
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
#include "GHOST_IEventConsumer.h"
|
||||
|
||||
#include "GHOST_ModifierKeys.h"
|
||||
|
||||
/**
|
||||
* Manages an event stack and a list of event consumers.
|
||||
@ -87,7 +88,31 @@ public:
|
||||
* @param event The event to push on the stack.
|
||||
*/
|
||||
virtual GHOST_TSuccess pushEvent(GHOST_IEvent* event);
|
||||
|
||||
|
||||
virtual GHOST_TSuccess beginRecord(FILE *file);
|
||||
virtual GHOST_TSuccess endRecord();
|
||||
virtual GHOST_TSuccess playbackEvents(FILE *file);
|
||||
|
||||
virtual bool playingEvents(bool *hasevent);
|
||||
|
||||
virtual bool recordingEvents() {
|
||||
return m_recfile != NULL;
|
||||
}
|
||||
|
||||
/** only used during playback **/
|
||||
virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
{
|
||||
keys = m_playmods;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
/** only used during playback **/
|
||||
virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
|
||||
{
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the given event directly, bypassing the event stack.
|
||||
* @return Indication as to whether any of the consumers handled the event.
|
||||
@ -168,6 +193,13 @@ protected:
|
||||
|
||||
/** The list with event consumers. */
|
||||
TConsumerVector m_consumers;
|
||||
private:
|
||||
/** used for playback functionality**/
|
||||
FILE *m_recfile;
|
||||
FILE *m_playfile;
|
||||
GHOST_ModifierKeys m_playmods;
|
||||
GHOST_TUns64 m_lasttime;
|
||||
GHOST_TInt32 m_x, m_y;
|
||||
};
|
||||
|
||||
#endif // _GHOST_EVENT_MANAGER_H_
|
||||
|
@ -60,7 +60,27 @@ public:
|
||||
m_trackpadEventData.deltaY = deltaY;
|
||||
m_data = &m_trackpadEventData;
|
||||
}
|
||||
|
||||
|
||||
GHOST_EventTrackpad(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256])
|
||||
: GHOST_Event(msec, type, window)
|
||||
{
|
||||
int subtype, x, y, dx, dy;
|
||||
sscanf(buf, "trackpad: %d %d %d %d %d", &subtype, &x, &y, &dx, &dy);
|
||||
|
||||
m_trackpadEventData.subtype = (GHOST_TTrackpadEventSubTypes) subtype;
|
||||
m_trackpadEventData.x = x;
|
||||
m_trackpadEventData.y = y;
|
||||
m_trackpadEventData.deltaX = dx;
|
||||
m_trackpadEventData.deltaY = dy;
|
||||
m_data = &m_trackpadEventData;
|
||||
}
|
||||
|
||||
virtual int serialize(char buf[256])
|
||||
{
|
||||
sprintf(buf, "trackpad: %d %d %d %d %d", m_trackpadEventData.subtype, m_trackpadEventData.x, m_trackpadEventData.y, m_trackpadEventData.deltaX, m_trackpadEventData.deltaY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
protected:
|
||||
/** The mouse pan data */
|
||||
GHOST_TEventTrackpadData m_trackpadEventData;
|
||||
|
@ -58,6 +58,22 @@ public:
|
||||
m_data = &m_wheelEventData;
|
||||
}
|
||||
|
||||
GHOST_EventWheel(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, char buf[256])
|
||||
: GHOST_Event(msec, type, window)
|
||||
{
|
||||
int z;
|
||||
sscanf(buf, "wheel: %d", &z);
|
||||
|
||||
m_wheelEventData.z = z;
|
||||
m_data = &m_wheelEventData;
|
||||
}
|
||||
|
||||
virtual int serialize(char buf[256])
|
||||
{
|
||||
sprintf(buf, "wheel: %d", m_wheelEventData.z);
|
||||
|
||||
return 0;
|
||||
}
|
||||
protected:
|
||||
/** The z-displacement of the mouse wheel. */
|
||||
GHOST_TEventWheelData m_wheelEventData;
|
||||
|
@ -222,10 +222,37 @@ GHOST_TSuccess GHOST_System::addEventConsumer(GHOST_IEventConsumer* consumer)
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_System::beginRecord(FILE *file)
|
||||
{
|
||||
return this->m_eventManager->beginRecord(file);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_System::endRecord()
|
||||
{
|
||||
return this->m_eventManager->endRecord();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_System::playbackEvents(FILE *file)
|
||||
{
|
||||
return this->m_eventManager->playbackEvents(file);
|
||||
}
|
||||
|
||||
|
||||
bool GHOST_System::playingEvents(bool *hasevent) const
|
||||
{
|
||||
return this->m_eventManager->playingEvents(hasevent);
|
||||
}
|
||||
|
||||
bool GHOST_System::recordingEvents()
|
||||
{
|
||||
return this->m_eventManager->recordingEvents();
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent* event)
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
if (m_eventManager) {
|
||||
if (m_eventManager && !m_eventManager->playingEvents(NULL)) {
|
||||
success = m_eventManager->pushEvent(event);
|
||||
}
|
||||
else {
|
||||
|
@ -236,6 +236,13 @@ public:
|
||||
** Other (internal) functionality.
|
||||
***************************************************************************************/
|
||||
|
||||
virtual GHOST_TSuccess beginRecord(FILE *file);
|
||||
virtual GHOST_TSuccess endRecord();
|
||||
virtual GHOST_TSuccess playbackEvents(FILE *file);
|
||||
|
||||
virtual bool playingEvents(bool *hasevent) const;
|
||||
virtual bool recordingEvents();
|
||||
|
||||
/**
|
||||
* Pushes an event on the stack.
|
||||
* To dispatch it, call dispatchEvent() or dispatchEvents().
|
||||
|
@ -388,6 +388,10 @@ processEvents(
|
||||
|
||||
bool anyProcessed = false;
|
||||
|
||||
if (playingEvents(&anyProcessed)) {
|
||||
return anyProcessed;
|
||||
}
|
||||
|
||||
do {
|
||||
GHOST_TimerManager* timerMgr = getTimerManager();
|
||||
|
||||
@ -835,7 +839,10 @@ GHOST_SystemX11::
|
||||
getModifierKeys(
|
||||
GHOST_ModifierKeys& keys
|
||||
) const {
|
||||
|
||||
if (this->playingEvents(NULL)) {
|
||||
return getEventManager()->getModifierKeys(keys);
|
||||
}
|
||||
|
||||
// analyse the masks retuned from XQueryPointer.
|
||||
|
||||
memset((void *)m_keyboard_vector,0,sizeof(m_keyboard_vector));
|
||||
@ -946,7 +953,11 @@ getCursorPosition(
|
||||
Window root_return, child_return;
|
||||
int rx,ry,wx,wy;
|
||||
unsigned int mask_return;
|
||||
|
||||
|
||||
if (playingEvents(NULL)) {
|
||||
return getEventManager()->getCursorPosition(x, y);
|
||||
}
|
||||
|
||||
if (XQueryPointer(
|
||||
m_display,
|
||||
RootWindow(m_display,DefaultScreen(m_display)),
|
||||
|
@ -263,7 +263,10 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
|
||||
|
||||
//stupid compiler flag isn't working
|
||||
//remember to undef this later
|
||||
#ifndef EVENT_RECORDER
|
||||
#define EVENT_RECORDER
|
||||
#endif
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -47,6 +47,10 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
#include "../../../../intern/ghost/GHOST_C-api.h"
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
#include "BPY_extern.h"
|
||||
#endif
|
||||
@ -108,14 +112,21 @@ bContext *CTX_copy(const bContext *C)
|
||||
}
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
extern GHOST_SystemHandle g_system;
|
||||
|
||||
int CTX_rec_events(bContext *C)
|
||||
{
|
||||
return C->evtrec;
|
||||
return GHOST_RecordingEvents(g_system);
|
||||
}
|
||||
|
||||
int CTX_rec_events_set(bContext *C, int state)
|
||||
{
|
||||
C->evtrec = state;
|
||||
FILE *f = CTX_rec_file(C);
|
||||
|
||||
if (GHOST_RecordingEvents(g_system) && !state)
|
||||
GHOST_StopRecording(g_system);
|
||||
else if (!GHOST_RecordingEvents(g_system) && state)
|
||||
GHOST_RecordEvents(g_system, f);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -128,25 +139,20 @@ FILE *CTX_rec_file(bContext *C)
|
||||
return f;
|
||||
}
|
||||
|
||||
double CTX_rec_lasttime(bContext *C, double newtime)
|
||||
{
|
||||
double ret;
|
||||
|
||||
if (C->evtlasttime == 0.0) {
|
||||
ret = newtime;
|
||||
} else ret = C->evtlasttime;
|
||||
|
||||
C->evtlasttime = newtime;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CTX_set_events_path(bContext *C, char *path)
|
||||
{
|
||||
if (!path)
|
||||
if (!path) {
|
||||
C->evtplaypath[0] = 0;
|
||||
else
|
||||
} else {
|
||||
FILE *file = fopen(path, "rb");
|
||||
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
strcpy(C->evtplaypath, path);
|
||||
if (g_system)
|
||||
GHOST_PlaybackEvents(g_system, file);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -156,8 +162,8 @@ int CTX_play_events(bContext *C, char **playpath)
|
||||
{
|
||||
if (playpath)
|
||||
*playpath = C->evtplaypath[0] ? C->evtplaypath : NULL;
|
||||
|
||||
return C->evtplaypath[0];
|
||||
|
||||
return GHOST_PlayingEvents(g_system);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -258,6 +258,8 @@ int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2, float
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*used for testing. returns an error string the two meshes don't match*/
|
||||
|
@ -72,10 +72,6 @@
|
||||
#include "wm_event_types.h"
|
||||
#include "wm_draw.h"
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
int erec_playing = 0;
|
||||
#endif
|
||||
|
||||
/* ************ event management ************** */
|
||||
|
||||
void wm_event_add(wmWindow *win, wmEvent *event_to_add)
|
||||
@ -1589,11 +1585,6 @@ void wm_event_do_handlers(bContext *C)
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
wmWindow *win;
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
static FILE *file = NULL;
|
||||
char *fpath = NULL;
|
||||
#endif
|
||||
|
||||
for(win= wm->windows.first; win; win= win->next) {
|
||||
wmEvent *event;
|
||||
|
||||
@ -1630,82 +1621,11 @@ void wm_event_do_handlers(bContext *C)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
if (CTX_play_events(C, &fpath) && fpath)
|
||||
{
|
||||
wmEvent evt;
|
||||
double nextdelay = 0.0;
|
||||
|
||||
erec_playing = 1;
|
||||
|
||||
if (!file)
|
||||
file= fopen(fpath, "rb");
|
||||
|
||||
while (file && !feof(file)) {
|
||||
char buf1[6];
|
||||
fread(buf1, 5, 1, file);
|
||||
buf1[5] = 0;
|
||||
|
||||
if (strcasecmp(buf1, "event")) {
|
||||
if (!strcasecmp(buf1, "break"))
|
||||
break;
|
||||
|
||||
fprintf(stderr, "EEK! bad event playback file!!");
|
||||
break;
|
||||
}
|
||||
|
||||
fread(&evt, sizeof(*event), 1, file);
|
||||
|
||||
/*add in artifical delay after button open events*/
|
||||
if (!evt.customdata) {
|
||||
evt.delay += nextdelay;
|
||||
nextdelay = 0.0;
|
||||
}
|
||||
|
||||
if (evt.type == EVT_BUT_OPEN)
|
||||
nextdelay = 1.0;
|
||||
|
||||
/*don't do anything if theres customdata in the
|
||||
event*/
|
||||
if (evt.customdata)
|
||||
continue;
|
||||
|
||||
wm_event_add(win, &evt);
|
||||
}
|
||||
|
||||
if (file && feof(file)) {
|
||||
erec_playing = 0;
|
||||
fclose(file);
|
||||
CTX_set_events_path(C, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (win->lasttime == 0.0)
|
||||
win->lasttime = PIL_check_seconds_timer();
|
||||
|
||||
while( (event= win->queue.first) ) {
|
||||
int action = WM_HANDLER_CONTINUE;
|
||||
#if 1
|
||||
/*used for hackish recorder playback*/
|
||||
while (event->delay>0.0 && PIL_check_seconds_timer()
|
||||
- win->lasttime < event->delay) ;
|
||||
|
||||
#endif
|
||||
#ifdef EVENT_RECORDER
|
||||
if (CTX_rec_events(C) && !CTX_play_events(C, NULL)) {
|
||||
FILE *file = CTX_rec_file(C);
|
||||
char tag[6] = "event";
|
||||
double delay = PIL_check_seconds_timer();
|
||||
|
||||
delay -= CTX_rec_lasttime(C, delay);
|
||||
event->delay = delay;
|
||||
|
||||
fwrite(tag, sizeof(tag)-1, 1, file);
|
||||
fwrite(event, sizeof(*event), 1, file);
|
||||
fflush(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
if((G.f & G_DEBUG) && event && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))
|
||||
printf("pass on evt %d val %d\n", event->type, event->val);
|
||||
@ -1842,22 +1762,9 @@ void wm_event_do_handlers(bContext *C)
|
||||
win->lasttime = PIL_check_seconds_timer();
|
||||
}
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
if (CTX_rec_events(C) && !CTX_play_events(C, NULL)) {
|
||||
FILE *file = CTX_rec_file(C);
|
||||
char tag[6] = "break";
|
||||
|
||||
fwrite(tag, 5, 1, file);
|
||||
fflush(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* only add mousemove when queue was read entirely */
|
||||
#ifdef EVENT_RECORDER
|
||||
if(win->addmousemove && win->eventstate && !erec_playing) {
|
||||
#else
|
||||
if(win->addmousemove && win->eventstate) {
|
||||
#endif
|
||||
wmEvent event= *(win->eventstate);
|
||||
event.type= MOUSEMOVE;
|
||||
event.prevx= event.x;
|
||||
@ -2256,11 +2163,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t
|
||||
switch (type) {
|
||||
/* mouse move */
|
||||
case GHOST_kEventCursorMove: {
|
||||
#ifdef EVENT_RECORDER
|
||||
if(win->active && !erec_playing) {
|
||||
#else
|
||||
if(win->active) {
|
||||
#endif
|
||||
|
||||
GHOST_TEventCursorData *cd= customdata;
|
||||
wmEvent *lastevent= win->queue.last;
|
||||
|
||||
@ -2308,10 +2212,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventTrackpad: {
|
||||
#ifdef EVENT_RECORDER
|
||||
if(wm->winactive && !erec_playing) {
|
||||
#endif
|
||||
|
||||
GHOST_TEventTrackpadData * pd = customdata;
|
||||
switch (pd->subtype) {
|
||||
case GHOST_kTrackpadEventMagnify:
|
||||
@ -2345,21 +2245,13 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t
|
||||
update_tablet_data(win, &event);
|
||||
wm_event_add(win, &event);
|
||||
break;
|
||||
#ifdef EVENT_RECORDER
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* mouse button */
|
||||
case GHOST_kEventButtonDown:
|
||||
case GHOST_kEventButtonUp: {
|
||||
GHOST_TEventButtonData *bd= customdata;
|
||||
event.val= (type==GHOST_kEventButtonDown) ? KM_PRESS:KM_RELEASE; /* Note!, this starts as 0/1 but later is converted to KM_PRESS/KM_RELEASE by tweak */
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
if (erec_playing)
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
if (bd->button == GHOST_kButtonMaskLeft)
|
||||
event.type= LEFTMOUSE;
|
||||
else if (bd->button == GHOST_kButtonMaskRight)
|
||||
@ -2399,11 +2291,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t
|
||||
event.ascii= kd->ascii;
|
||||
event.val= (type==GHOST_kEventKeyDown)?KM_PRESS:KM_RELEASE;
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
if (erec_playing)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* exclude arrow keys, esc, etc from text input */
|
||||
if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>0))
|
||||
event.ascii= '\0';
|
||||
@ -2455,10 +2342,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int t
|
||||
case GHOST_kEventWheel: {
|
||||
GHOST_TEventWheelData* wheelData = customdata;
|
||||
|
||||
#ifdef EVENT_RECORDER
|
||||
if (erec_playing)
|
||||
return;
|
||||
#endif
|
||||
if (wheelData->z > 0)
|
||||
event.type= WHEELUPMOUSE;
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user