zoukankan      html  css  js  c++  java
  • MAX脚本规范

    MAXScript Coding Standards

    17
    votes

    This document should be used as a source of input when developing your own, or your company’s, coding standards for MAXScript. There are many ways to format code, this style being just one of near infinite choices.

    When contributing code to an existing codebase write code that matches the dominant style of the already written code. It is always better to be consistent with what has already been done than to have multiple coding styles interspersed throughout a project.

    1. Names

    1.1. Make Names Fit

    Functions perform actions. A function’s name should reflect that fact. WriteSettingsData() is much more descriptive than SettingsData().

    Structures contain data but (normally) do not perform any actions. Structure names should be in the form of nouns. If the structure contains an embedded function the structure’s name should not imply an action, as the structure is more importantly a data format.

    Variable names should be long enough so that anyone reading the code can easily derive the type and use for the data the variable holds. While a simple for loop counter can be a single letter like, “i”, an array name of aVerts could mean an array of texture vertices, an array of geometry vertices, an array of free-form deformation modifier control points, or any of a number of different vertex types. aTextureVerts is a much more descriptive, therefore useful, name.

    1.2. Include Type in Names

    MAXScript has a large number of data types and trying to easily categorize all of them would be impossible. Yet, prefixes for variable names that hold the most often used types helps to make the code more readable.

    iVar: integer
    fVar: float
    tVar: time
    aVar: array
    sVar: string
    ssVar: stringStream
    cVar: color
    p2Var: point2
    p3Var: point3

    etc…

    MAXScript is a type-free language. It is possible, for instance, to store a string in a variable that is currently holding a float. To maintain readability of the code a variable should always hold the type of data it is assigned at declaration. If there is need to recast a variable the keyword as should be used to change the type of the variable for only the statement in which it is being used:

    messageBox (“The value is: “ + (fVar as string))

    In addition to variable names prefixes should be used when naming UI controls to help identify what type of control the name refers to:

    actxVar: activeXControl
    bmpVar: bitmap
    btnVar: button
    cbxVar: comboBox
    chkVar: checkbox
    ckbtnVar: checkButton
    cpVar: colorPicker
    ddlVar: dropDownList
    edtVar: editText
    grpVar: groupBox
    lblVar: label
    lbxVar: listBox
    mbtnVar: mapButton
    mlbxVar: multiListBox
    mtlbtnVar: materialButton
    pbVar: progressBar
    pbtnVar: pickButton
    rdoVar: radioButtons
    rltVar: rollout
    sldVar: slider
    spnVar: spinner
    tmrVar: timer

    1.3. Case Usage
    1.3.1.Variables

    The prefex of a variable name should be in all lowercase. The remaing words in the variable name should all be initial cap. iVar, not IVar, ivar, or iVAR.

    1.3.2.Functions, Structures, and Arrays

    Functions should be named with all words initial cap even if words or abbreviations within the name are normally written in all uppercase. GetBoolIniSetting() instead of GetBoolINISetting().

    1.3.3.Keywords and Methods

    MAXScript methods and keywords should be written with the first word in lowercase and any following words initial caps. This helps to differentiate MAXScript commands from user created functions or structures. messageBox, findString, matchPattern, getNodeByName, etc…

    2. Comments

    Documents should be written while the script is being written. There is rarely time to go back and comment a script after it is finished. Even if the chance arises to document a script later it won’t be as easy as documenting ideas while the script is being written.

    The first line after a function declaration and its opening parenthesis should be the beginning of a blockquote, /*. The blockquote should contain enough information to describe the purpose of the function, what parameters it uses, and what, if any, results it returns. Even if the description is one line long it should be contained within blockquotes. This helps separate the function description from any inline quotes contained within the function.

    fn CalculateResult iValue1 iValue2 &iResult =
    (
    /*
    Takes the two integer parameters iValue1
    and iValue2 and adds them together. The
    answer is assigned to the reference
    parameter iResult.
    /*


    iResult = iValue1 + iValue2
    )


    Quotes used elsewhere in the script should always be inline quotes, even if they require multiple lines. This helps differentiate them from function descriptions.

    -- Extract the properties for an animation so we can get
    -- the props. This will go through all notes in a range.
    -- Sometimes the properties aren't in the begin/end
    -- notes.

    local iKey
    local sPropName



    Always add a comment after the closing parenthesis of a loop or conditional indicating the end of that code block. This helps to delineate where each loop or conditional ends. This is especially useful in scripts that have multiple layers of nested loops and/or conditionals.

    -- For all of the gathered texturemaps scan them to
    -- see if any of them has the extension we’re looking
    -- for. This can’t be done mapped, unfortunately.
    for MyMap in aTextureMaps do
    (
    if (matchPattern MyMap.name pattern:”.dds”) then
    (
    ) -- if conditional valid
    else
    (
    ) -- condition not valid
    ) -- end of the “for MyMap in a Texturemaps” loop


    3. Formatting

    3.1. Indentation

    Different text editors interpret tabs in vastly different ways. What might look like a nice two space indent in UltraEdit can come across as a 16+ space indent in Max’s internal MAXScript editor. For this reason tabs should be avoided whenever possible. If there is consensus within a company or group as to how many spaces indented lines should be indented then each individual user can make the personal determination as to whether they want to manually space in or set their editor’s tab stop to use spaces instead of a tab character. In this way the code will retain it’s formatting on any number of machines and across any number of different text editors.

    Visually an indent of two (2) spaces is pleasing to the eye and indents the line enough to make the indentation noticeable.

    3.2. Spacing

    White space helps in readability. Spaces should be used wherever they will aid in readability. Spaces should always come after words/commands and around mathematical operators.

    for i = 1 to 100 do
    (
    iResult = iInput * i

    ) -- end of for loop

    is much more readable than

    for i=1 to 100 do
    (
    iResult=iInput*i
    ) -- end of for loop

    3.3. One Statement Per Line

    To provide maximum readability individual statements should be on separate lines.

    3.4. Maximum Line Length

    Lines of code should be no longer than 78 characters. While large monitors with high resolutions are the norm there are times when code needs to be printed. If a line of code exceeds 78 characters it will print on multiple lines, throwing off the code formatting.

    3.5. Parenthesis/Brace Policy

    There are two generally accepted strategies for parenthesis/brace placement:

    if (condition)
    (

    )

    or

    if (condition) (

    )

    The first form is the strategy that should be utilized. Without getting into yet another UNIX vs The World argument (UNIX code tends to use the second form) the first form provides two benefits of the second:

    1. It is easier to understand at a glance.
    2. If you use an editor that supports brace-matching, like UltraEdit, you can find the corresponding brace with a simple command. While this might not seem like an advantage to a simple conditional, as shown above, its increased efficiency is easily shown with a slightly more complex example:

    if (condition)
    (

    )
    else
    (

    )

    In this example to find the corresponding else clause to the if clause, regardless of how many lines of code lie between the two, all the user has to do is position their cursor to the left of the if statement, press the down arrow to go to the opening parenthesis, execute the brace-matching command to find the corresponding closing parenthesis, and press the down arrow a second time to get to the else statement. Regardless of how many blocks of code exist the user can get between them with the down arrow key and the brace-matching command.

    If the code was formatted using the UNIX style of having the opening parenthesis/brace on the statement line, the user would have to go to the end of the line to find an opening parenthesis in order to use it with the brace-matching command to find the end of the block.
    3.6. Function, If/Then/Else, For/Do, While/Do, and Try/Catch Formatting

    All conditionals, loops, exception handling blocks, and functions should always be formatted to use open/close parenthesis and multiple lines. For example:

    Correct
    for i = 1 to 10 do
    (

    )

    Incorrect
    for i = 1 to 10 do …

    The reason for this is simple. If the code needs to be edited later to add more statements to the loop the first example is already formatted to include those statements as part of the block. The parenthesis and multiple lines also provide visual cues as to what statements are included within the block.

    3.7. Never Use If/Do

    The conditional form of if/do should never be used in a MAXScript. While if/do is syntactically correct in MAXScript its use can cause problems when the script is edited later. If/do does not allow for an else clause. If there is an if/do conditional it is possible for a person editing the code later to add an else clause and then be presented with the cryptic error,

    -- Syntax error: at else, expected <factor>
    -- In line: else

    In extremely large scripts it could take quite some time to track down the cause of this error. Be safe, always use if/then. It doesn’t require an else clause, but will use one if it is available.

    3.8. Case/Of Statement Formatting

    Unlike other languages MAXScript’s case statements do not support fall-through. A determination is made at the start of the case/of statement to determine the of state. Then the correct provided case, or default, is jumped to immediately. For this reason the default case should always be provided. Without it the script will fail if an unsupported case is encountered. If the assumption is that the default case will never be triggered then it should be written to trap the error and alert the user.

    As with other formatting only one case expression should exist per line. If the case expression is comprised of multiple statements then the entire block should be within parenthesis.

    case iCounter of
    (
    1: print (“The counter is: “ + (iCounter as string))
    2: (
    for z = iCounter to aTextures.count do
    (
    print aTextures[z].name
    ) -- end of “for z” loop
    )
    default: messageBox “iCounter is out of bounds.”
    )

    4. Ways To Make MAXScript Faster

    Information contained in this section is paraphrased from the “How To Make It Faster?” topic in the MAXScript help file. The information appears here for the sake of brevity.

    4.1. Use Mapped Functions Instead Of For Loops

    MAXScript supports performing a single operation on multiple objects in a selection simultaneously. The internal loop that accomplishes this can be faster than a MAXScript loop performing the operation on each item in the selection. The MAXScript help file notes which methods and functions can be used
    as mapped.

    4.2. Cache Frequently Used Data

    If code frequently calls the same MAXScript method, object, property, etc.., say while in a loop, it is best to move that method statement outside of the loop, assign the results to a variable, and call that variable within the loop. Getting the resultant data from the variable is much faster than waiting for the method to generate a result during each loop iteration.

    4.3. Don't Use Return(), Break(), Exit(), Continue(), or Throw()

    These methods use C++ exceptions which are excruciatingly slow. If you need to return a result from a function code the function to accept a reference as a parameter and put the result directly into the reference. Instead of break(), exit(), or continue() use the for/while/do variant of a for loop. For/while/do loops behave exactly like for/do loops but will halt and the end of a loop iteration if the while condition has changed from true to false.

    4.4. Use StringStreams to Build Large Strings

    In MAXScript each string addition creates a new string to hold the result. If strA = “AAA” and you assign strB as strB = strA + strA + strA three strings will be created.

    StringStreams can be added to and the length of the stringstream will be increased to hold the new data without causing new strings to be created. Once you’ve added all of the information to the stringstream convert it back to a string for use.

    4.5. Don't use Execute()

    To paraphrase a quote by Larry Minton, “If you’re using execute() you’re doing it wrong.” The MAXScript reference help file lists only two valid uses for execute(), Dynamic rollout creation and dynamic scripted custom attribute creation. For anything else chances are great that a MAXScript method, property, keyword, or function exists.

    4.6. Don't Use Persistent Global Variables

    While not tied to performance, persistent global variables should not be used. Storing useful information in the .max scene file, for use during a later editing session does have its benefits, but the implementation of persistent global variables can lead to corrupt data, globals being inadvertently stored on all scene files opened after the globals are declared, and various other issues. Additionally persistent global variables are only accessible via MAXScript, which limits their usefulness.

    Instead of persistent global variables use scripted custom attribute blocks to store data that should remain between editing sessions. Scripted CAs don’t suffer the same limitations as persistent global variables and can be accessed via the Max SDK, making the data stored within them accessible to both scripts and plugins.
  • 相关阅读:
    html 锚点
    html table 表格详解
    IE6 不识别css固定元素位置(fixed)属性
    css hack 方法总汇2
    css hack 方法总汇1
    JS刷新父窗口的几种方式
    手动切换选项卡
    自动切换选项卡
    jquery 判断 radio,checkbox,select是否被选中
    EasyUI 各种json数据格式
  • 原文地址:https://www.cnblogs.com/softimagewht/p/1785963.html
Copyright © 2011-2022 走看看