Difference between revisions of "User:Void Singer/Formating"

From Second Life Wiki
Jump to navigation Jump to search
m (cleanup)
m (updating from LSL tags to SOURCE tags)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
<div id="box">
<div style="float:right;">__TOC__</div>{{void-box
== Coding Practices: Formatting ==
|title=[[User:Void_Singer|Return to Void Singers user page]]
<div style="padding: 0.5em">
}}
this is a listing of how I format code, for readability and self documentation, not everyone likes it, but if you use something and stick with it, others will thank you, and you'll thank yourself later when you look at it and your eyes want to glaze over thinking "WTF was I doing?"
 
{{void-box
|title=Disclaimer:
|content=
Some of these rules were chosen arbitrarily, because SOME standard is better than none at all. If my rules disagree with the ones you prefer, use your own. This is only what I do.
}}
 
{{void-box
|title=Formatting
|content=
this is a listing of how I generally format code, for readability and self documentation, not everyone likes it, but if you use something and stick with it, others will thank you, and you'll thank yourself later when you look at it and your eyes want to glaze over thinking "WTF was I doing?" You definitely don't have to format yours the same way. This is just here to share.
#variables:
#variables:
#* all user variables are prefixed with "v" (for variable) [so we can quickly Id variables]
#* all user local variables are prefixed with "v" (for variable) [to quickly Id variables]
#* all variables have their type included in 3 letters (eg. vStrData) [so we know the type, saves debugging typcast problems]
#* all variables have their type included in 3 letters (eg. vStrData) [so I know the type, saves debugging typecast problems]
#* all variables denote what they are for (eg. key vKeyOwner = llGetOwner();) [saves on comments, makes it esay to know what we're doing]
#* all variables denote what they are for (eg. key vKeyOwner = llGetOwner();) [saves on comments, makes it easy to know what I'm doing]
#* all States prefixed "vs" -eg vsStateName [so we can id states]
#* all States prefixed "s" -eg sStateName [to id states]
#* all user defined functions prefixed "vf" and return type -eg vfFunctionName [so we can Id functions and their return types]
#* all user defined functions prefixed "u" -eg uFunctionName [to Id functions and return types]
#* All Globals are prefixed with "vg" (for variable-global) [makes it easy to spot globals]
#* All Globals are prefixed with "g" [to spot globals]
#* All Constants are prefixed "c" and placed in all caps to distinguish from ll -eg cSTR_TITLE [easier to spot non ll constants, and avoid possible conflicts with new ll constants]
#* User Functions, User States, and variables use CamelBack style (capitalized words, no spaces/underscores)
#* Bitmasks and booleans are given type "vBit" and "vBoo" [so we know how they are being used]
#* All Constants are prefixed "c", use all Caps, and underscores -eg cSTR_TITLE [spot non-LSL constants, avoid conflicts with new LSL constants]
#* Vectors describing Size, Position, or Color are given as vSiz, vPos, & vCol, respectively
#* Integers only used for index numbers are given a type "Idx" [quickly Id usage]
#Comments: [use lots of them to help us remember/see what code is trying to do]
#* Bitmasks and booleans are given type "Bit" and "Boo" (eg. vBitX, gBooY) [to know how they are being used]
#*Sections/Headers: "//--// text //--//"
#* Vectors describing Size, Position, Degrees, or Color are given as Siz, Pos, Deg, & Col, respectively
#*Code: " //-- the line below does X" (note the extra space indent
#Braces, brackets, and parentheses:
#*Edit/Notes: " //-- the line to the left is editable or could use changes"
#* Functions: space away from the container -eg. llRound( vIntNumber ); [makes it different from grouping]
#Brackets/Whitespace:
#* math: always separate math (eg. "2 + 2", exception increments --x, ++x) [easier to read/debug, prevent unary operator errors]
#*Functions: space away from the container -eg. llRound( vIntNumber ); [makes it different from grouping]
#* Grouping: do not space inside, or out -eg. ((vIntNumber + 2) * 5) [makes it different from functions]
#*math: always separate math -eg 2 + 2, exception increments --x, ++x [easier to read/debug]
#* Events: follow function rules -eg. touch_start( integer vIntTouches ){
#*Grouping: do not space inside, or out -eg. ((vIntNumber + 2) * 5) [makes it different from functions]
#* If/Loop/while: follows grouping rules with a space before group -eg if (TRUE){
#*Events: follow function rules + { -eg. touch_start( integer vIntTouches ){
#* Variables in if/loop/while tests go to the right of the comparison operator -eg if (FALSE == vBooVariable) [reduces assignment errors]
#*If/Loop: follows grouping rules with a space before group, and trailing { -eg if (TRUE){
#* All control structures, states, user functions: "{" goes on the same line as the calling body, "}" after the last entry, and are ALWAYS used [readability, debugging, code insertion safety, see [1TBS]]
#*loops, if/else, events, states, functions: "{" goes on the same line as the calling body, "}" after the last entry, and are ALWAYS used (even where optional) [for readability & debugging]
#Comments: [use lots of them to remember/see what code is trying to do]
Note:
#* Sections/Headers: "/*//-- text --//*/"
Due to disagreement about placing "{" on the same line as the originating structure, they
#* Code: " //-- the line below does X" (note the extra space indent)
will be on the line following the structure for WIKI function examples... it's a matter of
#* Edit/Notes: " //-- the line to the left is editable or could use changes"
personal taste and practice for me, so not a big deal =)
#WhiteSpace/Indenting:
#General WhiteSpace:
#* blank line between event [groups event code]
#*blank line between event [easier to read]
#* blank line between sections of code doing different things [groups similar actions]
#*blank line between sections of code doing different things [groups like actions]
#* tabs are set at 2 spaces, use tabs for indenting when available [reduces wrapping of nested items]
#*tabs are 2 spaces, to reduce wrapping for nested items. any items inside a loop, if/else, event, state, or function recieves a tab [saves wrapping, eaiser to read/debug]
#* All items inside a control structure, state, or user function are indented one level [easier to read/debug]
#Special Cases:
#Special Items:
#* Bitmasks given as numbers are in uppercase hex -eg. 0xFFFFFFFF [easier to see usage]
#* Bitmasks, Keys, and hexadecimal codes are in uppercase -eg. 0xFFFFFFFF [to see usage, readability]
#* Long tests/function calls: wrap each variable/container to the next line with level spacing -eg see below [easier to read, less sloppy than built in wrapping]
#* Long tests/function calls: wrap each variable/container to the next line with level spacing -eg see below [readability, cleaner than built in wrapping]
<pre>
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
//--// this is an example script   //--//
}}
//--// it has no real purpose other //--//
 
