我正在尝试在GLFW窗口的包装类上实现更好的键状态检测。我需要确保,如果将我的键状态持续设置为按下状态,则某些操作将不会重新触发。因此,我总结了上升,下降,地板和天花板边缘触发器的想法。问题是,我不一定在代码的所有编译部分上都需要所有触发器。所以我想出了以下解决方案:
class Window{
public:
GLFWwindow *m_window_ptr = nullptr;
//...
bool isKeyPressed(int key) const{
return glfwGetKey(m_window_ptr, key) == GLFW_PRESS;
}
bool isKeyReleased(int key) const{
return glfwGetKey(m_window_ptr, key) == GLFW_RELEASE;
}
enum class KeyState {
pressed,
released
};
enum class SignalEdge {
rising,
falling,
floor,
ceiling,
};
template<int key_t>
SignalEdge getKeyState() {
static KeyState last_key_state = KeyState::released;
switch (last_key_state) {
case KeyState::released:
if (isKeyPressed(key_t)) {
last_key_state = KeyState::pressed;
return SignalEdge::rising;
} else {
return SignalEdge::floor;
}
break;
case KeyState::pressed:
if (isKeyReleased(key_t)) {
last_key_state = KeyState::released;
return SignalEdge::falling;
} else {
return SignalEdge::ceiling;
}
break;
}
}
template<int key_t>
bool isKeyRisingEdge() {
return getKeyState<key_t>() == SignalEdge::rising;
}
};
仅意识到I'll need this per window object,所以每个getKeyState模板实例化内的静态变量将应用于GLFW中的每个窗口。
那么,我避免这种情况的唯一方法是针对每个模板化的键类型使用成员变量,但是我不想花费精力来映射类中的每个键类型,而只是为每个键类型设置一个状态变量。我想自动将每个对象的变量映射到给定模板函数的存在,即正是我在这里设置的,但是每个GLFW窗口对象保存状态的位置。
如果我省去了手动映射GLFW枚举int的问题,我不确定该怎么做,我想到了variable templates,但我也没有看到前进的道路(我将如何获得一个变量仅存在于函数的模板实例中?)。我看到的唯一另一个选择是将动态分配的状态数组 as 作为成员函数静态变量存储,在内部为每个用于索引到静态变量数组的窗口对象存储一个递增的索引,或者执行相反的操作与功能,但似乎很乱?我还有其他方法可以在编译时使用模板吗?