XGL Architecture Guide
  Sök endast i den här boken
Ladda ner denna bok i PDF

XGL Coding Guidelines

7

This chapter discusses XGL naming conventions for C++ constructs and internal C++ classes, and presents the coding conventions for XGL member data accessor functions.

Naming Conventions for C++ Constructs

The intent of the XGL naming scheme is to provide consistency, simplicity, and ease of distinction between C and C++ features. In this scheme, XGL identifies C++-specific constructs by concatenating multiple-word names with the first letter of each word capitalized, while other constructs that fall within the C domain preserve the C underscore naming style to ease migration and maintain C API compatibility. Identifiers in the global name space are prefixed with the package name to avoid conflicts.
The specific naming conventions are as follows:
  • Class names: XglFooClass - Class names begin with the Xgl prefix to avoid name conflicts. The first letter of a class name is capitalized, and if the class name is a compound word, the first letter of each subsequent word is capitalized.
  • Class member data: dataMember - The first letter of a member data name is lower case, but if the member data name is a compound word, the first letter of each subsequent word is capitalized. Capitalization distinguishes member data and local variables/function arguments within a member function when the variable names are compound words. No further effort is made to distinguish member data from local variables or function
arguments, however, as the latter declarations are always within the same scope and should be easy to locate. Since global variables (which should be avoided) always start with a capital letter, no confusion will occur.
  • Member functions: memberFunc() - The first letter of a member function name is lower case, but if the member function name is a compound word, the first letter of each subsequent word is capitalized. Capitalization distinguishes member functions from non-member C++ functions and maintains consistency in naming C++-specific constructs.
  • Regular (global or file static) C++ functions (non-extern "C"): XgliGlobalFunc() - The first letter of regular C++ function is capitalized, and the first letter of each subsequent word in a compound function name is also capitalized.
  • Macro values, enumerated fields, and constants: XGL_CONST_VALUE - Macros, enumerated fields, and constants are upper case with underscores separating the words. This follows the C convention for #define constants; however, #define should not be used to define constants except in the C API. Instead, constants and enumerated values should be used to allow for proper type-checking and scope-related constants.
  • Macros and global inline functions: XGL_INLINE_FUNC() - Inline function names are upper case. Inline functions should be used in place of macro functions except in the C API. Inline functions are expanded at compile time and produce semantically correct results as well as allowing type checking.
  • Global variables: Xgli_global_var - In general, all global variables should be scoped within a class as static member data and accessed only through static member functions. However, if it is determined that a global variable is necessary, then the first letter of the global variable name is capitalized. Compound words are constructed with underscores separating the words. The Xgl package prefix is added where appropriate.
  • Local variables and function arguments: local_or_param - Local variables and function arguments are lower case, with multiple-word variables separated by underscores. The use of underscores distinguishes local variables and function arguments from member data inside member functions.
  • Typedef, enumerated types, and C API structures and unions: Xgl_typedef - Although typedef and enum identifiers are also type names, and structures and unions are semantically similar constructs to
classes, typedefs and enums are so extensively used in the existing C API that their naming should follow the C convention, which is the first letter capitalized and compound words separated by underscores. For the same reason, this rule extends to structure and union fields in the API. It is useful to be able to distinguish "pure" C structures and unions that do not use any C++ features in this way, although C++ does not differentiate them semantically. For C++-specific usage, class should always be used in place of struct, while the union type should be avoided as it defeats strong type checking.
  • Extern "C" functions: xgl_object_create() - To preserve the C API interface, all extern "C" functions used as C wrappers should use the C function naming style, which is lower case with compound words separated by underscores. This also allows clear distinction from their C++ counterparts.
  • Pointers and reference variables: int* a; int& b = *a For pointers and reference variables, bind * and & to the type except in lists. The placement of * and & should be consistent. It is visually less confusing to declare a C++ reference type as int& b than as int &b (since &b is like taking the address in C). It is more coherent to use
A& XgliGlobalFunc (A& a, B&);

than
A & XgliGlobalFUnc (A &a, B &);

Therefore, both * and & should be bound to the type.
One exception to this rule is when there is a list of declarators, as in:
A *x, &y=*x, *z;

in which * and & should be bound to the variables. Note that use of a declarator list is strongly discouraged. The recommended style is to declare one variable at a time with a comment for each to the right of the variable.

Summary of Naming Conventions for C++ Constructs

Table 7-1 provides a summary of the naming conventions.
Table 7-1
ConstructConventionExample
Class namesFirst letter of each word capitalized with remainder of word lowercase; Xgl prefixXglFooClass
Class member dataFirst letter lowercase with
following words mixed case
memberData
Member functionsFirst letter lowercase with
following words mixed case
memberFunc()
Regular (global or file static C++ funtions (non-extern "C")First letter capitalized with following words mixed caseXgliGlobalFunc()
Macro values, enumerated
types, constants
All capital letters with
underscores between words
XGL_CONST_VALUE
Macros and global inline
functions
All capital letters with
underscores between words
XGL_INLINE_FUNC()
Global variablesFirst letter capitalized (Xgl prefix where appropriate) and underscores between wordsXgli_global_var
Local variables and function argumentsAll lower case with underscores between wordslocal_variable
Typedefs, enumerated types, and C API structures and unionsFirst letter capitalized with underscores between wordsXgl_typedef
Extern "C" functions (for example API wrappers)All lowercase with underscores between wordsxgl_object_create()
Pointers and reference variablesBind pointers and reference types to type except in listint* a;

int& b = *a; A& XgliGlobalFunc (A& a);

exception:

A *x, &y = *x, *z;

Naming Conventions for C++ Internal Classes

The XGL C++ class naming conventions are as follows:
  1. All class names are prefixed with Xgl to avoid name collisions. For example, use XglDevice rather than Device.

  2. Compound class names are combined without underscores and with the first letter of each word capitalized.

  3. Classes are named in top-down order in the inheritance hierarchy. For example, the 2D subclass of XglContext is named XglContext2d.

  4. Common prefixes are removed when the meaning is obvious, as in the following example:

Imported image(504x109)

  1. Abbreviations are used where appropriate. For example, Context can be abbreviated as Ctx, Device can be abbreviated as Dev, and XglDevicepipelineDevice as XglDpDev.

  2. Follow common naming order, as in the example below:

Imported image(504x68)

  1. Prefix pipeline-related classes with Swp for software pipeline classes and Dp for Device pipeline classes, as in XglDpDev, or XglDpMgr.

  2. Follow the mixed-case rule even for acronyms. For example, use XglCgm rather than XglCGM.

Coding Conventions for set() and get() Interfaces

The following conventions have been adopted by XGL for the C++ member data accessor functions set() and get() both internally and externally (C++ API level).

Conventions for set() Member Functions

Following are the conventions for the set() member functions.
  1. Pass by value all base types and typedefs of base types.

    This convention includes all signed and unsigned integer base types, character base types, as well as float, double, etc. For example,

    void xgl_object_set(Xgl_ctx, XGL_CTX_CLIP_PLANES,
                  Xgl_clip_planes, 0);

maps to C++:
    void XglContext::setClipPlanes(Xgl_clip_planes);

  1. Pass "pure" C structures or unions as C++ object references.

    For example,

    void xgl_object_set(Xgl_ctx, XGL_CTX_BACKGROUND_COLOR,
              Xgl_color*, 0);

maps to C++:
    void XglContext::setBackgroundColor(const Xgl_color& color){
             backgroundColor = color; }

This is preferable to manually dereferencing a pointer every time you need to reference it as a structure, as in:
    void XglContext::setBackgroundColor(const Xgl_color* pcolor) {
              backgroundColor = *pcolor;  }

  1. Pass XGL objects, function pointers, and character strings as pointers.

    For example,

 void xgl_object_set(Xgl_ctx, XGL_CTX_DEVICE, Xgl_dev, 0);

maps to C++:
void XglContext3d::setDevice(XglDevice*);

Note that Xgl_dev is a pointer itself.
  1. Pass array types as arrays.

    For example:

 void xgl_object_set(Xgl_3d_ctx, XGL_3D_CTX_LIGHTS,
          Xgl_light[], 0);

maps to C++:
void XglContext3d::setLights(const XglLight[]);

Conventions for get() Member Functions

Following are the conventions for the get() member functions.
  1. Return by value for base types or typedefs of base types.

    For example,

 void xgl_object_get(Xgl_ctx, XGL_CTX_CLIP_PLANES,
           Xgl_clip_planes*);

maps to C++:
Xgl_clip_planes XglContext::getClipPlanes() const;

The const means that the XglContext object does not change after calling its getClipPlanes() member functions. const should be used wherever appropriate; otherwise, member functions cannot be called by class objects that are declared as const.
  1. Return "pure" C structures or unions as object references.

    For example:

 void xgl_object_get(Xgl_ctx, XGL_CTX_BACKGROUND_COLOR,
           Xgl_color*);

maps to C++:
 const Xgl_color& XglContext::getBackgroundColor() const;

const is used for return types if the internal structures are not supposed to be modified, and the user has to make a copy. So in a C++ program, you can have:
Xgl_color mycolor = ctx->getBackgroundColor();

Copying from the internal background color in the Context object to mycolor happens during the assignment.
  1. Return XGL objects, function pointers and character strings as pointers.

For example:
  void xgl_object_get(Xgl_ctx, XGL_CTX_DEVICE, Xgl_dev*);

maps to C++:
XglDevice* XglContext::getDevice() const;

  1. Follow the XGL API style for data that involve arrays of objects.

    This is an exception to the convention of returning results through function return types, as there is no implicit way to copy an array. More importantly, the only way to ensure that the internal array objects (pointers to lights in the example below) cannot be modified is to provide a copy of the whole array (of pointers), since return types like const Xgl_light[] are not allowed. Hence, array types or structures that contain pointers to array types should continue to be passed and retrieved as function parameters as in the XGL API.

    For example:

  void xgl_object_get(Xgl_3d_ctx, XGL_3D_CTX_LIGHTS, Xgl_light[]);

maps to C++:
void XglContext3d::getLights(Xgl_light[]);

Note that an exception exists even in XGL 2.0, where an application has to get the value for XGL_3D_CTX_LIGHT_NUM before it calls the above function.
 void xgl_object_get(Xgl_cmap, XGL_CMAP_COLOR_TABLE,
           Xgl_color_list*, 0);

maps to C++:
void XglCmap::getColorTable (Xgl_color_list&) const;