Enumeration etiquette

Just starting out? Need help? Post your questions and find answers here.
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Enumeration etiquette

Post by Zach »

Just curious how other programmers handle Enumeration of Constants, for things like Gadgat/Window ID's etc..

Are there some things you avoid Enumerating? If so, why?


Since I've been working on the GUI portion of my game engines World Editor tool, I have realized that I will have/need a lot of constants.
I don't have very many right now, although I did go back and re-establish some naming rules for myself to make it easier to type & recognize them.

I feel it would be easier when referring to constants by name, than an arbitrary number as I would end up backtracking all the time to look something up and see what it does. So I am thinking I want to also Enumerate my MenuID's and I figure I may as well do PanelID's etc as well.

I don't want to end up with any errors though (I got errors in some code due to some Enumeration issue one time, but I think it was an isolated case)

for things like Menu and Panel ID's though I'm not sure if I need to be careful to reset the Enumeration to 0, since I know some items maintain separate ID/position stacks. For example I could have my main Application Window with the ID "1", and I could also have my first Menu item as ID "1", as well as first Panel Item, and so on..

But I think this will confuse me more when looking at code, and I'd rather have a straight Enumeration section that enumerates every handle I will use for an object.
That way it won't matter if I am adding the object for the first time, or modifying it further down, or checking for an event /passing an event to an item. I can just use its constant everywhere and it will be much easier to read.


