iterate enumeration

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
A.D.
User
User
Posts: 98
Joined: Tue Oct 06, 2009 9:11 pm

iterate enumeration

Post by A.D. »

i wish we could iterate enumerations like this:

Code: Select all

 
Enumeration Gadgets
 #GadgetInfo 
 #GadgetText 
 #GadgetOK  
EndEnumeration
  
ForEach Gadgets
 Debug "enumeration value: " + #PB_Compiler_EnumerationValue
Next  
Repeat
PureBasic
ForEver
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Re: iterate enumeration

Post by wombats »

Out of interest, what would this be useful for?
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: iterate enumeration

Post by Dude »

A.D. wrote:i wish we could iterate enumerations like this:

Code: Select all

Enumeration Gadgets
 #GadgetInfo 
 #GadgetText 
 #GadgetOK  
EndEnumeration
  
ForEach Gadgets
 Debug "enumeration value: " + #PB_Compiler_EnumerationValue
Next  
You can already do it:

Code: Select all

Enumeration
  #GadgetInfo
  #GadgetText
  #GadgetOK 
EndEnumeration

For v = #GadgetInfo To #GadgetOK
  Debug "enumeration value: " + v
Next
User avatar
A.D.
User
User
Posts: 98
Joined: Tue Oct 06, 2009 9:11 pm

Re: iterate enumeration

Post by A.D. »

Code: Select all

For v = #GadgetInfo To #GadgetOK
  Debug "enumeration value: " + v
Next
That's not what i want to do. I want to enumerate each Enumerationlist i want to with ForEach Enumerationlist!
Repeat
PureBasic
ForEver
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: iterate enumeration

Post by Dude »

A.D. wrote:I want to enumerate each Enumerationlist i want to with ForEach Enumerationlist!
Maybe I misunderstood. Didn't you want to show what the enumerated value of each constant was?
User avatar
A.D.
User
User
Posts: 98
Joined: Tue Oct 06, 2009 9:11 pm

Re: iterate enumeration

Post by A.D. »

well, i'm not sure if my request is really needed as it can be done with a simple loop like you said. (i just wanted to iterate trough every gadget)
Repeat
PureBasic
ForEver
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Re: iterate enumeration

Post by wombats »

Since you are the one creating the gadgets, can't you just store their numbers in a list and iterate through that?
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: iterate enumeration

Post by TI-994A »

A.D. wrote:...i just wanted to iterate trough every gadget
Assuming that the named enumerations consist of valid PureBasic objects, this might do the trick:

Code: Select all

Enumeration Windows
  #Window1
  #Window2
EndEnumeration

Enumeration Gadgets
  #Gadget1
  #Gadget2
  #Gadget3
EndEnumeration

Enumeration Fonts
  #Font1
  #Font2
  #Font3
  #Font4
EndEnumeration

Enumeration Images
  #Image1
  #Image2
  #Image3
  #Image4
  #Image5
EndEnumeration

Macro NextEnumeration(e, name)
  Enumeration name 
  EndEnumeration
  e = #PB_Compiler_EnumerationValue
EndMacro

Procedure EnumerateGroup(objectType.s, lastEnumeration)
  Debug objectType + ":"
  For i = 0 To lastEnumeration
    Select objectType
      Case "windows":        
        If IsWindow(i)
          Debug "#Window" + Str(i + 1) + " is in use."
        EndIf
      Case "gadgets": 
        If IsGadget(i)
          Debug "#Gadget" + Str(i + 1) + " is in use."
        EndIf        
      Case "fonts":        
        If IsFont(i)
          Debug "#Font" + Str(i + 1) + " is in use."
        EndIf        
      Case "images":
        If IsImage(i)
          Debug "#Image" + Str(i + 1) + " is in use."
        EndIf        
    EndSelect    
  Next i      
  Debug "---"
