代码风格指南

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

C++和Objective-C

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

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

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

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

警告

Godot的代码风格应该 适用于第三方代码,即包含在Godot的源代码树中,但不是专门为我们的项目编写的代码。这样的代码通常来自不同的上游项目,具有自己的样式指南(或缺少样式指南),并且不希望引入会使上游存储库同步变得更难的差异。

第三方代码通常包含在 thirdparty / 文件夹中,因此可以轻松地从格式化脚本中排除。对于需要将第三方代码段直接包含在Godot文件中的极少数情况,您可以使用 /* clang-format off *//* clang-format on */ 来告诉clang-format忽略一个代码块。

在本地使用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标头引入的块应用一个空行以进行分隔。
  • 最后,第三方标头(来自 第三方 或系统的引入路径)接下来应该在<和>符号中引入,例如 #include <png.h>。第三方标头块后面还应跟一个空行进行分隔。
  • Godot和第三方标头应该在需要它们的文件中引入,即如果在声明性代码中使用则在 .h 头文件中引入,或者如果仅在命令式代码中使用则在 .cpp 中引入。

示例:

/*************************************************************************/
/*  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的Java代码(主要在 platform/android 中)也通过 clang-format 强制执行格式化,因此请参阅上面的说明进行设置。请记住,此样式指南仅适用于Godot编写和维护的代码,而不适用于第三方代码,例如 java/src/com/google 子文件夹。

Python

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

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