代码风格指南
在给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的美化插件的非详尽列表:
Qt Creator: 美化插件
Visual Studio Code: Clang-Format
Visual Studio: ClangFormat
vim: vim-clang-format
(欢迎拉取请求以使用测试过的插件来扩展此列表.)
标头引入
当添加新的C++或Objective-C文件或在现有文件中引入新的标头时,应遵循以下规则:
文件中的第一行应该是Godot的版权标头和MIT许可证,从另一个文件复制粘贴.确保调整文件名.
在
.h
头文件中,引入防护应该与FILENAME_H
形式一起使用.在
.cpp
文件(如filename.cpp
)中,第一个引入应该是声明类的那个(例如#include "filename.h"
),然后使用空行分隔.然后来自Godot自己的代码库的标头,按字母顺序(由
clang-format
强制)引入,并具有相对于根文件夹的路径.这些引入应该用引号来完成,例如#include "core/object.h"
.然后,Godot标头引入的块应用一个空行以进行分隔.最后,第三方头文件(无论是来自
thirdparty
还是来自系统的包含路径)接下来,应该用 < and > 符号包含,例如#include <png.h>
.第三方头文件块的后面也应该有一个空行来分隔.Godot和第三方标头应包含在需要它们的文件中,即,如果在声明性代码中使用,则在 .h 标头中;如果仅在命令性代码中使用,则在 .cpp 中.
示例:
/*************************************************************************/
/* my_new_file.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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.
对于这些,我们遵循 `黑色风格指南<https://github.com/psf/black#the-黑色代码样式>`__ .使用 `Black使Python更改变黑<https://pypi.org/project/black/>`__ .
本地使用黑色
首先,您需要安装black.Black需要python3.6.0+才能运行.
安装
下面介绍如何安装black:
pip install black --user
然后,您有不同的可能性将黑色应用于您的更改:
手动使用
您可以使用以下命令将 black
手动应用于一个或多个文件:
black -l 120 <path/to/file(s)>
``-l 120``表示每行允许的字符数为120.这个数字是开发商商定的.
该路径可以指向多个文件,可以一个接一个,也可以像典型的unixshell一样使用通配符.
预提交钩子
为了便于使用,我们为Git提供了一个预提交钩子,它将在您的所有提交上自动运行以检查您的提交,并让您在最终提交中应用其更改.
这个 “hook” 是一个脚本,可以在 misc/hooks
中找到.请参考该文件夹的 README.md
,了解安装说明.
编辑器集成
许多集成开发环境或代码编辑器都有美化插件,可以配置为自动运行black,例如每次保存文件时.有关详细信息,可以查看 `black编辑器集成<https://github.com/psf/black#editor-integration>`__ .
评论风格指南
本注释风格指南适用于Godot代码库中使用的所有编程语言.
以空间字符开始注释,以将其与禁用代码区分开来.
注释使用句子大小写.注释以大写字母开头,并始终以句号结束.
使用反引号引用变量和函数名和值.
将注释控制在~100个字符。
你可以在需要的时候使用
TODO:
、FIXME:
、NOTE:
、HACK:
作为强调.
示例:
// Compute the first 10,000 decimals of Pi.
// FIXME: Don't crash when computing the 1,337th decimal due to `increment`
// being negative.
不要在注释中重复代码的内容.解释 为什么 而不是 如何 .
Bad:
// Draw loading screen.
draw_load_screen();
你可以在函数或宏定义上面使用Javadoc风格的注释.建议只对不公开给脚本的方法使用Javadoc风格的注释.这是因为公开的方法应该在 class reference XML 中进行记录.
示例:
/**
* Returns the number of nodes in the universe.
* This can potentially be a very large number, hence the 64-bit return type.
*/
uint64_t Universe::get_node_count() {
// ...
}
对于成员变量,不要使用Javadoc式的注释,而是使用单行注释:
class Universe {
// The cached number of nodes in the universe.
// This value may not always be up-to-date with the current number of nodes
// in the universe.
uint64_t node_count_cached = 0;
};