Enumeration etiquette
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Enumeration etiquette
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?
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?
Re: Enumeration etiquette
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.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.
There are of other ways as well. I just don't think it makes a difference which way you do it.
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: Enumeration etiquette
I'm not sure I quite understand what that means?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
Are you saying I would be forced to, by the compiler or something? Because certain groups of items must always start from 0 ??
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
Re: Enumeration etiquette
I am completely unclear about exactly what is wrong with the current enum scheme?
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!
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! 
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


-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: Enumeration etiquette
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
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
Re: Enumeration etiquette
No, there would be no forcing going on. Use whatever numbers you choose.Zach wrote:I'm not sure I quite understand what that means?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
Are you saying I would be forced to, by the compiler or something? Because certain groups of items must always start from 0 ??
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.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..
Re: Enumeration etiquette
I dont use constants much for objects.
In most cases i use #PB_Any, it's more flexible.
In most cases i use #PB_Any, it's more flexible.
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: Enumeration etiquette
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?
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.
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)
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.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Enumeration etiquette
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:
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.
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
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: Enumeration etiquette
Yeah I wouldn't try to do that anyway. I would always start with a new var= after freeing something
Re: Enumeration etiquette
#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).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
Re: Enumeration etiquette
I like to group them for the final code...
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.
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
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.
Re: Enumeration etiquette
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:
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
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:
Enumerate(#test1)
Enumerate(#test2)
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
;
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
;
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... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
Re: Enumeration etiquette
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.
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: Enumeration etiquette
Thanks Fred.
I think that's the most clear answer I've gotten from anyone
I think that's the most clear answer I've gotten from anyone