Should I just have one single Enumeration List, or should I break them up by Components (Main Window/Gadgets, Menu/Submenus, Panels/Trees/etc.

So, What do you guys do?
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Enumeration etiquette

Post by Demivec »

Zach wrote:Should I just have one single Enumeration List, or should I break them up by Components (Main Window/Gadgets, Menu/Submenus, Panels/Trees/etc.
You can do it either way. If you do it as an all in one you would still have to group the items and set the first item in each group to a constant (i.e. 0) before enumerating the rest of that group. If you used separate enumerations you would just list the items without an initial value specified. As you can see they basically look the same.

There are of other ways as well. I just don't think it makes a difference which way you do it.
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Enumeration etiquette

Post by Zach »

Demivec wrote:If you do it as an all in one you would still have to group the items and set the first item in each group to a constant (i.e. 0) before enumerating the rest of that group
I'm not sure I quite understand what that means?

Are you saying I would be forced to, by the compiler or something? Because certain groups of items must always start from 0 ??
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Enumeration etiquette

Post by Rook Zimbabwe »

I am completely unclear about exactly what is wrong with the current enum scheme?

Code: Select all

Enumeration
  #Window_MAIN
  #Window_PPAD
  #Window_OPENTIK
  #Window_KEYBOARD
  #Window_TABLE
  #Window_KITTIK
  #Window_MANAGER
  #Window_PAY
  #Window_SPLIT
EndEnumeration

Enumeration
  #Button_DINNER
  #Button_LUNCH
  #ResultFile
  #Image_LOGO1
  #Button_OPBACKMAIN
  #Button_OPSCRUB
  #Button_OPLOUT
  #Button_OPCLEAN
  #Button_POP102
  #Button_POP103
  #Button_POPADD
  #Text_POPMENU
  #Frame3D_BW0
  #Button_BWIT0
  #Button_BWIT1
  #Button_BWIT2
  #Button_BWIT3
  #Button_BWIT4
EndEnumeration
;-
#ODBC_ADD_DSN = 1 ; Add Data source
#ODBC_ADD_SYS_DSN = 4 ; Add SYSTEM Data source
#ODBC_CONFIG_DSN = 2 ; Configure (edit) Data source
#ODBC_REMOVE_DSN = 3 ; Remove Data source
#ODBC_REMOVE_SYS_DSN = 6 ; Remove SYSTEM Data source
#SQL_SUCCESS = 0
#SQL_SUCCESS_WITH_INFO = 1
Both styles are supported but if you use the autoenum you just need to make sure you use LABELS you can remember or that are self explanitory... Use and ABUSE! :mrgreen: it is sooo much simpler than attempting to obfuscate with some sort of NUM system! You don't have to call it by number you call it by what it is... same speed! :D
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Enumeration etiquette

Post by Zach »

I never said anything was "wrong" with the auto-enumeration setup, did I?

I like to do certain things myself though, or at least setup any automation myself/the way I want, in this case.

All I did was ask what others do
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Enumeration etiquette

Post by Demivec »

Zach wrote:
Demivec wrote:If you do it as an all in one you would still have to group the items and set the first item in each group to a constant (i.e. 0) before enumerating the rest of that group
I'm not sure I quite understand what that means?

Are you saying I would be forced to, by the compiler or something? Because certain groups of items must always start from 0 ??
No, there would be no forcing going on. Use whatever numbers you choose.
Zach wrote:for things like Menu and Panel ID's though I'm not sure if I need to be careful to reset the Enumeration to 0, since I know some items maintain separate ID/position stacks. For example I could have my main Application Window with the ID "1", and I could also have my first Menu item as ID "1", as well as first Panel Item, and so on..
As you said, some things use separate 'sets' of ID's. If you intermingle them and number them all sequentially as a group (i.e. gadgets 1..2..3, windows 4..5..6, panels 7..8..9, etc.) you have the potential of simply wasting memory because PureBasic reserves space for those objects as determined by the highest number used (i.e. 9000 = space for 9001 objects, 0 - 9000), even if the lower numbered object ID's are never used. It is important to note that ID's returned using #PB_Any don't fall under this guideline.
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: Enumeration etiquette

Post by Thorium »

I dont use constants much for objects.
In most cases i use #PB_Any, it's more flexible.
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Enumeration etiquette

Post by Zach »

Yeah I just realized I forgot to ask about #PB_ANY

I've never really used it, or seen it used (that I can recall, probably used in examples all over the place)

I guess I don't understand how I could use it to recall an object later though

if I added two text gadgets and wanted to change text in one....how would I reference it / get the ID without knowing its number?

Or is this a case of having to use a variable every time?

Code: Select all

Label1 = TextGadget(#PB_ANY)
Label2 = TextGadget(#PB_ANY)

SetGadgetText(Label1)
like that?


I can see instances where both methods are beneficial... but even with #PB_ANY you are still creating a list of names to run by, I prefer to do it in advance with #CONSTANTS defined at the top, for mostly static objects, I think.. But for variable changing things like a Recent Files list, and similar things of that nature, I can see the usefulness of using #PB_ANY.


Thanks for the input everyone.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Enumeration etiquette

Post by netmaestro »

Yes, that's it. There are a couple of considerations for using PB_Any though. Firstly, as you reference the object# via a variable, that variable will often need to be global for use inside procedures unless it is a member of a passed structure. Secondly, using PB_Any means the Purebasic compiler will choose an object# for you from a pool it maintains. This number is going to be very high and so it can't be reused as a static object number. For example:

Code: Select all

image1 = CreateImage(#PB_Any, 64,64)
; use the image in some way
FreeImage(image1)
CreateImage(image1, 64,64) ; incorrect
; or, more commonly tried:
CopyImage(<someimage>, image1)

This represents attempts to reuse a PB_Any image# as a static image# and it's incorrect. The debugger will complain about it, and if you turn off the debugger it may well work, but you're interfering with Purebasic's management of PB_Any object#'s and, not knowing this one is gone, PB may try to use it if PB_Any is called again. That's the first reason. The second reason is that when you choose a static object#, PB will allocate memory for those objects with static object#'s from 0 up to the one you chose. Since this is going to be a very high number, you are allocating memory for thousands of images unnecessarily.
BERESHEIT
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Enumeration etiquette

Post by Zach »

Yeah I wouldn't try to do that anyway. I would always start with a new var= after freeing something
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: Enumeration etiquette

Post by Thorium »

Zach wrote: I can see instances where both methods are beneficial... but even with #PB_ANY you are still creating a list of names to run by, I prefer to do it in advance with #CONSTANTS defined at the top, for mostly static objects
#PB_Any is a must use if you dont know the count of objects. For example you write a MDI application and allow the user to open as many editing windows as he wants. There you need to use #PB_Any. And thats why i use it in most cases, because then it's easy to change my code to allow creation of multiple objects. If you used constants for all it's a lot of work if you decide later you want to allow the user to create multiple objects of the same type (like windows).
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: Enumeration etiquette

Post by SFSxOI »

I like to group them for the final code...

Code: Select all

Enumeration ;->Enumeration Window
  #WindowKey1
  #WindowKey2
  #WindowKey3
  ; etc....
EndEnumeration

Enumeration ;->Enumeration Array 1
  #Array1Key1
  #Array1Key2
  #Array1Key3
  #Array1Key4
  ; etc...
EndEnumeration

Enumeration ;->Enumeration Something Else
  ;etc....
EndEnumeration

; and sometimes for like a long procedure.....

Enumeration ;->Enumeration MyProc()
  #MyProc1Key1
  #MyProc1Key2
  #MyProc1Key3
  #MyProc1Key4
  ; etc...
EndEnumeration
For those occaisional use or one time use constants I may or may not place them in an enumeration for their associated process or use. If the occaisional or one time use constants are sequential for their value I sometimes do place them in an enumeration. Overall though, I try to pay attention to the needs of what i'm working on, for example - if i'm converting something from C++ code to PB use if the API calls for a constant and that constant is in an enumeration in the SDK then in my code the whole enumeration gets put in even though I may only use one or two constants from the enumeration as I may want to expand the code a little in the future and need the constants so they will already be there for use without having to stop and look them up again. I try also for the final code to arrange enumerations and constants in the order in which they are used in the code...e.g.. #MyKey1 is used in the first procedure and is used first in that procedure so that constant would go at the top of the list as one of the first constants listed, but thats just an 'organizational' thing.
Last edited by SFSxOI on Wed Aug 31, 2011 12:18 pm, edited 1 time in total.
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Enumeration etiquette

Post by blueznl »

A bit on enumeration:

http://bluez.home.xs4all.nl/purebasic/p ... numeration

A bit on #PB_Any:

http://bluez.home.xs4all.nl/purebasic/p ... htm#pb_any

Me myself I tend to throw all enumerations together, grouping them by type:

Code: Select all

Enumeration
  ; 
  ; *** windows
  ;
  #w_main_nr
  #w_about_nr
  ;
  ; *** toolbars
  ; 
  #tb_main_nr
  ;
EndEnumeration
;
; *** windows
;
Global w_main_h.i
Global w_about_h.i
;
; *** toolbars
;
tb_main_h.i
;
A perhaps better approach would be to group them, ie. a block for window 1, a block for window 2, and so on... Be careful though as you may end op with identical numbers, so you'll have to use the PureBasic constant #PB_Compiler_EnumerationValue

Code: Select all

;
; *** main window
;
Enumeration #PB_Compiler_EnumerationValue
  #w_main_nr
  #tb_main_nr
EndEnumeration
;
Global w_main_h.i
Global tb_main_h.i
;
; *** about window
;
Enumeration #PB_Compiler_EnumerationValue 
  #w_about_nr
EndEnumeration
;
Global w_about_h.i
;
Yet, writing it that way is a pain in the but, so you might want to use a macro and end up with better readable code:

Code: Select all

Macro enumerate(constant)
  Enumeration #PB_Compiler_EnumerationValue
    constant
  EndEnumeration
EndMacro
;
; *** main window
;
Enumerate(#w_main_nr)
Enumerate(#tb_main_nr)
Global w_main_h.i
global tb_main_h.i
;
; *** about window
;
Enumerate(#w_about_nr)
Global w_about_h.i
;

Enumerate(#test1)
Enumerate(#test2)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Enumeration etiquette

Post by Fred »

You have to group the enum per object type for optimal performance: ie, one enum for window, one for gadget, one for toolbar etc. Using only one enum for every object will lead to holes into the internal arrays for each objects.
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Enumeration etiquette

Post by Zach »

Thanks Fred.

I think that's the most clear answer I've gotten from anyone 8)
Post Reply