//--// than to show my formatting   //--//
{{void-box
|title=Practices
|content=
# Declarations
#* When declaring variables, or user functions, try to keep names short but descriptive. (improve readability)
#* If a name short descriptive name is not enough, add a comment to it explaining it (improve readability)
#* If a variable will need a non-default start value, include it in the declaration. (less code)
#* Use table style formatting for multiple variable declarations. (improve readability)
#* Rewrite LL supplied event variables names to the formatting rules above (improve readability)
#* When Possible declare variables before the scope they will be used in (less memory, clearer scope identification)
# user input / data integrity (AKA trust no one)
#* Sanitize everything. llToLower, break into parts (if needed), then llStringTrim (Users are stupid and/or malicious)
#* Never assume data types, check and cast if not sure (Users are stupid and/or malicious)
#* Filter all data for only the parts you need (LL can be stupid too)
# code structures
#* Do not make assumptions about order of operation, or order of execution (things are not always what they seem)
#* Never assign/increment a variable on a line where it's used more than once (improve readability, things can change)
#* Inline assignments should always be parenthesized  (improve readability, ensure integrity)
#* Avoid combining boolean tests with non-boolean tests in the same test statement (improve readability, ensure integrity)
#* prefer lists over if/else for static returns/actions (faster, less memory)
#* Prefer multiple lists over strided lists (memory and speed are improved)
#* Prefer Binary if trees over flat if/else chains (faster execution in general)
# Statements
#* avoid multiple statements on one line. (improve readability)
# Line Counts
#* Do not count comment lines (it doesn't do anything)
#* Do not count whitespace lines (it doesn't do anything)
#* Do not count lines with no statements -eg closing braces (it doesn't do anything)
#* Do not count required state/event declarations in which all variables are ignored (we didn't really write/use anything)
#* Do count user declarations, statement lines, and user defined state lines (this is actual written code)
#* Refer to as "lines of actual code"
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
}}
 
