Single Compilation Unit build.
Adds support for simple SCU build (DEV_ENABLED only). This speeds up compilation by compiling multiple cpp files within a single translation unit.
This commit is contained in:
parent
543750a1b3
commit
b69c8b4791
29 changed files with 531 additions and 137 deletions
12
SConstruct
12
SConstruct
|
@ -55,6 +55,7 @@ _helper_module("modules.modules_builders", "modules/modules_builders.py")
|
|||
import methods
|
||||
import glsl_builders
|
||||
import gles3_builders
|
||||
import scu_builders
|
||||
from platform_methods import architectures, architecture_aliases
|
||||
|
||||
if ARGUMENTS.get("target", "editor") == "editor":
|
||||
|
@ -223,6 +224,7 @@ opts.Add(
|
|||
"",
|
||||
)
|
||||
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
|
||||
opts.Add(EnumVariable("scu_build", "Use single compilation unit build", "none", ("none", "dev", "all")))
|
||||
|
||||
# Thirdparty libraries
|
||||
opts.Add(BoolVariable("builtin_certs", "Use the built-in SSL certificates bundles", True))
|
||||
|
@ -428,14 +430,20 @@ if env_base.debug_features:
|
|||
# to give *users* extra debugging information for their game development.
|
||||
env_base.Append(CPPDEFINES=["DEBUG_ENABLED"])
|
||||
|
||||
|
||||
if env_base.dev_build:
|
||||
# DEV_ENABLED enables *engine developer* code which should only be compiled for those
|
||||
# working on the engine itself.
|
||||
env_base.Append(CPPDEFINES=["DEV_ENABLED"])
|
||||
env_base["use_scu"] = env_base["scu_build"] in ("dev", "all")
|
||||
else:
|
||||
# Disable assert() for production targets (only used in thirdparty code).
|
||||
env_base.Append(CPPDEFINES=["NDEBUG"])
|
||||
|
||||
# SCU builds currently use a lot of compiler memory
|
||||
# in release builds, so disallow outside of DEV builds unless "all" is set.
|
||||
env_base["use_scu"] = env_base["scu_build"] == "all"
|
||||
|
||||
# SCons speed optimization controlled by the `fast_unsafe` option, which provide
|
||||
# more than 10 s speed up for incremental rebuilds.
|
||||
# Unsafe as they reduce the certainty of rebuilding all changed files, so it's
|
||||
|
@ -550,6 +558,10 @@ if selected_platform in platform_list:
|
|||
# LTO "auto" means we handle the preferred option in each platform detect.py.
|
||||
env["lto"] = ARGUMENTS.get("lto", "auto")
|
||||
|
||||
# Run SCU file generation script if in a SCU build.
|
||||
if env["use_scu"]:
|
||||
methods.set_scu_folders(scu_builders.generate_scu_files(env["verbose"], env_base.dev_build == False))
|
||||
|
||||
# Must happen after the flags' definition, as configure is when most flags
|
||||
# are actually handled to change compile options, etc.
|
||||
detect.configure(env)
|
||||
|
|
|
@ -29,9 +29,8 @@ if env.editor_build:
|
|||
reg_exporters_inc = '#include "register_exporters.h"\n\n'
|
||||
reg_exporters = "void register_exporters() {\n"
|
||||
for e in env.platform_exporters:
|
||||
# Glob all .cpp files in export folder
|
||||
files = Glob("#platform/" + e + "/export/" + "*.cpp")
|
||||
env.add_source_files(env.editor_sources, files)
|
||||
# Add all .cpp files in export folder
|
||||
env.add_source_files(env.editor_sources, "../platform/" + e + "/export/" + "*.cpp")
|
||||
|
||||
reg_exporters += "\tregister_" + e + "_exporter();\n"
|
||||
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "core/version.h"
|
||||
|
||||
// The metadata key used to store and retrieve the version text to copy to the clipboard.
|
||||
static const String META_TEXT_TO_COPY = "text_to_copy";
|
||||
const String EditorAbout::META_TEXT_TO_COPY = "text_to_copy";
|
||||
|
||||
void EditorAbout::_theme_changed() {
|
||||
const Ref<Font> font = get_theme_font(SNAME("source"), SNAME("EditorFonts"));
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
class EditorAbout : public AcceptDialog {
|
||||
GDCLASS(EditorAbout, AcceptDialog);
|
||||
|
||||
static const String META_TEXT_TO_COPY;
|
||||
|
||||
private:
|
||||
void _license_tree_selected();
|
||||
void _version_button_pressed();
|
||||
|
|
|
@ -46,14 +46,14 @@
|
|||
#include "scene/property_utils.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
|
||||
bool EditorInspector::_property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
|
||||
if (p_property_path.findn(p_filter) != -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const Vector<String> sections = p_property_path.split("/");
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
|
||||
const Vector<String> prop_sections = p_property_path.split("/");
|
||||
for (int i = 0; i < prop_sections.size(); i++) {
|
||||
if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(prop_sections[i], p_style))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -512,6 +512,7 @@ class EditorInspector : public ScrollContainer {
|
|||
void _property_deleted(const String &p_path);
|
||||
void _property_checked(const String &p_path, bool p_checked);
|
||||
void _property_pinned(const String &p_path, bool p_pinned);
|
||||
bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style);
|
||||
|
||||
void _resource_selected(const String &p_path, Ref<Resource> p_resource);
|
||||
void _property_selected(const String &p_path, int p_focusable);
|
||||
|
|
|
@ -6760,28 +6760,28 @@ EditorNode::EditorNode() {
|
|||
switch (display_scale) {
|
||||
case 0:
|
||||
// Try applying a suitable display scale automatically.
|
||||
editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
|
||||
EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
|
||||
break;
|
||||
case 1:
|
||||
editor_set_scale(0.75);
|
||||
EditorScale::set_scale(0.75);
|
||||
break;
|
||||
case 2:
|
||||
editor_set_scale(1.0);
|
||||
EditorScale::set_scale(1.0);
|
||||
break;
|
||||
case 3:
|
||||
editor_set_scale(1.25);
|
||||
EditorScale::set_scale(1.25);
|
||||
break;
|
||||
case 4:
|
||||
editor_set_scale(1.5);
|
||||
EditorScale::set_scale(1.5);
|
||||
break;
|
||||
case 5:
|
||||
editor_set_scale(1.75);
|
||||
EditorScale::set_scale(1.75);
|
||||
break;
|
||||
case 6:
|
||||
editor_set_scale(2.0);
|
||||
EditorScale::set_scale(2.0);
|
||||
break;
|
||||
default:
|
||||
editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
|
||||
EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_scale.h"
|
||||
|
||||
static Rect2i prev_rect = Rect2i();
|
||||
static bool was_showed = false;
|
||||
Rect2i EditorQuickOpen::prev_rect = Rect2i();
|
||||
bool EditorQuickOpen::was_showed = false;
|
||||
|
||||
void EditorQuickOpen::popup_dialog(const String &p_base, bool p_enable_multi, bool p_dont_clear) {
|
||||
base_type = p_base;
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
class EditorQuickOpen : public ConfirmationDialog {
|
||||
GDCLASS(EditorQuickOpen, ConfirmationDialog);
|
||||
|
||||
static Rect2i prev_rect;
|
||||
static bool was_showed;
|
||||
|
||||
LineEdit *search_box = nullptr;
|
||||
Tree *search_options = nullptr;
|
||||
String base_type;
|
||||
|
|
|
@ -30,14 +30,12 @@
|
|||
|
||||
#include "editor_scale.h"
|
||||
|
||||
#include "core/os/os.h"
|
||||
float EditorScale::_scale = 1.0f;
|
||||
|
||||
static float scale = 1.0;
|
||||
|
||||
void editor_set_scale(float p_scale) {
|
||||
scale = p_scale;
|
||||
void EditorScale::set_scale(float p_scale) {
|
||||
_scale = p_scale;
|
||||
}
|
||||
|
||||
float editor_get_scale() {
|
||||
return scale;
|
||||
float EditorScale::get_scale() {
|
||||
return _scale;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,14 @@
|
|||
#ifndef EDITOR_SCALE_H
|
||||
#define EDITOR_SCALE_H
|
||||
|
||||
void editor_set_scale(float p_scale);
|
||||
float editor_get_scale();
|
||||
class EditorScale {
|
||||
static float _scale;
|
||||
|
||||
#define EDSCALE (editor_get_scale())
|
||||
public:
|
||||
static void set_scale(float p_scale);
|
||||
static float get_scale();
|
||||
};
|
||||
|
||||
#define EDSCALE (EditorScale::get_scale())
|
||||
|
||||
#endif // EDITOR_SCALE_H
|
||||
|
|
|
@ -481,7 +481,7 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
|
|||
code_editor->convert_case(p_case);
|
||||
}
|
||||
|
||||
static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) {
|
||||
ScriptEditorBase *TextEditor::create_editor(const Ref<Resource> &p_resource) {
|
||||
if (Object::cast_to<TextFile>(*p_resource) || Object::cast_to<JSON>(*p_resource)) {
|
||||
return memnew(TextEditor);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
class TextEditor : public ScriptEditorBase {
|
||||
GDCLASS(TextEditor, ScriptEditorBase);
|
||||
|
||||
static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource);
|
||||
|
||||
private:
|
||||
CodeTextEditor *code_editor = nullptr;
|
||||
|
||||
|
|
|
@ -4982,7 +4982,7 @@ void VisualShaderEditor::_preview_size_changed() {
|
|||
preview_vbox->set_custom_minimum_size(preview_window->get_size());
|
||||
}
|
||||
|
||||
static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) {
|
||||
static ShaderLanguage::DataType _visual_shader_editor_get_global_shader_uniform_type(const StringName &p_variable) {
|
||||
RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable);
|
||||
return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt);
|
||||
}
|
||||
|
@ -5001,7 +5001,7 @@ void VisualShaderEditor::_update_preview() {
|
|||
info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode()));
|
||||
info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode()));
|
||||
info.shader_types = ShaderTypes::get_singleton()->get_types();
|
||||
info.global_shader_uniform_type_func = _get_global_shader_uniform_type;
|
||||
info.global_shader_uniform_type_func = _visual_shader_editor_get_global_shader_uniform_type;
|
||||
|
||||
ShaderLanguage sl;
|
||||
|
||||
|
|
|
@ -2763,28 +2763,28 @@ ProjectManager::ProjectManager() {
|
|||
switch (display_scale) {
|
||||
case 0:
|
||||
// Try applying a suitable display scale automatically.
|
||||
editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
|
||||
EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
|
||||
break;
|
||||
case 1:
|
||||
editor_set_scale(0.75);
|
||||
EditorScale::set_scale(0.75);
|
||||
break;
|
||||
case 2:
|
||||
editor_set_scale(1.0);
|
||||
EditorScale::set_scale(1.0);
|
||||
break;
|
||||
case 3:
|
||||
editor_set_scale(1.25);
|
||||
EditorScale::set_scale(1.25);
|
||||
break;
|
||||
case 4:
|
||||
editor_set_scale(1.5);
|
||||
EditorScale::set_scale(1.5);
|
||||
break;
|
||||
case 5:
|
||||
editor_set_scale(1.75);
|
||||
EditorScale::set_scale(1.75);
|
||||
break;
|
||||
case 6:
|
||||
editor_set_scale(2.0);
|
||||
EditorScale::set_scale(2.0);
|
||||
break;
|
||||
default:
|
||||
editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
|
||||
EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
|
||||
break;
|
||||
}
|
||||
EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon;
|
||||
|
|
84
methods.py
84
methods.py
|
@ -6,9 +6,23 @@ import subprocess
|
|||
from collections import OrderedDict
|
||||
from collections.abc import Mapping
|
||||
from typing import Iterator
|
||||
from pathlib import Path
|
||||
from os.path import normpath, basename
|
||||
|
||||
# Get the "Godot" folder name ahead of time
|
||||
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
|
||||
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
|
||||
# Listing all the folders we have converted
|
||||
# for SCU in scu_builders.py
|
||||
_scu_folders = set()
|
||||
|
||||
|
||||
def add_source_files(self, sources, files):
|
||||
def set_scu_folders(scu_folders):
|
||||
global _scu_folders
|
||||
_scu_folders = scu_folders
|
||||
|
||||
|
||||
def add_source_files_orig(self, sources, files, allow_gen=False):
|
||||
# Convert string to list of absolute paths (including expanding wildcard)
|
||||
if isinstance(files, (str, bytes)):
|
||||
# Keep SCons project-absolute path as they are (no wildcard support)
|
||||
|
@ -23,7 +37,7 @@ def add_source_files(self, sources, files):
|
|||
skip_gen_cpp = "*" in files
|
||||
dir_path = self.Dir(".").abspath
|
||||
files = sorted(glob.glob(dir_path + "/" + files))
|
||||
if skip_gen_cpp:
|
||||
if skip_gen_cpp and not allow_gen:
|
||||
files = [f for f in files if not f.endswith(".gen.cpp")]
|
||||
|
||||
# Add each path as compiled Object following environment (self) configuration
|
||||
|
@ -35,6 +49,72 @@ def add_source_files(self, sources, files):
|
|||
sources.append(obj)
|
||||
|
||||
|
||||
# The section name is used for checking
|
||||
# the hash table to see whether the folder
|
||||
# is included in the SCU build.
|
||||
# It will be something like "core/math".
|
||||
def _find_scu_section_name(subdir):
|
||||
section_path = os.path.abspath(subdir) + "/"
|
||||
|
||||
folders = []
|
||||
folder = ""
|
||||
|
||||
for i in range(8):
|
||||
folder = os.path.dirname(section_path)
|
||||
folder = os.path.basename(folder)
|
||||
if folder == base_folder_only:
|
||||
break
|
||||
folders += [folder]
|
||||
section_path += "../"
|
||||
section_path = os.path.abspath(section_path) + "/"
|
||||
|
||||
section_name = ""
|
||||
for n in range(len(folders)):
|
||||
# section_name += folders[len(folders) - n - 1] + " "
|
||||
section_name += folders[len(folders) - n - 1]
|
||||
if n != (len(folders) - 1):
|
||||
section_name += "/"
|
||||
|
||||
return section_name
|
||||
|
||||
|
||||
def add_source_files_scu(self, sources, files, allow_gen=False):
|
||||
if self["use_scu"] and isinstance(files, str):
|
||||
if "*." not in files:
|
||||
return False
|
||||
|
||||
# If the files are in a subdirectory, we want to create the scu gen
|
||||
# files inside this subdirectory.
|
||||
subdir = os.path.dirname(files)
|
||||
if subdir != "":
|
||||
subdir += "/"
|
||||
|
||||
section_name = _find_scu_section_name(subdir)
|
||||
# if the section name is in the hash table?
|
||||
# i.e. is it part of the SCU build?
|
||||
global _scu_folders
|
||||
if section_name not in (_scu_folders):
|
||||
return False
|
||||
|
||||
if self["verbose"]:
|
||||
print("SCU building " + section_name)
|
||||
|
||||
# Add all the gen.cpp files in the SCU directory
|
||||
add_source_files_orig(self, sources, subdir + "scu/scu_*.gen.cpp", True)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# Either builds the folder using the SCU system,
|
||||
# or reverts to regular build.
|
||||
def add_source_files(self, sources, files, allow_gen=False):
|
||||
if not add_source_files_scu(self, sources, files, allow_gen):
|
||||
# Wraps the original function when scu build is not active.
|
||||
add_source_files_orig(self, sources, files, allow_gen)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def disable_warnings(self):
|
||||
# 'self' is the environment
|
||||
if self.msvc:
|
||||
|
|
|
@ -941,7 +941,7 @@ void AnimationTree::_clear_playing_caches() {
|
|||
playing_caches.clear();
|
||||
}
|
||||
|
||||
static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
|
||||
void AnimationTree::_call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
|
||||
// Separate function to use alloca() more efficiently
|
||||
const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size());
|
||||
const Variant *args = p_params.ptr();
|
||||
|
|
|
@ -194,6 +194,8 @@ class AnimationNodeEndState : public AnimationRootNode {
|
|||
class AnimationTree : public Node {
|
||||
GDCLASS(AnimationTree, Node);
|
||||
|
||||
void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred);
|
||||
|
||||
public:
|
||||
enum AnimationProcessCallback {
|
||||
ANIMATION_PROCESS_PHYSICS,
|
||||
|
|
|
@ -34,12 +34,6 @@
|
|||
|
||||
#include "graph_edit.h"
|
||||
|
||||
struct _MinSizeCache {
|
||||
int min_size;
|
||||
bool will_stretch;
|
||||
int final_size;
|
||||
};
|
||||
|
||||
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
|
||||
|
|
|
@ -37,6 +37,12 @@
|
|||
class GraphNode : public Container {
|
||||
GDCLASS(GraphNode, Container);
|
||||
|
||||
struct _MinSizeCache {
|
||||
int min_size;
|
||||
bool will_stretch;
|
||||
int final_size;
|
||||
};
|
||||
|
||||
public:
|
||||
enum Overlay {
|
||||
OVERLAY_DISABLED,
|
||||
|
|
|
@ -795,8 +795,8 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, Local
|
|||
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
|
||||
}
|
||||
|
||||
static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
|
||||
static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
const uint32_t SurfaceTool::custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
|
||||
const uint32_t SurfaceTool::custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
|
||||
void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, LocalVector<SurfaceTool::Vertex> &ret, uint32_t *r_format) {
|
||||
ret.clear();
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
class SurfaceTool : public RefCounted {
|
||||
GDCLASS(SurfaceTool, RefCounted);
|
||||
|
||||
static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT];
|
||||
static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT];
|
||||
|
||||
public:
|
||||
struct Vertex {
|
||||
Vector3 vertex;
|
||||
|
|
339
scu_builders.py
Normal file
339
scu_builders.py
Normal file
|
@ -0,0 +1,339 @@
|
|||
"""Functions used to generate scu build source files during build time
|
||||
"""
|
||||
import glob, os
|
||||
import math
|
||||
from pathlib import Path
|
||||
from os.path import normpath, basename
|
||||
|
||||
base_folder_path = str(Path(__file__).parent) + "/"
|
||||
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
|
||||
_verbose = False
|
||||
_is_release_build = False
|
||||
_scu_folders = set()
|
||||
|
||||
|
||||
def clear_out_existing_files(output_folder, extension):
|
||||
output_folder = os.path.abspath(output_folder)
|
||||
# print("clear_out_existing_files from folder: " + output_folder)
|
||||
|
||||
if not os.path.isdir(output_folder):
|
||||
# folder does not exist or has not been created yet,
|
||||
# no files to clearout. (this is not an error)
|
||||
return
|
||||
|
||||
for file in glob.glob(output_folder + "/*." + extension):
|
||||
# print("removed pre-existing file: " + file)
|
||||
os.remove(file)
|
||||
|
||||
|
||||
def folder_not_found(folder):
|
||||
abs_folder = base_folder_path + folder + "/"
|
||||
return not os.path.isdir(abs_folder)
|
||||
|
||||
|
||||
def find_files_in_folder(folder, sub_folder, include_list, extension, sought_exceptions, found_exceptions):
|
||||
abs_folder = base_folder_path + folder + "/" + sub_folder
|
||||
|
||||
if not os.path.isdir(abs_folder):
|
||||
print("ERROR " + abs_folder + " not found.")
|
||||
return include_list, found_exceptions
|
||||
|
||||
os.chdir(abs_folder)
|
||||
|
||||
sub_folder_slashed = ""
|
||||
if sub_folder != "":
|
||||
sub_folder_slashed = sub_folder + "/"
|
||||
|
||||
for file in glob.glob("*." + extension):
|
||||
|
||||
simple_name = Path(file).stem
|
||||
|
||||
if file.endswith(".gen.cpp"):
|
||||
continue
|
||||
|
||||
li = '#include "../' + sub_folder_slashed + file + '"'
|
||||
|
||||
if not simple_name in sought_exceptions:
|
||||
include_list.append(li)
|
||||
else:
|
||||
found_exceptions.append(li)
|
||||
|
||||
return include_list, found_exceptions
|
||||
|
||||
|
||||
def write_output_file(file_count, include_list, start_line, end_line, output_folder, output_filename_prefix, extension):
|
||||
|
||||
output_folder = os.path.abspath(output_folder)
|
||||
|
||||
if not os.path.isdir(output_folder):
|
||||
# create
|
||||
os.mkdir(output_folder)
|
||||
if not os.path.isdir(output_folder):
|
||||
print("ERROR " + output_folder + " could not be created.")
|
||||
return
|
||||
print("CREATING folder " + output_folder)
|
||||
|
||||
file_text = ""
|
||||
|
||||
for l in range(start_line, end_line):
|
||||
if l < len(include_list):
|
||||
line = include_list[l]
|
||||
li = line + "\n"
|
||||
file_text += li
|
||||
|
||||
# print(file_text)
|
||||
|
||||
num_string = ""
|
||||
if file_count > 0:
|
||||
num_string = "_" + str(file_count)
|
||||
|
||||
short_filename = output_filename_prefix + num_string + ".gen." + extension
|
||||
output_filename = output_folder + "/" + short_filename
|
||||
if _verbose:
|
||||
print("generating: " + short_filename)
|
||||
|
||||
output_path = Path(output_filename)
|
||||
output_path.write_text(file_text, encoding="utf8")
|
||||
|
||||
|
||||
def write_exception_output_file(file_count, exception_string, output_folder, output_filename_prefix, extension):
|
||||
output_folder = os.path.abspath(output_folder)
|
||||
if not os.path.isdir(output_folder):
|
||||
print("ERROR " + output_folder + " does not exist.")
|
||||
return
|
||||
|
||||
file_text = exception_string + "\n"
|
||||
|
||||
num_string = ""
|
||||
if file_count > 0:
|
||||
num_string = "_" + str(file_count)
|
||||
|
||||
short_filename = output_filename_prefix + "_exception" + num_string + ".gen." + extension
|
||||
output_filename = output_folder + "/" + short_filename
|
||||
|
||||
if _verbose:
|
||||
print("generating: " + short_filename)
|
||||
|
||||
# print("text: " + file_text)
|
||||
# return
|
||||
output_path = Path(output_filename)
|
||||
output_path.write_text(file_text, encoding="utf8")
|
||||
|
||||
|
||||
def find_section_name(sub_folder):
|
||||
# Construct a useful name for the section from the path for debug logging
|
||||
section_path = os.path.abspath(base_folder_path + sub_folder) + "/"
|
||||
|
||||
folders = []
|
||||
folder = ""
|
||||
|
||||
for i in range(8):
|
||||
folder = os.path.dirname(section_path)
|
||||
folder = os.path.basename(folder)
|
||||
if folder == base_folder_only:
|
||||
break
|
||||
folders.append(folder)
|
||||
section_path += "../"
|
||||
section_path = os.path.abspath(section_path) + "/"
|
||||
|
||||
section_name = ""
|
||||
for n in range(len(folders)):
|
||||
section_name += folders[len(folders) - n - 1]
|
||||
if n != (len(folders) - 1):
|
||||
section_name += "_"
|
||||
|
||||
return section_name
|
||||
|
||||
|
||||
# "folders" is a list of folders to add all the files from to add to the SCU
|
||||
# "section (like a module)". The name of the scu file will be derived from the first folder
|
||||
# (thus e.g. scene/3d becomes scu_scene_3d.gen.cpp)
|
||||
|
||||
# "includes_per_scu" limits the number of includes in a single scu file.
|
||||
# This allows the module to be built in several translation units instead of just 1.
|
||||
# This will usually be slower to compile but will use less memory per compiler instance, which
|
||||
# is most relevant in release builds.
|
||||
|
||||
# "sought_exceptions" are a list of files (without extension) that contain
|
||||
# e.g. naming conflicts, and are therefore not suitable for the scu build.
|
||||
# These will automatically be placed in their own separate scu file,
|
||||
# which is slow like a normal build, but prevents the naming conflicts.
|
||||
# Ideally in these situations, the source code should be changed to prevent naming conflicts.
|
||||
|
||||
# "extension" will usually be cpp, but can also be set to c (for e.g. third party libraries that use c)
|
||||
def process_folder(folders, sought_exceptions=[], includes_per_scu=0, extension="cpp"):
|
||||
if len(folders) == 0:
|
||||
return
|
||||
|
||||
# Construct the filename prefix from the FIRST folder name
|
||||
# e.g. "scene_3d"
|
||||
out_filename = find_section_name(folders[0])
|
||||
|
||||
found_includes = []
|
||||
found_exceptions = []
|
||||
|
||||
main_folder = folders[0]
|
||||
abs_main_folder = base_folder_path + main_folder
|
||||
|
||||
# Keep a record of all folders that have been processed for SCU,
|
||||
# this enables deciding what to do when we call "add_source_files()"
|
||||
global _scu_folders
|
||||
_scu_folders.add(main_folder)
|
||||
|
||||
# main folder (first)
|
||||
found_includes, found_exceptions = find_files_in_folder(
|
||||
main_folder, "", found_includes, extension, sought_exceptions, found_exceptions
|
||||
)
|
||||
|
||||
# sub folders
|
||||
for d in range(1, len(folders)):
|
||||
found_includes, found_exceptions = find_files_in_folder(
|
||||
main_folder, folders[d], found_includes, extension, sought_exceptions, found_exceptions
|
||||
)
|
||||
|
||||
found_includes = sorted(found_includes)
|
||||
|
||||
# calculate how many lines to write in each file
|
||||
total_lines = len(found_includes)
|
||||
|
||||
# adjust number of output files according to whether DEV or release
|
||||
num_output_files = 1
|
||||
if _is_release_build:
|
||||
# always have a maximum in release
|
||||
includes_per_scu = 8
|
||||
num_output_files = max(math.ceil(total_lines / float(includes_per_scu)), 1)
|
||||
else:
|
||||
if includes_per_scu > 0:
|
||||
num_output_files = max(math.ceil(total_lines / float(includes_per_scu)), 1)
|
||||
|
||||
lines_per_file = math.ceil(total_lines / float(num_output_files))
|
||||
lines_per_file = max(lines_per_file, 1)
|
||||
|
||||
start_line = 0
|
||||
file_number = 0
|
||||
|
||||
# These do not vary throughout the loop
|
||||
output_folder = abs_main_folder + "/scu/"
|
||||
output_filename_prefix = "scu_" + out_filename
|
||||
|
||||
# Clear out any existing files (usually we will be overwriting,
|
||||
# but we want to remove any that are pre-existing that will not be
|
||||
# overwritten, so as to not compile anything stale)
|
||||
clear_out_existing_files(output_folder, extension)
|
||||
|
||||
for file_count in range(0, num_output_files):
|
||||
end_line = start_line + lines_per_file
|
||||
|
||||
# special case to cover rounding error in final file
|
||||
if file_count == (num_output_files - 1):
|
||||
end_line = len(found_includes)
|
||||
|
||||
write_output_file(
|
||||
file_count, found_includes, start_line, end_line, output_folder, output_filename_prefix, extension
|
||||
)
|
||||
|
||||
start_line = end_line
|
||||
|
||||
# Write the exceptions each in their own scu gen file,
|
||||
# so they can effectively compile in "old style / normal build".
|
||||
for exception_count in range(len(found_exceptions)):
|
||||
write_exception_output_file(
|
||||
exception_count, found_exceptions[exception_count], output_folder, output_filename_prefix, extension
|
||||
)
|
||||
|
||||
|
||||
def generate_scu_files(verbose, is_release_build):
|
||||
|
||||
print("=============================")
|
||||
print("Single Compilation Unit Build")
|
||||
print("=============================")
|
||||
print("Generating SCU build files")
|
||||
global _verbose
|
||||
_verbose = verbose
|
||||
global _is_release_build
|
||||
_is_release_build = is_release_build
|
||||
|
||||
curr_folder = os.path.abspath("./")
|
||||
|
||||
# check we are running from the correct folder
|
||||
if folder_not_found("core") or folder_not_found("platform") or folder_not_found("scene"):
|
||||
raise RuntimeError("scu_builders.py must be run from the godot folder.")
|
||||
return
|
||||
|
||||
process_folder(["core"])
|
||||
process_folder(["core/crypto"])
|
||||
process_folder(["core/debugger"])
|
||||
process_folder(["core/extension"])
|
||||
process_folder(["core/input"])
|
||||
process_folder(["core/io"])
|
||||
process_folder(["core/math"])
|
||||
process_folder(["core/object"])
|
||||
process_folder(["core/os"])
|
||||
process_folder(["core/string"])
|
||||
process_folder(["core/variant"], ["variant_utility"])
|
||||
|
||||
process_folder(["drivers/unix"])
|
||||
process_folder(["drivers/png"])
|
||||
|
||||
process_folder(["editor"], ["file_system_dock", "editor_resource_preview"], 32)
|
||||
process_folder(["editor/debugger"])
|
||||
process_folder(["editor/debugger/debug_adapter"])
|
||||
process_folder(["editor/export"])
|
||||
process_folder(["editor/gui"])
|
||||
process_folder(["editor/import"])
|
||||
process_folder(["editor/plugins"])
|
||||
process_folder(["editor/plugins/gizmos"])
|
||||
process_folder(["editor/plugins/tiles"])
|
||||
|
||||
process_folder(["platform/android/export"])
|
||||
process_folder(["platform/ios/export"])
|
||||
process_folder(["platform/linuxbsd/export"])
|
||||
process_folder(["platform/macos/export"])
|
||||
process_folder(["platform/uwp/export"])
|
||||
process_folder(["platform/web/export"])
|
||||
process_folder(["platform/windows/export"])
|
||||
|
||||
process_folder(["modules/gltf"])
|
||||
process_folder(["modules/gltf/structures"])
|
||||
process_folder(["modules/gltf/editor"])
|
||||
process_folder(["modules/gltf/extensions"])
|
||||
process_folder(["modules/gltf/extensions/physics"])
|
||||
process_folder(["modules/navigation"])
|
||||
process_folder(["modules/webrtc"])
|
||||
process_folder(["modules/websocket"])
|
||||
process_folder(["modules/gridmap"])
|
||||
process_folder(["modules/multiplayer"])
|
||||
process_folder(["modules/multiplayer/editor"])
|
||||
process_folder(["modules/openxr"], ["register_types"])
|
||||
process_folder(["modules/openxr/action_map"])
|
||||
process_folder(["modules/openxr/editor"])
|
||||
|
||||
process_folder(["modules/csg"])
|
||||
process_folder(["modules/gdscript"])
|
||||
process_folder(["modules/gdscript/editor"])
|
||||
process_folder(["modules/gdscript/language_server"])
|
||||
|
||||
process_folder(["scene/2d"])
|
||||
process_folder(["scene/3d"])
|
||||
process_folder(["scene/animation"])
|
||||
process_folder(["scene/gui"])
|
||||
process_folder(["scene/main"])
|
||||
process_folder(["scene/resources"])
|
||||
|
||||
process_folder(["servers"])
|
||||
process_folder(["servers/rendering"])
|
||||
process_folder(["servers/rendering/storage"])
|
||||
process_folder(["servers/rendering/renderer_rd"])
|
||||
process_folder(["servers/rendering/renderer_rd/effects"])
|
||||
process_folder(["servers/rendering/renderer_rd/environment"])
|
||||
process_folder(["servers/rendering/renderer_rd/storage_rd"])
|
||||
process_folder(["servers/physics_2d"])
|
||||
process_folder(["servers/physics_3d"])
|
||||
process_folder(["servers/physics_3d/joints"])
|
||||
process_folder(["servers/audio"])
|
||||
process_folder(["servers/audio/effects"])
|
||||
|
||||
# Finally change back the path to the calling folder
|
||||
os.chdir(curr_folder)
|
||||
|
||||
return _scu_folders
|
|
@ -39,6 +39,39 @@ protected:
|
|||
bool dynamic_A = false;
|
||||
bool dynamic_B = false;
|
||||
|
||||
void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
|
||||
if (Math::abs(n.z) > Math_SQRT12) {
|
||||
// choose p in y-z plane
|
||||
real_t a = n[1] * n[1] + n[2] * n[2];
|
||||
real_t k = 1.0 / Math::sqrt(a);
|
||||
p = Vector3(0, -n[2] * k, n[1] * k);
|
||||
// set q = n x p
|
||||
q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
|
||||
} else {
|
||||
// choose p in x-y plane
|
||||
real_t a = n.x * n.x + n.y * n.y;
|
||||
real_t k = 1.0 / Math::sqrt(a);
|
||||
p = Vector3(-n.y * k, n.x * k, 0);
|
||||
// set q = n x p
|
||||
q = Vector3(-n.z * p.y, n.z * p.x, a * k);
|
||||
}
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
|
||||
real_t coeff_1 = Math_PI / 4.0f;
|
||||
real_t coeff_2 = 3.0f * coeff_1;
|
||||
real_t abs_y = Math::abs(y);
|
||||
real_t angle;
|
||||
if (x >= 0.0f) {
|
||||
real_t r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
real_t r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual bool setup(real_t p_step) override { return false; }
|
||||
virtual bool pre_solve(real_t p_step) override { return true; }
|
||||
|
|
|
@ -51,39 +51,6 @@ Written by: Marcus Hennix
|
|||
|
||||
#include "godot_cone_twist_joint_3d.h"
|
||||
|
||||
static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
|
||||
if (Math::abs(n.z) > Math_SQRT12) {
|
||||
// choose p in y-z plane
|
||||
real_t a = n[1] * n[1] + n[2] * n[2];
|
||||
real_t k = 1.0 / Math::sqrt(a);
|
||||
p = Vector3(0, -n[2] * k, n[1] * k);
|
||||
// set q = n x p
|
||||
q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
|
||||
} else {
|
||||
// choose p in x-y plane
|
||||
real_t a = n.x * n.x + n.y * n.y;
|
||||
real_t k = 1.0 / Math::sqrt(a);
|
||||
p = Vector3(-n.y * k, n.x * k, 0);
|
||||
// set q = n x p
|
||||
q = Vector3(-n.z * p.y, n.z * p.x, a * k);
|
||||
}
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
|
||||
real_t coeff_1 = Math_PI / 4.0f;
|
||||
real_t coeff_2 = 3.0f * coeff_1;
|
||||
real_t abs_y = Math::abs(y);
|
||||
real_t angle;
|
||||
if (x >= 0.0f) {
|
||||
real_t r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
real_t r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
GodotConeTwistJoint3D::GodotConeTwistJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) :
|
||||
GodotJoint3D(_arr, 2) {
|
||||
A = rbA;
|
||||
|
|
|
@ -49,24 +49,6 @@ subject to the following restrictions:
|
|||
|
||||
#include "godot_hinge_joint_3d.h"
|
||||
|
||||
static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
|
||||
if (Math::abs(n.z) > Math_SQRT12) {
|
||||
// choose p in y-z plane
|
||||
real_t a = n[1] * n[1] + n[2] * n[2];
|
||||
real_t k = 1.0 / Math::sqrt(a);
|
||||
p = Vector3(0, -n[2] * k, n[1] * k);
|
||||
// set q = n x p
|
||||
q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
|
||||
} else {
|
||||
// choose p in x-y plane
|
||||
real_t a = n.x * n.x + n.y * n.y;
|
||||
real_t k = 1.0 / Math::sqrt(a);
|
||||
p = Vector3(-n.y * k, n.x * k, 0);
|
||||
// set q = n x p
|
||||
q = Vector3(-n.z * p.y, n.z * p.x, a * k);
|
||||
}
|
||||
}
|
||||
|
||||
GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameA, const Transform3D &frameB) :
|
||||
GodotJoint3D(_arr, 2) {
|
||||
A = rbA;
|
||||
|
@ -368,21 +350,6 @@ void HingeJointSW::updateRHS(real_t timeStep)
|
|||
|
||||
*/
|
||||
|
||||
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
|
||||
real_t coeff_1 = Math_PI / 4.0f;
|
||||
real_t coeff_2 = 3.0f * coeff_1;
|
||||
real_t abs_y = Math::abs(y);
|
||||
real_t angle;
|
||||
if (x >= 0.0f) {
|
||||
real_t r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
real_t r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
real_t GodotHingeJoint3D::get_hinge_angle() {
|
||||
const Vector3 refAxis0 = A->get_transform().basis.xform(m_rbAFrame.basis.get_column(0));
|
||||
const Vector3 refAxis1 = A->get_transform().basis.xform(m_rbAFrame.basis.get_column(1));
|
||||
|
|
|
@ -57,25 +57,6 @@ April 04, 2008
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
|
||||
real_t coeff_1 = Math_PI / 4.0f;
|
||||
real_t coeff_2 = 3.0f * coeff_1;
|
||||
real_t abs_y = Math::abs(y);
|
||||
real_t angle;
|
||||
if (x >= 0.0f) {
|
||||
real_t r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
real_t r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
GodotSliderJoint3D::GodotSliderJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB) :
|
||||
GodotJoint3D(_arr, 2),
|
||||
m_frameInA(frameInA),
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
#include "rendering_server_globals.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
|
||||
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
|
||||
|
||||
void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) {
|
||||
RENDER_TIMESTAMP("Cull CanvasItem Tree");
|
||||
|
||||
|
|
|
@ -183,6 +183,8 @@ private:
|
|||
void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask);
|
||||
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort, uint32_t canvas_cull_mask);
|
||||
|
||||
static constexpr int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
|
||||
|
||||
RendererCanvasRender::Item **z_list;
|
||||
RendererCanvasRender::Item **z_last_list;
|
||||
|
||||
|
|
Loading…
Reference in a new issue