[TUTO] Utiliser les flags
Publié : jeu. 22/déc./2016 18:50
Bonjour à tous,
Les flags (drapeaux, en français) sont largement utilisés par les fonctions de PureBASIC, par exemple avec OpenWindow() pour centrer une fenêtre et en même temps la mettre en plein écran. Ils permettent donc de spécifier certaines propriétés en n'utilisant qu'une seule variable.
Mais comment cela fonctionne-t-il ?
Pour arriver à cela, il va cependant falloir respecter quelques règles.
Nous pensons en base 2. On démarre du bit de poids faible 0 jusqu'au bit de poids fort 31. En décimal cela donne : Un manière plus simple est de le faire en hexadécimal, $1, $2, $4, $8 par 4 octets
Ou en utilisant une énumération binaire
2) Mettre une ou plusieurs valeurs, sans écraser les autres, par exemple pour passer vos flags à une fonction, se fait avec le OU logique (OR), opérateur "|" en PB.
Le OU logique se comprend avec une table de vérité.
Exemple avec 2 valeurs : Cet opérateur permet donc de ne modifier qu'un bit à la fois, sans altérer les autres.
3) Lire un flag, c'est à dire lire la valeur d'un bit spécifique.
Pour ce faire nous allons utiliser le ET logique (AND), opérateur "&" en PB. Voici sa table de vérité : La sortie n'est à 1 que si les deux entrées sont à 1.
Exemple :
Et si on veux maintenant modifié l'état d'un flags et le placer à 0, comment faire?
Pour cela nous allons utiliser l'opérateur AND (&) ainsi que l'opérateur NOT (~) comme ceci
L'opérateur not va inversé tous les bits
Donc tous les bits à 1 seront simplement copiés avec l'opérateur ET le bit à 0 sera quant à lui mit à 0.
Exemple complet:
Voila, j'espère que ce petit tuto vous sera utile.
Merci à majikeyric et djes pour leurs remarques et corrections
Les flags (drapeaux, en français) sont largement utilisés par les fonctions de PureBASIC, par exemple avec OpenWindow() pour centrer une fenêtre et en même temps la mettre en plein écran. Ils permettent donc de spécifier certaines propriétés en n'utilisant qu'une seule variable.
Mais comment cela fonctionne-t-il ?
- Un flag peut avoir pour valeur 0 ou 1.
- Un entier long (.l) est codé sur 4 octets, soit 32 bits
Pour arriver à cela, il va cependant falloir respecter quelques règles.
- La valeur de nos constantes doit être codée sur un seul bit des 32 bits.
- Il faudra veiller à ne pas écraser la valeur de la variable, on ne pourra donc pas utiliser l'affectation =
Nous pensons en base 2. On démarre du bit de poids faible 0 jusqu'au bit de poids fort 31. En décimal cela donne :
Code : Tout sélectionner
#Flag_0 = 1 ; = %1 en binaire (bit 0 fixé)
#Flag_1 = 2 ; = %10 (bit 1)
#Flag_2 = 4 ; = %100 (bit 2)
#Flag_3 = 8 ; = %1000 (bit 3)
#Flag_4 = 16 ; = %10000 (bit 4)
#Flag_5 = 32 ; = %100000 (bit 5)
#Flag_6 = 64 ; = %1000000 (bit 6)
#Flag_7 = 128 ; = %10000000 (bit 7)
#Flag_8 = 256 ; = %100000000 (bit 8)
; Etc...
Code : Tout sélectionner
#Flag_0 = $0001 (bit 0 fixé)
#Flag_1 = $0002 (bit 1)
#Flag_2 = $0004 (bit 2)
#Flag_3 = $0008 (bit 3)
#Flag_4 = $0010 (bit 4)
#Flag_5 = $0020 (bit 5)
#Flag_6 = $0040 (bit 6)
#Flag_7 = $0080 (bit 7)
#Flag_8 = $0100 (bit 8)
; etc...
Code : Tout sélectionner
EnumerationBinary
#Flags1 ; égale à 1
#Flags2 ; égale à 2
#Flags3 ; égale à 4
#Flags4 ; égale à 8
#Flags5 ; égale à 16
EndEnumeration
Code : Tout sélectionner
mesFlags = #Flag_0 | #Flag_6 ;(= %01000001 en binaire ou $0041 en hexa ou 65 en décimal)
Exemple avec 2 valeurs :
Code : Tout sélectionner
A B SORTIE
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1
3) Lire un flag, c'est à dire lire la valeur d'un bit spécifique.
Pour ce faire nous allons utiliser le ET logique (AND), opérateur "&" en PB. Voici sa table de vérité :
Code : Tout sélectionner
A B SORTIE
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1
Exemple :
Code : Tout sélectionner
mesFlags = #Flag_0 | #Flag_6
If mesFlags & #Flag_6
Debug "Le bit 6 est à 1"
EndIf
If mesFlags & #Flag_3
Debug "Le bit 3 est à 1"
Else
Debug "Le bit 3 est à 0"
EndIf
Pour cela nous allons utiliser l'opérateur AND (&) ainsi que l'opérateur NOT (~) comme ceci
Code : Tout sélectionner
mesFlags =mesFlags &~#Flags3
Code : Tout sélectionner
0000 0000 0010 0000 ; #Flag5 (32 en décimal)
1111 1111 1101 1111 ;devient après le NOT
Exemple complet:
Code : Tout sélectionner
EnumerationBinary
#Flags0 ; égale à 1
#Flags1 ; égale à 2
#Flags2 ; égale à 4
#Flags3 ; égale à 8
#Flags4 ; égale à 16
#Flags5 ; égale à .32
#Flags6 ;égale à 64
#Flags7 ;égale à 128
EndEnumeration
Global mesFlags .l
Procedure Lit()
For i=0 To 7
p.l=Pow(2,i)
If(mesFlags &p)
Debug "Le flags "+Str(i)+" est à 1"
Else
Debug "Le flags "+Str(i)+" est à 0"
EndIf
Next
EndProcedure
; Ici j'active le Flag 1,3 et 5
mesFlags =#Flags1|#Flags3|#Flags5
; Lecture des flags pour voir le résultat
Lit()
; ici je vai placer le flag 3 à 0
mesFlags =mesFlags &~#Flags3
; Lecture des flags pour voir le résultat
Lit()
Merci à majikeyric et djes pour leurs remarques et corrections