{{void-box
|title=Example
|content=
<source lang="lsl2">
/*//-- this is an example script --//*/
/*//
it has no real purpose other
than to show my formatting
//*/


string  cSTR_TITLE = "example script" //-- something to tell the user later
//-- notice table style formatting of the next two lines, uses spaces to do this
integer  vgIntTotalTouches = 0;
string  cSTR_TITLE = "example script:"; //-- the line to the left is a constant
integer  gIntTotalTouches = 0;


string vfStrFunctionExample( key vKeyOwner ){
string uStrKey2Name( key vKeyAvatar ){
   return llKey2Name( vKeyOwner );
   return llKey2Name( vKeyAvatar );
}
}


default{
default{
   state_entry(){
   state_entry(){
     llOwnerSay( "Hi, " + vfStrFunctionExample( llGetOwner() ) );
     llOwnerSay( "Hi, " + uStrKey2Name( llGetOwner() ) );
   }
   }


Line 56: Line 109:
       //-- below is the example of wrapping functions parameters
       //-- below is the example of wrapping functions parameters
       llSay( 0,
       llSay( 0,
             cSTR_TITLE + " has been touched "           //-- this is an example of
             cSTR_TITLE + " has been touched " +        //-- this is an example of my
                        + (string)(++vgIntTotalTouches) //-- string wrapping, always
                          (string)(++vIntTouchCount) //-- function wrapping, lines end
                        + " times" );                    //-- has + in the front
                          " times" );                    //-- with math/join symbols
     }while (--vIntTouchCount > -1);
     }while (--vIntTouchCount);
   }
   }


   changed( integer vBitChanged ){
   changed( integer vBitChanged ){
     if (vBitChanged & CHANGED_OWNER){
     if (CHANGED_OWNER & vBitChanged){ //-- variables on the right in tests
       state vsReset
       state sReset;
     }
     }
   }
   }
}
}


state vsReset{
state sReset{
   state_entry(){
   state_entry(){
     llSay( 0, "New Owner " + vfStrFunctionExample( llGetOwner() ) + " detected; reseting" );
     llSay( 0, "New Owner " + uStrKey2Name( llGetOwner() ) + " detected; resetting" );
     llResetScript();
     llResetScript();
   }
   }
}
}
</pre>
</source>
</div></div>
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
}}


<div id="box">
{{void-box
== Comments ==
|title=Comments
<div style="padding: 0.5em">
|content=
Feel free to leave me a note on my [[User_talk:Void_Singer|User Talk]] page.
Feel free to leave me a note on my [[User_talk:Void_Singer|User Talk]] page.
</div></div>
}}

Latest revision as of 09:45, 26 January 2015

Disclaimer:

Some of these rules were chosen arbitrarily, because SOME standard is better than none at all. If my rules disagree with the ones you prefer, use your own. This is only what I do.

Formatting

