Raised This Month: $12 Target: $400
 3% 

[TUT] Enumerations (enum)


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Exolent[jNr]
Veteran Member
Join Date: Feb 2007
Location: Tennessee
Old 10-08-2010 , 22:22   [TUT] Enumerations (enum)
Reply With Quote #1

Introduction:
Enumerations are basically data structures.
They allow you to:
  • create a block of data and set different values into it.
  • create your own constants with automatic incrementing.
  • create your own tags for variables.


Basic Syntax:
The basic syntax for enumerations is as follows:
Code:
enum [[_:]TagName] [(IncrementType)]
{
    [TagForConstant:]Constant1 [= Value1],
    [TagForConstant:]Constant2 [= Value2],
    ...
    [TagForConstant:]ConstantN [= ValueN]
}
Let's analyze each piece of the syntax:
  • First, the data encapsulated in square brackets [] are optional for syntax.
  • [_:]TagName
    This is the name of the tag that you would be creating.
    The tag name has a value that is the size of the enumeration, which is the last constant value + 1.
    If you put the optional _: before the tag name, it means that it is no longer a tag.
  • (IncrementType)
    This is the method used to give each constant a value in the enumeration.
    The syntax for this is: operator= value
    The default for this is (+= 1) so that each constant is 1 more than the constant before it.
  • [TagForConstant:]Constant1 [= Value1]
    This is the name of the constant that is being created and also optionally giving it a value.
    The first constant is 0 if it is not given a value.
    Remember, the last constant being listed does not have a comma after it!


Creating Tags:
Creating your own tags is easy.
Here is an example of the bool tag:
Code:
enum bool
{
    false,
    true
}
It creates the bool tag, and creates 2 constants.
false is equal to bool:0 because the first constant starts at 0.
true is equal to bool:1 because the default increment is the constant before it + 1.
bool is also a constant that equals bool:2, because true is the last constant and is bool:1.

Creating tags for handles is done with an enumeration to create the tag and a constant defined for a handle.
Example:
Code:
enum Array
{
    Invalid_Array = 0
}
This creates the Array tag for cellarrays and also a constant Invalid_Array that is equal to an invalid array handle.


Using Tags on Variables:
Using tags is simple. If you've worked with bools or Floats in AMXX before, then you have used tags before.
You can create variables that are tagged with a specific tag:
Code:
new myInteger = 1
new bool:myBoolean = true
new Float:myFloat = 1.0
Remember that variables that use tags that have defined constants are not limited to those constants.
Example:
Code:
new bool:myBoolean = bool:2
The problem with doing so is that true and false are only 1 and 0 respectively, so if you checked that variable to true, it would say it is not equal to true.


Constants:
Enumerations can be useful to create a list of constants without having to define each one.
Example:
Code:
#define CONSTANT1 0
#define CONSTANT2 1
#define CONSTANT3 2
#define CONSTANT_SIZE 3
This could be annoying to try to add/edit/delete constants because you may have to edit more than one line.
Here is how an enumeration would look for this:
Code:
enum _:CONSTANT_SIZE
{
    CONSTANT1,
    CONSTANT2,
    CONSTANT3
}
You can do something like this to create a list of constants that represent bits:
Code:
enum (<<= 1) // each value is the value before it shifted left once
{
    BIT1 = 1, // start with 1 because that is the first bit
    BIT2,     // 1 << 1 = 2
    BIT3,     // 2 << 1 = 4
    BIT4      // 4 << 1 = 8
}
If you have constants defined for player tasks so that you can have different tasks for each player at a time, you may have this:
Code:
#define TASK_ID_1 1000
#define TASK_ID_2 2000
#define TASK_ID_3 3000

// ...

set_task(1.0, "TaskHandler", id + TASK_ID_1)

// ...

public TaskHandler(taskid)
{
    new id = taskid - TASK_ID_1
}
Well you may have different constant values for your task ids, so you can do this easily to copy that style shown above:
Code:
enum (+= 1000) // task ids are 1000 apart
{
    TASK_ID_1 = 1000, // start with 1000
    TASK_ID_2,
    TASK_ID_3
}


Data structures:
Data structures allow you to put different types of data in an array.
Here is an example code that could use a data structure:
Code:
new g_iKills[ 33 ]
new g_iDeaths[ 33 ]
new Float:g_flSpeed[ 33 ];

// g_iKills[ id ] = kills for id
// g_iDeaths[ id ] = deaths for id
// g_flSpeed[ id ] = run speed for id
To put this into a data structure, you could do this:
Code:
enum _:PlayerData
{
    Player_Kills,
    Player_Deaths,
    Float:Player_Speed
}

new g_ePlayerData[ 33 ][ PlayerData ]

// g_ePlayerData[ id ][ Player_Kills ] = kills for id
// g_ePlayerData[ id ][ Player_Deaths ] = deaths for id
// g_ePlayerData[ id ][ Player_Speed ] = run speed for id
When using tags for structure constants that are used as an array index (ie. Player_Speed), you may need to tag the array itself when setting/getting a value.
Example:
Code:
g_ePlayerData[ id ][ Player_Speed ] = 250.0
// If the above code gives a tag mismatch warning, you can change it to this:
g_ePlayerData[ id ][ Player_Speed ] = _:250.0

// ...

if( g_ePlayerData[ id ][ Player_Speed ] == 250.0 )
// If the above code gives a tag mismatch warning, you can change it to this:
if( Float:g_ePlayerData[ id ][ Player_Speed ] == 250.0 )
With data structures, you can even create arrays and strings.
Example:
Code:
new g_szName[ 33 ][ 32 ];
new g_szAuthID[ 33 ][ 32 ];
new g_iUserID[ 33 ];

// can be changed to

enum _:PlayerInfo
{
    Player_Name[ 32 ],
    Player_AuthID[ 35 ],
    Player_UserID
}

new g_ePlayerData[ 33 ][ PlayerInfo ]
When using arrays and strings inside data structures, there are a few rules:
Code:
sizeof( Player_Name )
charsmax( Player_Name )
Those 2 lines are invalid because Player_Name is not a variable that has a size.
The constant Player_Name just reserves indexes 0-31 for the data structure, and Player_AuthID starts are 32 and stops at 66.
To get the size of those arrays/strings from a data structure, there are 2 ways:

Method #1:
Code:
Player_AuthID // sizeof( Player_Name )
Player_AuthID - 1 // charsmax( Player_Name )
// ...
Player_UserID - Player_AuthID // sizeof( Player_AuthID )
Player_UserID - Player_AuthID - 1 // charsmax( Player_AuthID )
Method #2:
Code:
new eTempData[ PlayerData ]
// ...
sizeof( eTempData[ Player_Name ] )
charsmax( eTempData[ Player_Name ] )
// ...
sizeof( eTempData[ Player_AuthID ] )
charsmax( eTempData[ Player_AuthID ] )
Method #2 is the best way because it ensures proper sizes in the event that an enum is modified.
Also, it would be the most practical way since the only reason you're using a data structure is to create an array that uses it.
So you should use the variable that uses the data structure for readability.

When using variable arrays that are sized by a data structure in functions, the data structure cannot have a tag.
Example:
Code:
enum PlayerData // PlayerData is a tag
{
    Player_Kills,
    Player_Deaths,
    Float:Player_Speed
}

// ...

new ePlayerData[ PlayerData ]
ePlayerData[ Player_Kills ] = 0
ePlayerData[ Player_Deaths ] = 0
ePlayerData[ Player_Speed ] = 250.0

// this line will throw an error
// because it does not accept arrays from data structures that are tagged
set_task( 1.0, "TaskSetPlayerData", id, ePlayerData, PlayerData )
To fix that, you just need to untag the data structure:
Code:
enum _:PlayerData // PlayerData is no longer a tag
{
    Player_Kills,
    Player_Deaths,
    Float:Player_Speed
}

// ...

new ePlayerData[ PlayerData ]
ePlayerData[ Player_Kills ] = 0
ePlayerData[ Player_Deaths ] = 0
ePlayerData[ Player_Speed ] = 250.0

// this line will work properly
set_task( 1.0, "TaskSetPlayerData", id, ePlayerData, PlayerData )
I think this tutorial is complete.
If I confused any information or left anything out, please let me know.
Feedback and suggestions are welcome.
__________________
No private work or selling mods.
Quote:
Originally Posted by xPaw View Post
I love you exolent!
Exolent[jNr] is offline
wrecked_
Veteran Member
Join Date: Jan 2010
Location: New York (GMT-5)
Old 10-08-2010 , 22:35   Re: [TUT] Enumerations (enum)
Reply With Quote #2

Good job, Exolent. I feel like a lot of people don't fully understand how much is capable with enum and this should definitely help.

