AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83)
-   -   [TUT] Code Styling & Good Programming Habits (https://forums.alliedmods.net/showthread.php?t=85274)

Hawk552 02-08-2009 01:09

[TUT] Code Styling & Good Programming Habits
 
Before we begin, this article is for anyone of any skill level. If you're just starting out, this will help you avoid nasty habits that you may pick up now or later. If you're an intermediate level scripter, you're probably relatively capable in terms of producing something that people can use, but may have trouble helping others understand your code properly.

This is an addendum to this post, which I don't feel is complete enough and needed some additions.

This article will teach you what I believe are the best coding styles. I don't even follow all of these because I started out with some bad habits and they are hard to break. All of these are tried and tested but may still be up for debate. Some of these are indisputable while others are highly subjective. For those which I think are subjective, I'll always leave multiple options and state that they are not conventions. So without further ado, here we go.

The Opening Comment Block

The best place to start is, logically, the beginning of the plugin, where you place comments explaining what the plugin is and does. I often ignore this section for small plugins or ones which I'm not going to release. This is, however, good form for a plugin which you are planning on releasing on its own. A typical comment block may look like this:

PHP Code:

/*

Copyleft 2008
Plugin thread: http://forums.alliedmods.net/showthread.php?p=633284

DUEL MOD
========

Description
This mod is designed to allow dueling, where players challenge each 
other and engage in battle. It is designed for the mod "The Specialists", 
but can be used on other mods.

Commands
say /duel - Will challenge the player being looked at to a duel.
say /accept - Will accept a challenge. Note that you can also use /duel, 
but you must be looking at the person who challenged you. With /accept, 
the last person to challenge you will be accepted.
say /punchingbag - Turns the player into a punching bag 
(requires amx_duel_punchingbag to be set to 1).

Credits
Havoc9 Community - Testing help (specifically SaderBiscut and Jimmy Striker).
Lord_Destros - Testing help.
Steely - Testing help.
sawyer - Testing help.
Frost - Testing help.
coderiz - New semiclip method.
Charming - Encouragement.

Changelog:

    Jun 1, 2008 - v1.0 -    Initial release
    Jun 2, 2008 - v1.1 -    [FIXED] Some repeated variables
                [FIXED] Message printing incorrectly
                [FIXED] Duel off not working properly
                [ADDED] Punching bag mode
                [ADDED] True semiclip
                [ADDED] Attack blocking between 
                duelists <-> players
                [ADDED] God mode to normal players
    Jun 4, 2008 - v1.2 -    [ADDED] Deny command
                [ADDED] Pair command
                [ADDED] Name parameter to /duel command
                [ADDED] Glow cvar
                [FIXED] Messages printing incorrectly
    
*/ 

This is a strong opening because it does a number of things:
  • It clearly states what the plugin is and does.
  • It clearly states the plugin thread (this is, by far, the most important of all of these).
  • It clearly states which game it works for.
  • It clearly states commands. Cvars are optional, but I typically leave them in the plugin thread to keep it uncluttered in the source code.
  • It clearly states credits. You should always list these both in the source code and in the plugin thread.
  • It has a clear and informative changelog so users know which version they're looking at just by glancing at it.
The copyleft notification is unnecessary but may be considered good form just to remind people that all AMXX plugins are GPL'd.

Your opening comment block can look however you want it to, but the most important thing is that it gets the information out. If you find your style is impeding this, it's probably a good idea to revise it.

Macros and the Preprocessor

This section includes stuff such as your header inclusions (a.k.a. "#include") and compiler definitions (a.k.a. "#define"). There's not a whole lot you can do here in terms of messing up convention, but one of the important things to remember is that all macros should be capitalized from beginning to end. For example,

PHP Code:

#define MAX_ITEMS 10 

... as opposed to ...

PHP Code:

#define max_items 10 

This avoids mistaking macros for variables and is a widely held convention - it is not really up for debate. The only exception to this is for macro function definitions, an example of which being:

PHP Code:

#define MyNewIsUserAlive(%1) is_user_alive( %1 ) 

This is acceptable because the macro essentially acts as a function as opposed to a location of data in memory.

Another stylistic consideration is that your header inclusions should be as minimalistic as possible. For example, if you don't use any FakeMeta functions, don't include the fakemeta.inc file as it is useless clutter.

One other important thing you should know about preprocessor styling is that conditions should generally be left untabbed. This makes it very clear where blocks of code will operate and where they won't. For example:

PHP Code:

PunishUserid )
{
#if defined KILL_USER
    
user_killid )
    
client_print0print_chat"[Kill] The user has been killed")
#else // KILL_USER
    
user_slapid)
    
client_print0print_chat"[Kill] The user has been slapped")
#endif // KILL_USER


