Better callbacks
This commit is contained in:
@@ -31,6 +31,86 @@ class GLFWError : public Error<GLFWError> {
|
||||
static const ErrorCodeMap ErrorMessages;
|
||||
};
|
||||
|
||||
class OGLWindow;
|
||||
|
||||
enum WindowCallbacks {
|
||||
KEY, CHAR, CHAR_MODS, MOUSE_BUTTON, CURSOR_POS, CURSOR_ENTER,
|
||||
SCROLL, DROP, WINDOW_POS, WINDOW_SIZE, WINDOW_CLOSE, WINDOW_REFRESH,
|
||||
WINDOW_FOCUS, WINDOW_ICONIFY, WINDOW_MAX, FRAMEBUFFER_SIZE, WINDOW_SCALE,
|
||||
};
|
||||
|
||||
template<WindowCallbacks>
|
||||
struct OGLWindowCallbacks;
|
||||
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::KEY> {
|
||||
using type = typename std::function<void(OGLWindow*, int, int, int, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::CHAR> {
|
||||
using type = typename std::function<void(OGLWindow*, unsigned int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::CHAR_MODS> {
|
||||
using type = typename std::function<void(OGLWindow*, unsigned int, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::CURSOR_ENTER> {
|
||||
using type = typename std::function<void(OGLWindow*, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::CURSOR_POS> {
|
||||
using type = typename std::function<void(OGLWindow*, double, double)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::MOUSE_BUTTON> {
|
||||
using type = typename std::function<void(OGLWindow*, int, int, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::SCROLL> {
|
||||
using type = typename std::function<void(OGLWindow*, double, double)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::DROP> {
|
||||
using type = typename std::function<void(OGLWindow*, int, const char**)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_POS> {
|
||||
using type = typename std::function<void(OGLWindow*, int, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_SIZE> {
|
||||
using type = typename std::function<void(OGLWindow*, int, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_CLOSE> {
|
||||
using type = typename std::function<void(OGLWindow*)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_REFRESH> {
|
||||
using type = typename std::function<void(OGLWindow*)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_FOCUS> {
|
||||
using type = typename std::function<void(OGLWindow*, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_ICONIFY> {
|
||||
using type = typename std::function<void(OGLWindow*, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_MAX> {
|
||||
using type = typename std::function<void(OGLWindow*, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::FRAMEBUFFER_SIZE> {
|
||||
using type = typename std::function<void(OGLWindow*, int, int)>;
|
||||
};
|
||||
template<>
|
||||
struct OGLWindowCallbacks<WindowCallbacks::WINDOW_SCALE> {
|
||||
using type = typename std::function<void(OGLWindow*, int)>;
|
||||
};
|
||||
|
||||
class OGLWindow {
|
||||
using GLFWHint = std::array<int, 2>;
|
||||
private:
|
||||
@@ -39,12 +119,6 @@ class OGLWindow {
|
||||
THROW(GLFWError(GLFWError::Codes::NOT_MAIN));
|
||||
}
|
||||
}
|
||||
template<typename... Args>
|
||||
using CallbackFuncType = void (*)(GLFWwindow*, Args...);
|
||||
template<typename... Args>
|
||||
struct CallbackSetterFuncType {
|
||||
typedef CallbackFuncType<Args...> (*type)(GLFWwindow*, CallbackFuncType<Args...>);
|
||||
};
|
||||
|
||||
protected:
|
||||
static std::atomic<unsigned int> _count;
|
||||
@@ -63,21 +137,14 @@ class OGLWindow {
|
||||
unsigned int,
|
||||
unsigned int,
|
||||
const std::string&,
|
||||
const std::vector<std::array<int, 2>>&,
|
||||
const std::vector<std::tuple<int, std::string>>&,
|
||||
const std::vector<std::array<int, 2>>& integerWindowHints,
|
||||
const std::vector<std::tuple<int, std::string>>& stringWindowHints={},
|
||||
GLFWwindow* sharingContext = NULL
|
||||
);
|
||||
GLFWwindow* makeCurrent() const;
|
||||
void detachWindow();
|
||||
|
||||
public:
|
||||
enum Callbacks {
|
||||
KEY, CHAR, CHAR_MODS, MOUSE_BUTTON, CURSOR_POS, CURSOR_ENTER,
|
||||
SCROLL, DROP, WINDOW_POS, WINDOW_SIZE, WINDOW_CLOSE, WINDOW_REFRESH,
|
||||
WINDOW_FOCUS, WINDOW_ICONIFY, WINDOW_MAX, FRAMEBUFFER_SIZE, WINDOW_SCALE,
|
||||
};
|
||||
template<typename... T>
|
||||
using CallbackFunc = void(*)(OGLWindow*, T...);
|
||||
|
||||
static inline bool IsGLFWInitialized() { return _glfwInitialized; }
|
||||
static bool InitGLFW(const std::vector<GLFWHint>& hints={});
|
||||
@@ -121,8 +188,84 @@ class OGLWindow {
|
||||
void setTitle(const std::string&);
|
||||
void shouldClose(bool);
|
||||
|
||||
template<enum Callbacks, typename Func>
|
||||
void setCallback(std::function<Func> callback);
|
||||
template<WindowCallbacks CallbackType, typename CallbackFunc>
|
||||
void setCallback(CallbackFunc callback) {
|
||||
CheckForMainThread();
|
||||
auto tmp = makeCurrent();
|
||||
static auto this_ptr = this;
|
||||
static typename OGLWindowCallbacks<CallbackType>::type tmp_callback = callback;
|
||||
if constexpr (CallbackType == KEY) {
|
||||
glfwSetKeyCallback(_window_ptr, [](GLFWwindow*, int a, int b, int c, int d){
|
||||
tmp_callback(this_ptr, a,b,c,d);
|
||||
});
|
||||
} else if constexpr (CallbackType == CHAR) {
|
||||
glfwSetCharCallback(_window_ptr, [](GLFWwindow*, int a) {
|
||||
tmp_callback(this_ptr, a);
|
||||
});
|
||||
} else if constexpr (CallbackType == CHAR_MODS) {
|
||||
glfwSetCharModsCallback(_window_ptr, [](GLFWwindow*, unsigned int a, int b) {
|
||||
tmp_callback(this_ptr, a, b);
|
||||
});
|
||||
} else if constexpr (CallbackType == CURSOR_ENTER) {
|
||||
glfwSetCursorEnterCallback(_window_ptr, [](GLFWwindow*, int a) {
|
||||
tmp_callback(this_ptr, a);
|
||||
});
|
||||
} else if constexpr (CallbackType == CURSOR_POS) {
|
||||
glfwSetCursorPosCallback(_window_ptr, [](GLFWwindow*, double a, double b){
|
||||
tmp_callback(this_ptr, a,b);
|
||||
});
|
||||
} else if constexpr (CallbackType == MOUSE_BUTTON) {
|
||||
glfwSetMouseButtonCallback(_window_ptr, [](GLFWwindow*, int a, int b, int c){
|
||||
tmp_callback(this_ptr, a,b,c);
|
||||
});
|
||||
} else if constexpr (CallbackType == SCROLL) {
|
||||
glfwSetScrollCallback(_window_ptr, [](GLFWwindow*, double a, double b) {
|
||||
tmp_callback(this_ptr, a,b);
|
||||
});
|
||||
} else if constexpr (CallbackType == DROP) {
|
||||
glfwSetDropCallback(_window_ptr, [](GLFWwindow*, int a, const char** b) {
|
||||
tmp_callback(this_ptr, a, b);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_POS) {
|
||||
glfwSetWindowPosCallback(_window_ptr, [](GLFWwindow*, int a, int b){
|
||||
tmp_callback(this_ptr, a,b);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_SIZE) {
|
||||
glfwSetWindowSizeCallback(_window_ptr, [](GLFWwindow*, int a, int b){
|
||||
tmp_callback(this_ptr, a,b);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_CLOSE) {
|
||||
glfwSetWindowCloseCallback(_window_ptr, [](GLFWwindow*){
|
||||
tmp_callback(this_ptr);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_REFRESH) {
|
||||
glfwSetWindowRefreshCallback(_window_ptr, [](GLFWwindow*){
|
||||
tmp_callback(this_ptr);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_FOCUS) {
|
||||
glfwSetWindowFocusCallback(_window_ptr, [](GLFWwindow*, int a) {
|
||||
tmp_callback(this_ptr, a);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_ICONIFY) {
|
||||
glfwSetWindowIconifyCallback(_window_ptr, [](GLFWwindow*, int a) {
|
||||
tmp_callback(this_ptr, a);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_MAX) {
|
||||
glfwSetWindowMaximizeCallback(_window_ptr, [](GLFWwindow*, int a) {
|
||||
tmp_callback(this_ptr, a);
|
||||
});
|
||||
} else if constexpr (CallbackType == FRAMEBUFFER_SIZE) {
|
||||
glfwSetFramebufferSizeCallback(_window_ptr, [](GLFWwindow*, int a, int b) {
|
||||
tmp_callback(this_ptr, a, b);
|
||||
});
|
||||
} else if constexpr (CallbackType == WINDOW_SCALE) {
|
||||
glfwSetWindowContentScaleCallback(_window_ptr, [](GLFWwindow*, int a, int b) {
|
||||
tmp_callback(this_ptr, a, b);
|
||||
});
|
||||
} else {
|
||||
static_assert(false, "No matching callback.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user