Merge pull request #78113 from lawnjelly/scu_build_3
[3.x] Add support for single compilation unit builds
This commit is contained in:
commit
ac5d7dc821
35 changed files with 542 additions and 130 deletions
|
@ -14,6 +14,7 @@ from collections import OrderedDict
|
|||
# Local
|
||||
import methods
|
||||
import gles_builders
|
||||
import scu_builders
|
||||
from platform_methods import run_in_subprocess
|
||||
|
||||
# scan possible build platforms
|
||||
|
@ -155,6 +156,7 @@ opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and be
|
|||
opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True))
|
||||
opts.Add("system_certs_path", "Use this path as SSL certificates default for editor (for package maintainers)", "")
|
||||
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
|
||||
opts.Add(BoolVariable("scu_build", "Use single compilation unit build", False))
|
||||
opts.Add(
|
||||
EnumVariable(
|
||||
"rids",
|
||||
|
@ -442,6 +444,10 @@ if selected_platform in platform_list:
|
|||
"for an optimized template with debug features)."
|
||||
)
|
||||
|
||||
# Run SCU file generation script if in a SCU build.
|
||||
if env["scu_build"]:
|
||||
methods.set_scu_folders(scu_builders.generate_scu_files(env["verbose"], env_base["target"] != "debug"))
|
||||
|
||||
# Must happen after the flags' definition, as configure is when most flags
|
||||
# are actually handled to change compile options, etc.
|
||||
detect.configure(env)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// Names from https://en.wikipedia.org/wiki/X11_color_names
|
||||
#pragma once
|
||||
|
||||
#include "core/map.h"
|
||||
|
||||
static Map<String, Color> _named_colors;
|
||||
|
|
|
@ -86,7 +86,8 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$
|
|||
#endif
|
||||
"""
|
||||
|
||||
template = """
|
||||
template = """#pragma once
|
||||
|
||||
#ifndef TYPED_METHOD_BIND
|
||||
$iftempl template<$ $ifret class R$ $ifretargs ,$ $arg, class P@$ $iftempl >$
|
||||
class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
static const GLenum _cube_side_enum[6] = {
|
||||
const GLenum RasterizerSceneGLES2::_cube_side_enum[6] = {
|
||||
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
|
@ -1332,7 +1332,7 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
|
|||
}
|
||||
}
|
||||
|
||||
static const GLenum gl_primitive[] = {
|
||||
const GLenum RasterizerSceneGLES2::gl_primitive[] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_LINE_STRIP,
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
|
||||
private:
|
||||
uint32_t _light_counter;
|
||||
static const GLenum gl_primitive[];
|
||||
static const GLenum _cube_side_enum[6];
|
||||
|
||||
public:
|
||||
RasterizerStorageGLES2 *storage;
|
||||
|
|
|
@ -126,7 +126,7 @@ static void _display_error_with_code(const String &p_error, const Vector<const c
|
|||
ERR_PRINT(p_error);
|
||||
}
|
||||
|
||||
static String _mkid(const String &p_id) {
|
||||
String ShaderGLES2::_mkid(const String &p_id) {
|
||||
String id = "m_" + p_id;
|
||||
return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
class RasterizerStorageGLES2;
|
||||
|
||||
class ShaderGLES2 {
|
||||
static String _mkid(const String &p_id);
|
||||
|
||||
protected:
|
||||
struct Enum {
|
||||
uint64_t mask;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define glClearDepth glClearDepthf
|
||||
#endif
|
||||
|
||||
static const GLenum _cube_side_enum[6] = {
|
||||
const GLenum RasterizerSceneGLES3::_cube_side_enum[6] = {
|
||||
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
|
@ -52,7 +52,7 @@ static const GLenum _cube_side_enum[6] = {
|
|||
|
||||
};
|
||||
|
||||
static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_array) {
|
||||
void RasterizerSceneGLES3::store_transform(const Transform &p_mtx, float *p_array) {
|
||||
p_array[0] = p_mtx.basis.elements[0][0];
|
||||
p_array[1] = p_mtx.basis.elements[1][0];
|
||||
p_array[2] = p_mtx.basis.elements[2][0];
|
||||
|
@ -71,7 +71,7 @@ static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_arra
|
|||
p_array[15] = 1;
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
|
||||
void RasterizerSceneGLES3::store_camera(const CameraMatrix &p_mtx, float *p_array) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
p_array[i * 4 + j] = p_mtx.matrix[i][j];
|
||||
|
@ -1482,7 +1482,7 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
|
|||
}
|
||||
}
|
||||
|
||||
static const GLenum gl_primitive[] = {
|
||||
const GLenum RasterizerSceneGLES3::gl_primitive[] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_LINE_STRIP,
|
||||
|
|
|
@ -863,6 +863,13 @@ public:
|
|||
virtual void set_scene_pass(uint64_t p_pass);
|
||||
virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw);
|
||||
|
||||
private:
|
||||
_FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_array);
|
||||
_FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array);
|
||||
static const GLenum gl_primitive[];
|
||||
static const GLenum _cube_side_enum[6];
|
||||
|
||||
public:
|
||||
void iteration();
|
||||
void initialize();
|
||||
void finalize();
|
||||
|
|
|
@ -32,6 +32,7 @@ if env["tools"]:
|
|||
reg_exporters = "void register_exporters() {\n"
|
||||
for e in env.platform_exporters:
|
||||
# Glob all .cpp files in export folder
|
||||
if not env["scu_build"]:
|
||||
files = Glob("#platform/" + e + "/export/" + "*.cpp")
|
||||
env.add_source_files(env.editor_sources, files)
|
||||
|
||||
|
@ -39,6 +40,10 @@ if env["tools"]:
|
|||
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'
|
||||
reg_exporters += "}\n"
|
||||
|
||||
# If we are in a SCU build, we add all the platform exporters in one SCU file.
|
||||
if env["scu_build"]:
|
||||
env.add_source_files(env.editor_sources, "../platform/*.cpp")
|
||||
|
||||
# NOTE: It is safe to generate this file here, since this is still executed serially
|
||||
with open_utf8("register_exporters.gen.cpp", "w") as f:
|
||||
f.write(reg_exporters_inc)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "editor_node.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::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
|
|
|
@ -53,6 +53,7 @@ class EditorAbout : public AcceptDialog {
|
|||
GDCLASS(EditorAbout, AcceptDialog);
|
||||
|
||||
private:
|
||||
static const String META_TEXT_TO_COPY;
|
||||
void _license_tree_selected();
|
||||
void _version_button_pressed();
|
||||
ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char *const *const p_src[], const int p_flag_single_column = 0);
|
||||
|
|
|
@ -43,20 +43,6 @@
|
|||
#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) {
|
||||
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_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Size2 EditorProperty::get_minimum_size() const {
|
||||
Size2 ms;
|
||||
Ref<Font> font = get_font("font", "Tree");
|
||||
|
@ -1232,6 +1218,20 @@ EditorInspectorSection::~EditorInspectorSection() {
|
|||
Ref<EditorInspectorPlugin> EditorInspector::inspector_plugins[MAX_PLUGINS];
|
||||
int EditorInspector::inspector_plugin_count = 0;
|
||||
|
||||
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_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
|
||||
for (int i = inspector_plugin_count - 1; i >= 0; i--) {
|
||||
inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage);
|
||||
|
|
|
@ -319,6 +319,7 @@ class EditorInspector : public ScrollContainer {
|
|||
void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance);
|
||||
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, RES p_resource);
|
||||
void _property_selected(const String &p_path, int p_focusable);
|
||||
|
|
|
@ -34,20 +34,6 @@
|
|||
#include "editor_scale.h"
|
||||
#include "editor_settings.h"
|
||||
|
||||
static bool _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_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class SectionedInspectorFilter : public Object {
|
||||
GDCLASS(SectionedInspectorFilter, Object);
|
||||
|
||||
|
@ -145,6 +131,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
bool SectionedInspector::_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_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SectionedInspector::_bind_methods() {
|
||||
ClassDB::bind_method("_section_selected", &SectionedInspector::_section_selected);
|
||||
ClassDB::bind_method("_search_changed", &SectionedInspector::_search_changed);
|
||||
|
|
|
@ -55,6 +55,7 @@ class SectionedInspector : public HSplitContainer {
|
|||
void _section_selected();
|
||||
|
||||
void _search_changed(const String &p_what);
|
||||
bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
|
|
@ -494,7 +494,7 @@ void TextEditor::_bind_methods() {
|
|||
ClassDB::bind_method("_prepare_edit_menu", &TextEditor::_prepare_edit_menu);
|
||||
}
|
||||
|
||||
static ScriptEditorBase *create_editor(const RES &p_resource) {
|
||||
ScriptEditorBase *TextEditor::create_editor(const RES &p_resource) {
|
||||
if (Object::cast_to<TextFile>(*p_resource)) {
|
||||
return memnew(TextEditor);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ private:
|
|||
BOOKMARK_GOTO_PREV,
|
||||
BOOKMARK_REMOVE_ALL,
|
||||
};
|
||||
static ScriptEditorBase *create_editor(const RES &p_resource);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
|
|
@ -1330,3 +1330,5 @@ MainLoop *test() {
|
|||
return nullptr;
|
||||
}
|
||||
} // namespace TestString
|
||||
|
||||
#undef CHECK
|
||||
|
|
|
@ -301,3 +301,5 @@ MainLoop *test() {
|
|||
return nullptr;
|
||||
}
|
||||
} // namespace TestTheme
|
||||
|
||||
#undef CHECK
|
||||
|
|
84
methods.py
84
methods.py
|
@ -13,8 +13,23 @@ from SCons.Script import ARGUMENTS
|
|||
from SCons.Script import Glob
|
||||
from SCons.Variables.BoolVariable import _text2bool
|
||||
|
||||
from pathlib import Path
|
||||
from os.path import normpath, basename
|
||||
|
||||
def add_source_files(self, sources, files):
|
||||
# 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 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 isbasestring(files):
|
||||
# Keep SCons project-absolute path as they are (no wildcard support)
|
||||
|
@ -29,7 +44,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
|
||||
|
@ -41,6 +56,71 @@ 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]
|
||||
if n != (len(folders) - 1):
|
||||
section_name += "/"
|
||||
|
||||
return section_name
|
||||
|
||||
|
||||
def add_source_files_scu(self, sources, files, allow_gen=False):
|
||||
if self["scu_build"] 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:
|
||||
|
|
|
@ -2227,27 +2227,6 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
|
|||
return false;
|
||||
}
|
||||
|
||||
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
|
||||
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<Script> scr = p_current_node->get_script();
|
||||
|
||||
if (scr.is_valid() && scr == script) {
|
||||
return p_current_node;
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_current_node->get_child_count(); i++) {
|
||||
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
|
||||
if (n) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
|
||||
if (p_from != graph) {
|
||||
return;
|
||||
|
@ -2441,7 +2420,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
|
|||
}
|
||||
|
||||
if (String(d["type"]) == "nodes") {
|
||||
Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
|
||||
Node *sn = NSVisualScript::_find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
|
||||
|
||||
if (!sn) {
|
||||
EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop nodes because script '%s' is not used in this scene."), get_name()));
|
||||
|
@ -2495,7 +2474,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
|
|||
}
|
||||
|
||||
if (String(d["type"]) == "obj_property") {
|
||||
Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
|
||||
Node *sn = NSVisualScript::_find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
|
||||
|
||||
if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
|
||||
EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name()));
|
||||
|
@ -4145,7 +4124,7 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
|
|||
if (pinfo.type == Variant::NODE_PATH) {
|
||||
Node *edited_scene = get_tree()->get_edited_scene_root();
|
||||
if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open)
|
||||
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
|
||||
Node *script_node = NSVisualScript::_find_script_node(edited_scene, edited_scene, script);
|
||||
|
||||
if (script_node) {
|
||||
//pick a node relative to the script, IF the script exists
|
||||
|
|
|
@ -53,30 +53,7 @@ int VisualScriptFunctionCall::get_output_sequence_port_count() const {
|
|||
bool VisualScriptFunctionCall::has_input_sequence_port() const {
|
||||
return !((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_method_const(basic_type, function)));
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
|
||||
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<Script> scr = p_current_node->get_script();
|
||||
|
||||
if (scr.is_valid() && scr == script) {
|
||||
return p_current_node;
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_current_node->get_child_count(); i++) {
|
||||
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
|
||||
if (n) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
Node *VisualScriptFunctionCall::_get_base_node() const {
|
||||
#ifdef TOOLS_ENABLED
|
||||
Ref<Script> script = get_visual_script();
|
||||
|
@ -97,7 +74,7 @@ Node *VisualScriptFunctionCall::_get_base_node() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
|
||||
Node *script_node = NSVisualScript::_find_script_node(edited_scene, edited_scene, script);
|
||||
|
||||
if (!script_node) {
|
||||
return nullptr;
|
||||
|
@ -933,7 +910,7 @@ Node *VisualScriptPropertySet::_get_base_node() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
|
||||
Node *script_node = NSVisualScript::_find_script_node(edited_scene, edited_scene, script);
|
||||
|
||||
if (!script_node) {
|
||||
return nullptr;
|
||||
|
@ -1682,7 +1659,7 @@ Node *VisualScriptPropertyGet::_get_base_node() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
|
||||
Node *script_node = NSVisualScript::_find_script_node(edited_scene, edited_scene, script);
|
||||
|
||||
if (!script_node) {
|
||||
return nullptr;
|
||||
|
|
|
@ -2342,7 +2342,8 @@ VisualScriptNodeInstance *VisualScriptSceneNode::instance(VisualScriptInstance *
|
|||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
|
||||
namespace NSVisualScript {
|
||||
Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
|
||||
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2354,7 +2355,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
|
|||
}
|
||||
|
||||
for (int i = 0; i < p_current_node->get_child_count(); i++) {
|
||||
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
|
||||
Node *n = NSVisualScript::_find_script_node(p_edited_scene, p_current_node->get_child(i), script);
|
||||
if (n) {
|
||||
return n;
|
||||
}
|
||||
|
@ -2362,6 +2363,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
} //namespace NSVisualScript
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -2389,7 +2391,7 @@ VisualScriptSceneNode::TypeGuess VisualScriptSceneNode::guess_output_type(TypeGu
|
|||
return tg;
|
||||
}
|
||||
|
||||
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
|
||||
Node *script_node = NSVisualScript::_find_script_node(edited_scene, edited_scene, script);
|
||||
|
||||
if (!script_node) {
|
||||
return tg;
|
||||
|
@ -2426,7 +2428,7 @@ void VisualScriptSceneNode::_validate_property(PropertyInfo &property) const {
|
|||
return;
|
||||
}
|
||||
|
||||
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
|
||||
Node *script_node = NSVisualScript::_find_script_node(edited_scene, edited_scene, script);
|
||||
|
||||
if (!script_node) {
|
||||
return;
|
||||
|
|
|
@ -1060,4 +1060,10 @@ public:
|
|||
void register_visual_script_nodes();
|
||||
void unregister_visual_script_nodes();
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
namespace NSVisualScript {
|
||||
Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VISUAL_SCRIPT_NODES_H
|
||||
|
|
|
@ -217,30 +217,7 @@ int VisualScriptYieldSignal::get_output_sequence_port_count() const {
|
|||
bool VisualScriptYieldSignal::has_input_sequence_port() const {
|
||||
return true;
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
|
||||
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<Script> scr = p_current_node->get_script();
|
||||
|
||||
if (scr.is_valid() && scr == script) {
|
||||
return p_current_node;
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_current_node->get_child_count(); i++) {
|
||||
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
|
||||
if (n) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
Node *VisualScriptYieldSignal::_get_base_node() const {
|
||||
#ifdef TOOLS_ENABLED
|
||||
Ref<Script> script = get_visual_script();
|
||||
|
@ -261,7 +238,7 @@ Node *VisualScriptYieldSignal::_get_base_node() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
|
||||
Node *script_node = NSVisualScript::_find_script_node(edited_scene, edited_scene, script);
|
||||
|
||||
if (!script_node) {
|
||||
return nullptr;
|
||||
|
|
|
@ -32,12 +32,6 @@
|
|||
#include "label.h"
|
||||
#include "margin_container.h"
|
||||
|
||||
struct _MinSizeCache {
|
||||
int min_size;
|
||||
bool will_stretch;
|
||||
int final_size;
|
||||
};
|
||||
|
||||
void BoxContainer::_resort() {
|
||||
/** First pass, determine minimum size AND amount of stretchable elements */
|
||||
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
class BoxContainer : public Container {
|
||||
GDCLASS(BoxContainer, Container);
|
||||
|
||||
struct _MinSizeCache {
|
||||
int min_size;
|
||||
bool will_stretch;
|
||||
int final_size;
|
||||
};
|
||||
|
||||
public:
|
||||
enum AlignMode {
|
||||
ALIGN_BEGIN,
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "editor/editor_settings.h"
|
||||
#endif
|
||||
|
||||
static bool _is_text_char(CharType c) {
|
||||
bool LineEdit::_is_text_char(CharType c) {
|
||||
return !is_symbol(c);
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ private:
|
|||
void _text_changed();
|
||||
void _emit_text_change();
|
||||
bool expand_to_text_length;
|
||||
bool _is_text_char(CharType c);
|
||||
|
||||
void update_cached_width();
|
||||
void update_placeholder_width();
|
||||
|
|
351
scu_builders.py
Executable file
351
scu_builders.py
Executable file
|
@ -0,0 +1,351 @@
|
|||
"""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
|
||||
|
||||
os.chdir(output_folder)
|
||||
|
||||
for file in glob.glob("*." + 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 "' + folder + "/" + 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
|
||||
|
||||
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)
|
||||
|
||||
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 / includes_per_scu), 1)
|
||||
else:
|
||||
if includes_per_scu > 0:
|
||||
num_output_files = max(math.ceil(total_lines / includes_per_scu), 1)
|
||||
|
||||
# error condition
|
||||
if total_lines == 0:
|
||||
return
|
||||
|
||||
lines_per_file = math.ceil(total_lines / 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/math"])
|
||||
process_folder(["core/os"])
|
||||
process_folder(["core/io"])
|
||||
process_folder(["core/crypto"])
|
||||
|
||||
process_folder(["drivers/gles2"])
|
||||
process_folder(["drivers/gles3"])
|
||||
process_folder(["drivers/unix"])
|
||||
process_folder(["drivers/png"])
|
||||
|
||||
process_folder(["editor"])
|
||||
process_folder(["editor/import"])
|
||||
process_folder(["editor/plugins"])
|
||||
|
||||
process_folder(["main"])
|
||||
process_folder(["main/tests"])
|
||||
|
||||
process_folder(
|
||||
[
|
||||
"platform",
|
||||
"android/export",
|
||||
"iphone/export",
|
||||
"javascript/export",
|
||||
"osx/export",
|
||||
"uwp/export",
|
||||
"windows/export",
|
||||
"x11/export",
|
||||
]
|
||||
)
|
||||
|
||||
process_folder(["modules/gltf"])
|
||||
process_folder(["modules/gltf/structures"])
|
||||
process_folder(["modules/gltf/extensions"])
|
||||
process_folder(["modules/gltf/extensions/physics"])
|
||||
|
||||
process_folder(["modules/bullet"])
|
||||
process_folder(["modules/navigation"])
|
||||
process_folder(["modules/visual_script"])
|
||||
process_folder(["modules/webrtc"])
|
||||
process_folder(["modules/webxr"])
|
||||
process_folder(["modules/websocket"])
|
||||
process_folder(["modules/gridmap"])
|
||||
|
||||
process_folder(["modules/csg"])
|
||||
process_folder(["modules/gdscript"])
|
||||
process_folder(["modules/gdscript/language_server"])
|
||||
|
||||
process_folder(["modules/fbx"])
|
||||
process_folder(["modules/fbx/tools"])
|
||||
process_folder(["modules/fbx/data"])
|
||||
process_folder(["modules/fbx/fbx_parser"])
|
||||
|
||||
process_folder(["modules/gdnative"])
|
||||
process_folder(["modules/gdnative/gdnative"])
|
||||
process_folder(["modules/gdnative/nativescript"])
|
||||
|
||||
process_folder(["modules/gdnative/arvr"])
|
||||
process_folder(["modules/gdnative/pluginscript"])
|
||||
process_folder(["modules/gdnative/net"])
|
||||
|
||||
process_folder(["modules/mbedtls"])
|
||||
|
||||
process_folder(["scene"])
|
||||
process_folder(["scene/audio"])
|
||||
process_folder(["scene/debugger"])
|
||||
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/visual"])
|
||||
process_folder(["servers/visual/portals"])
|
||||
process_folder(["servers/physics_2d"])
|
||||
process_folder(["servers/physics"])
|
||||
process_folder(["servers/physics/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
|
|
@ -49,7 +49,7 @@ subject to the following restrictions:
|
|||
|
||||
#include "hinge_joint_sw.h"
|
||||
|
||||
static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
|
||||
void HingeJointSW::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];
|
||||
|
@ -382,7 +382,7 @@ void HingeJointSW::updateRHS(real_t timeStep)
|
|||
}
|
||||
*/
|
||||
|
||||
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
|
||||
real_t HingeJointSW::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);
|
||||
|
|
|
@ -95,6 +95,9 @@ class HingeJointSW : public JointSW {
|
|||
|
||||
real_t m_appliedImpulse;
|
||||
|
||||
void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q);
|
||||
_FORCE_INLINE_ real_t atan2fast(real_t y, real_t x);
|
||||
|
||||
public:
|
||||
virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_HINGE; }
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ April 04, 2008
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
|
||||
real_t SliderJointSW::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);
|
||||
|
|
|
@ -150,6 +150,9 @@ protected:
|
|||
//------------------------
|
||||
void initParams();
|
||||
|
||||
private:
|
||||
_FORCE_INLINE_ real_t atan2fast(real_t y, real_t x);
|
||||
|
||||
public:
|
||||
// constructors
|
||||
SliderJointSW(BodySW *rbA, BodySW *rbB, const Transform &frameInA, const Transform &frameInB);
|
||||
|
|
Loading…
Reference in a new issue