Doxygen

From Bohemia Interactive Community
Revision as of 18:58, 24 July 2024 by Lou Montana (talk | contribs) (Some additional details)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Doxygen is a tool that generates documentation from code comment respecting a certain format. This code documentation is used across Enfusion projects, starting with Arma Reforger.

What is not documented does not exist!


Project Documentation

Game File Location Download
Arma Reforger Arma Reforger Tools \ Workbench\docs Arma Reforger Scripting Guidelines Hub


Bohemia Interactive Guidelines

Documentation is important:

  • Document what is public (protected methods go second - people should use public methods anyway)
  • Document what is important (features, concepts, specifics like variables or constants, etc)
  • Document what is dangerous (performance-wise, crash-wise)


Bohemia Interactive recommendations:

  • use //! and //!<
    • /*! */, /// and /** */ are to be avoided (inline comment is preferred in order to remain able to comment big chunks of code with /* */ without conflict)
  • do not go too much into details (e.g //! This method does xxx if provided Y but will not do it if Z is set to true at line 246 and ...)
  • do not over-document code (e.g //! Get the name on string GetName() is of absolutely no value); again, code should be self-explanatory and a comment should explain a design decision (if needed)

See Examples below.


Reminder: an eventual code comment tells why code is done this way,

method comment plainly explains what the method does / when it should be used, and class comment explains the whole system / feature of this class.

For a system / feature that spans across multiple classes, Doxygen grouping is required. See Doxygen Grouping documentation.

Class

A class documentation explains what the class does. It can add said class to groups (see Doxygen's grouping documentation). Grouping is usually done in a different comment block than class comment.

//! This class is a databag used by the TAG_WholeSystemClass's WholeSystem feature. //! Member variables are public for that purpose. It holds info X and Y related to Z. class TAG_MyDataClass { bool m_bIsValid; int m_iNumber; ref TAG_OtherDataClass m_OtherData; }

Method

A method documentation goes below the //--- separator and must ideally document the method's purpose, its parameters, and its return value.

Always amend the documentation when changing a method's signature/behaviour!

class Example { //------------------------------------------------------------------------------------------------ //! Documentation goes here with the same indent int GetIntMethod1(bool returnPositive) { // method content } //------------------------------------------------------------------------------------------------ /*! Alternative syntax - not recommended in Arma Reforger Note that indentation is on the same level as the comment start */ int GetIntMethod2(bool returnPositive) { // method content } }

Various parameter formats:

//! \param[in] myParam parameter description //! \param[out] myParam parameter description //! \param[in,out] myParam parameter description

Only one return format:

//! \return return value description

To be used when a void signature is not used.

Variable

//! a member variable can be documented like this protected float m_fVar1; protected float m_fVar2; //!< or like this - the '<' symbol means "document what just precedes"


Examples

Do

This example is taken from SCR_ObstacleDetector:

//------------------------------------------------------------------------------------------------ //! Detects obstacles based on current settings - a SCR_ObstacleDetector.RefreshObstaclesBy*() method must have been called earlier //! \param[in] worldPos the location to check - only the 2D position will be checked //! \param[in] exclusionList list of entities that should not be considered as obstacles //! \return true if an obstacle has been detected or on error, false otherwise bool HasObstacle(vector worldPos, array<IEntity> exclusionList = null)

This comment is fine for multiple reasons:

  • the main description states the method's goal and usage condition
  • parameters are documented and specifics (when present) are explained
  • the return value is described accurately
  • error cases are covered

Don't

Example Explanation
//------------------------------------------------------------------------------------------------ //! Returns true if has obstacle bool HasObstacle(vector worldPos, array<IEntity> exclusionList = null)
  • the description is straightforward but does not provide context
  • parameters are not described
  • return value is included in the description and only covers one case (when everything works)
//------------------------------------------------------------------------------------------------ //! Returns true if has obstacle //! \param[in] worldPos the world position //! \param[in] exclusionList the exclusion list //! \return true or false bool HasObstacle(vector worldPos, array<IEntity> exclusionList = null)
  • the description is still straightforward without context
  • parameter descriptions are based on their name and do not help understanding further
  • the return value's description describes the value itself and not the added value
//------------------------------------------------------------------------------------------------ //! Returns false when an obstacle is detected bool HasObstacle(vector worldPos, array<IEntity> exclusionList = null)

This one is one of the worst possible cases: no comment is better than a wrong comment.
Prefer leaving it undocumented (ideally with a // TODO) if you do not have the time to document your code at the moment.


See Also