Burst bits field management (masks management)

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Burst bits field management (masks management)

Post by Olli »

Let's see the procedure previewed by two schemes

Sch.1 : VarName & Designation
S : masks Support record
C : operation Code
M : specific Mask (binary pattern) (ex : 101001011 to threat b0, b1, b3, b6 and b8)

Sch.2 : Op Code & Designation
0 : Set mask to logical 0
1 : Set mask to logical 1
2 : Get mask logical value (non exclusive result)
3 : Toggle mask logical value

Code: Select all

Procedure Mask(S, C, M)
  C + 1
  D = Bool(S & M)
  If C = 3
   S = D
  Else
   S = (S & ~M) | (((D ! Bool(C & 4) ) | Bool(C & 2) & Not(C & 1) ) * M)
  EndIf
  ProcedureReturn S
EndProcedure
Short example :

Code: Select all

WinFlag = Mask(WinFlag, 1, #PB_Window_SystemMenu) ; will set pb window system menu flag to logical 1
Note : a more explicit and complete source code is available on the bottom of this message.







Very brieve history
There is Michel Marchand who wondered this behaviour here.

ListIconCheckbox(Gadget, Element, Code = 0)
ListIconSelection(Gadget, Element, Code = 0)

The 1st procedure returns the status of a ListIconGadget checkbox.
Plus, the status can be changed in adding the 3rd argument (code) :

0 = get the binary status
1 = set to zero
2 = set to one
4 = set to the binary opposite status

Natively better.

Code: Select all

Procedure ListIconCheckbox(G, E, C = 0)
 Chk = #PB_ListIcon_Checked
 S = GetGadgetItemState(G, E)
  D = Bool(S & Chk)
  If C & 7
   D = (D ! Bool(C & 4) ) | Bool(C & 2) & Not(C & 1)
   SetGadgetItemState(G, E, (S & ~Chk) | (D * Chk) )
  EndIf
  ProcedureReturn D
EndProcedure
By modifying the Chk value, the list icon selection can follow the same management through the 2nd procedure :

Code: Select all

Procedure ListIconSelection(G, E, C = 0)
 Chk = #PB_ListIcon_Selected
 S = GetGadgetItemState(G, E)
  D = Bool(S & Chk)
  If C & 7
   D = (D ! Bool(C & 4) ) | Bool(C & 2) & Not(C & 1)
   SetGadgetItemState(G, E, (S & ~Chk) | (D * Chk) )
  EndIf
  ProcedureReturn D
EndProcedure
By generalizing this procedure, nesting Chk variable in the procedure arguments template, we get this :

Code: Select all

Procedure GadgetItemState(G, E, C, Chk)
  S = GetGadgetItemState(G, E)
  D = Bool(S & Chk)
  If C & 7
   D = (D ! Bool(C & 4) ) | Bool(C & 2) & Not(C & 1)
   SetGadgetItemState(G, E, (S & ~Chk) | (D * Chk) )
  EndIf
  ProcedureReturn D
EndProcedure
And by generalizing again... (same op codes as the previewing procedures : 0=get, 1=set0, 2=set1 and 4=toggle)

Code: Select all

Procedure GeneralMask(S, C, M)
  D = Bool(S & M)
  S = D
  If C & 7
   S = (S & ~M) | (((D ! Bool(C & 4) ) | Bool(C & 2) & Not(C & 1) ) * M)
  EndIf
  ProcedureReturn S
EndProcedure
The final procedure is on the top.

Note : it is equivalent to this (added op code #4, #5 and #6) :

Code: Select all

Procedure Mask(S, C, M)
 Select C
   Case 0: S & ~M
   Case 1: S | M
   Case 2: S = Bool(S & M) ; non exclusive result (only a 1-bit set returns a logical one else zero)
   Case 3: S ! M
   Case 4: S = Not((S & M) - M) ; exclusive result (all the bits of the mask must be set to cause a logical one else zero)
   Case 5: S = Bool(S & M) ! Mask(S, 4, M) ; mask error (1) or valid mask (0)
   Case 6: S = (- Mask(S, 5, M) << 1) ! Mask(S, 2, M) 
 EndSelect
 ProcedureReturn S
EndProcedure
If a mask contains more than one lonely bit, the case #5 can be used to check if all the bits have the same logical value.

Case #6 : complete process of a mask read.
1 : all the bits are set (logical 1)
0 : all the bits are reset (logical 0)
-1 : mask error (mask bits differ between themselves)