Some people tab it out to whatever level the code is already at, but I think it's easy to miss that a preprocessor condition is necessary for any of it to run. Both are acceptable but I believe not tabbing out the condition macros is better.

The final thing you should know is that, as in my previous example, it's a good idea to leave a comment at each #else, #elseif and #endif command denoting what exactly it's checking.

Indentation, Tabbing and Spacing

Tabbing should always be done whenever you open a code block (which will be discussed more in detail later). A standard tab is either done using the "Tab" key or using 4 spaces. Less commonly, people use 1, 3 or 8 spaces for their tabs, but this is very rare and generally frowned upon. Almost everyone uses the "Tab" key because then other people can set their tab-size higher or lower in their text editors.

There are also many styles of spacing, but I believe the best (despite my not using it personally) is to add a space whenever you put a parameter in brackets, after a comma, immediately after a condition/loop keyword and before/after any operators which take two parameters on the left and right. For example:

PHP Code:

if ( !cmd_accessidlevelcid ) ) 

... or...

PHP Code:

for ( new i10i++ ) 

This allows you to easily distinguish functions from conditions/loops and also allows you to easily pick out parameters, operators, etc.

This is by no means standard and is highly up for debate, but to me this makes the most logical sense and is what I would use if I had the option of immediately wiping my habits and picking a new set of them. I would, however, advise you to always add spaces between operators with two parameters and after commas.

You may also consider adding two carriage returns as opposed to one between functions as it may make them easier to read. This is by no means a convention but I recommend it personally.

Case

This is important mostly for variables and functions. I'm putting this here because I'm going to be implying it in my next section, which covers global variables. This section is largely up for debate, but I believe the strongest and most legible way of doing it is what is commonly referred to as "camel case".

There's a slight variant of camel case called "mixed case" which I believe is slightly better. Here's how it goes:

For functions, you always capitalize the first letter of every word. For example:

PHP Code:

public EventDeathMsg() 

With variables that are untagged, you capitalize the first letter of every word after the first. For tagged variables, you capitalize the first letter of every word other than the tag. For example:

PHP Code:

new gMyVariable
new myVariable
new userKills 

In full camel case, you would capitalize the first letter of every word, regardless of whether or not it was the first word in the variable name or not. For example,

PHP Code:

new MyVariable
new UserKills 

The problem with this method is that it doesn't distinguish local variables from functions effectively. That's why mixed case is the best way to case your variables.

Mixed/camel case more or less necessitates totally avoiding using underscores. For example, this looks really weird:

PHP Code:

new My_Variable 

As such, you should either use underscores and avoid mixed/camel case or use mixed/camel case and avoid underscores.

Also, as noted earlier, macros should be full upper-case.

Global Variables and Type Prefixing

Lots of confusion can come from not knowing that something is global. As such, all global variables should be prefixed with some sort of tag identifying them as such. For example:

PHP Code:

new gMyVariable 

Another way of tagging variables is by using the "g_" prefix. For example:

PHP Code:

new g_MyVariable 

While both are perfectly acceptable, I personally prefer the former slightly more although I use the latter for almost all of my works. It is simply a recommendation of form based on my experience.

You should add a carriage return at the end of every global variable as it makes it easier to search out any variables you need. For example:

PHP Code:

new gMyVariable
new gMyOtherVariable 

... as opposed to...

PHP Code:

new gMyVariablegMyOtherVariable 

Some people also tag their variable names with the type that they are associated with. This idea is highly up for debate and almost everyone has moved away from it as it is relatively archaic (Microsoft used to use it, but then moved away from it). This form of tagging is commonly referred to as "Hungarian Notation" (HN, for short). While I personally believe you should avoid using it, being a user of it myself at one point, it is still important to be able to read and understand. HN goes something like this:
  • g or g_ - globals (this is perfectly acceptable to use although you should avoid the others)
  • p or p_ - pointers (this is also perfectly acceptable to use)
  • i - integers/cells
  • f or fl - floats
  • sz - strings
  • b - bools
  • h - handles (can also be used in place of the pointer tag since either is technically correct)
  • v - vectors (not standard to HN but still useful)
  • fn - function (very rarely used even by people who use HN)
There are many more tags, but these are the only ones you can use in Pawn. Here are a few examples of variables tagged in HN:

PHP Code:

// a global cell
new g_iKills

// a global float
new Float:g_flSpeed

// a bool
new bool:bFlag

// a function
public fnEventResetHUD()

// a pointer
new g_pCvar 

If you're not using full HN, I advise you to use "g" as opposed to "g_", as shown in the beginning of this section.

In terms of a technical analysis, HN for anything other than global variables and pointers doesn't make any sense. Pawn is typeless and therefore incapable of actual data types. Booleans are actually just a meaningless tag and floats are cells which are converted by the virtual machine (AMXX's C++ side) whenever they are needed. There are many situations where HN will make variable casting/detagging confusing.

