|
@@ -12,13 +12,11 @@ class **Terrain** = **Terrain**.h + **Terrain**.cpp
|
|
|
| Behaviour | Convention |
|
|
| Behaviour | Convention |
|
|
|
| --- | --- |
|
|
| --- | --- |
|
|
|
| Classes, Structs, Enum Classes and Typedefs | PascalCase |
|
|
| Classes, Structs, Enum Classes and Typedefs | PascalCase |
|
|
|
-| Functions | camelCase |
|
|
|
|
|
|
|
+| Functions | under_case |
|
|
|
| Private + Protected member variables | _camelCase |
|
|
| Private + Protected member variables | _camelCase |
|
|
|
| Public member variables | camelCase |
|
|
| Public member variables | camelCase |
|
|
|
| Local variables | camelCase |
|
|
| Local variables | camelCase |
|
|
|
| Constants | UNDER_CASE |
|
|
| Constants | UNDER_CASE |
|
|
|
-| Enum class values | UNDER_CASE |
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
## Class Layout
|
|
## Class Layout
|
|
|
```cpp
|
|
```cpp
|
|
@@ -33,7 +31,7 @@ namespace example
|
|
|
|
|
|
|
|
class Bar;
|
|
class Bar;
|
|
|
|
|
|
|
|
-class Foo
|
|
|
|
|
|
|
+class GP_API Foo
|
|
|
{
|
|
{
|
|
|
public:
|
|
public:
|
|
|
|
|
|
|
@@ -41,9 +39,9 @@ public:
|
|
|
|
|
|
|
|
~Foo();
|
|
~Foo();
|
|
|
|
|
|
|
|
- Bar* getBar() const;
|
|
|
|
|
|
|
+ Bar* get_bar() const;
|
|
|
|
|
|
|
|
- void setBar(Bar* bar);
|
|
|
|
|
|
|
+ void set_bar(Bar* bar);
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
std::unique_ptr<Bar> _bar;
|
|
std::unique_ptr<Bar> _bar;
|
|
@@ -62,6 +60,7 @@ private:
|
|
|
- Constructors and destructors are the first methods in a class after **public** member variables.
|
|
- Constructors and destructors are the first methods in a class after **public** member variables.
|
|
|
- The method implementations in cpp should appears in the order which they are declared in the class.
|
|
- The method implementations in cpp should appears in the order which they are declared in the class.
|
|
|
- Avoid **inline** implementations unless absolutely needed and are trivial and short.
|
|
- Avoid **inline** implementations unless absolutely needed and are trivial and short.
|
|
|
|
|
+- Add GP_API on all classes for export into shared library
|
|
|
|
|
|
|
|
## Enums
|
|
## Enums
|
|
|
- Should be declared in classes directly after constructor and destructors.
|
|
- Should be declared in classes directly after constructor and destructors.
|
|
@@ -69,9 +68,7 @@ private:
|
|
|
```cpp
|
|
```cpp
|
|
|
namespace gameplay
|
|
namespace gameplay
|
|
|
{
|
|
{
|
|
|
-namespace scene
|
|
|
|
|
-{
|
|
|
|
|
-class Camera
|
|
|
|
|
|
|
+class GP_API Camera
|
|
|
{
|
|
{
|
|
|
public:
|
|
public:
|
|
|
|
|
|
|
@@ -79,40 +76,27 @@ public:
|
|
|
|
|
|
|
|
~Camera();
|
|
~Camera();
|
|
|
|
|
|
|
|
- enum class Mode
|
|
|
|
|
|
|
+ enum class Mode : uint32_t
|
|
|
{
|
|
{
|
|
|
PERSPECTIVE,
|
|
PERSPECTIVE,
|
|
|
ORTHOGRAPHIC
|
|
ORTHOGRAPHIC
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- Camera::Mode getMode() const;
|
|
|
|
|
|
|
+ Mode get_mode() const;
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
## Flags (bitwise)
|
|
## Flags (bitwise)
|
|
|
-- We do not use enums for flags. They are instead
|
|
|
|
|
|
|
+- We do not use enums for flags. They are instead flags, hints, etc:
|
|
|
```cpp
|
|
```cpp
|
|
|
namespace gameplay
|
|
namespace gameplay
|
|
|
{
|
|
{
|
|
|
-namespace graphics
|
|
|
|
|
-{
|
|
|
|
|
-
|
|
|
|
|
-typedef uint32_t DeviceFlags;
|
|
|
|
|
-constexpr DeviceFlags DEVICE_FLAG_NONE = 0;
|
|
|
|
|
-constexpr DeviceFlags DEVICE_FLAG_VALIDATION = 1 << 0;
|
|
|
|
|
-constexpr DeviceFlags DEVICE_FLAG_RAYTRACING = 1 << 1;
|
|
|
|
|
-constexpr DeviceFlags DEVICE_FLAG_SHARED_RESOURCE = 1 << 2;
|
|
|
|
|
-
|
|
|
|
|
-}
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
|
|
+typedef uint32_t SpecialFlags;
|
|
|
|
|
+constexpr SpecialFlags SPECIAL_FLAG_NONE = 0;
|
|
|
|
|
+constexpr SpecialFlags SPECIAL_FLAG_THIS = 1 << 0;
|
|
|
|
|
+constexpr SpecialFlags SPECIAL_FLAG_THAT = 1 << 1;
|
|
|
|
|
+
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-## Smart Pointers vs Pointers
|
|
|
|
|
-- Use **std::unique_ptr<Foo>** for pointers whenever possible especially for public api pointers.
|
|
|
|
|
-- Any **delete** function call appearing in the code is a red flag and needs a good reason.
|
|
|
|
|
-- Use **std::shared_ptr<Foo>** only when sharing is required.
|
|
|
|
|
-- Use **std::vector** if you need an array and use **std::vector::data()** to get a raw pointer to the beginning of a vector.
|
|
|
|
|
-
|
|
|
|
|
## Auto
|
|
## Auto
|
|
|
- Use **auto** sparingly and when needed to abstract a complex type.
|
|
- Use **auto** sparingly and when needed to abstract a complex type.
|
|
|
- Great for use on **std::** stl containers and smart pointers.
|
|
- Great for use on **std::** stl containers and smart pointers.
|
|
@@ -126,13 +110,7 @@ constexpr DeviceFlags DEVICE_FLAG_SHARED_RESOURCE = 1 << 2;
|
|
|
|
|
|
|
|
## Range-based loops
|
|
## Range-based loops
|
|
|
- They're great, use them.
|
|
- They're great, use them.
|
|
|
-- They don't have to be combined with **auto**.
|
|
|
|
|
-- They are often more readable to not use auto for simple types:
|
|
|
|
|
```cpp
|
|
```cpp
|
|
|
-// More obvious that the iterator is a device index.
|
|
|
|
|
-for (int device : devices)
|
|
|
|
|
-```
|
|
|
|
|
-**vs.**
|
|
|
|
|
```cpp
|
|
```cpp
|
|
|
// Suggests dev might be of type Device.
|
|
// Suggests dev might be of type Device.
|
|
|
for (const auto& device : devices)
|
|
for (const auto& device : devices)
|
|
@@ -141,7 +119,6 @@ for (const auto& device : devices)
|
|
|
## Friend
|
|
## Friend
|
|
|
- Avoid using **friend** unless it is needed to restrict access to inter-class interop only.
|
|
- Avoid using **friend** unless it is needed to restrict access to inter-class interop only.
|
|
|
- It easily leads to _difficult-to-untangle_ interdependencies that are hard to maintain.
|
|
- It easily leads to _difficult-to-untangle_ interdependencies that are hard to maintain.
|
|
|
-- We will continue to remove where possible in existing code.
|
|
|
|
|
|
|
|
|
|
## size_t
|
|
## size_t
|
|
|
- Use **size_t** for all size counts and accessing **std::size()** results.
|
|
- Use **size_t** for all size counts and accessing **std::size()** results.
|
|
@@ -167,9 +144,9 @@ for (const auto& device : devices)
|
|
|
- Use **nullptr** instead of _0_ or _NULL_.
|
|
- Use **nullptr** instead of _0_ or _NULL_.
|
|
|
|
|
|
|
|
## Errors and Logging
|
|
## Errors and Logging
|
|
|
-- Use **GP_ERROR** macro for all errors that will stop the program in release and debug modes.
|
|
|
|
|
|
|
+- Use **GP_LOG_ERROR** macro for all errors that will stop the program in release and debug modes.
|
|
|
```cpp
|
|
```cpp
|
|
|
-GP_ERROR("Invalid json base64 string for propertyName: %s", propertyName);
|
|
|
|
|
|
|
+GP_LOG_ERROR("Invalid json base64 string for propertyName: {}", propertyName);
|
|
|
```
|
|
```
|
|
|
- Use **GP_LOG_INFO** for one time logging events such as initialization or unexpected singularities.
|
|
- Use **GP_LOG_INFO** for one time logging events such as initialization or unexpected singularities.
|
|
|
- Avoid excessive logging which can impact game engine performance, such as logging every frame.
|
|
- Avoid excessive logging which can impact game engine performance, such as logging every frame.
|
|
@@ -181,26 +158,18 @@ GP_ERROR("Invalid json base64 string for propertyName: %s", propertyName);
|
|
|
## Assertions
|
|
## Assertions
|
|
|
- Use **GP_ASSERT** for quick danger checks in start of impl that is checked in debug mode.
|
|
- Use **GP_ASSERT** for quick danger checks in start of impl that is checked in debug mode.
|
|
|
```cpp
|
|
```cpp
|
|
|
-size_t MyReader::readXxxx(const char* propertyName, float** data)
|
|
|
|
|
|
|
+size_t MyReader::read_xxxx(const char* propertyName, float** data)
|
|
|
{
|
|
{
|
|
|
GP_ASSERT(propertyName);
|
|
GP_ASSERT(propertyName);
|
|
|
- GP_ASSERT(_type == Foo::Type::XYZ);
|
|
|
|
|
|
|
+ GP_ASSERT(data);
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-## Public member variable access
|
|
|
|
|
-- Use **this->** when accessing public variables in implementation code.
|
|
|
|
|
-```cpp
|
|
|
|
|
-void Sphere::set(const gameplay::Float3& center, float radius)
|
|
|
|
|
-{
|
|
|
|
|
- this->center = center;
|
|
|
|
|
- this->radius = radius;
|
|
|
|
|
- ...
|
|
|
|
|
-```
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
## Public member variable initialization
|
|
## Public member variable initialization
|
|
|
- Initialize public member variables directly in .h file for awareness.
|
|
- Initialize public member variables directly in .h file for awareness.
|
|
|
```cpp
|
|
```cpp
|
|
|
-class Rectangle
|
|
|
|
|
|
|
+class GP_API Rectangle
|
|
|
{
|
|
{
|
|
|
public:
|
|
public:
|
|
|
float x = 0.0f;
|
|
float x = 0.0f;
|
|
@@ -210,6 +179,7 @@ public:
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
## Protected + private member variable initialization
|
|
## Protected + private member variable initialization
|
|
|
|
|
+- Use static initializers as a first line of de
|
|
|
- Initialize all **protected** and **private** member variables in constructor in cpp to obscure.
|
|
- Initialize all **protected** and **private** member variables in constructor in cpp to obscure.
|
|
|
- Initialize all **protected** and **private** member variables in the order they are declared.
|
|
- Initialize all **protected** and **private** member variables in the order they are declared.
|
|
|
```cpp
|
|
```cpp
|
|
@@ -222,16 +192,17 @@ MyClass::MyClass() :
|
|
|
## Commenting Headers
|
|
## Commenting Headers
|
|
|
- Avoid spelling and grammatical errors.
|
|
- Avoid spelling and grammatical errors.
|
|
|
- Header comments use _doxygen_ format. We are not too sticky on _doxygen_ formatting policy.
|
|
- Header comments use _doxygen_ format. We are not too sticky on _doxygen_ formatting policy.
|
|
|
|
|
+- We dont need [in] and [out] on params. It should be obvious in comments anyhow.
|
|
|
- All public functions and variables must be documented.
|
|
- All public functions and variables must be documented.
|
|
|
- The level of detail for the comment is based on the complexity for the api.
|
|
- The level of detail for the comment is based on the complexity for the api.
|
|
|
- Most important is that comments are simple and have clarity on how to use the api.
|
|
- Most important is that comments are simple and have clarity on how to use the api.
|
|
|
-- **@brief** is not required and automatic assumed on first line of code. Easier to read too.
|
|
|
|
|
|
|
+- **@brief** is not required and automatic assumed on first line of code summary. Easier to read too.
|
|
|
- **@details** is not dropped and automatic assumed proceeding the summary line.
|
|
- **@details** is not dropped and automatic assumed proceeding the summary line.
|
|
|
-- **@param** and **@return** are followed with a space after summary brief or details.
|
|
|
|
|
|
|
+- **@param** and **@return** are followed with a space after summary or details.
|
|
|
|
|
|
|
|
```cpp
|
|
```cpp
|
|
|
/**
|
|
/**
|
|
|
- * Tests whether this cube intersects the specified cube.
|
|
|
|
|
|
|
+ * Checks whether this cube intersects the specified cube.
|
|
|
*
|
|
*
|
|
|
* You would add any specific details that may be needed here. This is
|
|
* You would add any specific details that may be needed here. This is
|
|
|
* only necessary if there is complexity to the user of the function.
|
|
* only necessary if there is complexity to the user of the function.
|
|
@@ -247,7 +218,7 @@ MyClass::MyClass() :
|
|
|
- Clean simple code is the best form of commenting.
|
|
- Clean simple code is the best form of commenting.
|
|
|
- Do not add comments above function definitions in .cpp they are already in header.
|
|
- Do not add comments above function definitions in .cpp they are already in header.
|
|
|
- Used to comment necessary non-obvious implementation details not the api.
|
|
- Used to comment necessary non-obvious implementation details not the api.
|
|
|
-- Only use // line comments on the line above the code you plan to comment.
|
|
|
|
|
|
|
+- Only use // line comments on the line above the code you plan to comment with lower case comments.
|
|
|
- Avoid /* */ block comments. Preventing others from easily doing their own block comments when testing, debugging, etc.
|
|
- Avoid /* */ block comments. Preventing others from easily doing their own block comments when testing, debugging, etc.
|
|
|
- Avoid explicitly referring to identifiers in comments, since that's an easy way to make your comment outdated when an identifier is renamed.
|
|
- Avoid explicitly referring to identifiers in comments, since that's an easy way to make your comment outdated when an identifier is renamed.
|
|
|
|
|
|
|
@@ -257,9 +228,8 @@ MyClass::MyClass() :
|
|
|
|
|
|
|
|
## Include
|
|
## Include
|
|
|
- **#pragma** once is first line of the .h class header.
|
|
- **#pragma** once is first line of the .h class header.
|
|
|
-- **#include "Base.h"** is the first line of the .cpp class implementation.
|
|
|
|
|
-- Include the corresponding class header to the second line just after including "Base.h".
|
|
|
|
|
-- All the other headers, sorted by **local** to **distant** directories. (Ex. std headers come last)
|
|
|
|
|
|
|
+- Include the corresponding class .h on the first line of the .cpp
|
|
|
|
|
+- All the other headers, sorted by **local** to **distant** directories. (Ex. #include <vector> stl headers come last)
|
|
|
|
|
|
|
|
## Tabs
|
|
## Tabs
|
|
|
- Insert **4** spaces for tabs to avoid avoid tab wars.
|
|
- Insert **4** spaces for tabs to avoid avoid tab wars.
|
|
@@ -274,21 +244,13 @@ MyClass::MyClass() :
|
|
|
- No space just inside brackets.
|
|
- No space just inside brackets.
|
|
|
- One space after each comma separating parameters.
|
|
- One space after each comma separating parameters.
|
|
|
```cpp
|
|
```cpp
|
|
|
-foo->doThis(x, y, z);
|
|
|
|
|
|
|
+foo->do_this(x, y, z);
|
|
|
```
|
|
```
|
|
|
- Conditional statement spacing:
|
|
- Conditional statement spacing:
|
|
|
- One space after conditional keywords.
|
|
- One space after conditional keywords.
|
|
|
- No space just inside the brackets.
|
|
- No space just inside the brackets.
|
|
|
- One space separating commas, colons and condition comparison operators.
|
|
- One space separating commas, colons and condition comparison operators.
|
|
|
-```cpp
|
|
|
|
|
- if (lightType.compare("gameplay::scene::Light::Type") == 0)
|
|
|
|
|
- {
|
|
|
|
|
- switch (static_cast<gameplay::scene::Light::Type>(value))
|
|
|
|
|
- {
|
|
|
|
|
- case gameplay::scene::Light::Type::DIRECTIONAL:
|
|
|
|
|
- return "DIRECTIONAL";
|
|
|
|
|
- ...
|
|
|
|
|
-```
|
|
|
|
|
|
|
+
|
|
|
- **Do not** align blocks of member variables to match spacing causing unnecessary line changes when new variables are introduced.
|
|
- **Do not** align blocks of member variables to match spacing causing unnecessary line changes when new variables are introduced.
|
|
|
```cpp
|
|
```cpp
|
|
|
private:
|
|
private:
|
|
@@ -300,15 +262,16 @@ private:
|
|
|
|
|
|
|
|
- Align indentation space for parameters when wrapping lines to match the initial bracket.
|
|
- Align indentation space for parameters when wrapping lines to match the initial bracket.
|
|
|
|
|
|
|
|
-**Example:**
|
|
|
|
|
|
|
+**Example 1:**
|
|
|
```cpp
|
|
```cpp
|
|
|
-Matrix::Matrix(float m11, float m12, float m13, float m14,
|
|
|
|
|
- float m21, float m22, float m23, float m24,
|
|
|
|
|
- float m31, float m32, float m33, float m34,
|
|
|
|
|
- float m41, float m42, float m43, float m44)
|
|
|
|
|
|
|
+CrazyData::CrazyData(float a0, float b0, float c0, float d0,
|
|
|
|
|
+ float a1, float b1, float c1, float d1,
|
|
|
|
|
+ float a2, float b2, float c2, float d2,
|
|
|
|
|
+ float a3, float b3, float c3, float d3)
|
|
|
```
|
|
```
|
|
|
|
|
+Generally you should use a struct value by reference or pointer to data instead here anyhow.
|
|
|
|
|
|
|
|
-**Example:**
|
|
|
|
|
|
|
+**Example 2:**
|
|
|
```cpp
|
|
```cpp
|
|
|
return sqrt((point.x - sphere.center.x) * (point.x - sphere.center.x) +
|
|
return sqrt((point.x - sphere.center.x) * (point.x - sphere.center.x) +
|
|
|
(point.y - sphere.center.y) * (point.y - sphere.center.x) +
|
|
(point.y - sphere.center.y) * (point.y - sphere.center.x) +
|
|
@@ -330,19 +293,21 @@ return sqrt((point.x - sphere.center.x) * (point.x - sphere.center.x) +
|
|
|
|
|
|
|
|
## Indentation
|
|
## Indentation
|
|
|
- Indent next line after all braces { }.
|
|
- Indent next line after all braces { }.
|
|
|
-- Braces should
|
|
|
|
|
-- Move code after braces { } to the next line.
|
|
|
|
|
|
|
+- Braces should always align vertically.
|
|
|
- Always indent the next line of any condition statement line.
|
|
- Always indent the next line of any condition statement line.
|
|
|
|
|
+- Indent 1 space after each condition or loop before the brackets.
|
|
|
|
|
|
|
|
-**Example**
|
|
|
|
|
|
|
+**Example 1**
|
|
|
```cpp
|
|
```cpp
|
|
|
-if (box.isEmpty())
|
|
|
|
|
|
|
+if (box.is_empty())
|
|
|
|
|
+{
|
|
|
return;
|
|
return;
|
|
|
|
|
+}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-**Example**
|
|
|
|
|
|
|
+**Example 2**
|
|
|
```cpp
|
|
```cpp
|
|
|
-for (size_t i = 0; i < count; ++i)
|
|
|
|
|
|
|
+for (size_t i = 0; i < count; i++)
|
|
|
{
|
|
{
|
|
|
if (distance(sphere, points[i]) > sphere.radius)
|
|
if (distance(sphere, points[i]) > sphere.radius)
|
|
|
{
|
|
{
|
|
@@ -350,7 +315,8 @@ for (size_t i = 0; i < count; ++i)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
+
|
|
|
- Never leave conditional code statements on same line as condition test:
|
|
- Never leave conditional code statements on same line as condition test:
|
|
|
```cpp
|
|
```cpp
|
|
|
-if (box.isEmpty()) return;
|
|
|
|
|
|
|
+if (box.is_mpty()) return;
|
|
|
```
|
|
```
|