Contributing.md 10.7 KB
Newer Older
1
# <a name="main-heading"></a>Dolphin Coding Style & Licensing
Lioncash's avatar
Lioncash committed
2

3
4
If you make any contributions to Dolphin after December 1st, 2014, you are agreeing that any code you have contributed will be licensed under the GNU GPL version 2 (or any later version).

5
# <a name="main-section-overview"></a>Main sections
Lioncash's avatar
Lioncash committed
6

7
8
9
10
- [Introduction](#introduction)
- [C++ coding style and formatting](#cpp-coding-style-and-formatting)
- [C++ code-specific guidelines](#cpp-code-specific-guidelines)
- [Android and Java](#android-and-java)
Lioncash's avatar
Lioncash committed
11
12


13
14
15
16
17
18
19
20
# <a name="introduction"></a>Introduction

Summary:

- [Aims](#intro-aims)
- [Checking and fixing formatting issues](#intro-formatting-issues)

## <a name="intro-aims"></a>Aims
Lioncash's avatar
Lioncash committed
21
22
23
24
25

This guide is for developers who wish to contribute to the Dolphin codebase. It will detail how to properly style and format code to fit this project. This guide also offers suggestions on specific functions and other varia that may be used in code.

Following this guide and formatting your code as detailed will likely get your pull request merged much faster than if you don't (assuming the written code has no mistakes in itself).

26
27
28
This project uses clang-format (stable branch) to check for common style issues. In case of conflicts between this guide and clang-format rules, the latter should be followed instead of this guide.


29
## <a name="intro-formatting-issues"></a>Checking and fixing formatting issues
30

Anthony's avatar
Anthony committed
31
32
Windows users need to be careful about line endings. Windows users should configure git to checkout UNIX-style line endings to keep clang-format simple.

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
In most cases, clang-format can and **should** be used to automatically reformat code and solve most formatting issues.

- To run clang-format on all staged files:
  ```
  git diff --cached --name-only | egrep '[.](cpp|h|mm)$' | xargs clang-format -i
  ```

- Formatting issues can be checked for before committing with a lint script that is included with the codebase. To enable it as a pre-commit hook (assuming you are in the repository root):
  ```
  ln -s ../../Tools/lint.sh .git/hooks/pre-commit
  ```

- Alternatively, a custom git filter driver can be used to automatically and transparently reformat any changes:
  ```
  git config filter.clang_format.smudge 'cat'
  git config filter.clang_format.clean 'clang-format %f'
  echo '/Source/Core/**/*.cpp filter=clang_format' >> .git/info/attributes
  echo '/Source/Core/**/*.h filter=clang_format' >> .git/info/attributes
  echo '/Source/Core/**/*.mm filter=clang_format' >> .git/info/attributes
  ```

54
55
56
# <a name="cpp-coding-style-and-formatting"></a>C++ coding style and formatting

Summary:
Lioncash's avatar
Lioncash committed
57

58
59
60
61
62
63
- [General](#cpp-style-general)
- [Naming](#cpp-style-naming)
- [Conditionals](#cpp-style-conditionals)
- [Classes and structs](#cpp-style-classes-and-structs)

## <a name="cpp-style-general"></a>General
Lioncash's avatar
Lioncash committed
64
65
- Try to limit lines of code to a maximum of 100 characters.
    - Note that this does not mean you should try and use all 100 characters every time you have the chance. Typically with well formatted code, you normally shouldn't hit a line count of anything over 80 or 90 characters.
66
- The indentation style we use is 2 spaces per level.
Lioncash's avatar
Lioncash committed
67
68
69
- The opening brace for namespaces, classes, functions, enums, structs, unions, conditionals, and loops go on the next line.
  - With array initializer lists and lambda expressions it is OK to keep the brace on the same line.
- References and pointers have the ampersand or asterisk against the type name, not the variable name. Example: `int* var`, not `int *var`.
Lioncash's avatar
Lioncash committed
70
- Don't use multi-line comments (`/* Comment text */`), use single-line comments (`// Comment text`) instead.
Lioncash's avatar
Lioncash committed
71
72
73
74
75
- Don't collapse single line conditional or loop bodies onto the same line as its header. Put it on the next line.
  - Yes:

    ```c++
    if (condition)
76
      return 0;
Lioncash's avatar
Lioncash committed
77
78

    while (var != 0)
79
      var--;
Lioncash's avatar
Lioncash committed
80
81
82
83
84
85
86
87
88
    ```
  - No:

    ```c++
    if (condition) return 0;

    while (var != 0) var--;
    ```

89
## <a name="cpp-style-naming"></a>Naming
Lioncash's avatar
Lioncash committed
90
91
92
93
- All class, enum, function, and struct names should be in upper CamelCase. If the name contains an abbreviation uppercase it.
  - `class SomeClassName`
  - `enum IPCCommandType`
- All compile time constants should be fully uppercased. With constants that have more than one word in them, use an underscore to separate them.
94
95
  - `constexpr double PI = 3.14159;`
  - `constexpr int MAX_PATH = 260;`
Lioncash's avatar
Lioncash committed
96
97
98
99
100
101
102
- All variables should be lowercase with underscores separating the individual words in the name.
  - `int this_variable_name;`
- Please do not use [Hungarian notation](http://en.wikipedia.org/wiki/Hungarian_notation) prefixes with variables. The only exceptions to this are the variable prefixes below.
  - Global variables – `g_`
  - Class variables – `m_`
  - Static variables – `s_`

103
## <a name="cpp-style-conditionals"></a>Conditionals
Lioncash's avatar
Lioncash committed
104
105
106
107
108
109
- Do not leave `else` or `else if` conditions dangling unless the `if` condition lacks braces.
  - Yes:

    ```c++
    if (condition)
    {
110
      // code
Lioncash's avatar
Lioncash committed
111
112
113
    }
    else
    {
114
      // code
Lioncash's avatar
Lioncash committed
115
116
117
118
119
120
    }
    ```
  - Acceptable:

    ```c++
    if (condition)
121
      // code line
Lioncash's avatar
Lioncash committed
122
    else
123
      // code line
Lioncash's avatar
Lioncash committed
124
125
126
127
128
129
    ```
  - No:

    ```c++
    if (condition)
    {
130
      // code
Lioncash's avatar
Lioncash committed
131
132
    }
    else
133
      // code line
Lioncash's avatar
Lioncash committed
134
135
136
    ```


137
## <a name="cpp-style-classes-and-structs"></a>Classes and structs
Lioncash's avatar
Lioncash committed
138
139
140
141
142
143
144
145
146
147
- If making a [POD](http://en.wikipedia.org/wiki/Plain_Old_Data_Structures) type, use a `struct` for this. Use a `class` otherwise.
- Class layout should be in the order, `public`, `protected`, and then `private`.
  - If one or more of these sections are not needed, then simply don't include them.
- For each of the above specified access levels, the contents of each should follow this given order: constructor, destructor, operator overloads, functions, then variables.
- When defining the variables, define `static` variables before the non-static ones.

```c++
class ExampleClass : public SomeParent
{
public:
148
  ExampleClass(int x, int y);
149

150
151
  int GetX() const;
  int GetY() const;
Lioncash's avatar
Lioncash committed
152
153

protected:
154
155
  virtual void SomeProtectedFunction() = 0;
  static float s_some_variable;
Lioncash's avatar
Lioncash committed
156
157

private:
158
159
  int m_x;
  int m_y;
Lioncash's avatar
Lioncash committed
160
161
162
};
```

163
164
165
166
167
168
169
170
171
# <a name="cpp-code-specific-guidelines"></a>C++ code-specific guidelines

Summary:

- [General](#cpp-code-general)
- [Headers](#cpp-code-headers)
- [Loops](#cpp-code-loops)
- [Functions](#cpp-code-functions)
- [Classes and Structs](#cpp-code-classes-and-structs)
Lioncash's avatar
Lioncash committed
172

173
## <a name="cpp-code-general"></a>General
174
- The codebase currently uses C++17.
Lioncash's avatar
Lioncash committed
175
176
177
178
179
180
181
- Use the [nullptr](http://en.cppreference.com/w/cpp/language/nullptr) type over the macro `NULL`.
- If a [range-based for loop](http://en.cppreference.com/w/cpp/language/range-for) can be used instead of container iterators, use it.
- Obviously, try not to use `goto` unless you have a *really* good reason for it.
- If a compiler warning is found, please try and fix it.
- Try to avoid using raw pointers (pointers allocated with `new`) as much as possible. There are cases where using a raw pointer is unavoidable, and in these situations it is OK to use them. An example of this is functions from a C library that require them. In cases where it is avoidable, the STL usually has a means to solve this (`vector`, `unique_ptr`, etc).
- Do not use the `auto` keyword everywhere. While it's nice that the type can be determined by the compiler, it cannot be resolved at 'readtime' by the developer as easily. Use auto only in cases where it is obvious what the type being assigned is (note: 'obvious' means not having to open other files or reading the header file). Some situations where it is appropriate to use `auto` is when iterating over a `std::map` container in a foreach loop, or to shorten the length of container iterator variable declarations.
- Do not use `using namespace [x];` in headers. Try not to use it at all if you can.
182
- The preferred form of the increment and decrement operator in for-loops is prefix-form (e.g. `++var`).
Lioncash's avatar
Lioncash committed
183

184
## <a name="cpp-code-headers"></a>Headers
Lioncash's avatar
Lioncash committed
185
186
187
- If a header is not necessary in a certain source file, remove them.
- If you find duplicate includes of a certain header, remove it.
- When declaring includes in a source file, make sure they follow the given pattern:
188
  - The header for the source file
Lioncash's avatar
Lioncash committed
189
190
  - Standard library headers
  - System-specific headers (these should also likely be in an `#ifdef` block unless the source file itself is system-specific).
191
  - Other Dolphin source file headers
Lioncash's avatar
Lioncash committed
192
193
194
195
- Each of the above header sections should also be in alphabetical order
- Project source file headers should be included in a way that is relative to the `[Dolphin Root]/Source/Core` directory.
- This project uses `#pragma once` as header guards.

196
## <a name="cpp-code-loops"></a>Loops
Lioncash's avatar
Lioncash committed
197
198
199
200
- If an infinite loop is required, do not use `for (;;)`, use `while (true)`.
- Empty-bodied loops should use braces after their header, not a semicolon.
  - Yes: `while (condition) {}`
  - No: `while (condition);`
201
202
203
204
205
206
207
- For do-while loops, place 'while' on the same line as the closing brackets

  ```c++
  do
  {
  } while (false);
  ```
Lioncash's avatar
Lioncash committed
208

209
## <a name="cpp-code-functions"></a>Functions
Lioncash's avatar
Lioncash committed
210
211
212
213
214
215
216
217
- If a function parameter is a pointer or reference and its value or data isn't intended to be changed, please mark that parameter as `const`.
- Functions that specifically modify their parameters should have the respective parameter(s) marked as a pointer so that the variables being modified are syntaxically obvious.
  - What not to do:

    ```c++
    template<class T>
    inline void Clamp(T& val, const T& min, const T& max)
    {
218
219
220
221
      if (val < min)
        val = min;
      else if (val > max)
        val = max;
Lioncash's avatar
Lioncash committed
222
223
224
225
226
227
228
229
230
231
232
    }
    ```

    Example call: `Clamp(var, 1000, 5000);`

  - What to do:

    ```c++
    template<class T>
    inline void Clamp(T* val, const T& min, const T& max)
    {
233
234
235
236
      if (*val < min)
        *val = min;
      else if (*val > max)
        *val = max;
Lioncash's avatar
Lioncash committed
237
238
239
240
241
242
243
244
245
246
247
    }
    ```

    Example call: `Clamp(&var, 1000, 5000);`

- Class member functions that you do not want to be overridden in inheriting classes should be marked with the `final` specifier.

  ```c++
  class ClassName : ParentClass
  {
  public:
248
    void Update() final;
Lioncash's avatar
Lioncash committed
249
250
251
252
253
254
255
256
257
  };
  ```

- Overridden member functions that can also be inherited should be marked with the `override` specifier to make it easier to see which functions belong to the parent class.

  ```c++
  class ClassName : ParentClass
  {
  public:
258
    void Update() override;
Lioncash's avatar
Lioncash committed
259
260
261
  };
  ```

262
## <a name="cpp-code-classes-and-structs"></a>Classes and structs
Lioncash's avatar
Lioncash committed
263
264
265
266
267
- Classes and structs that are not intended to be extended through inheritance should be marked with the `final` specifier.

  ```c++
  class ClassName final : ParentClass
  {
268
    // Class definitions
Lioncash's avatar
Lioncash committed
269
270
  };
  ```
271

272
# <a name="android-and-java"></a>Android and Java
273

274
The Android project is currently written in Java. If you are using Android Studio to contribute, you can import the project's code style from `code-style-java.jar`, located in `[Dolphin Root]/Source/Android`. Please organize imports before committing.