Code Blocks

A code block is anything that is separated by curly braces. While this may be an imprecise definition since in many code blocks the curly braces can simply be left out, I'm going to be addressing this style anyway.

The first thing I'd like to address is spacing. There are two common ways of spacing your code blocks, one of which I believe is vastly superior. The first is by adding a return before the condition opening a block, the second is not doing this. For example:

PHP Code:

MyFunction()


... or...

PHP Code:

MyFunction() { 

I prefer the first much more as the entering and exit brackets will always line up properly and it just looks cleaner anyway. There's no real reason to do the latter and I can't see it as being easier to read.

Another very important concept in code blocks is whether or not to drop them entirely. Under some very special circumstances, you can actually ignore the brackets denoting a code block. There are two cases which make this acceptable:
  • There is a single function call or operation inside it, even if it itself requires data from other function calls (i.e. log_amx( "%d", get_user_kills( id ) )).
  • There is a single code block inside it, even if it contains a lot more code that does not fit in a single function call.
Here are examples of these:

1.
PHP Code:

MyFunctionid )
    
user_killid 

2.
PHP Code:

MyFunctionid )
    if( 
is_user_aliveid ) )
    {
        
client_print0print_chat"We are now killing %d"id )
        
user_killid )
    } 

Both of these are perfectly valid and will compile without warnings/errors (context exclusive).

This method of dropping brackets is highly subjective. There are many arguments both for and against each. Dropping brackets allows you to type less code, but including them makes it less ambiguous. It can be argued, however, that ambiguity is resolved by tabbing even if there's no brackets. This style is up to you and either way is perfectly acceptable.

Commenting

Commenting is one of the most important things you can do for your code. Even if you break all of these habits, you can still get away with it if your commenting is good enough.

Large blocks of text outside of functions should be commented using the "/* ... */" operators, as in the first section which covered the opening code block. All other sections should be commented using the "//" operator. The reason for this is that Pawn does not support nested comments, i.e.:

PHP Code:

/* 
    this is the first comment
    /* this is a nested comment */
                                               
*/ 

Just look at how the code looks from this view. The last "*/" is green, showing that the interpreter doesn't actually understand what's going on here.

If you need nested comments, a little-known way of doing this is by using the preprocessor #if along with the condition 0, i.e.:

PHP Code:

#if 0
    
this is the first comment
#if 0
        
this is a nested comment
#endif
#endif 

This is, however ugly and is more suited to code which you need to be able to activate and deactivate quickly. As such, you will not see it in production code very often and is generally reserved for debugging.

When commenting, you should keep your comment on each line below 80 characters. This is to prevent the compiler from complaining and is also for people who do not have widescreen displays. The "line below 80 characters" rule applies for any line of code, not just comments. Some people also space their comment out with one extra space (for two spaces in total) after the first line. I believe this makes it more readable, but this is highly subjective.

Your comments should always be as descriptive as possible. You should inform the reader of what you're doing, why and what the result will be. For example, this is a bad comment as it serves no constructive use:

PHP Code:

// Start the for loop.
for ( new i7i++ ) 

A much better comment would be something like this:

PHP Code:

// There's a strange memory corruption bug in this function.
//  As such, we have to loop through each of the 7 elements
//  in the array and set them to the value that they should be.
for ( new i7i++ ) 

Comments should also be placed between large blocks of code (such as functions which are grouped together as they are similar). These can be in the form of titles or just small descriptions. For example:

PHP Code:

//////////////////////////////////
// HELPER FUNCTIONS             //
////////////////////////////////// 

As is implied, it's a good idea to put your functions in an order where they are related to one another. These grouping tags are then much more meaningful.

Whitespace

Whitespace is a very important concept in coding. Although it has technically been covered previously in the "Tabbing and Spacing" section, there is still the issue of when to use carriage returns. If used correctly, whitespace allows people to understand your code more effectively. There are many different styles of using whitespace, but I believe the best is to simply add an extra carriage return whenever you break away from a part of a function which has similar results. For example:

PHP Code:

// Ignore the fact that this function would bear no real
//  useful results when actually used in a server.
MyFunction()
{
    new 
id random_num113 )
    
user_killid )

    
set_pcvar_nump_MyCvar)


As you can see, the cvar setting call has little to do with finding a player and killing them. Thus, we add an extra carriage return to separate it.

Variable and Function Naming

As a rule of thumb, variable and function names should be as descriptive as possible. For example, this is a bad variable name:

PHP Code:

new temp 

It doesn't tell you anything about it other than the fact that it's more or less temporary (although, more often than not, this variable is pivotal to the operation of the function and may be used as part of or the return). A much more descriptive variable name would be something like this:

