2010-10-21 10 views
0
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 
     } 
    } 
} 

Cette fonction serait une fonction membre d'une classe, classe. L'autre fonction membre, IsDown, renvoie une valeur true si la clé en question est en panne et false si elle ne l'est pas.Ma logique de programmation est-elle correcte ici?

Pouvez-vous envisager une amélioration supplémentaire de cette fonction?

Merci

EDIT:

Je vais développer un peu à ce qui se fait pourquoi. C'est une modification d'un bit de code qui fonctionne à travers un tableau keyStates (qui était une structure de trois booléens) en définissant IsPressed sur false pour toutes les clés. puis, à nouveau, la valeur Ispressed est attribuée à la valeur de this-> IsDown, puis une troisième fois en vérifiant si la clé a été maintenue, si elle n'a plus la première pression, définissez-la sur false. si elle n'était pas maintenue enfoncée, appuyez d'abord sur pour confirmer et elle était également vraie, donc la prochaine fois, elle est signalée comme ayant été tenue.

EDIT2:

a ajouté quelques commentaires à code et corriger une ligne

+1

Ajouter des commentaires? À propos de ce que vous essayez de faire et pourquoi vous le faites de cette façon, et quelles sont les entrées et les sorties de votre fonction. – mouviciel

+0

Un peu hors sujet, mais de nombreuses API de clavier sont basées sur des événements, auquel cas vous pouvez simplement écouter les événements clés et mettre à jour le modèle dans ces événements. –

+0

@mouviciel, alors que je ne dirais pas que les commentaires ne sont pas du tout nécessaires. Ce code est assez explicite n'est-ce pas? clairement, il n'y a pas d'E/S. J'accepterais que le bitwise puisse faire des commentaires, sauf qu'un programmeur devrait probablement être capable de savoir ce que fait une opération au niveau du bit. – thecoshman

Répondre

1

Personnellement, je définirais les principaux états comme des états disjoints et écrire un simple machine d'état, ainsi:

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; 
     } 
    } 
} 

Il est plus facile d'étendre, et plus facile à lire si elle devient plus complexe.

+0

Je devrais vraiment cesser d'oublier les enums étant en C++ et pas seulement C#. J'apprécie cette solution, je fais de l'aide si vous considérez la première presse comme un état séparé à une prise répétée. IsDown est une fonction non un tableau btw, mais cela ne devrait pas faire de différence ici. – thecoshman

+0

+1 pour suggestion de machine d'état. – mouviciel

0

Vous définissez toujours IsFirstPress si la clé est en baisse, ce qui pourrait ne pas être ce que vous voulez.

0

Je ne suis pas sûr de ce que vous voulez atteindre avec IsFirstPress, car le keystate ne peut pas se souvenir des presses précédentes de toute façon. Si vous voulez marquer avec ce bit, que c'est la première fois que vous reconnaissez la clé en panne, alors votre logique est fausse dans l'instruction if correspondante.

keystates[i] & WasHeldDown est évalué à true si vous avez déjà défini le bit WasHeldDown précédemment pour ce keystate. Dans ce cas, ce que vous voulez faire est en fait de supprimer le bit IsFirstPress par xor-it: keystates[i] ^= IsFirstPress

+0

votre droite, je me suis trompé avec mon essayant de tourner de IsFirstPress. J'ai eu le code juste en train de l'allumer, mais je voulais juste le faire tourner, pas basculer. Corrigé ma question. – thecoshman