blocking Session::processEvents() function

metadata
Wenzel Jakob 2011-03-21 18:08:39 +01:00
parent d08a351a6c
commit a90a8606bd
13 changed files with 129 additions and 39 deletions

View File

@ -16,22 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*************************************************************************
Apollyon, a set of C++ utilities including standard templates and
a OpenGL-based rendering subsystem.
Copyright (C) 2005 Wenzel Jakob
Apollyon is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation. This program
is distributed WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
*************************************************************************/
#if !defined(__NSGLSESSION_H)
#define __NSGLSESSION_H
@ -52,8 +36,13 @@ public:
/// Shut the session down
void shutdown();
/// Process all events and call event callbacks
void processEvents();
/**
* \brief Process all events and call event callbacks.
*
* This function will run until the \c stop parameter is set
* to \c true from within an event callback.
*/
void processEventsBlocking(bool &stop);
MTS_DECLARE_CLASS()
protected:

View File

@ -42,6 +42,14 @@ public:
/// Process all events and call event callbacks
virtual void processEvents() = 0;
/**
* \brief Process all events and call event callbacks.
*
* This function will run until the \c stop parameter is set
* to \c true from within an event callback.
*/
virtual void processEventsBlocking(bool &stop) = 0;
MTS_DECLARE_CLASS()
protected:
/// Virtual destructor

View File

@ -47,6 +47,9 @@ protected:
/// Draw a heads-up display
void drawHUD(const std::string &text);
/// Request that the draw() routine be called
inline void redraw() { m_leaveEventLoop = true; }
/// To be overwritten by the subclass: main drawing routine
virtual void draw() = 0;
@ -98,7 +101,7 @@ protected:
ref<Device> m_device;
ref<Renderer> m_renderer;
ref<Font> m_font;
bool m_quit;
bool m_quit, m_leaveEventLoop;
};
MTS_NAMESPACE_END

View File

@ -41,6 +41,15 @@ public:
/// Process all events and call event callbacks
void processEvents();
/**
* \brief Process all events and call event callbacks.
*
* This function will run until the \c stop parameter is set
* to \c true from within an event callback.
*/
void processEventsBlocking(bool &stop);
MTS_DECLARE_CLASS()
protected:
/// Virtual destructor

View File

@ -47,6 +47,14 @@ public:
/// Process all events and call event callbacks
void processEvents();
/**
* \brief Process all events and call event callbacks.
*
* This function will run until the \c stop parameter is set
* to \c true from within an event callback.
*/
void processEventsBlocking(bool &stop);
MTS_DECLARE_CLASS()
protected:
/// Virtual destructor

View File

@ -150,10 +150,6 @@ public:
int samplerResID = sched->registerManifoldResource(
static_cast<std::vector<SerializableObject*> &>(samplers));
#if !defined(__OSX__) && defined(_OPENMP)
omp_set_num_threads(nCores);
#endif
#ifdef MTS_DEBUG_FP
enableFPExceptions();
#endif

View File

