我的编程逻辑在这里是否正确?

时间:2010-10-21 14:36:26

标签: algorithm language-agnostic optimization

const char IsPressed = 1; // 1
const char WasHeldDown = 2; // 10
const char IsFirstPress = 4; // 100

char* keystates[256];

Class::CalculateKeyStates()
{
    for(int i = 0; i < 256; ++i)
    {
        if(this->IsDown(i))
        {
            keystates[i] |= IsPressed; // turn on
            if(keystates[i] & WasHeldDown)
            {
                //keystates[i] |= IsFirstPress;
                keystates[i] &= ~IsFirstPress; // turn off
            }
            else
            {
                keystates[i] |= WasHeldDown + IsFirstPress; // Turn on
            }
        }
        else
        {
            keystates[i] = 0; // Turn ALL off
        }
    }
}

此函数将是类Class的成员函数。如果有问题的密钥是关闭的话,另一个成员函数IsDown将返回true,否则返回false。

你能看到进一步改进这项功能的方法吗?

由于

编辑:

我将扩展一下为什么要做的事情。这是对通过数组keyStates(这是三个bool的结构)的一些代码的修改,将所有键的IsPressed设置为false。然后再次将Ispressed设置为this-&gt; IsDown的值,然后第三次循环检查键是否已被保持,如果它已经不再是第一次按下则将其设置为false。如果它没有被按下,那么先设置为true并保持为true,所以下次它被标记为已被保持。

EDIT2:

为代码添加了一些注释并更正了一行

3 个答案:

答案 0 :(得分:1)

就个人而言,我会将关键状态定义为不相交状态并编写一个简单的状态机,因此:

enum keystate
{
    inactive,
    firstPress,
    active
};

keystate keystates[256];

Class::CalculateKeyStates()
{
    for (int i = 0; i < 256; ++i)
    {
        keystate &k = keystates[i];

        switch (k)
        {
        inactive:
            k = (isDown(i)) ? firstPress : inactive;
            break;
        firstPress:
            k = (isDown(i)) ? active : inactive;
            break;
        active:
            k = (isDown(i)) ? active : inactive;
            break;
        }
    }
}

如果它变得更复杂,这更容易扩展,更容易阅读。

答案 1 :(得分:0)

如果密钥已关闭,您总是设置IsFirstPress,这可能不是您想要的。

答案 2 :(得分:0)

我不确定你想要用IsFirstPress实现什么,因为关键状态无论如何都记不起任何先前的印刷机。如果你想用这个位标记,那是你第一次认识到关键是关闭的,那么你的逻辑在相应的if语句中是错误的。

如果您之前已为此关键状态设置了位keystates[i] & WasHeldDown,则

WasHeldDown的计算结果为true。 在这种情况下,您可能想要做的是通过xor-it删除IsFirstPress位:keystates[i] ^= IsFirstPress