-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Coding Style
Note: All new C and C++ files and existing ones should adopt this style.
Coding style can be based on the following example source code. ///
comments are just for the purpose of this coding style page.
- Indent: spaces
- Indent width: 4ch
- Max line width: 128ch
Example.cpp:
/// Start with a description of the contents of this source file.
/**
* Functions related to guest creation and guest animation logic.
*/
/// Alphabetically ordered standard headers
#include <stdlib.h>
#include <string.h>
/// Alphabetically ordered library headers
#include <SDL/SDL.h>
/// Alphabetically ordered application headers
#include "addresses.h"
#include "example.h"
#include "park.h"
#include "window.h"
/// Global (extern) variables are prefixed with 'g', followed by title case.
int32_t gNumGuests = 0;
/// Local (static) variables are prefixed with '_', followed by lower camel case.
static int32_t _nextGuestIndex;
/// Local function declarations
static Peep* GetLastGuest();
/// All functions should be Upper CamelCase (PascalCase)
/// Only local functions need documentation (javadoc style)
/// Global functions should have their documentation in the header file.
static Peep* CreateGuest(const int32_t spawnIndex);
{
/// Arguments and local variables use camelCase
Entity* peepSprite = CreateEntity(spawnIndex);
}
/**
* Gets the last guest in the linked list of guests.
* @return A reference to the last peep.
*/
static Peep* GetLastGuest()
{
/// all braces must be on their own lines.
if (gNumGuests == 0)
{
return nullptr;
}
/// Flag checking and integers representing booleans do not need
/// to use boolean comparison operators.
if (!(gParkFlags & PARK_FLAG_OPEN))
{
return nullptr;
}
/// Do not place comments on the same line as code
if (gNumGuests == 1)
{
return gSprites[_nextGuestIndex];
}
else
{
/// Block comments use // not /* */
// The following will iterate through the linked list
// until the last peep is found.
/// Pointer asterisks are placed next to the variable name.
/// E.g. int32_t a, *ptrA, *ptrB
Peep* peep = gSprites[_nextGuestIndex];
/// Always be explicit with NULL checks
while (peep->next != nullptr)
{
peep = peep->next;
}
/// Always use the explicit auto* over auto
auto* peep2 = peep;
/// Avoid comments that describe what the code says, e.g.
// Returns the peep
return peep;
}
}
/// Use regions to allow text editors to collapse large blocks of code
#pragma region Animation Tables
/// Public structure members are camelCase.
/**
* Represents a currently running animation.
*/
struct PeepAnimation
{
int32_t animationIndex;
int32_t animationLength;
};
class PeepAction
{
private:
/// Private or Protected variables start with an underscore
int32_t _actionType;
}
/// Local constants do not require underscore prefix. They are title case.
static const int32_t WalkingAnimation[] =
{
0, 0, 0, 1, 1, 1, 2, 2, 3, 2, 3, 2, 1, 0,
3, 0, 0, 1, 1, 1, 2, 2, 3, 2, 2, 2, 1, 0
};
static const int32_t JumpingAnimation[] =
{
8, 7, 9, 5, 5
};
#pragma endregion
/// Feel free to sign parts of the code with your name / user name
// ~IntelOrca: This should be moved into Animation.cpp in the future.
PeepAnimation CreateAnimation(const int32_t startFrameIndex, const int32_t length)
{
PeepAnimation result;
result.AnimationIndex = startFrameIndex;
result.AnimationLength = length;
return result;
}
/// If a function definition runs over the line length limit, the arguments
/// should be broken up as follows:
void ShowAnimation(int32_t columns,
int32_t rows,
int32_t isResizable)
{
/// Function calls with many arguments can be broken up like the following.
/// The closing parenthesis should appear at the end of the last argument.
CreateWindow(
gDefaultWindowX,
gDefaultWindowY,
columns * 200,
rows * 300,
isResizable ? WF_RESIZABLE : 0);
}
/// Template parameters should be prefixed with `T`, e.g. `TFoo`
template<typename TGenerator, typename TSizeType = size_t>
void take(TGenerator g, TSizeType num)
{
}
Example.h:
/// Use the following header guard style to prevent multiple inclusions.
#pragma once
/// Keep includes to a minimum in header files. Usually just the header files necessary
/// for the rest of the header file.
#include "common.h"
/// Constants use constexpr (not #define) and use title case with a "k" prefix.
constexpr uint8_t kMapBaseZ = 7;
/// Actual macros (that are not expressible as constexpr) use SHOUTING_SNAKE_CASE.
#define SOME_MACRO(foo, bar) .foo = bar
/// Global (extern) variables are prefixed with g and then title case.
extern int32_t gNumGuests;
/// Documentation for global functions are kept in the header file and use javadoc style.
/**
* Creates a new guest ready to enter the park.
* @param spawnIndex The index of the spawn spot to create the guest at.
* @return A new peep.
*/
Peep* CreateGuest(int32_t spawnIndex);
/// Enums should be enum classes with specified types.
enum class ClimateType : uint8_t
{
coolAndWet,
warm,
hotAndDry,
};
The .clang-format
file in this repository reflects the code style described above. The program clang-format
can be used to reformat code style 'issues'. This is also what the CI pipeline does when building PRs. The repository also features a Python script scripts/run-clang-format.py
that wraps clang-format
and provides a patch instead of modifying the files.
To make life a little easier, a Git hook can be installed. This hook will execute pre-commit and halt the commit when issues arise and supply a patch to fix the issues. Just use the following lines in the .git/hooks/pre-commit
file.
#!/bin/bash
src=`git diff-index --cached --name-only HEAD -- 'src/*.cpp' 'src/*.hpp' 'src/*.h'`
if [ ! -z "$src" ]; then
./scripts/run-clang-format.py $src
fi
Another way to format your code in-place is to run git clang-format
.
- Home
- FAQ & Common Issues
- Roadmap
- Installation
- Building
- Features
- Development
- Benchmarking & stress testing OpenRCT2
- Coding Style
- Commit Messages
- Overall program structure
- Data Structures
- CSS1.DAT
- Custom Music and Ride Music Objects
- Game Actions
- G1 Elements Layout
- game.cfg structure
- Maps
- Music Cleanup
- Objects
- Official extended scenery set
- Peep AI
- Peep Sprite Type
- RCT1 ride and vehicle types and their RCT2 equivalents
- RCT12_MAX_SOMETHING versus MAX_SOMETHING
- Ride rating calculation
- SV6 Ride Structure
- Settings in config.ini
- Sizes and angles in the game world
- Sprite List csg1.dat
- Sprite List g1.dat
- Strings used in RCT1
- Strings used in the game
- TD6 format
- Terminology
- Track Data
- Track Designs
- Track drawers, RTDs and vehicle types
- Track types
- Vehicle Sprite Layout
- Widget colours
- Debugging OpenRCT2 on macOS
- OpenGL renderer
- Rebase and Sync fork with OpenRCT2
- Release Checklist
- Replay System
- Using minidumps from crash reports
- Using Track Block Get Previous
- History
- Testing