界面&实施困境?

时间:2014-07-04 05:10:03

标签: c++ macros glfw

目前,在我正在进行的游戏中,我有一个窗口类:

class UserWindow{
    *interface here*
};

我已经竭尽全力避免暴露此窗口的实现细节;特别是它在引擎盖下使用GLFW的事实。在我最终最终删除/替换它的情况下,我不想向客户端暴露任何GLFW。一切都很好,直到我最终处理窗口的键输入。你看,GLFW使用宏来识别密钥,如下所示:

auto GLFWKeyPressCallback(GLFWwindow* wind, int key, int, int, int) -> void {
    if(key == GLFW_KEY_???)
        *do stuff*
} 

正如大多数C ++程序员所知,宏是有毒的,应该避免。这里的问题是我提供了一个UserWindowEventListener接口,供用户连接和接收事件。问题是,如何在不暴露整个GLFW API本身的情况下公开这些GLFW键的标识符?由于GLFW使用前面提到的(邪恶的)宏来识别它们,它们会渗透到全局命名空间中,这破坏了拥有内部"命名空间。我想到的唯一的另一个解决方案就是拥有一个简单的ol'包含每个键的静态整数的struct,并将它们分配到.cpp文件中,如下所示:

.HPP:

struct UserWindowKey{
    static const int up, down, left, right... (repeat ad nauseam)   
};

的.cpp:

const int UserWindowKey::up = GLFW_KEY_UP...

然而,这看起来很乏味,难以管理,而且通常感觉就像是糟糕的做法。有什么想法吗?

编辑:psuedocode中的一些实现细节,以消除任何含糊之处:

UserWindow:

//constructor
UserWindow(){
    //key_func just fires the signal that's in the event handler below.
    glfwSetKeyCallback(window_handle, key_func);
}

UserWindowEventListener:

struct UserWindowEventListener{
    key_signal_type key_signal;
};

用法:

auto main() -> int {
    UserWindow wind;
    wind.event_listener.key_signal.connect(*MY_FUNC*);
    wind.event_listener.poll();
}

1 个答案:

答案 0 :(得分:2)

我会创建一个中间方法,将GLFW键转换为您自己的键,以您感觉舒适且感觉清醒的方式定义。就个人而言,我会像这样列举:

enum MyKeys
{
    UP,
    DOWN,
    LEFT,
    RIGHT,
    // the rest
}

然后用户会为您提供回调,并且您将为GLFW提供不同的回调。当GLFW调用您的回调时,您将密钥转换为公共枚举,然后触发用户提供的回调。

回调的伪代码可能类似于:

auto GLFWKeyPressCallback(GLFWwindow* wind, int glfwKey, int a, int b, int c) -> void
{
    auto myKey = ConvertGlfwKeyToMyKey(glfwKey);
    user_callback(myKey, a, b, c);
}

user_callback签名看起来像:

void user_callback(MyKeys, int, int, int);

ConvertGlfwKeyToMyKey可能如下所示:

MyKeys ConvertGlfwKeyToMyKey(glfwKey)
{
    switch (glfwKey)
    {
    case GLFW_KEY_UP:
        return MyKeys.UP;
    case GLFW_KEY_DOWN:
        return MyKeys.DOWN;
    // the rest
    }
}

这个系统的明显缺点是你必须经历并填写转换功能。优点是你已经从用户那里抽象掉了所有的GLFW内容,而不必使用任何宏或用一堆结构污染你的代码。

或者,您可以选择一些其他机制将GLFW键映射到MyKeys。如果GLFW键覆盖范围内的所有值,您可以按相同的顺序对枚举进行排序,然后从GLFW int到枚举进行偏移和类型转换。