PHP Code:

new KillsSinceLastSpawn 

This tells you everything you need to know about it while also making you immediately realize that it's probably an integer (cell).

For functions, it is generally advised to follow the same rule except in the situation where you're creating a hook. Often, you should tag your hook callbacks with what type of callback they are. For example, an event might be tagged with "Event" or a forward with "Forward". This can be seen as follows:

PHP Code:

register_forwardFM_Spawn"ForwardSpawn" 

... or...

PHP Code:

register_event"DeathMsg""EventDeathMsg""a" 

It matters little what tag you use (many people use ev, Fwd, etc.) but it is generally advised to tag these functions as it distinguishes them from utility functions.

Extras

This section contains things that didn't really fit into other sections.

For starters, you should always use constants whenever they're provided. For example, use:

PHP Code:

return PLUGIN_CONTINUE 

... as opposed to...

PHP Code:

return 

This makes it much easier to get into the habit of using your own constants which you have declared in your plugin, which is also a good practice.

Semicolons are useful if you plan on moving to C/C++/PHP or any related language, but are often misused (for example, most people don't know do while loops have to be ended with one) or are passively used. Being a C and other related languages programmer myself, I have no trouble switching between using and not using semicolons. Since it's a convenience Pawn affords, I take it and don't use them. You can force semicolons using the following:

PHP Code:

#pragma semicolon 1 

Sometimes, when writing an API or header, you will have to document your functions so others can understand them. Doxygen (a source code documenting software package) uses a specific format for this, which AMXX has started using since SQLx was introduced. This is probably the best way to do it simply because it's the most readable and can be fed to Doxygen later. Here is an example of a Doxygen-documented utility function:

PHP Code:

/**
 * Print command activity.

 * @param id           Calling admin's id
 * @param key[]      Language key
 * @param any:...    Arguments to the format function (w/out the id/lang key)
 
 * @return    True on success, False on fail
**/

stock UTIL_PrintActivity(const id, const szLangKey[],any:...) 

Finally, sometimes in a collaborative project you will have difficulty identifying who did what parts. For this reason, I believe it's best to comment your code as follows:

PHP Code:

// Hawk552: Added this function to gather and store player
//  names, then sort them alphabetically.
SortNamesNames[][], NumNamesMaxLength 

Conclusion

In conclusion, even if you ignore most of these tips, I hope you follow at least some of them as you will find them invaluable as you move along in the process of learning how to code. Ideally, you should follow all of these, but many people find them difficult to use or not as clean as their alternative.

As I think of more stuff to add, I may do this, but for the most part I believe this tutorial is complete. As always, if you have questions or comments, feel free to post or PM me.

EDIT: I bit the bullet and decided to actually learn to use the style that I advocate here. I have posted a plugin that uses this here:
http://forums.alliedmods.net/showthread.php?t=102839

danielkza 02-08-2009 01:38

Re: [TUT] Code Styling
 
Awesome work Hawk, but I'd like to share some personal beliefs and preferences:

I believe Pawn is the kind of language that needs HN the most. Not having explicit typing makes it impossible to people not familiar with the code to find out what a cell actually holds without reading through a chunk of it. That information should be present in the variable itself, not in how it's used.

And as there are no pointers in Pawn, I prefer to use the word 'handle', but both are perfectly fine as far as you're consistent in your code.

Also, I prefer to include type prefixes even in global vars:
g_iUseCount, g_szWebsite, etc

2 prefixes that you might see in some code (including mine), not included in your post:
h for handles: Handle:hSQLConnection
v for vectors: Float:vPlayerOrigin[3]

And finally, I use the 'doxygen style' to document functions possibly used a lot, or that may interest other authors in case there is a sub-plugin system or anything like that:
PHP Code:

/**
 * Print command activity.

 * @param id           Calling admin's id
 * @param key[]      Language key
 * @param any:...    Arguments to the format function (w/out the id/lang key)
 
 * @return    True on success, False on fail
**/

stock UTIL_PrintActivity(const id, const szLangKey[],any:...) 


darkman488 02-08-2009 12:09

Re: [TUT] Code Styling
 
great tut hawk :wink:

hleV 02-08-2009 12:15

Re: [TUT] Code Styling
 
Nice.

I myself prefer HN.

Didn't knew that this was possible:
Code:
MyFunction( id )     if( is_user_alive( id ) )     {         client_print( 0, print_chat, "We are now killing %d", id )         user_kill( id )     }
o_O

About function names... I'm still not decided, but currently I write only the first letter (or letters, if function's type title is made from 2 words, like forward - fw). Like eDeathMsg() for event and cSay for command. Also sPrint() for stock.