EndProcedure

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#Window2, 0, 0, 300, 50, "Named Enumerations", wFlags)
ButtonGadget(#Gadget1, 10, 10, 135, 30, "Gadget 1")
ButtonGadget(#Gadget3, 155 , 10, 135, 30, "Gadget 3")
LoadFont(#Font2, "Arial", 10)
LoadFont(#Font4, "Arial", 10)
CreateImage(#Image2, 10, 10)
CreateImage(#Image5, 10, 10)
CreateImage(#Image1, 10, 10)

NextEnumeration(x, Windows)
EnumerateGroup("windows", x)
NextEnumeration(x, Fonts)
EnumerateGroup("fonts", x)
NextEnumeration(x, Images)
EnumerateGroup("images", x)
NextEnumeration(x, Gadgets)
EnumerateGroup("gadgets", x)

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
#NULL
Addict
Addict
Posts: 1497
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: iterate enumeration

Post by #NULL »

A.D. wrote:i wish we could iterate enumerations like this:

Code: Select all

 
Enumeration Gadgets
 #GadgetInfo 
 #GadgetText 
 #GadgetOK  
EndEnumeration
  
ForEach Gadgets
 Debug "enumeration value: " + #PB_Compiler_EnumerationValue
Next  
+1
User avatar
Sicro
Enthusiast
Enthusiast
Posts: 559
Joined: Wed Jun 25, 2014 5:25 pm
Location: Germany
Contact:

Re: iterate enumeration

Post by Sicro »

A.D. wrote:i wish we could iterate enumerations like this:

Code: Select all

 
Enumeration Gadgets
 #GadgetInfo 
 #GadgetText 
 #GadgetOK  
EndEnumeration
  
ForEach Gadgets
 Debug "enumeration value: " + #PB_Compiler_EnumerationValue
Next  
The enumeration block no longer exists after compilation.

To make iteration of the constants of an enumeration block possible at runtime, the compiler would have to insert this enumeration block into the compiled program as a list. The PB compiler simply processes the code from top to bottom and doesn't look ahead, so it would always have to insert the list into the compiled program, which is an unnecessary ballast if you don't iterate through an enumeration block in the later code.

At compile time, however, the compiler could do the following:

Code: Select all

ForEach Gadgets
 Debug "enumeration value: " + #PB_Compiler_EnumerationValue
Next
will be converted to:

Code: Select all

Debug "enumeration value: " + #GadgetInfo
Debug "enumeration value: " + #GadgetText
Debug "enumeration value: " + #GadgetOK
This variant would be fine, because no additional list of the enumeration block has to be created and integrated into the compiled program.
Image
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
#NULL
Addict
Addict
Posts: 1497
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: iterate enumeration

Post by #NULL »

Code: Select all

For v = #GadgetInfo To #GadgetOK
  Debug "enumeration value: " + v
Next
Doesn't work with irregular enums like this one:

Code: Select all

Enumeration enum
  #a    ; 0
  #b=10
  #c=10
  #d=5
  #ee   ; 6
EndEnumeration
The feature would be almost useless if we don't get also the constant name (as a string or whatever). Otherwise you could only check if a value is part of the enum set, but I would want to use it for debugging like printing the 'name' of an integer etc., I used manual name/string lists or arrays sometimes as well as the manual integer loop, but it's error prone.
<edit>
If the compiler could just generate a stringyfied list of enum names and values that would be fine. Any loop could be done with that then at runtime. But named enums can be expanded later and the compiler never knows if that's still going to happen during compilation.
Cyllceaux
Enthusiast
Enthusiast
Posts: 510
Joined: Mon Jun 23, 2014 1:18 pm

Re: iterate enumeration

Post by Cyllceaux »

I use this :)

Code: Select all


Macro IteraEnum(enum,const,val=)
	Enumeration enum
		const val
	EndEnumeration
	CompilerIf Not Defined(enum,#PB_List)
		Global NewList enum()
	CompilerEndIf
	AddElement(enum())
	enum()=#PB_Compiler_EnumerationValue - 1
EndMacro

IteraEnum(_t2,#bla1)
IteraEnum(_t2,#bla2,=2)
IteraEnum(_t2,#bla3)

ForEach _t2()
	Debug _t2()
Next

Debug #bla2

You can make a Map or a Runtime-Enum. Works with every kind of Enums and Enumvalues.

Code: Select all

IteraEnum(_t2,#bla2,= 1 << 1 )
workes, too.
User avatar
mk-soft
Always Here
Always Here
Posts: 6207
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: iterate enumeration

Post by mk-soft »

Another way... :wink: (viewtopic.php?f=12&t=66856)

Code: Select all

;-TOP

DeclareModule System
  Declare GetParentWindowID(Gadget)
  Declare GetGadgetList(List Gadgets(), WindowID=0)
EndDeclareModule

; ---------------------------------------------------------------------------------------
Module System
  
  EnableExplicit
  
  ;-- Import internal function
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Import ""
      PB_Object_EnumerateStart( PB_Objects )
      PB_Object_EnumerateNext( PB_Objects, *ID.Integer )
      PB_Object_EnumerateAbort( PB_Objects )
      PB_Object_GetObject( PB_Object , DynamicOrArrayID)
      PB_Window_Objects.i
      PB_Gadget_Objects.i
      PB_Image_Objects.i
      ;PB_Font_Objects.i
    EndImport
  CompilerElse
    ImportC ""
      PB_Object_EnumerateStart( PB_Objects )
      PB_Object_EnumerateNext( PB_Objects, *ID.Integer )
      PB_Object_EnumerateAbort( PB_Objects )
      PB_Object_GetObject( PB_Object , DynamicOrArrayID)
      PB_Window_Objects.i
      PB_Gadget_Objects.i
      PB_Image_Objects.i
      ;PB_Font_Objects.i
    EndImport
  CompilerEndIf
  
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    ; PB Interne Struktur Gadget MacOS
    Structure sdkGadget
      *gadget
      *container
      *vt
      UserData.i
      Window.i
      Type.i
      Flags.i
    EndStructure
  CompilerEndIf
  
  ; ---------------------------------------------------------------------------------------
  
  Procedure GetParentWindowID(Gadget)
    Protected GadgetID, GadgetWindowID
    
    If IsGadget(Gadget)
      CompilerSelect #PB_Compiler_OS
        CompilerCase #PB_OS_MacOS
          Protected *Gadget.sdkGadget = IsGadget(Gadget)
          GadgetWindowID = WindowID(*Gadget\Window)
        CompilerCase #PB_OS_Linux
          GadgetID = GadgetID(Gadget)
          GadgetWindowID = gtk_widget_get_toplevel_ (GadgetID)
        CompilerCase #PB_OS_Windows
          GadgetID = GadgetID(Gadget)
          GadgetWindowID = GetAncestor_(GadgetID, #GA_ROOT)
      CompilerEndSelect
    EndIf
    ProcedureReturn GadgetWindowID
  EndProcedure
  
  ; ---------------------------------------------------------------------------------------
  
  Procedure GetGadgetList(List Gadgets(), WindowID=0)
    Protected object
    ClearList(Gadgets())
    PB_Object_EnumerateStart(PB_Gadget_Objects)
    While PB_Object_EnumerateNext(PB_Gadget_Objects, @object)
      If WindowID = 0 Or GetParentWindowID(object) = WindowID
        AddElement(Gadgets())
        Gadgets() = object
      EndIf
    Wend
    ProcedureReturn ListSize(Gadgets())
  EndProcedure
  
  ; ---------------------------------------------------------------------------------------
  
EndModule

;-Test

UseModule System

Global NewList Gadgets()

; Zeigt mögliche Flags des ButtonGadget in Aktion...
If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(0, 10, 10, 200, 20, "Standard Button")
  ButtonGadget(1, 10, 40, 200, 20, "Left Button", #PB_Button_Left)
  ButtonGadget(2, 10, 70, 200, 20, "Right Button", #PB_Button_Right)
  ButtonGadget(3, 10,100, 200, 60, "Multiline Button  (längerer Text wird automatisch umgebrochen)", #PB_Button_MultiLine)
  ;ButtonGadget(4, 10,170, 200, 20, "Toggle Button", #PB_Button_Toggle)
  ButtonGadget(#PB_Any, 10,170, 200, 20, "Toggle Button", #PB_Button_Toggle)
  
  cnt = GetGadgetList(Gadgets());, WindowID(0))
  Debug "Count of gadgets = " + cnt
  ForEach Gadgets()
    Debug "Gadget-Number = " + Gadgets() + " / Text = " + GetGadgetText(Gadgets())
  Next
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: iterate enumeration

Post by Bisonte »

I like the code of Cyllceaux, but it's useless if you need several enumerations. Therefore the whole thing with maps :

Code: Select all

Macro DoubleQuote
  "  
EndMacro
Macro iEnum(EnumerationName, Constant, Value=)
  Enumeration EnumerationName#Enum
    Constant Value
  EndEnumeration
  CompilerIf Not Defined(LastEnum, #PB_Map)
    Global NewMap LastEnum()
  CompilerEndIf
  LastEnum(Trim(DoubleQuote#EnumerationName#DoubleQuote)) = #PB_Compiler_EnumerationValue - 1
EndMacro

iEnum(Gadget, #a, = 1)
iEnum(Gadget, #b)
iEnum(Gadget, #c)
iEnum(Gadget, #d)

iEnum(Window, #wa)
iEnum(Window, #wb)

Debug LastEnum("Gadget")
Debug LastEnum("Window")
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
User avatar
mk-soft
Always Here
Always Here
Posts: 6207
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: iterate enumeration

Post by mk-soft »

Everything's too expensive. Is a question of declaration...

Code: Select all

Enumeration Gadgets
  #BeginOfGadget
  #Gadget1
  #Gadget2
  #Gadget3
  #EndOfGadget
EndEnumeration

For i = #BeginOfGadget + 1 To #EndOfGadget - 1
  Debug i
Next
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply