Browse Source

Platform: setup GlfwApplication callbacks in a central place.

Removes all needless private static class members and fixes a bug
introduced when getting rid of the global window pointer -- the user
window pointer was set only in the case of having a GL context, not in
the contextless case. Boom. (This bug happened after 2018.04, so I'm not
putting that in the changelog.)
pull/191/head
Vladimír Vondruš 8 years ago
parent
commit
1b5e6812fb
  1. 149
      src/Magnum/Platform/GlfwApplication.cpp
  2. 9
      src/Magnum/Platform/GlfwApplication.h

149
src/Magnum/Platform/GlfwApplication.cpp

@ -64,7 +64,9 @@ GlfwApplication::GlfwApplication(const Arguments& arguments, NoCreateT):
#endif #endif
{ {
/* Init GLFW */ /* Init GLFW */
glfwSetErrorCallback(staticErrorCallback); glfwSetErrorCallback([](int, const char* const description) {
Error{} << description;
});
if(!glfwInit()) { if(!glfwInit()) {
Error() << "Could not initialize GLFW"; Error() << "Could not initialize GLFW";
@ -138,12 +140,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration) {
glfwSetInputMode(_window, GLFW_CURSOR, Int(configuration.cursorMode())); glfwSetInputMode(_window, GLFW_CURSOR, Int(configuration.cursorMode()));
/* Set callbacks */ /* Set callbacks */
glfwSetFramebufferSizeCallback(_window, staticViewportEvent); setupCallbacks();
glfwSetKeyCallback(_window, staticKeyEvent);
glfwSetCursorPosCallback(_window, staticMouseMoveEvent);
glfwSetMouseButtonCallback(_window, staticMouseEvent);
glfwSetScrollCallback(_window, staticMouseScrollEvent);
glfwSetCharCallback(_window, staticTextInputEvent);
return true; return true;
} }
@ -325,13 +322,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf
glfwSetInputMode(_window, GLFW_CURSOR, Int(configuration.cursorMode())); glfwSetInputMode(_window, GLFW_CURSOR, Int(configuration.cursorMode()));
/* Set callbacks */ /* Set callbacks */
glfwSetWindowUserPointer(_window, this); setupCallbacks();
glfwSetFramebufferSizeCallback(_window, staticViewportEvent);
glfwSetKeyCallback(_window, staticKeyEvent);
glfwSetCursorPosCallback(_window, staticMouseMoveEvent);
glfwSetMouseButtonCallback(_window, staticMouseEvent);
glfwSetScrollCallback(_window, staticMouseScrollEvent);
glfwSetCharCallback(_window, staticTextInputEvent);
/* Make the final context current */ /* Make the final context current */
glfwMakeContextCurrent(_window); glfwMakeContextCurrent(_window);
@ -351,37 +342,12 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf
} }
#endif #endif
GlfwApplication::~GlfwApplication() { void GlfwApplication::setupCallbacks() {
glfwDestroyWindow(_window); glfwSetWindowUserPointer(_window, this);
glfwTerminate(); glfwSetFramebufferSizeCallback(_window, [](GLFWwindow* const window, const int w, const int h) {
}
Vector2i GlfwApplication::windowSize() {
Vector2i size;
glfwGetWindowSize(_window, &size.x(), &size.y());
return size;
}
void GlfwApplication::setSwapInterval(const Int interval) {
glfwSwapInterval(interval);
}
int GlfwApplication::exec() {
while(!glfwWindowShouldClose(_window)) {
if(_flags & Flag::Redraw) {
_flags &= ~Flag::Redraw;
drawEvent();
}
glfwPollEvents();
}
return 0;
}
void GlfwApplication::staticViewportEvent(GLFWwindow* const window, const int w, const int h) {
static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->viewportEvent({w, h}); static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->viewportEvent({w, h});
} });
glfwSetKeyCallback(_window, [](GLFWwindow* const window, const int key, int, const int action, const int mods) {
void GlfwApplication::staticKeyEvent(GLFWwindow* const window, const int key, int, const int action, const int mods) {
const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window)); const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
KeyEvent e(static_cast<KeyEvent::Key>(key), {static_cast<InputEvent::Modifier>(mods)}, action == GLFW_REPEAT); KeyEvent e(static_cast<KeyEvent::Key>(key), {static_cast<InputEvent::Modifier>(mods)}, action == GLFW_REPEAT);
@ -393,33 +359,8 @@ void GlfwApplication::staticKeyEvent(GLFWwindow* const window, const int key, in
} else if(action == GLFW_REPEAT) { } else if(action == GLFW_REPEAT) {
instance->keyPressEvent(e); instance->keyPressEvent(e);
} }
} });
glfwSetMouseButtonCallback(_window, [](GLFWwindow* const window, const int button, const int action, const int mods) {
auto GlfwApplication::MouseMoveEvent::buttons() -> Buttons {
if(!_buttons) {
_buttons = Buttons{};
for(const Int button: {GLFW_MOUSE_BUTTON_LEFT,
GLFW_MOUSE_BUTTON_MIDDLE,
GLFW_MOUSE_BUTTON_RIGHT}) {
if(glfwGetMouseButton(_window, button) == GLFW_PRESS)
*_buttons |= Button(1 << button);
}
}
return *_buttons;
}
auto GlfwApplication::MouseMoveEvent::modifiers() -> Modifiers {
if(!_modifiers) _modifiers = currentGlfwModifiers(_window);
return *_modifiers;
}
auto GlfwApplication::MouseScrollEvent::modifiers() -> Modifiers {
if(!_modifiers) _modifiers = currentGlfwModifiers(_window);
return *_modifiers;
}
void GlfwApplication::staticMouseEvent(GLFWwindow* window, int button, int action, int mods) {
const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window)); const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
double x, y; double x, y;
@ -431,14 +372,12 @@ void GlfwApplication::staticMouseEvent(GLFWwindow* window, int button, int actio
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
instance->mouseReleaseEvent(e); instance->mouseReleaseEvent(e);
} /* we don't handle GLFW_REPEAT */ } /* we don't handle GLFW_REPEAT */
} });
glfwSetCursorPosCallback(_window, [](GLFWwindow* const window, const double x, const double y) {
void GlfwApplication::staticMouseMoveEvent(GLFWwindow* window, double x, double y) {
MouseMoveEvent e{window, Vector2i{Int(x), Int(y)}}; MouseMoveEvent e{window, Vector2i{Int(x), Int(y)}};
static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->mouseMoveEvent(e); static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->mouseMoveEvent(e);
} });
glfwSetScrollCallback(_window, [](GLFWwindow* window, double xoffset, double yoffset) {
void GlfwApplication::staticMouseScrollEvent(GLFWwindow* window, double xoffset, double yoffset) {
const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window)); const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)}); MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)});
@ -457,9 +396,8 @@ void GlfwApplication::staticMouseScrollEvent(GLFWwindow* window, double xoffset,
instance->mousePressEvent(e1); instance->mousePressEvent(e1);
} }
#endif #endif
} });
glfwSetCharCallback(_window, [](GLFWwindow* window, unsigned int codepoint) {
void GlfwApplication::staticTextInputEvent(GLFWwindow* window, unsigned int codepoint) {
const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window)); const auto instance = static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
if(!(instance->_flags & Flag::TextInputActive)) return; if(!(instance->_flags & Flag::TextInputActive)) return;
@ -468,10 +406,57 @@ void GlfwApplication::staticTextInputEvent(GLFWwindow* window, unsigned int code
const std::size_t size = Utility::Unicode::utf8(codepoint, utf8); const std::size_t size = Utility::Unicode::utf8(codepoint, utf8);
TextInputEvent e{{utf8, size}}; TextInputEvent e{{utf8, size}};
instance->textInputEvent(e); instance->textInputEvent(e);
});
}
GlfwApplication::~GlfwApplication() {
glfwDestroyWindow(_window);
glfwTerminate();
}
Vector2i GlfwApplication::windowSize() {
Vector2i size;
glfwGetWindowSize(_window, &size.x(), &size.y());
return size;
}
void GlfwApplication::setSwapInterval(const Int interval) {
glfwSwapInterval(interval);
} }
void GlfwApplication::staticErrorCallback(int, const char* description) { int GlfwApplication::exec() {
Error() << description; while(!glfwWindowShouldClose(_window)) {
if(_flags & Flag::Redraw) {
_flags &= ~Flag::Redraw;
drawEvent();
}
glfwPollEvents();
}
return 0;
}
auto GlfwApplication::MouseMoveEvent::buttons() -> Buttons {
if(!_buttons) {
_buttons = Buttons{};
for(const Int button: {GLFW_MOUSE_BUTTON_LEFT,
GLFW_MOUSE_BUTTON_MIDDLE,
GLFW_MOUSE_BUTTON_RIGHT}) {
if(glfwGetMouseButton(_window, button) == GLFW_PRESS)
*_buttons |= Button(1 << button);
}
}
return *_buttons;
}
auto GlfwApplication::MouseMoveEvent::modifiers() -> Modifiers {
if(!_modifiers) _modifiers = currentGlfwModifiers(_window);
return *_modifiers;
}
auto GlfwApplication::MouseScrollEvent::modifiers() -> Modifiers {
if(!_modifiers) _modifiers = currentGlfwModifiers(_window);
return *_modifiers;
} }
void GlfwApplication::viewportEvent(const Vector2i&) {} void GlfwApplication::viewportEvent(const Vector2i&) {}

9
src/Magnum/Platform/GlfwApplication.h

@ -467,14 +467,7 @@ class GlfwApplication {
typedef Containers::EnumSet<Flag> Flags; typedef Containers::EnumSet<Flag> Flags;
CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) CORRADE_ENUMSET_FRIEND_OPERATORS(Flags)
static void staticErrorCallback(int error, const char* description); void setupCallbacks();
static void staticViewportEvent(GLFWwindow* window, int w, int h);
static void staticKeyEvent(GLFWwindow* window, int key, int scancode, int action, int mod);
static void staticMouseEvent(GLFWwindow* window, int button, int action, int mods);
static void staticMouseMoveEvent(GLFWwindow* window, double x, double y);
static void staticMouseScrollEvent(GLFWwindow* window, double xoffset, double yoffset);
static void staticTextInputEvent(GLFWwindow* window, unsigned int codepoint);
GLFWwindow* _window{nullptr}; GLFWwindow* _window{nullptr};
Flags _flags; Flags _flags;

Loading…
Cancel
Save