BTW is the g_Test pointer (although danielkza said there are no pointers in Pawn) or a normal integer?
Code:
g_Test = register_cvar("amx_test", "1");
I was used to treat it as pointers (so g_Test was g_pTest) but then I realized I have no idea what pointer really is so now I treat is as normal integer (g_Test is now g_iTest). Which one is more correct?

ConnorMcLeod 02-08-2009 12:23

Re: [TUT] Code Styling
 
Quote:

Originally Posted by hleV (Post 758140)
BTW is the g_Test pointer (although danielkza said there are no pointers in Pawn) or a normal integer?
Code:
g_Test = register_cvar("amx_test", "1");
I was used to treat it as pointers (so g_Test was g_pTest) but then I realized I have no idea what pointer really is so now I treat is as normal integer (g_Test is now g_iTest). Which one is more correct?

It's a pointer, so, an integer.

minimiller 02-08-2009 12:54

Re: [TUT] Code Styling
 
I strongly agree with the "Tabbing and Spacing" part
Its soo annoying when u get a wall of text in the source

Good tut
+k

hleV 02-08-2009 13:02

Re: [TUT] Code Styling
 
Quote:

Originally Posted by ConnorMcLeod (Post 758146)
It's a pointer, so, an integer.

Are there any other pointers in Pawn I should know about? I remember something from reading a file. Maybe pPointer = fopen() or something. ^^

BTW I prefer 8 spaces if there's no way to display big tab-space (like in this forum). In Notepad 8 spaces have equal lenght as 1 tab-space.

Exolent[jNr] 02-08-2009 13:13

Re: [TUT] Code Styling
 
Quote:

Originally Posted by hleV (Post 758176)
BTW I prefer 8 spaces if there's no way to display big tab-space (like in this forum). In Notepad 8 spaces have equal lenght as 1 tab-space.

When using tabbed spacing on this forum, I use 4 spaces, because when you post code that has tabs in them, they are converted to 4 spaces.

XxAvalanchexX 02-08-2009 13:45

Re: [TUT] Code Styling
 
Good post! Lots of controversial stuff. ;)

I thought that I read somewhere that it is more efficient for the assembly to use one "new" statement for all of your vars (where applicable), as opposed to a different "new" for each one. Is there any truth to that?

hleV 02-08-2009 13:48

Re: [TUT] Code Styling
 
Quote:

Originally Posted by Exolent[jNr] (Post 758187)
When using tabbed spacing on this forum, I use 4 spaces, because when you post code that has tabs in them, they are converted to 4 spaces.

Deppends on browser.

Hawk552 02-08-2009 14:12

Re: [TUT] Code Styling
 
Quote:

Originally Posted by danielkza (Post 757844)
I believe Pawn is the kind of language that needs HN the most. Not having explicit typing makes it impossible to people not familiar with the code to find out what a cell actually holds without reading through a chunk of it. That information should be present in the variable itself, not in how it's used.

I would argue that since "types" are really just tags which can be changed or detagged, HN is irrelevant. Bools especially are a meaningless tag which usually create more confusion than help. The biggest problem is that almost all function returns are untagged cells rather than bools, which defeats the purpose of them. In C/C++, bools are used because they use much less memory (1 byte I believe). Since this doesn't reduce memory usage in Pawn, there's no reason to tag them as such.

This is obviously problematic because you either have to never use bools or just not tag them as being bools. This is a bad precedent because you now have similar problems with floats. For example, in a set_task() call, the third parameter is a standard cell:

PHP Code:

set_task Float:time, const function[], id 0parameter[]=""len 0flags[]=""repeat 

What if you want to send a float as the id? You're going to have to detag it, then retag it once it gets there. You can get into a mess with stuff like this at other times too. What if you have to pass a string as an array separated by delimiters (i.e. "25 1 91 83 4")? Is it really a string, or is a really an array?

I used to use HN and I thought it was great for a few months. Some of my scripts are still using it, actually. But I really started turning away from it when I began developing APIs. Its major downfall, as far as I'm concerned, is that it discourages good variable naming. For example, I might use "i" as an iterator but according to HN it might be "iI". What if it's a global pointer to a handle for a null terminated string? As crazy as that sounds, I've had things like that before. The tag would look something like "g_phsz" which is just ridiculous and confusing. If you decide not to tag that as such, you are inconsistent. That's why I suggest only tagging globals and pointers.

Quote:

Originally Posted by danielkza (Post 757844)
And as there are no pointers in Pawn, I prefer to use the word 'handle', but both are perfectly fine as far as you're consistent in your code.

Right, but it's being passed into a function that calls it a pointer. The most important thing, though, is to differentiate it. Calling it a handle makes sense but may be confusing when you look at things like SQLx which call everything handles.

The point is, though, that if you detag a pointer, you're going to get useless data. If you detag a bool, you're going to get a cell which is just as useful. That's more what I was talking about.

Quote:

Originally Posted by danielkza (Post 757844)
Also, I prefer to include type prefixes even in global vars:
g_iUseCount, g_szWebsite, etc

Yes, I included those in my HN explanation.

Quote:

Originally Posted by danielkza (Post 757844)
2 prefixes that you might see in some code (including mine), not included in your post:
h for handles: Handle:hSQLConnection
v for vectors: Float:vPlayerOrigin[3]

Agreed. "v" is non-standard so I'll add it but I'll add a note saying it's not part of HN.

Quote:

Originally Posted by danielkza (Post 757844)
And finally, I use the 'doxygen style' to document functions possibly used a lot, or that may interest other authors in case there is a sub-plugin system or anything like that:
PHP Code:

/**
 * Print command activity.

 * @param id           Calling admin's id
 * @param key[]      Language key
 * @param any:...    Arguments to the format function (w/out the id/lang key)
 
 * @return    True on success, False on fail
**/

stock UTIL_PrintActivity(const id, const szLangKey[],any:...) 


Agreed again. I'll add that too.

Quote:

Originally Posted by hleV (Post 758140)
BTW is the g_Test pointer (although danielkza said there are no pointers in Pawn) or a normal integer?
Code:
g_Test = register_cvar("amx_test", "1");
I was used to treat it as pointers (so g_Test was g_pTest) but then I realized I have no idea what pointer really is so now I treat is as normal integer (g_Test is now g_iTest). Which one is more correct?

You would call it g_pTest according to HN. My way of tagging it is just with p_ (so it would be p_Test) because you are almost never going to use a pointer that isn't global.

Technically, the only correct tag would be g_iTest, but since the data it stores is useless without first passing it into get_pcvar_<x>(), it's a bad idea to tag it as what it actually is.

Hawk552 02-08-2009 14:15

Re: [TUT] Code Styling
 
Quote:

Originally Posted by XxAvalanchexX (Post 758221)
I thought that I read somewhere that it is more efficient for the assembly to use one "new" statement for all of your vars (where applicable), as opposed to a different "new" for each one. Is there any truth to that?

I don't think so just because of the way the assembly is mapped out. It can't declare a bunch of variables in sequence in a way that would be different from one at a time. Either way, zeroing it is the most expensive part by far and that still happens even when condensing it.

XxAvalanchexX 02-08-2009 22:20

Re: [TUT] Code Styling
 
Quote:

Originally Posted by Hawk552 (Post 758253)
I don't think so just because of the way the assembly is mapped out. It can't declare a bunch of variables in sequence in a way that would be different from one at a time. Either way, zeroing it is the most expensive part by far and that still happens even when condensing it.

I see. Cool, thanks!

anakin_cstrike 02-09-2009 10:54

Re: [TUT] Code Styling
 
Very nice thread. I agree with everything.

By the way, i have a question about semicolons. I know it has been discussed before, but i don't understand what is actually doing.
Let's say, i have a code with no identition wich ignores you advices (tabs, spaces, brackets, etc.. ). If i put "#pragma semicolon 1" it will automatically make identitation or what ? sorry for asking without testing.

AntiBots 02-09-2009 11:00

Re: [TUT] Code Styling
 
Quote:

Originally Posted by anakin_cstrike (Post 758774)
Very nice thread. I agree with everything.

By the way, i have a question about semicolons. I know it has been discussed before, but i don't understand what is actually doing.
Let's say, i have a code with no identition wich ignores you advices (tabs, spaces, brackets, etc.. ). If i put "#pragma semicolon 1" it will automatically make identitation or what ? sorry for asking without testing.

http://en.wikipedia.org/wiki/Semicolon#Computing_usage

Well if semicolon is in 1

You need to close all lines with ;

Example without semicolon
PHP Code:

if( is_user_alive(id) )
{
         
set_pev(idpev_maxspeed300.0)
         
set_pev(idpev_gravity0.45)


with semicolon
PHP Code:

if( is_user_alive(id) )
{
         
set_pev(idpev_maxspeed300.0); set_pev(idpev_gravity0.45);


or like this:
PHP Code:

if( is_user_alive(id) )
{
         
set_pev(idpev_maxspeed300.0); 
         
set_pev(idpev_gravity0.45);



anakin_cstrike 02-09-2009 11:03

Re: [TUT] Code Styling
 
Ahh...thanks.
PS: it closes automatically or i have to do that?

AntiBots 02-09-2009 11:06

Re: [TUT] Code Styling
 
Quote:

Originally Posted by anakin_cstrike (Post 758779)
Ahh...thanks.
PS: it closes automatically or i have to do that?


You need to closes all lines execpts "if( )" "{ }" and blank lines,
others like params you need to put the ( ; ) to Closes.

EDIT: For new, static lines you need to...
You dont new for lines that you open { }

Example

public somethin(x) // Here no.
{
//
}

anakin_cstrike 02-09-2009 11:14

Re: [TUT] Code Styling
 
I know you're anti - bots, but i know that. I've asked something else.
However, i do understand know.

Hawk552 02-09-2009 11:15

Re: [TUT] Code Styling
 
Quote:

Originally Posted by anakin_cstrike (Post 758790)
I know you're anti - bots, but i know that. I've asked something else.
However, i do understand know.

All #pragma semicolon 1 does is throw an error whenever you missed a semicolon.

Exolent[jNr] 02-09-2009 11:57

Re: [TUT] Code Styling
 
Quote:

Originally Posted by AntiBots (Post 758776)
PHP Code:

if( is_user_alive(id) )
{
         
set_pev(idpev_maxspeed300.0); set_pev(idpev_gravity0.45);



Don't put 2 statements on one line.

Hawk552 02-09-2009 12:01

Re: [TUT] Code Styling
 
Quote:

Originally Posted by Exolent[jNr] (Post 758820)
Don't put 2 statements on one line.

It was an example to show how semicolons can be used. He gave another example right after that where they were on two different lines.

Exolent[jNr] 02-09-2009 12:11

Re: [TUT] Code Styling
 
I know, but some beginners won't know it was wrong if it wasn't stated.

SchlumPF* 02-11-2009 15:34

Re: [TUT] Code Styling
 
nice thread hawk + i agree cuz its very similar to my style :D
good codes are one thing, finding solutions for huge problems is another thing BUT having a readable code has a very high priority as soon as you are planning to release a plugin or share the source in any way. just look at numbs plugins, then you know what i mean (at least most of his plugins show how a code shouldnt... :P).
numb <3

tuty 02-22-2009 11:13

Re: [TUT] Code Styling
 
hey Hawk, nice tut but I allways use in my plugins semicolons at the end of line.....
My question is, i must put this #pragma semicolon 1 in every plugin?

hleV 02-22-2009 11:37

Re: [TUT] Code Styling
 
No.

tuty 02-22-2009 11:45

Re: [TUT] Code Styling
 
ok thank you :mrgreen:

xPaw 02-22-2009 12:29

Re: [TUT] Code Styling
 
you can put it to be sure what you placed ; at end of all lines :]

hleV 02-22-2009 15:20

Re: [TUT] Code Styling
 
IMO it's useless because there's nothing bad if you forgot to put ; somewhere.

Exolent[jNr] 02-22-2009 16:08

Re: [TUT] Code Styling
 
It's a nice habit to use ; so that you won't need to have to remember to use it in one language and not another.

Hawk552 02-23-2009 01:27

Re: [TUT] Code Styling
 
Quote:

Originally Posted by Exolent[jNr] (Post 766858)
It's a nice habit to use ; so that you won't need to have to remember to use it in one language and not another.

I program in C++ at work and I have no problem switching between the two at any time.

Spunky 02-23-2009 02:17

Re: [TUT] Code Styling
 
Switching about every two weeks can throw you off though. I program in C++ for two weeks, then switch to Pawn for two weeks, then switch back. It's not easy because I usually forget like half of what I learned about AMXX (since that's the only thing I would ever use such a painfully simple language like Pawn for) the last time around when I finally come back, even down to basic stuff. x_x

Hawk552 09-14-2009 10:43

Re: [TUT] Code Styling
 
I finally got around to writing a plugin that uses this style. You can see it here:
http://forums.alliedmods.net/showthread.php?t=102839

I also added it to the conclusion.

GordonFreeman (RU) 01-06-2010 01:52

Re: [TUT] Code Styling & Good Programming Habits
 
Thanks!

Seta00 01-15-2010 10:06

Re: [TUT] Code Styling & Good Programming Habits
 
Nice tut, only thing I disagree is with the new line before opening bracket.
If you're a programmer, you can easily recognize identifiers that imply a code block, and the new lines before every block allow for less code to fit in one page.

SnoW 01-15-2010 15:22

Re: [TUT] Code Styling & Good Programming Habits
 
Quote:

Originally Posted by Seta00 (Post 1055664)
Nice tut, only thing I disagree is with the new line before opening bracket.
If you're a programmer, you can easily recognize identifiers that imply a code block, and the new lines before every block allow for less code to fit in one page.

Your reasoning is just unbelievable. If you wanted to have all the code in one line you could, but that's not you want. You want the code to look decent, readable and not ugly and that's why you line break. As simple as that.

Hawk, this is a sticky thread and a lot of people read this, so better to fix.
PHP Code:

#define MyNewIsUserAlive( %1 ) is_user_alive( %1 ) 


Bugsy 01-15-2010 21:55

Re: [TUT] Code Styling & Good Programming Habits
 
Quote:

Originally Posted by Seta00 (Post 1055664)
Nice tut, only thing I disagree is with the new line before opening bracket.
If you're a programmer, you can easily recognize identifiers that imply a code block, and the new lines before every block allow for less code to fit in one page.

Readability is far more important than line count. If you are worried about fitting more code on one page, reduce your font size :grrr:. Furthermore, code looks ugly when there's not a new-line before an opening bracket. Yes, I can look at any code and still know what is going on but it is a hell of a lot easier to read with proper line-breaks, spacing, and indentation.

:bacon:
PHP Code:

public Uglyid ) {

}

public 
Niceid )
{




Hawk552 01-16-2010 00:59

Re: [TUT] Code Styling & Good Programming Habits
 
Quote:

Originally Posted by SnoW (Post 1055985)
Your reasoning is just unbelievable. If you wanted to have all the code in one line you could, but that's not you want. You want the code to look decent, readable and not ugly and that's why you line break. As simple as that.

Hawk, this is a sticky thread and a lot of people read this, so better to fix.
PHP Code:

#define MyNewIsUserAlive( %1 ) is_user_alive( %1 ) 


Fixed, thanks.

joaquimandrade 01-16-2010 01:48

Re: [TUT] Code Styling
 
Quote:

Originally Posted by hleV (Post 758140)
Nice.

I myself prefer HN.

Didn't knew that this was possible:
Code:
MyFunction( id ) if( is_user_alive( id ) ) { client_print( 0, print_chat, "We are now killing %d", id ) user_kill( id ) }

o_O

About function names... I'm still not decided, but currently I write only the first letter (or letters, if function's type title is made from 2 words, like forward - fw). Like eDeathMsg() for event and cSay for command. Also sPrint() for stock.

BTW is the g_Test pointer (although danielkza said there are no pointers in Pawn) or a normal integer?
Code:
g_Test = register_cvar("amx_test", "1");

I was used to treat it as pointers (so g_Test was g_pTest) but then I realized I have no idea what pointer really is so now I treat is as normal integer (g_Test is now g_iTest). Which one is more correct?

There is some confusion in this old post but for those who read it and don't understand why is pointer mentioned on it and what does pointers have to do with pawn:

In pawn there isn't the concept "pointer" (a variable which value is an address and that, with features of the language, can be used to perform operations on/with the data that is located at that address).

What is happening here is that register_cvar returns an address that in a language like C++ can be used as a pointer but in Pawn it can only be provided to a native in C++ so that it can be used as a pointer. So g_Test holds an address but that isn't enough to make it a pointer because pawn doesn't has pointers.

Seta00 01-16-2010 12:27

Re: [TUT] Code Styling & Good Programming Habits
 
Quote:

Originally Posted by SnoW (Post 1055985)
Your reasoning is just unbelievable. If you wanted to have all the code in one line you could, but that's not you want. You want the code to look decent, readable and not ugly and that's why you line break. As simple as that.

You didn't understand what I mean, I don't want 1-line code.

Quote:

Originally Posted by Bugsy (Post 1056461)
Readability is far more important than line count. If you are worried about fitting more code on one page, reduce your font size :grrr:. Furthermore, code looks ugly when there's not a new-line before an opening bracket. Yes, I can look at any code and still know what is going on but it is a hell of a lot easier to read with proper line-breaks, spacing, and indentation.

Having the opening bracket in the same line of the "code block starter" statement doesn't interfer with readability. Think of you reading some code, when you see an "if" or a "do" or a "while" or anything that imply a code block, you already know that there's a code block coming, and indentation makes that more explicit. But, in the other hand, you can't predict when the code block will end, that's the reason to put the closing bracket alone in one line. More code fitting in the page is for consistency, is way better to have functions that fit in one page, so you don't need to scroll up and down following the execution path.

Bugsy 01-16-2010 12:50

Re: [TUT] Code Styling & Good Programming Habits
 
Quote:

Originally Posted by Seta00 (Post 1057132)
You didn't understand what I mean, I don't want 1-line code.

Having the opening bracket in the same line of the "code block starter" statement doesn't interfer with readability. Think of you reading some code, when you see an "if" or a "do" or a "while" or anything that imply a code block, you already know that there's a code block coming, and indentation makes that more explicit. But, in the other hand, you can't predict when the code block will end, that's the reason to put the closing bracket alone in one line. More code fitting in the page is for consistency, is way better to have functions that fit in one page, so you don't need to scroll up and down following the execution path.

You can explain it to me any way you want, I personally think putting the opening bracket on a new line looks much nicer. Do you put an opening bracket on the same line as a for loop and a switch too?

PHP Code:

for ( new i++ ) {

switch ( 
Val ) { 



All times are GMT -4. The time now is 02:32.

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