#PB_Event_FirstCustomValue & #PB_Compiler_EnumerationValue

Just starting out? Need help? Post your questions and find answers here.
User avatar
SparrowhawkMMU
User
User
Posts: 56
Joined: Fri Jan 17, 2014 8:55 pm
Location: UK

#PB_Event_FirstCustomValue & #PB_Compiler_EnumerationValue

Post by SparrowhawkMMU »

Hi,

Back to trying out PB - I bought license a while back but never really used it much. After succesfully using the excellent SpiderBasic on a couple of projects, I thought I'd try it's older sibling again :)

Is the following behaviour as expected for the PB constants #PB_Event_FirstCustomValue and #PB_Compiler_EnumerationValue?

Scenario: I need to set up some custom events, and I'm using #PB_Event_FirstCustomValue to define these, but the compiler's enumeration value is then bumped up to that level - is there only a single enumeration stack/counter in the compiler?

Simplified sample code:

Code: Select all

Enumeration #PB_Event_FirstCustomValue
	#CONST_1
EndEnumeration

Enumeration #PB_Compiler_EnumerationValue
	#CONST_2
EndEnumeration

Debug "1: " + Str(#CONST_1) + ", 2: " + Str(#CONST_2)

OpenWindow(#CONST_2, 0,0,100,100, "TEST")

End
Gives the following output in the debugger:

Code: Select all

1: 65536, 2: 65537
And the program then exits when trying to execute the OpenWindow() command with the following error:

Code: Select all

[10:11:55] [ERROR] #Window object number is very high (over 5000), are You sure of that ?
Should custom events always be defined last to avoid this problem? Just seeking guidance on PB best practice when using enumerations including custom events.

Thanks
User avatar
TI-994A
Addict
Addict
Posts: 2771
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by TI-994A »

SparrowhawkMMU wrote:Should custom events always be defined last to avoid this problem?
The short answer would be no.

Just don't continue enumerating from the custom values with the #PB_Compiler_EnumerationValue directive:

Code: Select all

Enumeration #PB_Event_FirstCustomValue
   #CONST_1
EndEnumeration

Enumeration   ;#PB_Compiler_EnumerationValue   <--- remove this
   #CONST_2
EndEnumeration

Debug "1: " + Str(#CONST_1) + ", 2: " + Str(#CONST_2)

OpenWindow(#CONST_2, 0,0,100,100, "TEST")

End
A good practice would be to maintain named enumerations for different object types:

Code: Select all

Enumeration Windows
  #win1
  #win2
  #win3
EndEnumeration

Enumeration Gadgets
  #gad1
  #gad2
  #gad3
EndEnumeration

Enumeration Misc
  #misc1
  #misc2
  #misc3
EndEnumeration

Debug #win1
Debug #win2
Debug #win3
Debug #gad1
Debug #gad2
Debug #gad3
Debug #misc1
Debug #misc2
Debug #misc3
The manual has more:

The PureBasic Manual - Enumerations
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
Marc56us
Addict
Addict
Posts: 1600
Joined: Sat Feb 08, 2014 3:26 pm

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by Marc56us »

Debug show this as Error, but it must be show as Wanning (IMHO)

Run with debug OFF or in EXE and it work

Code: Select all

 Enumeration #PB_Event_FirstCustomValue
   #CONST_1
EndEnumeration

Enumeration #PB_Compiler_EnumerationValue
   #CONST_2
EndEnumeration

Debug "1: " + Str(#CONST_1) + ", 2: " + Str(#CONST_2)

OpenWindow(#CONST_2, 0,0,100,100, "TEST")

While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend

End 
Why this message ? Simply, because if you define an object number, ie 5000, PB reserve 4999 free values before. So wast of memory space !

So with this example, you've created a table of 65537 value which unused 65536

:wink:
User avatar
SparrowhawkMMU
User
User
Posts: 56
Joined: Fri Jan 17, 2014 8:55 pm
Location: UK

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by SparrowhawkMMU »

Hi and thanks for the information.

The problem is that I am trying to abstract my code out to modules as much as possible, so one module per window for example, each module having it's own gadget enum.

As such, I was using the #PB_Compiler_EnumerationValue to ensure no gadget clash.

A workaround I have is to set the start value for each gadget enum based on the window number, eg:

Code: Select all

	Enumeration (#WINDOW_Main + 1) * 100
		#GADGET_ValueText
		#GADGET_OpenChildButton
		#GADGET_CloseButton
	EndEnumeration
Not sure whether this is a common/good approach but it's working so far.

As you can probably tell, I'm very much at the feeling my way around PB stage at the moment. ;)
Fred
Administrator
Administrator
Posts: 18396
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by Fred »

Named enumeration is the way to go:

Code: Select all

Enumeration Gadget
  #Gadget1
  #Gadget2
EndEnumeration

Enumeration Window
  #Window1
  #Window2
EndEnumeration

Enumeration Gadget
  #Gadget3
  #Gadget4
EndEnumeration

Debug #Gadget1
Debug #Gadget2
Debug #Gadget3
Debug #Gadget4
User avatar
SparrowhawkMMU
User
User
Posts: 56
Joined: Fri Jan 17, 2014 8:55 pm
Location: UK

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by SparrowhawkMMU »

Righto chaps - Named enumeration sit is! :)
User avatar
SparrowhawkMMU
User
User
Posts: 56
Joined: Fri Jan 17, 2014 8:55 pm
Location: UK

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by SparrowhawkMMU »

Except... having tried it I get the same problem with gadgets - because gadget enumeration in the modules are starting from 0 now, they override each other.

I need abstraction as I want to be easily able to replace one version of a window with another - the app pulls in the various windows using a master control file that pulls in individual modules (so windows defs too), each one in its own file.
Marc56us
Addict
Addict
Posts: 1600
Joined: Sat Feb 08, 2014 3:26 pm

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by Marc56us »

What do you call a "module" ?

PB Module : https://www.purebasic.com/documentation ... odule.html ?

or an include file ? (*.pbi)

If this is only an IncludeFile, you have to do nothing, named enumeration will follow number whatever order of included files.
Last edited by Marc56us on Tue Aug 09, 2016 5:08 pm, edited 1 time in total.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by ts-soft »

Code: Select all

DeclareModule CommonConstants
  ; Form
  Enumeration FormWindow
  EndEnumeration
  Enumeration FormGadget
  EndEnumeration
  Enumeration FormMenu
  EndEnumeration
  Enumeration FormImage
  EndEnumeration
  Enumeration FormFont
  EndEnumeration
  ; Event
  Enumeration EventCustom #PB_Event_FirstCustomValue
  EndEnumeration
  Enumeration EventTypeCustom #PB_EventType_FirstCustomValue
  EndEnumeration
EndDeclareModule

Module CommonConstants
EndModule

; ------------
; Examples
DeclareModule Example1
  UseModule CommonConstants
  Enumeration FormGadget
    #Gadget1
  EndEnumeration
EndDeclareModule

Module Example1
 Debug #Gadget1
EndModule

DeclareModule Example2
  UseModule CommonConstants
  Enumeration FormGadget
    #Gadget2
  EndEnumeration
EndDeclareModule

Module Example2
 Debug #Gadget2
EndModule

UseModule CommonConstants

Enumeration FormGadget
  #Gadget3
EndEnumeration

Debug #Gadget3

Debug "-----------"
Debug Example2::#Gadget2
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
SparrowhawkMMU
User
User
Posts: 56
Joined: Fri Jan 17, 2014 8:55 pm
Location: UK

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by SparrowhawkMMU »

@Marc56us: A PB module, but I structure my code to one module per file (also a general module declaration file I load up front)

This makes it easier when doing version control in git as I have more flexibility.

@ts-soft. Thanks for example - That's pretty much exactly how I'm doing it. However, when I open a second window, the controls on the new windows clearly take the ids of the parent as the originals disappear!

I have an example at work. I'll post it here tomorrow.

Thanks all for your help :)
User avatar
TI-994A
Addict
Addict
Posts: 2771
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by TI-994A »

SparrowhawkMMU wrote:...I structure my code to one module per file (also a general module declaration file I load up front)...

...when I open a second window, the controls on the new windows clearly take the ids of the parent as the originals disappear!
The placement of the general module, and its usage in each module, is key. Here's a slightly simplified, visual version of ts-soft's example:

Code: Select all

; --- common module
;
DeclareModule generalModule
  Enumeration windows
  EndEnumeration
  Enumeration gadgets
  EndEnumeration  
EndDeclareModule

Module generalModule
EndModule

; --- module A
;
DeclareModule a
  UseModule generalModule
  Enumeration windows
    #win
  EndEnumeration
  Enumeration gadgets
    #gadget
  EndEnumeration  
  Declare openWin()
EndDeclareModule

Module a
  Procedure openWin()
    OpenWindow(#win, 160, 300, 250, 100, "Module A Window")
    ButtonGadget(#gadget, 25, 20, 200, 30, "Module A Gadget")
  EndProcedure
EndModule

; --- module B
;
DeclareModule b
  UseModule generalModule
  Enumeration windows
    #win
  EndEnumeration
  Enumeration gadgets
    #gadget
  EndEnumeration  
  Declare openWin()
EndDeclareModule

Module b
  Procedure openWin()
    OpenWindow(#win, 220, 400, 250, 100, "Module B Window")
    ButtonGadget(#gadget, 25, 20, 200, 30, "Module B Gadget ")
  EndProcedure
EndModule

; --- module C
;
DeclareModule c
  UseModule generalModule
  Enumeration windows
    #win
  EndEnumeration
  Enumeration gadgets
    #gadget
  EndEnumeration  
  Declare openWin()
EndDeclareModule

Module c
  Procedure openWin()
    OpenWindow(#win, 280, 500, 250, 100, "Module C Window")
    ButtonGadget(#gadget, 25, 20, 200, 30, "Module C Gadget")
  EndProcedure
EndModule

; --- main module
;
UseModule generalModule
Enumeration windows
  #win
  #childWin
EndEnumeration

Enumeration gadgets
  #gadget
  #childGadget
EndEnumeration  

OpenWindow(#win, 100, 200, 250, 100, "Main Window")
ButtonGadget(#gadget, 25, 20, 200, 30, "Main Gadget")
 
a::openWin()
b::openWin()
c::openWin()

OpenWindow(#childWin, 340, 600, 250, 100, "Child Window")
ButtonGadget(#childGadget, 25, 20, 200, 30, "Child Gadget")

MessageRequester("Modules", "Perfectly black-boxed - no clashes!")
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend 
Works perfectly without clash or conflict, even when each module is loaded from separate files. Furthermore, there are no worries about maintaining unique constant names, as they could be reused. The constants, #win and #gadget in this example, are used in all three modules, and also in the main module, without issue.

Hope it helps. :wink:
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
User avatar
SparrowhawkMMU
User
User
Posts: 56
Joined: Fri Jan 17, 2014 8:55 pm
Location: UK

Re: #PB_Event_FirstCustomValue & #PB_Compiler_EnumerationVal

Post by SparrowhawkMMU »

Ah I see - I had not set an empty Gadgets enumeration in my common module. When I added that it all worked as with yours.

MANY, MANY THANKS TO YOU ALL. :)
Post Reply