However, whenever I get a question about enumerations I like to show them the CsTeams enum to show them how it would be set up and used, since many people are familiar with the functionality of the CsTeams tagging and constants. Perhaps you could show that as an example, some might understand its practical capabilities this way.
__________________
[ Paid Requests ]
DO NOT PM ME ABOUT BLOCKMAKER
NO PRIVATE SUPPORT
wrecked_ is offline
shuttle_wave
Veteran Member
Join Date: Apr 2009
Location: New Zealand
Old 10-08-2010 , 22:39   Re: [TUT] Enumerations (enum)
Reply With Quote #3

gj. Nice Tut Exolent
__________________
JailBreak Mod with Plugin API ( 90% ) Public
shuttle_wave is offline
lazarev
Veteran Member
Join Date: Sep 2008
Old 10-09-2010 , 02:13   Re: [TUT] Enumerations (enum)
Reply With Quote #4

thanks for sharing!
lazarev is offline
abdul-rehman
Veteran Member
Join Date: Jan 2010
Location: Khi, Pakistan
Old 10-09-2010 , 02:44   Re: [TUT] Enumerations (enum)
Reply With Quote #5

Thnx Again X-0lent !

PS: Atleast make the tutorial a little colorful like bugsy's bits tutorial
__________________

My Plugins For ZP

Inactive due to College and Studies

Last edited by abdul-rehman; 10-09-2010 at 03:05.
abdul-rehman is offline
Send a message via Yahoo to abdul-rehman Send a message via Skype™ to abdul-rehman
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 10-09-2010 , 04:46   Re: [TUT] Enumerations (enum)
Reply With Quote #6

That's not complete and there are few things to say :

- You don't talk about weak (lower case letter) and strong tag (upper case letter). The weak tag can be dropped implicitly in some situations. Check the pawn language guide to get more informations.
- Stop to cast the tags in your examples. At least the 3 first, there is no reason to cast.
- I would like to see an example with tagName + IncrementType.
- Don't say random things like "If the above code gives a tag mismatch warning[...]" ; When you set a value, which is important is the tag of the var (g_ePlayerData). When you get a value which is important is the tag of the item (Player_Speed). g_ePlayerData is untag, so if you try to set a value with a strong tag, you will get an error. If the tag was weak or if the the var (g_ePlayerData) was tagged with the same tag as the value you want to set, you won't get errors. In the next example when you get the value, since Player_Speed is a fload and since 250.0 too, the tag is the same, no error and no need to specify Float:.
- I don't see the point to show "Method #1:". Explaining the size it's ok, but showing an example is really a bad idea. It's confusing and you should avoid to show weird ways.
- ePlayerData[ Player_Speed ] = 250.0 ; should be casted.
- There is no example with custom tags.
- There is no example with structure inside a structure.
- In your last example, the problem can be simply solved by using a weak tag. The tag will be dropped automatically.

Here an old thread you may find some ideas
__________________
Arkshine is offline
hleV
Veteran Member
Join Date: Mar 2007
Location: Lithuania
Old 10-09-2010 , 07:22   Re: [TUT] Enumerations (enum)
Reply With Quote #7

If I go with HN, shouldn't members of enumeration be prefixed with m_?
PHP Code:
enum EData
{
        
m_iItem1,
        
m_iItem2,
        
m_iItem3
};
 
new 
g_eData[EData]; 
PHP Code:
enum SData
{
        
m_iInteger,
        
Float:m_fFloat,
        
m_szString[32]
};
 
new 
g_sData[SData]; 
__________________

Last edited by hleV; 10-09-2010 at 07:25.
hleV is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 10-09-2010 , 07:24   Re: [TUT] Enumerations (enum)
Reply With Quote #8

It doesn't matter, and it's up to the coders.
__________________
Arkshine is offline
hleV
Veteran Member
Join Date: Mar 2007
Location: Lithuania
Old 10-09-2010 , 07:27   Re: [TUT] Enumerations (enum)
Reply With Quote #9

But how would it be done in, let's say C[++] by a hardcore HN coder?
__________________
hleV is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 10-09-2010 , 07:33   Re: [TUT] Enumerations (enum)
Reply With Quote #10

That's not related to the subject. I don't see the point to talk about that. See yourself in the HLSDK or whatever. Coders are free to choose the style they want to their plugins.
__________________
Arkshine is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 11:43.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode