代码风格指南

在给Godot的源代码做贡献时,您需要遵循下面概述的样式指南。其中一些是通过持续集成过程进行检查的,评审人员将要求您修复潜在的问题,因此最好按照下面概述的方式设置系统,以确保所有提交都遵循指导原则。

C++和Objective-C

没有书面的指导方针,但是开发人员默认的代码风格是通过 clang-format 代码美化器强制执行的,它可以满足我们所有的约定。举几个示例:

  • 缩进和对齐都是基于制表符的(分别是一个和两个制表符)
  • 数学和赋值运算符以及逗号后面有一个空格
  • 指针和引用运算符附加到变量标识符,而不是类型名称
  • 有关标头引入,请参见下文

Clang格式使用的规则在Godot存储库的 .clang-format 文件中进行了概述。

只要您确保您的样式与周围的代码匹配,并且您没有引入尾随空格或基于空格的缩进,就应该没问题。 但如果您计划定期贡献,我们强烈建议您在本地设置clang-format以检查并自动修复所有提交。

警告

Godot's code style should not be applied to third-party code, i.e. that is included in Godot's source tree but was not written specifically for our project. Such code usually come from different upstream projects with their own style guides (or lack thereof), and don't want to introduce differences that would make syncing with upstream repositories harder.

Third-party code is usually included in the thirdparty/ folder and can thus easily be excluded from formatting scripts. For the rare cases where a third-party code snippet needs to be included directly within a Godot file, you can use /* clang-format off */ and /* clang-format on */ to tell clang-format to ignore a chunk of code.

在本地使用clang-format

首先,您需要安装clang-format。截至目前,您需要使用 clang-format 8.x 与Godot的格式兼容。更高版本可能是合适的,但以前的版本有错误,将导致当前代码库的格式更改。

安装

以下是如何安装clang-format:

  • Linux:通常会随您的发行版打包的clang工具链一起提供。如果您的分发版本不是必需的版本,您可以从 LLVM网站 下载预编译的版本,或者,如果您使用的是Debian衍生版本,请使用 上游仓库
  • macOS和Windows:您可以从 LLVM网站 下载预编译的二进制文件。您可能需要将二进制文件的文件夹的路径添加到系统的 PATH 环境变量中,以便能够直接调用 clang-format

然后,您就有不同的可能性将clang-format应用于您的更改:

手动使用

您可以使用以下命令手动将clang-format应用于一个或多个文件:

clang-format -i <path/to/file(s)>
  • -i 表示更改应直接写入文件(默认情况下,clang-format只会将固定版本输出到终端)。
  • 该路径可以指向几个文件,一个接一个,也可以使用如在典型的Unix shell中的通配符。在通配时要小心,以免对Godot树中的已编译对象(.o和.a文件)运行clang格式。因此,最好使用 core/*.{cpp,h} 而不是 core/*

预提交钩子

为了易于使用,我们为Git提供了一个预提交钩子,它将在您的所有提交上自动运行clang-format来检查它们,并允许您在最终提交中应用其更改。

这个 钩子 是一个可以在 misc/hooks 中找到的脚本,请参阅该文件夹的README.md以获取安装说明。

如果您的clang-format不在 PATH 中,您可能需要编辑 pre-commit-clang-format 来指向正确的二进制格式才能工作。钩子在Linux和macOS上测试过,但也应该在Windows上的Git Shell中运行。

IDE插件

大多数IDE或代码编辑器都有美化插件,可以配置为自动运行clang-format,例如每次保存文件时。

以下是一些IDE的美化插件的非详尽列表:

(欢迎拉取请求以使用测试过的插件来扩展此列表。)

标头引入

当添加新的C++或Objective-C文件或在现有文件中引入新的标头时,应遵循以下规则:

  • 文件中的第一行应该是Godot的版权标头和MIT许可证,从另一个文件复制粘贴。确保调整文件名。
  • .h 头文件中,引入防护应该与 FILENAME_H 形式一起使用。
  • .cpp 文件(如 filename.cpp )中,第一个引入应该是声明类的那个(例如 #include "filename.h"),然后使用空行分隔。
  • 然后来自Godot自己的代码库的标头,按字母顺序(由 clang-format 强制)引入,并具有相对于根文件夹的路径。这些引入应该用引号来完成,例如 #include "core/object.h"。然后,Godot标头引入的块应用一个空行以进行分隔。
  • Finally, third-party headers (either from thirdparty or from the system's include paths) come next and should be included with the < and > symbols, e.g. #include <png.h>. The block of third-party headers should also be followed by an empty line for separation.
  • Godot and third-party headers should be included in the file that requires them, i.e. in the .h header if used in the declarative code or in the .cpp if used only in the imperative code.

示例:

/*************************************************************************/
/*  my_new_file.h                                                        */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#ifndef MY_NEW_FILE_H
#define MY_NEW_FILE_H

#include "core/hash_map.h"
#include "core/list.h"
#include "scene/gui/control.h

#include <png.h>

...

#endif // MY_NEW_FILE_H
/*************************************************************************/
/*  my_new_file.cpp                                                      */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "my_new_file.h"

#include "core/math/math_funcs.h"
#include "scene/gui/line_edit.h

#include <zlib.h>
#include <zstd.h>

Java

Godot's Java code (mostly in platform/android) is also enforced via clang-format, so see the instructions above to set it up. Keep in mind that this style guide only applies to code written and maintained by Godot, not third-party code such as the java/src/com/google subfolder.

Python

Godot的SCons构建系统是用Python编写的,源代码树中包含的各种脚本也使用Python。

对于那些,我们遵循 PEP-8样式指南 ,但这并不像C++代码那样强制执行。如果您如此倾向,可以使用 autopep8 来检查和格式化您的Python更改。