this is a listing of how I generally format code, for readability and self documentation, not everyone likes it, but if you use something and stick with it, others will thank you, and you'll thank yourself later when you look at it and your eyes want to glaze over thinking "WTF was I doing?" You definitely don't have to format yours the same way. This is just here to share.

  1. variables:
    • all user local variables are prefixed with "v" (for variable) [to quickly Id variables]
    • all variables have their type included in 3 letters (eg. vStrData) [so I know the type, saves debugging typecast problems]
    • all variables denote what they are for (eg. key vKeyOwner = llGetOwner();) [saves on comments, makes it easy to know what I'm doing]
    • all States prefixed "s" -eg sStateName [to id states]
    • all user defined functions prefixed "u" -eg uFunctionName [to Id functions and return types]
    • All Globals are prefixed with "g" [to spot globals]
    • User Functions, User States, and variables use CamelBack style (capitalized words, no spaces/underscores)
    • All Constants are prefixed "c", use all Caps, and underscores -eg cSTR_TITLE [spot non-LSL constants, avoid conflicts with new LSL constants]
    • Integers only used for index numbers are given a type "Idx" [quickly Id usage]
    • Bitmasks and booleans are given type "Bit" and "Boo" (eg. vBitX, gBooY) [to know how they are being used]
    • Vectors describing Size, Position, Degrees, or Color are given as Siz, Pos, Deg, & Col, respectively
  2. Braces, brackets, and parentheses:
    • Functions: space away from the container -eg. llRound( vIntNumber ); [makes it different from grouping]
    • math: always separate math (eg. "2 + 2", exception increments --x, ++x) [easier to read/debug, prevent unary operator errors]
    • Grouping: do not space inside, or out -eg. ((vIntNumber + 2) * 5) [makes it different from functions]
    • Events: follow function rules -eg. touch_start( integer vIntTouches ){
    • If/Loop/while: follows grouping rules with a space before group -eg if (TRUE){
    • Variables in if/loop/while tests go to the right of the comparison operator -eg if (FALSE == vBooVariable) [reduces assignment errors]
    • All control structures, states, user functions: "{" goes on the same line as the calling body, "}" after the last entry, and are ALWAYS used [readability, debugging, code insertion safety, see [1TBS]]
  3. Comments: [use lots of them to remember/see what code is trying to do]
    • Sections/Headers: "/*//-- text --//*/"
    • Code: " //-- the line below does X" (note the extra space indent)
    • Edit/Notes: " //-- the line to the left is editable or could use changes"
  4. WhiteSpace/Indenting:
    • blank line between event [groups event code]
    • blank line between sections of code doing different things [groups similar actions]
    • tabs are set at 2 spaces, use tabs for indenting when available [reduces wrapping of nested items]
    • All items inside a control structure, state, or user function are indented one level [easier to read/debug]
  5. Special Items:
    • Bitmasks, Keys, and hexadecimal codes are in uppercase -eg. 0xFFFFFFFF [to see usage, readability]
    • Long tests/function calls: wrap each variable/container to the next line with level spacing -eg see below [readability, cleaner than built in wrapping]
Return to top

Practices

  1. Declarations
    • When declaring variables, or user functions, try to keep names short but descriptive. (improve readability)
    • If a name short descriptive name is not enough, add a comment to it explaining it (improve readability)
    • If a variable will need a non-default start value, include it in the declaration. (less code)
    • Use table style formatting for multiple variable declarations. (improve readability)
    • Rewrite LL supplied event variables names to the formatting rules above (improve readability)
    • When Possible declare variables before the scope they will be used in (less memory, clearer scope identification)
  2. user input / data integrity (AKA trust no one)
    • Sanitize everything. llToLower, break into parts (if needed), then llStringTrim (Users are stupid and/or malicious)
    • Never assume data types, check and cast if not sure (Users are stupid and/or malicious)
    • Filter all data for only the parts you need (LL can be stupid too)
  3. code structures
    • Do not make assumptions about order of operation, or order of execution (things are not always what they seem)
    • Never assign/increment a variable on a line where it's used more than once (improve readability, things can change)
    • Inline assignments should always be parenthesized (improve readability, ensure integrity)
    • Avoid combining boolean tests with non-boolean tests in the same test statement (improve readability, ensure integrity)
    • prefer lists over if/else for static returns/actions (faster, less memory)
    • Prefer multiple lists over strided lists (memory and speed are improved)
    • Prefer Binary if trees over flat if/else chains (faster execution in general)
  4. Statements
    • avoid multiple statements on one line. (improve readability)
  5. Line Counts
    • Do not count comment lines (it doesn't do anything)
    • Do not count whitespace lines (it doesn't do anything)
    • Do not count lines with no statements -eg closing braces (it doesn't do anything)
    • Do not count required state/event declarations in which all variables are ignored (we didn't really write/use anything)
    • Do count user declarations, statement lines, and user defined state lines (this is actual written code)
    • Refer to as "lines of actual code"
Return to top

Example

/*//-- this is an example script  --//*/
/*//
 it has no real purpose other
 than to show my formatting
//*/

//-- notice table style formatting of the next two lines, uses spaces to do this
string   cSTR_TITLE = "example script:"; //-- the line to the left is a constant
integer  gIntTotalTouches = 0;

string uStrKey2Name( key vKeyAvatar ){
  return llKey2Name( vKeyAvatar );
}

default{
  state_entry(){
    llOwnerSay( "Hi, " + uStrKey2Name( llGetOwner() ) );
  }

  touch_start( integer vIntTouchCount ){
    do{
       //-- below is the example of wrapping functions parameters
      llSay( 0,
             cSTR_TITLE + " has been touched " +         //-- this is an example of my
                          (string)(++vIntTouchCount) +   //-- function wrapping, lines end
                          " times" );                    //-- with math/join symbols
    }while (--vIntTouchCount);
  }

  changed( integer vBitChanged ){
    if (CHANGED_OWNER & vBitChanged){ //-- variables on the right in tests
      state sReset;
    }
  }
}

state sReset{
  state_entry(){
    llSay( 0, "New Owner " + uStrKey2Name( llGetOwner() ) + " detected; resetting" );
    llResetScript();
  }
}
Return to top

Comments

Feel free to leave me a note on my User Talk page.