@ -36,6 +36,9 @@ void GLProgram::init() {
Assert(m_id[0] == 0 && m_id[1] == 0 && m_program == 0);
Log(EDebug, "Uploading a GPU program : %s", toString().c_str());
if (!GLEW_ARB_shader_objects)
Log(EError, "Your OpenGL implementation does not support shader objects!");
m_program = glCreateProgramObjectARB();
m_id[EVertexProgram] = createShader(GL_VERTEX_SHADER_ARB,
@ -82,6 +85,9 @@ int GLProgram::createShader(int type, const std::string &source) {
if (source == "")
return 0;
if (type == GL_GEOMETRY_SHADER_ARB && !GLEW_ARB_geometry_shader4)
Log(EError, "Your OpenGL implementation does not support geometry shaders!");
int id = glCreateShaderObjectARB(type);
const char *string = source.c_str();

View File

@ -579,10 +579,8 @@ void NSGLDevice::processEvents() {
Assert(m_initialized);
m_mutex->lock();
std::vector<DeviceEvent>::iterator it = m_deviceEvents.begin();
for (; it!=m_deviceEvents.end(); ++it) {
for (std::vector<DeviceEvent>::iterator it = m_deviceEvents.begin(); it!=m_deviceEvents.end(); ++it)
fireDeviceEvent(*it);
}
m_deviceEvents.clear();
m_mutex->unlock();
}

View File

@ -48,12 +48,12 @@ void NSGLSession::processEvents() {
/* Separate autorelease pool */
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDate *distantPast = [NSDate distantPast];
NSEvent *event;
/* NSRunloop emulation */
do {
event = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: distantPast inMode: NSDefaultRunLoopMode dequeue: YES];
event = [NSApp nextEventMatchingMask: NSAnyEventMask
untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES];
if (event == nil)
break;
[NSApp sendEvent: event];
@ -61,12 +61,45 @@ void NSGLSession::processEvents() {
[pool release];
/* After the events have been delivered to the devices,
process them */
for (; it!=m_devices.end(); ++it) {
NSGLDevice *device = static_cast<NSGLDevice *>(*it);
device->processEvents();
/* After the events have been delivered to the devices, process them */
for (std::vector<Device *>::iterator it = m_devices.begin(); it!=m_devices.end(); ++it)
static_cast<NSGLDevice *>(*it)->processEvents();
}
void NSGLSession::processEventsBlocking(bool &stop) {
/* Separate autorelease pool */
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSEvent *event;
/* NSRunloop emulation */
while (true) {
event = [NSApp nextEventMatchingMask: NSAnyEventMask
untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES];
if (event != nil) {
[NSApp sendEvent: event];
} else {
/* No more event -- process them */
for (std::vector<Device *>::iterator it = m_devices.begin(); it!=m_devices.end(); ++it)
static_cast<NSGLDevice *>(*it)->processEvents();
if (stop)
break;
/* Wait for the next event (blocking) */
event = [NSApp nextEventMatchingMask: NSAnyEventMask
untilDate: [NSDate distantFuture] inMode: NSDefaultRunLoopMode dequeue: YES];
if (event != nil)
[NSApp sendEvent: event];
}
}
[pool release];
/* After the events have been delivered to the devices, process them */
for (std::vector<Device *>::iterator it = m_devices.begin(); it!=m_devices.end(); ++it)
static_cast<NSGLDevice *>(*it)->processEvents();
}
MTS_IMPLEMENT_CLASS(NSGLSession, false, Session)

View File

@ -36,10 +36,14 @@ int Viewer::run(int argc, char **argv) {
m_font = new Font(Font::EBitstreamVeraMono14);
m_font->init(m_renderer);
m_quit = false;
m_leaveEventLoop = true;
if (init(argc, argv)) {
while (!m_quit) {
m_session->processEvents();
while (true) {
m_session->processEventsBlocking(m_leaveEventLoop);
m_leaveEventLoop = false;
if (m_quit)
break;
m_renderer->clear();
draw();
m_device->flip();
@ -77,10 +81,12 @@ bool Viewer::deviceEventOccurred(const DeviceEvent &event) {
switch (event.getType()) {
case Device::EKeyDownEvent:
if (event.getKeyboardKey() == 'q'
|| event.getKeyboardSpecial() == Device::EKeyEscape)
|| event.getKeyboardSpecial() == Device::EKeyEscape) {
m_quit = true;
else
m_leaveEventLoop = true;
} else {
keyPressed(event);
}
break;
case Device::EKeyUpEvent: keyReleased(event); break;
case Device::EMouseMotionEvent: mouseMoved(event); break;
@ -91,6 +97,7 @@ bool Viewer::deviceEventOccurred(const DeviceEvent &event) {
case Device::EMouseEndDragEvent: mouseEndDrag(event); break;
case Device::EQuitEvent:
m_quit = true;
m_leaveEventLoop = true;
break;
}

View File

@ -77,9 +77,19 @@ void WGLSession::processEvents() {
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
if (GetMessage(&msg, NULL, 0, 0) > 0) {
if (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage(&msg);
}
}
void WGLSession::processEventsBlocking(bool &stop) {
MSG msg;
while (true) {
if (!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) && stop)
break;
if (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage(&msg);
}
}
}

View File

@ -109,5 +109,26 @@ void X11Session::processEvents() {
}
}
void X11Session::processEventsBlocking(bool &stop) {
XEvent event;
while (true) {
if (!XPending(m_display) && stop)
break;
XNextEvent(m_display, &event);
Window window = event.xany.window;
std::vector<Device *>::iterator it = m_devices.begin();
for (; it!=m_devices.end(); ++it) {
X11Device *device = static_cast<X11Device *>(*it);
if (device->getWindow() == window) {
device->processEvent(event);
break;
}
}
}
}
MTS_IMPLEMENT_CLASS(X11Session, false, Session)
MTS_NAMESPACE_END

View File

@ -54,6 +54,7 @@ public:
event.getMouseRelative().y / 300.0f
);
}
redraw();
}
/**
@ -217,6 +218,7 @@ public:
m_radius /= 1.1;
break;
}
redraw();
}
bool init(int argc, char **argv) {