Clean 4.0 (#66)

* Clean 4.0

* Memory leak
This commit is contained in:
Rafał Mikrut 2022-01-06 08:36:36 +01:00 committed by GitHub
parent f72410ff44
commit 14757de3a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 1312 additions and 1212 deletions

View File

@ -1,60 +0,0 @@
name: 🐧 Linux GLES2
on: [push, pull_request]
jobs:
gles2:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, debug_symbols=yes, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip python scons git
# - name: Download Godot
# run: |
# wget2 https://archive.hugo.pro/builds/godot/master/editor/godot-linux-nightly-x86_64.zip
# unzip godot-linux-nightly-x86_64.zip
# rm godot-linux-nightly-x86_64.zip
# mv godot godot.linuxbsd.tools.64s
# - name: Download Godot(ZIP)
# run: |
# wget2 https://github.com/godotengine/godot/archive/3.2.zip
# unzip 3.2.zip
# rm 3.2.zip
- name: Download Godot(GIT)
run: |
git clone https://github.com/lawnjelly/godot.git
cd godot
git checkout jarjar
cd ../
- name: Compile Godot
run: |
cd godot
scons p=linuxbsd -j2 use_asan=yes use_ubsan=yes CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr"
cp bin/godot.linuxbsd.tools.64s ../
true || cp bin/godot.linuxbsd.opt.64s ../
cd ../
rm -rf godot
- name: Use Godot
run: |
echo "-------------------- RUN PROJECT -----------------------"
DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s 60 --rendering-driver GLES2 --audio-driver Dummy --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt

View File

@ -1,66 +0,0 @@
name: 🐧 Linux Vulkan
on: [push, pull_request]
jobs:
vulkan-normal:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, debug_symbols=yes, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip python scons git
# - name: Download Godot
# run: |
# wget2 https://archive.hugo.pro/builds/godot/master/editor/godot-linux-nightly-x86_64.zip
# unzip godot-linux-nightly-x86_64.zip
# rm godot-linux-nightly-x86_64.zip
# mv godot godot.linuxbsd.tools.64s
# - name: Download Godot(ZIP)
# run: |
# wget2 https://github.com/godotengine/godot/archive/3.2.zip
# unzip 3.2.zip
# rm 3.2.zip
- name: Download Godot(GIT)
run: |
git clone https://github.com/godotengine/godot.git
cd godot
git checkout master
cd ../
- name: Compile Godot
run: |
cd godot
scons p=linuxbsd -j2 use_asan=yes use_ubsan=yes CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr"
cp bin/godot.linuxbsd.tools.64s ../
true || cp bin/godot.linuxbsd.opt.64s ../
cd ../
rm -rf godot
- name: Use Godot
run: |
echo "-------------------- OPEN EDITOR TO IMPORT PROJECT -----------------------"
DRI_PRIME=0 timeout 25s xvfb-run ./godot.linuxbsd.tools.64s --audio-driver Dummy -e --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt
echo "-------------------- OPEN EDITOR SECOND TIME TO BE SURE THAT EVERYTHING WAS IMPORTED -----------------------"
DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s --audio-driver Dummy -e -q --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt
echo "-------------------- RUN PROJECT -----------------------"
DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s 60 --audio-driver Dummy --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt

View File

@ -47,9 +47,8 @@ jobs:
- name: Compile Godot - name: Compile Godot
run: | run: |
cd godot cd godot
sed -i "s|ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|//ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|" drivers/vulkan/rendering_device_vulkan.cpp
scons p=linuxbsd -j2 use_asan=yes use_ubsan=yes CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr" scons p=linuxbsd -j2 use_asan=yes use_ubsan=yes CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr"
cp bin/godot.linuxbsd.tools.64s ../ cp bin/godot.linuxbsd.tools.64.san ../
cd ../ cd ../
rm -rf godot rm -rf godot
@ -62,11 +61,12 @@ jobs:
curr="$(pwd)/libvk_swiftshader.so" curr="$(pwd)/libvk_swiftshader.so"
sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json
- name: Use Godot - name: Open Editor
run: | run: |
echo "-------------------- OPEN EDITOR -----------------------" VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64.san --audio-driver Dummy -e -q --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s --audio-driver Dummy -e -q --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt misc/check_ci_log.py sanitizers_log.txt
echo "-------------------- RUN PROJECT -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s 60 --audio-driver Dummy --path $(pwd) 2>&1 | tee sanitizers_log.txt || true - name: Run Project
run: |
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64.san 180 --audio-driver Dummy --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt misc/check_ci_log.py sanitizers_log.txt

View File

@ -1,72 +0,0 @@
name: 🐧 SwiftShader Long 1h
on: [push, pull_request]
jobs:
vulkan-normal:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, debug_symbols=yes, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip python scons git
# - name: Download Godot
# run: |
# wget2 https://archive.hugo.pro/builds/godot/master/editor/godot-linux-nightly-x86_64.zip
# unzip godot-linux-nightly-x86_64.zip
# rm godot-linux-nightly-x86_64.zip
# mv godot godot.linuxbsd.tools.64s
# - name: Download Godot(ZIP)
# run: |
# wget2 https://github.com/godotengine/godot/archive/3.2.zip
# unzip 3.2.zip
# rm 3.2.zip
- name: Download Godot(GIT)
run: |
git clone https://github.com/godotengine/godot.git
cd godot
git checkout master
cd ../
- name: Compile Godot
run: |
cd godot
sed -i "s|ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|//ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|" drivers/vulkan/rendering_device_vulkan.cpp
scons p=linuxbsd -j2 use_asan=yes use_ubsan=yes CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr"
cp bin/godot.linuxbsd.tools.64s ../
cd ../
rm -rf godot
# Download, unzip and setup SwiftShader library
- name: Download SwiftShader
run: |
wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/swiftshader.zip
unzip swiftshader.zip
rm swiftshader.zip
curr="$(pwd)/libvk_swiftshader.so"
sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json
- name: Use Godot
run: |
echo "-------------------- OPEN EDITOR -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s --audio-driver Dummy -e -q --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt
echo "-------------------- RUN PROJECT -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s 3600 --audio-driver Dummy --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt

View File

@ -1,81 +0,0 @@
name: 🐧 SwiftShader Exported 1h
on: [push, pull_request]
jobs:
vulkan-normal:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, debug_symbols=yes, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip python scons git
# - name: Download Godot
# run: |
# wget2 https://archive.hugo.pro/builds/godot/master/editor/godot-linux-nightly-x86_64.zip
# unzip godot-linux-nightly-x86_64.zip
# rm godot-linux-nightly-x86_64.zip
# mv godot godot.linuxbsd.tools.64s
# - name: Download Godot(ZIP)
# run: |
# wget2 https://github.com/godotengine/godot/archive/3.2.zip
# unzip 3.2.zip
# rm 3.2.zip
- name: Download Godot(GIT)
run: |
git clone https://github.com/godotengine/godot.git
cd godot
git checkout master
cd ../
- name: Compile Godot
run: |
cd godot
sed -i "s|ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|//ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|" drivers/vulkan/rendering_device_vulkan.cpp
scons p=linuxbsd -j2 use_asan=yes use_ubsan=yes CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr"
cp bin/godot.linuxbsd.tools.64s ../
git clean -xqdf
scons tools=no target=release debug_symbols=yes use_asan=yes use_ubsan=yes optimize=none CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr"
cp bin/godot.linuxbsd.opt.64s ../
cd ../
rm -rf godot
# Download, unzip and setup SwiftShader library
- name: Download SwiftShader
run: |
wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/swiftshader.zip
unzip swiftshader.zip
rm swiftshader.zip
curr="$(pwd)/libvk_swiftshader.so"
sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json
# Export project and run it to check for possible leaks and invalid memory usage
- name: Export project
run: |
curr="$(pwd)/godot.linuxbsd.opt.64s"
sed -i "s|PATH_TO_CHANGE|$curr|" export_presets.cfg
echo "-------------------- Export project -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s --export-debug "Linux/X11" test_project 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt
- name: Run project
run: |
echo "-------------------- RUN PROJECT -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./test_project 3600 --audio-driver Dummy 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt

View File

@ -1,73 +0,0 @@
name: 🐧 SwiftShader Stress 1h
on: [push, pull_request]
jobs:
vulkan-normal:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, debug_symbols=yes, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip python scons git
# - name: Download Godot
# run: |
# wget2 https://archive.hugo.pro/builds/godot/master/editor/godot-linux-nightly-x86_64.zip
# unzip godot-linux-nightly-x86_64.zip
# rm godot-linux-nightly-x86_64.zip
# mv godot godot.linuxbsd.tools.64s
# - name: Download Godot(ZIP)
# run: |
# wget2 https://github.com/godotengine/godot/archive/3.2.zip
# unzip 3.2.zip
# rm 3.2.zip
- name: Download Godot(GIT)
run: |
git clone https://github.com/godotengine/godot.git
cd godot
git checkout master
cd ../
- name: Compile Godot
run: |
cd godot
sed -i "s|ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|//ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|" drivers/vulkan/rendering_device_vulkan.cpp
scons p=linuxbsd -j2 use_asan=yes use_ubsan=yes CCFLAGS="-fsanitize=shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr"
cp bin/godot.linuxbsd.tools.64s ../
cd ../
rm -rf godot
# Download, unzip and setup SwiftShader library
- name: Download SwiftShader
run: |
wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/swiftshader.zip
unzip swiftshader.zip
rm swiftshader.zip
curr="$(pwd)/libvk_swiftshader.so"
sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json
- name: Use Godot
run: |
sed -i "s|NUMBER_OF_INSTANCES : int = 1|NUMBER_OF_INSTANCES : int = 10|" Start.gd
echo "-------------------- OPEN EDITOR -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s --audio-driver Dummy -e -q --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt
echo "-------------------- RUN PROJECT -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64s 3600 --audio-driver Dummy --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt

View File

@ -1,76 +0,0 @@
name: 🐧 SwiftShader Thread Sanitizer 1h
on: [push, pull_request]
jobs:
vulkan-normal:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, debug_symbols=yes, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip python scons git llvm clang
# - name: Download Godot
# run: |
# wget2 https://archive.hugo.pro/builds/godot/master/editor/godot-linux-nightly-x86_64.zip
# unzip godot-linux-nightly-x86_64.zip
# rm godot-linux-nightly-x86_64.zip
# mv godot godot.linuxbsd.tools.64s
# - name: Download Godot(ZIP)
# run: |
# wget2 https://github.com/godotengine/godot/archive/3.2.zip
# unzip 3.2.zip
# rm 3.2.zip
- name: Download Godot(GIT)
run: |
git clone https://github.com/godotengine/godot.git
cd godot
git checkout master
cd ../
- name: Compile Godot
run: |
cd godot
sed -i "s|ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|//ERR_FAIL_COND_V(p_rasterization_state.patch_control_points|" drivers/vulkan/rendering_device_vulkan.cpp
scons -j2 use_tsan=yes use_llvm=yes
cp bin/godot.linuxbsd.tools.64.llvms ../
cd ../
rm -rf godot
# Download, unzip and setup SwiftShader library
- name: Download SwiftShader
run: |
wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/swiftshader.zip
unzip swiftshader.zip
rm swiftshader.zip
curr="$(pwd)/libvk_swiftshader.so"
sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json
- name: Open Editor
run: |
echo "-------------------- OPEN EDITOR -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64.llvms --audio-driver Dummy -e -q --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt
- name: Use Godot
run: |
sed -i "s|NUMBER_OF_INSTANCES : int = 1|NUMBER_OF_INSTANCES : int = 2|" Start.gd
echo "-------------------- RUN PROJECT -----------------------"
VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ./godot.linuxbsd.tools.64.llvms 3600 --audio-driver Dummy --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
misc/check_ci_log.py sanitizers_log.txt

6
.gitignore vendored
View File

@ -8,10 +8,8 @@ logs/
TEMP/ TEMP/
#export_presets.cfg #export_presets.cfg
logs/ logs/
.import/ .godot/
#.godot/
.godot/imported/ .godot/imported/
.godot/editor .godot/editor
.godot/shader_cache/
shader_cache/ shader_cache/
.godot/ .import/

View File

@ -1,3 +1,3 @@
source_md5="d98fe5b307b619f42f0bd920ee4f170d" source_md5="d98fe5b307b619f42f0bd920ee4f170d"
dest_md5="5619edcbaebc4d55dacdefaa2177f0e0" dest_md5="81b444fc2bdc6ece1bac1f0f60b9deb1"

View File

@ -2,63 +2,65 @@ extends Node
const screen_size = Vector2(1024, 600) const screen_size = Vector2(1024, 600)
var start_time : int var start_time: int
var last_time : int var last_time: int
const PRINT_TIME_EVERY_MILISECONDS : int = 5000 const PRINT_TIME_EVERY_MILISECONDS: int = 5000
var time_to_print_next_time : int = PRINT_TIME_EVERY_MILISECONDS var time_to_print_next_time: int = PRINT_TIME_EVERY_MILISECONDS
var time_to_show: int = 25 * 1000 # How long test works in miliseconds var time_to_show: int = 25 * 1000 # How long test works in miliseconds
var time_for_each_step : int = -1 var time_for_each_step: int = -1
var os var can_be_closed: bool = true
# Each scene runs alone # Each scene runs alone
const alone_steps : Array = [ const alone_steps: Array = [
"res://CreatingAllThings/CreatingAllThings.tscn", "res://CreatingAllThings/CreatingAllThings.tscn",
"res://Nodes/Nodes.tscn", "res://Nodes/Nodes.tscn",
# "res://ReparentingDeleting/ReparentingDeleting.tscn", # Really slow in 4.0 "res://Physics/2D/Physics2D.tscn",
"res://AutomaticBugs/FunctionExecutor.tscn", # Only Needs to be executed once, but this is workaround a little "res://Physics/3D/Physics3D.tscn",
# "res://ReparentingDeleting/ReparentingDeleting.tscn", Not always reproducible
"res://AutomaticBugs/FunctionExecutor.tscn", # Only need to run once
] ]
func _init(): var time_object: Object
if ClassDB.class_exists("OS"):
os = get_instance_from_name("OS")
func _init():
# Workaround for Time/OS breaking change - https://github.com/godotengine/godot/pull/54056
if ClassDB.class_exists("_Time"):
time_object = ClassDB.instantiate("_Time")
elif ClassDB.class_exists("Time"):
time_object = ClassDB.instantiate("Time")
else: else:
os = get_instance_from_name("Platform") time_object = ClassDB.instantiate("_OS")
start_time = Time.get_ticks_msec() start_time = time_object.get_ticks_msec()
# In case when user doesn't provide time # In case when user doesn't provide time
time_for_each_step = time_to_show / (alone_steps.size()) time_for_each_step = time_to_show / (alone_steps.size())
for argument in os.get_cmdline_args(): for argument in OS.get_cmdline_args():
if argument.is_valid_float(): # Ignore all non numeric arguments if argument.is_valid_float(): # Ignore all non numeric arguments
time_to_show = int(argument.to_float() * 1000) time_to_show = int(argument.to_float() * 1000)
time_for_each_step = time_to_show / (alone_steps.size()) time_for_each_step = time_to_show / (alone_steps.size())
print("Time set to: " + str(time_to_show / 1000.0) + " seconds with "+ str(alone_steps.size()) + " steps, each step will take " + str(time_for_each_step / 1000.0) + " seconds.") print("Time set to: " + str(time_to_show / 1000.0) + " seconds with " + str(alone_steps.size()) + " steps, each step will take " + str(time_for_each_step / 1000.0) + " seconds.")
break # We only need to take first argument break # We only need to take first numeric argument
func _process(delta: float) -> void: func _process(delta: float) -> void:
var current_run_time : int = Time.get_ticks_msec() - start_time var current_run_time: int = time_object.get_ticks_msec() - start_time
# While loop instead if, will allow to properly flush results under heavy operations(e.g. Thread sanitizer) # While loop instead simple if, because will allow to properly flush results under heavy operations(e.g. Thread sanitizer)
while current_run_time > time_to_print_next_time: while current_run_time > time_to_print_next_time:
print("Test is running now " + str(int(time_to_print_next_time / 1000)) + " seconds") print("Test is running now " + str(int(time_to_print_next_time / 1000)) + " seconds")
time_to_print_next_time += PRINT_TIME_EVERY_MILISECONDS time_to_print_next_time += PRINT_TIME_EVERY_MILISECONDS
if current_run_time > time_to_show: if current_run_time > time_to_show && can_be_closed:
print("######################## Ending test ########################") print("######################## Ending test ########################")
get_tree().quit() get_tree().quit()
func get_instance_from_name(method: String):
if ClassDB.class_has_method("_ClassDB","instance"):
return ClassDB.call("instance",method)
else:
return ClassDB.call("instantiate",method)
func _exit_tree(): func _exit_tree() -> void:
os.free() time_object.free()

View File

@ -1,101 +1,135 @@
extends Node extends Node
var regression_test_project : bool = true # Set it to true in RegressionTestProject
### Contains info about disabled classes and allows to take info about allowed methods ### Contains info about disabled classes and allows to take info about allowed methods
# Globablly disabled functions for all classes # Globablly disabled functions for all classes
var function_exceptions : Array = [ var function_exceptions: Array = [
# GODOT 4.0
"create_from_image",
"set_point_position",
"connect", # OTHER THINGS
"set_base",
"particles_collision_set_height_field_resolution",
"set_deconstruct_type",
"set_constant_type",
"set_enabled_inputs",
"load_threaded_request",
"get_sdfgi_max_distance",
"draw_multiline_string",
"draw_font",
"create",
"add_string",
"draw_string",
"set_dropcap",
"set_sdfgi_max_distance",
"get_inverse_inertia_tensor",
"generate_lod",
"optimize_indices_for_cache",
"add_file",
"set_texture",
"_activate",
"add_node", #GH 46012
"set_peering_bit_terrain", #GH 48799
"get_peering_bit_terrain",
"get_packet", # TODO
"_gui_input", # TODO probably missing cherrypick #GH 47636
"_input",
"_unhandled_input",
"_unhandled_key_input",
"connect_to_signal", # Should be chrrypicked
# They exists without assigment like Class.method, because they may be a parent of other objects and children also should have disabled child.method, its children also etc. which is too much to do # They exists without assigment like Class.method, because they may be a parent of other objects and children also should have disabled child.method, its children also etc. which is too much to do
#"connect_to_signal", # GH 47572 ###
"_editor_settings_changed",# GH 45979 ### Godot 4.0
"_submenu_timeout", # GH 45981 ###
"_thread_done", #GH 46000 "set_mesh", # 55266
"generate", #GH 46001 "set_use_all_surfaces", # 55266
"_proximity_group_broadcast", #GH 46002 "set_visibility_range_begin_margin", #54655
"_direct_state_changed", #GH 46003 "set_visibility_range_begin", #54655
"create_from", #GH 46004 "map_pattern", #54103
"create_from_blend_shape", #GH 46004 "_broadcast", #53873
"append_from", #GH 46004 "get_indexed", #53840
"_set_tile_data", #GH 46015 "make_polygons_from_outlines", #53808
"get", #GH 46019 "set_clip_children", #53667
"instance_has", #GH 46020 "set_base", #53723
"get_var", #GH 46096 "set_polygon", #53722
"set_script", #GH 46120 "add_bone", #53646
"getvar", #GH 46019 "set_bone_children", #53646
"get_available_chars", #GH 46118 "global_pose_z_forward_to_bone_forward", #53646
"open_midi_inputs", #GH 46183 "lightmap_unwrap", # 52929
"set_icon", #GH 46189 "get_property_list", #53604
"get_latin_keyboard_variant", #GH TODO Memory Leak "set_projector", #53604
"set_editor_hint", #GH 46252 "commit", #53191
"get_item_at_position", #TODO hard to find "commit_to_arrays", #53191
"set_probe_data", #GH 46570 "popup_centered_ratio", #53566
"_range_click_timeout", #GH 46648 "set_stream", #52853
"get_indexed", #GH 46019 "shaped_text_draw_outline", #53562
"add_vertex", #GH 47066 "set_input_as_handled", #53560
"create_client", # TODO, strange memory leak "add_node", #53558
"create_shape_owner", #47135 "set_language", #53218
"shape_owner_get_owner", #47135 "set_texture", #46828
"_activate", #45984
"get_bind_bone", #GH 47358 "compress_from_channels", # Image
"get_bind_name", #GH 47358 "open_midi_inputs", #52821
"get_bind_pose", #GH 47358 "load_threaded_request", #46762
"bake_navigation_mesh", # TODO too hard to find for now
# TODO Check this later "set_is_setup", # Just don't use, in SkeletonModification crashes
"_update_shape", # TODO, probably crashes exported build
"get_custom_monitor", # TODO crashes only in exported build
###
### Input crashes, still are some problems TODO
###
"_gui_input",
"_input",
"_unhandled_input",
"_unhandled_key_input",
"_vp_input",
"_vp_unhandled_input",
###
### Reported crashes
###
"lightmap_unwrap", # 52929
"replace_by", #53775
"bake", #53774
"create_debug_tangents", #53182
"create_from_mesh", #53181
"remove_line", # 49571 - Memory leak
"connect_to_signal", # 53622
"set_extra_cull_margin", # 53623
"_thread_done", #53621
"set_physics_enabled", #53620
"_iter_init", #53554
"set_block_signals", #53553
"make_atlas", #51154
"set_basic_type", #53456
"set_custom_viewport", #53445
"_draw_soft_mesh", #53437
"light_unwrap", #52929
"create_action", #50769
"_editor_settings_changed", # 45979
"set_script", #46120
"set_icon", #46189
"set_editor_hint", #46252 - Fixed only for master(due compatibility)
"set_probe_data", #46570
"add_vertex", #47066
"create_shape_owner", #47135
"shape_owner_get_owner", #47135
"get_bind_bone", #47358
"get_bind_name", #47358
"get_bind_pose", #47358
"decompress", #50787
"convert", # 46479
"save_png_to_buffer", # 50787
###
### Not worth to check, cause a lot of crashes but it is very unlikelly that users will use them
###
"propagate_notification", "propagate_notification",
"notification", "notification",
###
# TODO Adds big spam when i>100 - look for possiblity to ### Error spam when using it TODO
###
"get_recognized_extensions_for_type", # Spam
"load", # Spam - _ResourceLoader
"add_sphere", "add_sphere",
"_update_inputs", # Cause big spam with add_input "_update_inputs",
# Spam when i~1000 - change to specific
"update_bitmask_region", "update_bitmask_region",
"set_enabled_inputs", "set_enabled_inputs",
###
# Slow Function ### Slow Function
###
"set_pre_process_time",
"create_convex_collision",
"create_multiple_convex_collisions",
"load_webp_from_buffer",
"_update_sky", "_update_sky",
"interpolate_baked",
# Undo/Redo function which doesn't provide enough information about types of objects, probably due vararg(variable size argument) "get_baked_length",
"add_do_method", "get_baked_points",
"add_undo_method", "get_closest_offset",
"get_closest_point", # Only Curve, but looks that a lot of other classes uses this
# Do not save files and create files and folders "get_baked_up_vectors",
"interpolate_baked_up_vector",
"tessellate",
"get_baked_tilts",
"set_enabled_inputs",
"grow_mask",
"force_update_transform",
"is_enabler_enabled",
"set_enabler",
"get_aabb",
"set_aabb",
"is_on_screen",
"set_rings",
"set_amount",
###
### Do not save files and create files and folders, this probably can be enabled in CI
###
"pck_start", "pck_start",
"save", "save",
"save_png", "save_png",
@ -108,25 +142,31 @@ var function_exceptions : Array = [
"save_exr", "save_exr",
"dump_resources_to_file", "dump_resources_to_file",
"dump_memory_to_file", "dump_memory_to_file",
# This also allow to save files ###
### This also allow to save files
###
"open", "open",
"open_encrypted", "open_encrypted",
"open_encrypted_with_pass", "open_encrypted_with_pass",
"open_compressed", "open_compressed",
###
# Do not warp mouse ### Do not warp mouse, because I'm unable to do anything
###
"warp_mouse", "warp_mouse",
"warp_mouse_position", "warp_mouse_position",
###
# OS ### OS
###
"kill", "kill",
"shell_open", "shell_open",
"execute", "execute",
"alert", # Stupid alert window opens
###
### Godot freeze or run very cslow
###
"poll",
"delay_usec", "delay_usec",
"delay_msec", "delay_msec",
"alert", # Stupid alert window opens
# Godot Freeze
"wait_to_finish", "wait_to_finish",
"accept_stream", "accept_stream",
"connect_to_stream", "connect_to_stream",
@ -134,34 +174,32 @@ var function_exceptions : Array = [
"wait", "wait",
"debug_bake", "debug_bake",
"bake", "bake",
"set_gizmo", # Stupid function, needs as parameter an object which can't be instanced # TODO, create issue to hide it
"_create", # TODO Check ###
### Spams Output and aren't very useful
###
"set_gizmo", # Stupid function, needs as parameter an object which can't be instanced # TODO, create issue to hide it
# Spams Output
"print_tree", "print_tree",
"print_stray_nodes", "print_stray_nodes",
"print_tree_pretty", "print_tree_pretty",
"print_all_textures_by_size", "print_all_textures_by_size",
"print_all_resources", "print_all_resources",
"print_resources_in_use", "print_resources_in_use",
###
# Do not call other functions ### Can call other functions and broke everything
###
"_call_function", "_call_function",
"call", "call",
"call_deferred", "call_deferred",
"callv", "callv",
# Looks like a bug in FuncRef, probably but not needed, because it call other functions
"call_func", "call_func",
###
# Too dangerous, because add, mix and remove randomly nodes and objects ### Too dangerous, because add, mix and remove randomly nodes and objects
###
"replace_by", "replace_by",
"create_instance", "create_instance",
"set_owner", "set_owner",
"set_root_node", "set_root_node",
"instance", "instantiate",
"init_ref", "init_ref",
"reference", "reference",
"unreference", "unreference",
@ -174,42 +212,52 @@ var function_exceptions : Array = [
"move_child", "move_child",
"raise", "raise",
"add_child", "add_child",
"add_child_below_node",
"add_sibling", "add_sibling",
#####
##### Goost
##### TODO: these take too long to execute, does not make sense to limit number of iterations ether.
##### TODO - remove this and put it into setting file
#####
"smooth_polyline_approx",
"smooth_polygon_approx",
] ]
# Globally disabled classes which causes bugs or are very hard to us # Globally disabled classes which causes bugs or are very hard to use properly
var disabled_classes : Array = [ var disabled_classes: Array = [
"ProjectSettings", # Don't mess with project settings, because they can broke entire your workflow "GLTFDocument", # TODO memory leak
"EditorSettings", # Also don't mess with editor settings ###
"_OS", # This may sometimes crash compositor, but it should be tested manually sometimes ### Crashes, Freezes
"GDScript", # Broke script ###
"ProjectSettings", # Don't mess with project settings, because they can broke entire your workflow
# This classes have problems with static/non static methods "EditorSettings", # Also don't mess with editor settings
"PhysicsDirectSpaceState", "GDScript", # Broke script
"PhysicsDirectSpaceState2D", "SceneTree",
"PhysicsDirectBodyState", "JNISingleton", # Freeze - who use it?
"PhysicsDirectBodyState2D", "Engine", # Crashes only in Godot 4 but not really usable
"BulletPhysicsDirectSpaceState", ###
"InputDefault", ### JavaClass is only functions that returns Null when using JavaClass.new().get_class
"IP_Unix", ###
"JNISingleton",
"JavaClass", "JavaClass",
###
# Godot 4.0 Leaks, crashes etc. ### Android
"World3D", ###
"GPUParticlesCollisionHeightField", #4.0 Crash "JavaClassWrapper", # Looks that JavaClassWrapper.new() crashes android
"NavigationAgent2D", ###
"NavigationAgent3D", ### Exported build - some checks are disabled in exported build due to too big performance impact
###
"Image", "Image",
"GIProbe", # TODOGODOT4 - update here exluded list from Godot4
###
# Just don't use these because they are not normal things ### Godot 4.0
"_Thread", ###
"_Semaphore", "OS",
"_Mutex", "Thread",
"Semaphore",
"Mutex",
"GodotSharp",
# Class which is non instantable, and have non instantable childrens, but
# is used as argument
"Node3DGizmo",
# Creating them is really slow in Godot 4.0 # Creating them is really slow in Godot 4.0
"ColorPicker", "ColorPicker",
"FileDialog", "FileDialog",
@ -218,47 +266,81 @@ var disabled_classes : Array = [
"ProceduralSkyMaterial" "ProceduralSkyMaterial"
] ]
# Checks if function can be executed # Checks if function can be executed
func check_if_is_allowed(method_data : Dictionary) -> bool: # Looks at its arguments and checks if are recognized and supported
func check_if_is_allowed(method_data: Dictionary) -> bool:
# Function is virtual or vararg, so we just skip it # Function is virtual or vararg, so we just skip it
if method_data.get("flags") == method_data.get("flags") | METHOD_FLAG_VIRTUAL: if method_data["flags"] == method_data["flags"] | METHOD_FLAG_VIRTUAL:
return false return false
if method_data.get("flags") == method_data.get("flags") | 128: # VARARG TODO, Godot issue, add missing flag binding if method_data["flags"] == method_data["flags"] | 128: # VARARG TODO, Godot issue, add missing flag binding
return false return false
for arg in method_data.get("args"): for arg in method_data["args"]:
var name_of_class : String = arg.get("class_name") var name_of_class: String = arg["class_name"]
if name_of_class.is_empty(): if name_of_class.is_empty():
continue continue
if name_of_class in disabled_classes: if name_of_class in disabled_classes:
return false return false
if name_of_class.find("Server") != -1 && ClassDB.class_exists(name_of_class) && !obj_is_reference(name_of_class):
if !ClassDB.class_exists(name_of_class):
return false return false
# Editor stuff usually aren't good choice for arhuments
if !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "RefCounted"):
return false
if name_of_class.find("Editor") != -1 || name_of_class.find("SkinReference") != -1: if name_of_class.find("Editor") != -1 || name_of_class.find("SkinReference") != -1:
return false return false
# In case of adding new type, this prevents from crashing due not recognizing this type # In case of adding new type, this prevents from crashing due not recognizing this type
# In case of removing/rename type, just comment e.g. TYPE_ARRAY and all occurencies on e.g. switch statement with it # In case of removing/rename type, just comment e.g. TYPE_ARRAY and all occurencies on e.g. switch statement with it
# In case of adding new type, this prevents from crashing due not recognizing this type var t: int = arg["type"]
var t : int = arg.get("type") if !(
t == TYPE_NIL
if !(t == TYPE_NIL|| t == TYPE_CALLABLE || t == TYPE_MAX|| t == TYPE_AABB|| t == TYPE_ARRAY|| t == TYPE_BASIS|| t == TYPE_BOOL|| t == TYPE_COLOR|| t == TYPE_COLOR_ARRAY|| t == TYPE_DICTIONARY|| t == TYPE_INT|| t == TYPE_INT32_ARRAY|| t == TYPE_INT64_ARRAY|| t == TYPE_NODE_PATH|| t == TYPE_OBJECT|| t == TYPE_PLANE|| t == TYPE_QUATERNION|| t == TYPE_RAW_ARRAY|| t == TYPE_FLOAT|| t == TYPE_FLOAT32_ARRAY|| t == TYPE_FLOAT64_ARRAY|| t == TYPE_RECT2|| t == TYPE_RECT2I|| t == TYPE_RID|| t == TYPE_STRING|| t == TYPE_STRING_NAME|| t == TYPE_STRING_ARRAY|| t == TYPE_TRANSFORM3D|| t == TYPE_TRANSFORM2D|| t == TYPE_VECTOR2|| t == TYPE_VECTOR2I|| t == TYPE_VECTOR2_ARRAY|| t == TYPE_VECTOR3|| t == TYPE_VECTOR3I|| t == TYPE_VECTOR3_ARRAY): || t == TYPE_CALLABLE
print("----------------------------------------------------------- TODO - MISSING TYPE, ADD SUPPORT IT") || t == TYPE_MAX
|| t == TYPE_AABB
|| t == TYPE_ARRAY
|| t == TYPE_BASIS
|| t == TYPE_BOOL
|| t == TYPE_COLOR
|| t == TYPE_COLOR_ARRAY
|| t == TYPE_DICTIONARY
|| t == TYPE_INT
|| t == TYPE_INT32_ARRAY
|| t == TYPE_INT64_ARRAY
|| t == TYPE_NODE_PATH
|| t == TYPE_OBJECT
|| t == TYPE_PLANE
|| t == TYPE_QUATERNION
|| t == TYPE_RAW_ARRAY
|| t == TYPE_FLOAT
|| t == TYPE_FLOAT32_ARRAY
|| t == TYPE_FLOAT64_ARRAY
|| t == TYPE_RECT2
|| t == TYPE_RECT2I
|| t == TYPE_RID
|| t == TYPE_STRING
|| t == TYPE_STRING_NAME
|| t == TYPE_STRING_ARRAY
|| t == TYPE_TRANSFORM3D
|| t == TYPE_TRANSFORM2D
|| t == TYPE_VECTOR2
|| t == TYPE_VECTOR2I
|| t == TYPE_VECTOR2_ARRAY
|| t == TYPE_VECTOR3
|| t == TYPE_VECTOR3I
|| t == TYPE_VECTOR3_ARRAY
):
print("----------------------------------------------------------- TODO - MISSING TYPE, ADD SUPPORT IT") # Add assert here to get info which type is missing
return false return false
#This is only for RegressionTestProject, because it needs for now clear visual info what is going on screen, but some nodes broke view
if regression_test_project:
# That means that this is constant, not class
if !ClassDB.class_exists(name_of_class):
continue
if !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "Reference"):
return false
return true return true
func remove_disabled_methods(method_list : Array, exceptions : Array) -> Array:
var new_list : Array = [] # Workaround for GH 50139 renaming remove to remove_at # Removes disabled methods from classes
func remove_disabled_methods(method_list: Array, exceptions: Array) -> Array:
var new_list: Array = [] # Workaround for GH 50139 renaming remove to remove_at
for method_index in range(method_list.size()): for method_index in range(method_list.size()):
var index: int = -1 var index: int = -1
for exception in exceptions: for exception in exceptions:
@ -267,45 +349,34 @@ func remove_disabled_methods(method_list : Array, exceptions : Array) -> Array:
break break
if index == -1: if index == -1:
new_list.append(method_list[method_index]) new_list.append(method_list[method_index])
method_list = new_list method_list = new_list
return new_list return new_list
# Return all available classes which can be used # Return all available classes which can be used
func get_list_of_available_classes(must_be_instantable : bool = true) -> Array: func get_list_of_available_classes(must_be_instantable: bool = true) -> Array:
var full_class_list : Array = Array(ClassDB.get_class_list()) var full_class_list: Array = Array(ClassDB.get_class_list())
var classes : Array = [] var classes: Array = []
full_class_list.sort() full_class_list.sort()
var c = 0 var c = 0
# var rr = 0
for name_of_class in full_class_list: for name_of_class in full_class_list:
# rr += 1
if name_of_class in disabled_classes: if name_of_class in disabled_classes:
continue continue
# if rr < 550:
# continue
#This is only for RegressionTestProject, because it needs for now clear visual info what is going on screen, but some nodes broke view #This is only for RegressionTestProject, because it needs for now clear visual info what is going on screen, but some nodes broke view
if regression_test_project: if !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "RefCounted"):
if !ClassDB.is_parent_class(name_of_class, "Node") && !obj_is_reference(name_of_class): continue
continue # Don't test Servers objects like TranslationServer
if name_of_class.find("Server") != -1:
continue
# Don't test Editor nodes
if name_of_class.find("Editor") != -1:
continue
if name_of_class.find("Server") != -1 && !(obj_is_reference(name_of_class)):
continue
if name_of_class.find("Editor") != -1 && regression_test_project:
continue
if !must_be_instantable || ClassDB.can_instantiate(name_of_class): if !must_be_instantable || ClassDB.can_instantiate(name_of_class):
classes.push_back(name_of_class) classes.push_back(name_of_class)
c+= 1 c += 1
print(str(c) + " choosen classes from all " + str(full_class_list.size()) + " classes.") print(str(c) + " choosen classes from all " + str(full_class_list.size()) + " classes.")
return classes return classes
func obj_is_reference(name_of_class : String) -> bool:
if ClassDB.class_exists("Reference"):
return ClassDB.is_parent_class(name_of_class, "Reference")
return ClassDB.is_parent_class(name_of_class, "RefCounted")

View File

@ -6,6 +6,7 @@ extends Node
### - checks each argument if is allowed(in case e.g. adding new, to prevent crashes due not recognizing types) ### - checks each argument if is allowed(in case e.g. adding new, to prevent crashes due not recognizing types)
### - print info if needed to console ### - print info if needed to console
### - execute function with parameters ### - execute function with parameters
### - removes all objects/nodes to prevent memory leak
var debug_print: bool = true var debug_print: bool = true
var add_to_tree: bool = false # Adds nodes to tree, freeze godot when removing a lot of nodes var add_to_tree: bool = false # Adds nodes to tree, freeze godot when removing a lot of nodes
@ -15,23 +16,9 @@ var exiting: bool = false
func _ready() -> void: func _ready() -> void:
if BasicData.regression_test_project:
ValueCreator.random = false # Results in RegressionTestProject must be always reproducible
else:
ValueCreator.random = true
ValueCreator.number = 100 ValueCreator.number = 100
ValueCreator.should_be_always_valid = false
if BasicData.regression_test_project: tests_all_functions()
tests_all_functions()
func _process(_delta: float) -> void:
if !BasicData.regression_test_project:
tests_all_functions()
if exiting:
get_tree().quit()
# Test all functions # Test all functions
@ -40,8 +27,8 @@ func tests_all_functions() -> void:
if debug_print: if debug_print:
print("\n#################### " + name_of_class + " ####################") print("\n#################### " + name_of_class + " ####################")
var object: Object = Autoload.get_instance_from_name(name_of_class) var object: Object = ClassDB.instantiate(name_of_class)
assert(object != null, "Object must be instantable") assert(object != null) #,"Object must be instantable")
if add_to_tree: if add_to_tree:
if object is Node: if object is Node:
add_child(object) add_child(object)
@ -50,57 +37,51 @@ func tests_all_functions() -> void:
# Removes excluded methods # Removes excluded methods
method_list = BasicData.remove_disabled_methods(method_list, BasicData.function_exceptions) method_list = BasicData.remove_disabled_methods(method_list, BasicData.function_exceptions)
for _i in range(1): for method_data in method_list:
for method_data in method_list: if !BasicData.check_if_is_allowed(method_data):
if !BasicData.check_if_is_allowed(method_data): continue
continue
var arguments: Array = ParseArgumentType.parse_and_return_objects(method_data, name_of_class, debug_print) var arguments: Array = ParseArgumentType.parse_and_return_objects(method_data, name_of_class, debug_print)
if debug_print: if debug_print:
var to_print: String = "GDSCRIPT CODE: " var to_print: String = "GDSCRIPT CODE: "
if ( if (
ClassDB.is_parent_class(name_of_class, "Object") ClassDB.is_parent_class(name_of_class, "Object")
&& !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "Node")
&& !obj_is_reference(name_of_class) && !ClassDB.is_parent_class(name_of_class, "RefCounted")
&& !ClassDB.class_has_method(name_of_class, "new") && !ClassDB.class_has_method(name_of_class, "new")
): ):
to_print += "ClassDB.instance(\"" + name_of_class + "\")." + method_data.get("name") + "(" to_print += 'ClassDB.instantiate("' + name_of_class + '").' + method_data["name"] + "("
else: else:
to_print += name_of_class.trim_prefix("_") + ".new()." + method_data.get("name") + "(" to_print += name_of_class.trim_prefix("_") + ".new()." + method_data["name"] + "("
for i in arguments.size(): for i in arguments.size():
to_print += ParseArgumentType.return_gdscript_code_which_run_this_object(arguments[i]) to_print += ParseArgumentType.return_gdscript_code_which_run_this_object(arguments[i])
if i != arguments.size() - 1: if i != arguments.size() - 1:
to_print += ", " to_print += ", "
to_print += ")" to_print += ")"
print(to_print) print(to_print)
object.callv(method_data.get("name"), arguments) object.callv(method_data["name"], arguments)
for argument in arguments: for argument in arguments:
if argument is Node: if argument is Node:
argument.queue_free() argument.queue_free()
elif argument is Object && !(obj_is_reference(argument.get_class())): elif argument is Object && !(argument is RefCounted):
argument.free() argument.free()
if use_always_new_object: if use_always_new_object:
if object is Node:
object.queue_free()
elif object is Object && !(object is RefCounted):
object.free()
object = ClassDB.instantiate(name_of_class)
if add_to_tree:
if object is Node: if object is Node:
object.queue_free() add_child(object)
elif object is Object && !(obj_is_reference(object.get_class())):
object.free()
object = Autoload.get_instance_from_name(name_of_class)
if add_to_tree:
if object is Node:
add_child(object)
if object is Node: if object is Node:
object.queue_free() object.queue_free()
elif object is Object && !(obj_is_reference(object.get_class())): elif object is Object && !(object is RefCounted):
object.free() object.free()
func obj_is_reference(name_of_class : String) -> bool:
if ClassDB.class_exists("Reference"):
return ClassDB.is_parent_class(name_of_class, "Reference")
return ClassDB.is_parent_class(name_of_class, "RefCounted")

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=2 format=3 uid="uid://b7slcpsx4l8p8"] [gd_scene load_steps=2 format=3 uid="uid://bqmnk4i6yhac3"]
[ext_resource type="Script" path="res://AutomaticBugs/FunctionExecutor.gd" id="1"] [ext_resource type="Script" path="res://AutomaticBugs/FunctionExecutor.gd" id="1"]

View File

@ -1,29 +1,10 @@
extends Node extends Node
### Scripts to arguments and return needed info about them.
### Class which contains informations about used
class SingleArgument:
var name: String # E.G. var roman, can be empty, so temp variable isn't created(nodes and objects must be created with temp_variable due to memory leaks)
var type: String # np. Vector2 or Object
var value: String # np. randi() % 100 or
var is_object: bool = false # Check if this is object e.g. Node not Vector2
var is_only_object: bool = false # Only needs to freed with .free()
var is_only_reference: bool = false # Don't needs to be removed manually
var is_only_node: bool = false # Needs to be removed with .queue_free()
func parse_and_return_objects(method_data: Dictionary, name_of_class: String, debug_print: bool = false) -> Array: func parse_and_return_objects(method_data: Dictionary, name_of_class: String, debug_print: bool = false) -> Array:
var arguments_array: Array = Array([]) var arguments_array: Array = Array([])
if BasicData.regression_test_project: ValueCreator.number = 100
ValueCreator.number = 100
ValueCreator.random = false # Results in RegressionTestProject must be always reproducible
else:
ValueCreator.number = 1000
ValueCreator.random = true
ValueCreator.should_be_always_valid = false
for argument in method_data.get("args"): for argument in method_data.get("args"):
var type = argument.get("type") var type = argument.get("type")
@ -193,10 +174,10 @@ func return_gdscript_code_which_run_this_object(data) -> String:
if ( if (
ClassDB.is_parent_class(name_of_class, "Object") ClassDB.is_parent_class(name_of_class, "Object")
&& !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "Node")
&& !obj_is_reference(name_of_class) && !ClassDB.is_parent_class(name_of_class, "RefCounted")
&& !ClassDB.class_has_method(name_of_class, "new") && !ClassDB.class_has_method(name_of_class, "new")
): ):
return_string += "ClassDB.instance(\"" + name_of_class + "\")" return_string += 'ClassDB.instance("' + name_of_class + '")'
else: else:
return_string = name_of_class.trim_prefix("_") return_string = name_of_class.trim_prefix("_")
return_string += ".new()" return_string += ".new()"
@ -259,7 +240,7 @@ func return_gdscript_code_which_run_this_object(data) -> String:
elif type == TYPE_RID: elif type == TYPE_RID:
return_string = "RID()" return_string = "RID()"
elif type == TYPE_STRING: elif type == TYPE_STRING:
return_string = "\"" + data + "\"" return_string = '"' + data + '"'
elif type == TYPE_STRING_ARRAY: elif type == TYPE_STRING_ARRAY:
return_string = "PackedStringArray([" return_string = "PackedStringArray(["
for i in data.size(): for i in data.size():
@ -328,14 +309,9 @@ func return_gdscript_code_which_run_this_object(data) -> String:
return_string += ", " return_string += ", "
return_string += "])" return_string += "])"
elif type == TYPE_CALLABLE: elif type == TYPE_CALLABLE:
return_string = "Callable(BoxMesh.new(),\"\")" return_string = 'Callable(BoxMesh.new(),"")'
else: else:
print(type) print(type)
assert(false, "Missing type, needs to be added to project") assert(false, "Missing type, needs to be added to project")
return return_string return return_string
func obj_is_reference(name_of_class : String) -> bool:
if ClassDB.class_exists("Reference"):
return ClassDB.is_parent_class(name_of_class, "Reference")
return ClassDB.is_parent_class(name_of_class, "RefCounted")

View File

@ -1,10 +1,8 @@
extends Node extends Node
# Creates random or not objects, variables etc. # Creates random or not objects, variables etc.
var number: float = 0.0
var random: bool = false
var should_be_always_valid: bool = true # Generate only valid values e.g. to Node generate Node2D instead
var number: float = 0.0
var max_array_size: int = 15 var max_array_size: int = 15
@ -13,53 +11,27 @@ func _ready() -> void:
func get_int() -> int: func get_int() -> int:
if random: return int(number)
if int(number) == 0:
return 0
return (randi() % int(number)) - int(number / 2.0)
else:
return int(number)
func get_int_string() -> String: func get_int_string() -> String:
if random: return str(int(number))
if int(number) == 0:
return "0"
return "(randi() % int(number)) - int(number / 2.0)".replace("number", str(number))
else:
return str(int(number))
func get_float() -> float: func get_float() -> float:
if random: return number
return (randf() * number) - (number / 2.0)
else:
return number
func get_float_string() -> String: func get_float_string() -> String:
if random: return str(number)
return "(randf() * number) - (number / 2.0)".replace("number", str(number))
else:
return str(number)
func get_bool() -> bool: func get_bool() -> bool:
if random: return bool()
if number < 2:
return bool()
return bool(randi() % 2)
else:
return bool()
func get_bool_string() -> String: func get_bool_string() -> String:
if random: return str(bool())
if number < 2:
return str(bool())
return "bool(randi() % 2)"
else:
return str(bool())
func get_vector2() -> Vector2: func get_vector2() -> Vector2:
@ -70,14 +42,6 @@ func get_vector2i() -> Vector2i:
return Vector2i(get_int(), get_int()) return Vector2i(get_int(), get_int())
func get_vector2_string() -> String:
return "Vector2(" + get_float_string() + ", " + get_float_string() + ")"
func get_vector2i_string() -> String:
return "Vector2i(" + get_int_string() + ", " + get_int_string() + ")"
func get_vector3() -> Vector3: func get_vector3() -> Vector3:
return Vector3(get_float(), get_float(), get_float()) return Vector3(get_float(), get_float(), get_float())
@ -86,60 +50,28 @@ func get_vector3i() -> Vector3i:
return Vector3i(get_int(), get_int(), get_int()) return Vector3i(get_int(), get_int(), get_int())
func get_vector3i_string() -> String:
return "Vector3i(" + get_int_string() + ", " + get_int_string() + ", " + get_int_string() + ")"
func get_vector3_string() -> String:
return "Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
func get_aabb() -> AABB: func get_aabb() -> AABB:
return AABB(get_vector3(), get_vector3()) return AABB(get_vector3(), get_vector3())
func get_aabb_string() -> String:
return "AABB(" + get_vector3_string() + ", " + get_vector3_string() + ")"
func get_transform3D() -> Transform3D: func get_transform3D() -> Transform3D:
return Transform3D(get_vector3(), get_vector3(), get_vector3(), get_vector3()) return Transform3D(get_vector3(), get_vector3(), get_vector3(), get_vector3())
func get_transform3D_string() -> String:
return "Transform3D(" + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ")"
func get_transform2D() -> Transform2D: func get_transform2D() -> Transform2D:
return Transform2D(get_vector2(), get_vector2(), get_vector2()) return Transform2D(get_vector2(), get_vector2(), get_vector2())
func get_transform2D_string() -> String:
return "Transform2D(" + get_vector2_string() + ", " + get_vector2_string() + ", " + get_vector2_string() + ")"
func get_plane() -> Plane: func get_plane() -> Plane:
return Plane(get_vector3(), get_vector3(), get_vector3()) return Plane(get_vector3(), get_vector3(), get_vector3())
func get_plane_string() -> String:
return "Plane(" + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ")"
func get_quaternion() -> Quaternion: func get_quaternion() -> Quaternion:
return Quaternion(get_vector3()) return Quaternion(get_vector3())
func get_quaternion_string() -> String:
return "Quaternion(" + get_vector3_string() + ")"
func get_basis() -> Basis: func get_basis() -> Basis:
return Basis(get_vector3(),get_vector3(),get_vector3()) return Basis(get_vector3(), get_vector3(), get_vector3())
func get_basis_string() -> String:
return "Basis(" + get_vector3_string() + ")"
func get_rect2() -> Rect2: func get_rect2() -> Rect2:
@ -150,47 +82,22 @@ func get_rect2i() -> Rect2i:
return Rect2i(get_vector2i(), get_vector2i()) return Rect2i(get_vector2i(), get_vector2i())
func get_rect2_string() -> String:
return "Rect2(" + get_vector2_string() + ", " + get_vector2_string() + ")"
func get_rect2i_string() -> String:
return "Rect2i(" + get_vector2i_string() + ", " + get_vector2i_string() + ")"
func get_color() -> Color: func get_color() -> Color:
return Color(get_float(), get_float(), get_float()) return Color(get_float(), get_float(), get_float())
func get_color_string() -> String:
return "Color(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
# TODO
func get_string() -> String: func get_string() -> String:
if random:
if randi() % 2 == 0:
return String(".")
else:
return str(randi())
return String() return String()
func get_string_string() -> String:
if random:
if randi() % 2 == 0:
return "\".\""
else:
return "\"randi())\""
return "\"\""
# TODO
func get_nodepath() -> NodePath: func get_nodepath() -> NodePath:
return NodePath(get_string()) return NodePath(get_string())
# TODO func get_dictionary() -> Dictionary:
return Dictionary({})
func get_array() -> Array: func get_array() -> Array:
var array: Array = [] var array: Array = []
for _i in range(int(min(max_array_size, number))): for _i in range(int(min(max_array_size, number))):
@ -198,11 +105,6 @@ func get_array() -> Array:
return Array([]) return Array([])
# TODO
func get_dictionary() -> Dictionary:
return Dictionary({})
func get_Packed_string_array() -> PackedStringArray: func get_Packed_string_array() -> PackedStringArray:
var array: Array = [] var array: Array = []
for _i in range(int(min(max_array_size, number))): for _i in range(int(min(max_array_size, number))):
@ -267,150 +169,19 @@ func get_Packed_color_array() -> PackedColorArray:
func get_object(object_name: String) -> Object: func get_object(object_name: String) -> Object:
assert(ClassDB.class_exists(object_name), "Class doesn't exists.") assert(ClassDB.class_exists(object_name)) #,"Class " + object_name + " doesn't exists.")
if object_name == "PhysicsDirectSpaceState3D" || object_name == "PhysicsDirectSpaceState2D": # if object_name == "PhysicsDirectSpaceState3D" || object_name == "PhysicsDirectSpaceState2D":
return BoxShape3D.new() # return BoxShape3D.new()
var a = 0 var a = 0
if random: if ClassDB.can_instantiate(object_name): # E.g. Texture2D is not instantable or shouldn't be, but ImageTexture is
var classes = ClassDB.get_inheriters_from_class("Node") + ClassDB.get_inheriters_from_class("Reference") + ClassDB.get_inheriters_from_class("RefCounted") return ClassDB.instantiate(object_name)
if object_name == "Object":
while true:
var choosen_class: String = classes[randi() % classes.size()]
if (
ClassDB.can_instantiate(choosen_class)
&& (ClassDB.is_parent_class(choosen_class, "Node") || obj_is_reference(choosen_class))
&& !(choosen_class in BasicData.disabled_classes)
):
return Autoload.get_instance_from_name(choosen_class)
if ClassDB.is_parent_class(object_name, "Node") || obj_is_reference(object_name):
if should_be_always_valid:
var to_use_classes = ClassDB.get_inheriters_from_class(object_name)
to_use_classes.append(object_name)
if !ClassDB.can_instantiate(object_name) && object_name in BasicData.disabled_classes:
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for ")
while true:
a += 1
if a > 50:
# Object doesn't have children which can be instanced
# This shouldn't happens, but sadly happen with e.g. SpatialGizmo
assert(false, "Cannot find proper instantable child for ")
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
if ClassDB.can_instantiate(choosen_class) && !(choosen_class in BasicData.disabled_classes):
return Autoload.get_instance_from_name(choosen_class)
else:
while true:
a += 1
if a > 50:
assert(false, "Cannot find proper instantable child for ")
var choosen_class: String = classes[randi() % classes.size()]
if ClassDB.can_instantiate(choosen_class) && !ClassDB.is_parent_class(choosen_class, object_name) && !(choosen_class in BasicData.disabled_classes):
return Autoload.get_instance_from_name(choosen_class)
# Non Node/Resource object
var to_use_classes = ClassDB.get_inheriters_from_class(object_name)
to_use_classes.append(object_name)
if !ClassDB.can_instantiate(object_name) && object_name in BasicData.disabled_classes:
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for ")
while true:
a += 1
if a > 50:
# Object doesn't have children which can be instanced
# This shouldn't happens, but sadly happen with e.g. SpatialGizmo
assert(false, "Cannot find proper instantable child for ")
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
if ClassDB.can_instantiate(choosen_class) && !(choosen_class in BasicData.disabled_classes):
return Autoload.get_instance_from_name(choosen_class)
else: else:
if ClassDB.can_instantiate(object_name): # E.g. Texture is not instantable or shouldn't be, but LargeTexture is # Checking for children of non instantable object
return Autoload.get_instance_from_name(object_name) var list_of_class = ClassDB.get_inheriters_from_class(object_name)
else: # Found child of non instantable object assert(list_of_class.size() > 0) # Number of inherited class of non instantable class must be greater than 0, otherwise this function would be useless#,"Cannot find proper instantable child for " + object_name)
var list_of_class = ClassDB.get_inheriters_from_class(object_name) for i in list_of_class:
assert(list_of_class.size() > 0, "Cannot find proper instantable child for ") # Number of inherited class of non instantable class must be greater than 0, otherwise this function would be useless if ClassDB.can_instantiate(i) && (ClassDB.is_parent_class(i, "Node") || ClassDB.is_parent_class(i, "RefCounted")):
for i in list_of_class: return ClassDB.instantiate(i)
if ClassDB.can_instantiate(i) && (ClassDB.is_parent_class(i, "Node") || obj_is_reference(i)): assert(false) #,"Cannot find proper instantable child for " + object_name)
return Autoload.get_instance_from_name(i)
assert(false, "Cannot find proper instantable child for ")
assert(false, "Cannot find proper instantable child for ")
return BoxShape3D.new() return BoxShape3D.new()
# TODO Update this with upper implementation
func get_object_string(object_name: String) -> String:
assert(ClassDB.class_exists(object_name))
var a = 0
if random:
var classes = ClassDB.get_inheriters_from_class("Node") + ClassDB.get_inheriters_from_class("Reference") + ClassDB.get_inheriters_from_class("RefCounted")
if object_name == "Object":
while true:
var choosen_class: String = classes[randi() % classes.size()]
if ClassDB.can_instantiate(choosen_class) && (ClassDB.is_parent_class(choosen_class, "Node") || obj_is_reference(choosen_class)):
return choosen_class
if ClassDB.is_parent_class(object_name, "Node") || obj_is_reference(object_name):
if should_be_always_valid:
var to_use_classes = ClassDB.get_inheriters_from_class(object_name)
to_use_classes.append(object_name)
if !ClassDB.can_instantiate(object_name):
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for ")
while true:
a += 1
if a > 30:
# Object doesn't have children which can be instanced
# This shouldn't happens, but sadly happen with e.g. SpatialGizmo
assert(false, "Cannot find proper instantable child for ")
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
if ClassDB.can_instantiate(choosen_class):
return choosen_class
else:
while true:
a += 1
if a > 30:
assert(false, "Cannot find proper instantable child for ")
var choosen_class: String = classes[randi() % classes.size()]
if !ClassDB.is_parent_class(choosen_class, object_name):
return choosen_class
# Non Node/Resource object
var to_use_classes = ClassDB.get_inheriters_from_class(object_name)
to_use_classes.append(object_name)
if !ClassDB.can_instantiate(object_name) && object_name in BasicData.disabled_classes:
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for ")
while true:
a += 1
if a > 50:
# Object doesn't have children which can be instanced
# This shouldn't happens, but sadly happen with e.g. SpatialGizmo
assert(false, "Cannot find proper instantable child for ")
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
if ClassDB.can_instantiate(choosen_class) && !(choosen_class in BasicData.disabled_classes):
return choosen_class
else:
if ClassDB.can_instantiate(object_name): # E.g. Texture is not instantable or shouldn't be, but LargeTexture is
return object_name
else: # Found child of non instantable object
var list_of_class = ClassDB.get_inheriters_from_class(object_name)
assert(list_of_class.size() > 0, "Cannot find proper instantable child for ") # Number of inherited class of non instantable class must be greater than 0, otherwise this function would be useless
for i in list_of_class:
if ClassDB.can_instantiate(i) && (ClassDB.is_parent_class(i, "Node") || obj_is_reference(i)):
return i
assert(false, "Cannot find proper instantable child for ")
assert(false, "Cannot find proper instantable child for ")
return "BoxMesh"
func obj_is_reference(name_of_class : String) -> bool:
if ClassDB.class_exists("Reference"):
return ClassDB.is_parent_class(name_of_class, "Reference")
return ClassDB.is_parent_class(name_of_class, "RefCounted")

View File

@ -1,30 +1,32 @@
extends Node2D extends Node2D
var available_classes : Array = [] var available_classes: Array = []
var exeptions : Array = ["SceneTree", "EditorSettings", "ProjectSettings", "InputEventShortcut", "InputMap"] var exeptions: Array = ["SceneTree", "EditorSettings", "ProjectSettings", "InputEventShortcut", "InputMap"]
func _ready(): func _ready():
var cl : Array = Array(ClassDB.get_class_list()) var cl: Array = Array(ClassDB.get_class_list())
cl.sort() cl.sort()
for name_of_class in cl: for name_of_class in cl:
if !ClassDB.can_instantiate(name_of_class): # Repeat 3 times, to be sure that code don't crash in unreleated function
continue for _i in range(3):
if name_of_class in exeptions: if !ClassDB.can_instantiate(name_of_class):
continue continue
if name_of_class.to_lower().find("server") != -1: if name_of_class in exeptions:
continue continue
if name_of_class.to_lower().find("server") != -1:
print("########### " + name_of_class) continue
print("GDSCRIPT CODE: var thing = ClassDB.instantiate(\"" + name_of_class + "\")")
print("GDSCRIPT CODE: str(" + name_of_class + ")") print("########### " + name_of_class)
print('GDSCRIPT CODE: var thing = ClassDB.instantiate("' + name_of_class + '")')
var thing = ClassDB.instantiate(name_of_class) print("GDSCRIPT CODE: str(" + name_of_class + ")")
str(thing)#
var thing = ClassDB.instantiate(name_of_class)
if thing is Node: str(thing)
print("GDSCRIPT CODE: thing.queue_free()")
thing.queue_free() if thing is Node:
elif thing is Object && !(thing is RefCounted): print("GDSCRIPT CODE: thing.queue_free()")
print("GDSCRIPT CODE: thing.free()") thing.queue_free()
thing.free() elif thing is Object && !(thing is RefCounted):
print("GDSCRIPT CODE: thing.free()")
thing.free()

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://bj2rcig1emwek"] [gd_scene load_steps=2 format=2]
[ext_resource type="Script" path="res://CreatingAllThings/CreatingAllThings.gd" id="1_vqkfm"] [ext_resource path="res://CreatingAllThings/CreatingAllThings.gd" type="Script" id=1]
[node name="CreatingAllThings" type="Node2D"] [node name="CreatingAllThings" type="Node2D"]
script = ExtResource( "1_vqkfm" ) script = ExtResource( 1 )

View File

@ -1,34 +0,0 @@
#!/bin/bash
grep -rl "onready" . --exclude-dir=.git,Godot4Update.sh | xargs sed -i 's/@onready /@onready /'
grep -rl "extends RigidBody3D" . --exclude-dir=.git | xargs sed -i 's/extends RigidBody/extends RigidBody3D/'
grep -rl "extends RigidBody3D3D2D" . --exclude-dir=.git | xargs sed -i 's/extends RigidBody2D/extends RigidBody2D/'
grep -rl "PointLight2D" . --exclude-dir=.git | xargs sed -i 's/Light2D/PointLight2D/'
grep -rl "Camera3D" . --exclude-dir=.git | xargs sed -i 's/Camera/Camera3D/'
grep -rl "Camera3D3D2D" . --exclude-dir=.git | xargs sed -i 's/Camera2D/Camera2D/'
grep -rl "if i.get_name() != \"Camera3D3D\":" . --exclude-dir=.git | xargs sed -i 's/if i.get_name() != "Camera":/if i.get_name() != "Camera":/'
grep -rl "DirectionalLight3D" . --exclude-dir=.git | xargs sed -i 's/DirectionalLight/DirectionalLight3D/'
grep -rl "DirectionalLight3D3D2D" . --exclude-dir=.git | xargs sed -i 's/DirectionalLight2D/DirectionalPointLight2D/'
grep -rl "SpotLight3D" . --exclude-dir=.git | xargs sed -i 's/SpotLight/SpotLight3D/'
grep -rl "SpotLight3D3D2D" . --exclude-dir=.git | xargs sed -i 's/SpotLight2D/SpotPointLight2D/'
grep -rl "OmniLight3D" . --exclude-dir=.git | xargs sed -i 's/OmniLight/OmniLight3D/'
grep -rl "OmniLight3D3D2D" . --exclude-dir=.git | xargs sed -i 's/OmniLight2D/OmniPointLight2D/'
grep -rl "Node3D" . --exclude-dir=.git | xargs sed -i 's/Spatial/Node3D/'

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Rafał Mikrut
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.

View File

@ -4,19 +4,22 @@ extends Node
# of time # of time
# Counters which are used to delete and adds nodes in loop # Counters which are used to delete and adds nodes in loop
var TIME_TO_DELETE: float = 60.0 var TIME_TO_DELETE: float = 3.0
var time_to_delete: float = TIME_TO_DELETE var time_to_delete: float = TIME_TO_DELETE
# List of disabled classes # List of disabled classes
var disabled_classes: Array = ["NavigationAgent2D", "NavigationAgent3D","GPUParticlesCollisionHeightField", var disabled_classes: Array = [
"NavigationAgent2D",
"NavigationAgent3D",
"GPUParticlesCollisionHeightField",
# Creating them is really slow in Godot 4.0 # Creating them is really slow in Godot 4.0
"ColorPicker", "ColorPicker",
"FileDialog", "FileDialog",
"ColorPickerButton", "ColorPickerButton",
"PhysicalSkyMaterial", "PhysicalSkyMaterial",
"ProceduralSkyMaterial"] "ProceduralSkyMaterial"
# List of all collected nodes which ]
# List of all collected nodes
var classes: Array = [] var classes: Array = []
var debug_enabled: bool = false var debug_enabled: bool = false
@ -48,10 +51,9 @@ func collect() -> void:
var to_print: String = "DEBUG: List of classes used in Nodes scene:\n" var to_print: String = "DEBUG: List of classes used in Nodes scene:\n"
to_print += "DEBUG: [" to_print += "DEBUG: ["
for index in range(classes.size()): for index in range(classes.size()):
to_print += "\"" + classes[index] + "\"" to_print += '"' + classes[index] + '"'
if index != classes.size() - 1: if index != classes.size() - 1:
to_print += ", " to_print += ", "
to_print += "]"
print(to_print) print(to_print)
@ -70,15 +72,15 @@ func _ready() -> void:
func _process(delta: float) -> void: func _process(delta: float) -> void:
# Moves nodes a little # Moves nodes a little
# for i in get_children(): for i in get_children():
# if i is Control: if i is Control:
# i._set_size(Vector2(200 * randf() - 100, 200 * randf() - 100)) i._set_size(Vector2(200 * randf() - 100, 200 * randf() - 100))
# if i is Node2D: if i is Node2D:
# i.set_position(Vector2(1000 * randf() - 500, 1000 * randf() - 500)) i.set_position(Vector2(1000 * randf() - 500, 1000 * randf() - 500))
# if i is Node3D: if i is Node3D:
# if i.get_name() != "Camera": if i.get_name() != "Camera3D":
# i.set_scale(Vector3(delta + 1, delta + 1, delta + 1)) i.set_scale(Vector3(delta + 1, delta + 1, delta + 1))
# i.set_position(Vector3(10 * randf(), 10 * randf(), 10 * randf())) i.set_position(Vector3(10 * randf(), 10 * randf(), 10 * randf()))
time_to_delete -= delta time_to_delete -= delta
# Delete and adds later nodes # Delete and adds later nodes

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dd3cshhjwrlvi"] [gd_scene load_steps=2 format=2]
[ext_resource type="Script" path="res://Nodes/Nodes.gd" id="1"] [ext_resource path="res://Nodes/Nodes.gd" type="Script" id=1]
[node name="Nodes" type="Node"] [node name="Nodes" type="Node"]
script = ExtResource( "1" ) script = ExtResource( 1 )

29
Physics/2D/Area2D.gd Normal file
View File

@ -0,0 +1,29 @@
extends Node2D
var move_vector: Vector2 = Vector2(1, 1)
var speed: float = 1000.0
func _ready():
pass
func _process(delta):
position += Vector2(move_vector.x * delta * speed, move_vector.y * delta * speed)
if position.y > Autoload.screen_size.y:
move_vector.y = -1
elif position.y < 0:
move_vector.y = 1
elif position.x > Autoload.screen_size.x:
move_vector.x = -1
elif position.x < 0:
move_vector.x = 1
func _on_Area2D_area_entered(area):
move_vector = -move_vector
func _on_Area2D_body_entered(body):
move_vector = Vector2(move_vector.x, -move_vector.y)

19
Physics/2D/Area2D.tscn Normal file
View File

@ -0,0 +1,19 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://icon.png" type="Texture2D" id=1]
[ext_resource path="res://Physics/2D/Area2D.gd" type="Script" id=2]
[node name="Area2D" type="Area2D"]
script = ExtResource( 2 )
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PackedVector2Array( 4.018, -13.1782, -15.9057, 3.23778, 1.63277, 17.5492, 19.3115, 2.39594 )
[node name="CollisionPolygon2D2" type="CollisionPolygon2D" parent="."]
polygon = PackedVector2Array( -4.58427, -16.8342, -20.5974, -4.94143, -8.23639, 16.784, 20.4187, 13.5065 )
[node name="Sprite2D" type="Sprite2D" parent="."]
texture = ExtResource( 1 )
[connection signal="area_entered" from="." to="." method="_on_Area2D_area_entered"]
[connection signal="body_entered" from="." to="." method="_on_Area2D_body_entered"]

View File

@ -0,0 +1,21 @@
extends CharacterBody2D
var move_vector: Vector2 = Vector2(1, 1)
var speed: float = 1000.0
func _ready():
pass
func _process(delta):
position += Vector2(move_vector.x * delta * speed, move_vector.y * delta * speed)
if position.y > Autoload.screen_size.y:
move_vector.y = -1
elif position.y < 0:
move_vector.y = 1
elif position.x > Autoload.screen_size.x:
move_vector.x = -1
elif position.x < 0:
move_vector.x = 1

View File

@ -0,0 +1,15 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://icon.png" type="Texture2D" id=1]
[ext_resource path="res://Physics/2D/KinematicBody2D.gd" type="Script" id=2]
[node name="CharacterBody2D" type="CharacterBody2D"]
script = ExtResource( 2 )
[node name="Sprite2D" type="Sprite2D" parent="."]
modulate = Color( 0.74902, 0.133333, 0.133333, 1 )
rotation = 4.45932
texture = ExtResource( 1 )
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PackedVector2Array( -10.6781, -7.48182, -12.4953, 17.1263, 15.2543, 6.19464, 4.32263, -14.4073 )

5
Physics/2D/Physics2D.gd Normal file
View File

@ -0,0 +1,5 @@
extends Node2D
func _physics_process(delta):
pass

262
Physics/2D/Physics2D.tscn Normal file
View File

@ -0,0 +1,262 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://Physics/2D/Physics2D.gd" type="Script" id=1]
[ext_resource path="res://Physics/2D/Area2D.tscn" type="PackedScene" id=2]
[ext_resource path="res://Physics/2D/KinematicBody2D.tscn" type="PackedScene" id=3]
[ext_resource path="res://Physics/2D/StaticBody2D.tscn" type="PackedScene" id=4]
[ext_resource path="res://Physics/2D/RigidBody2D.tscn" type="PackedScene" id=5]
[sub_resource type="RectangleShape2D" id=1]
extents = Vector2( 552.521, 10.3948 )
[node name="Physics2D" type="Node2D"]
script = ExtResource( 1 )
[node name="Area2D" type="Node2D" parent="."]
[node name="Area2D" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 166.677, 52.3842 )
[node name="Area2D2" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 209.537, 193.663 )
[node name="Area2D3" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 450.822, 122.23 )
[node name="Area2D4" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 336.529, 293.669 )
[node name="Area2D5" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 555.59, 42.8598 )
[node name="Area2D6" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 598.45, 184.139 )
[node name="Area2D7" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 839.735, 112.705 )
[node name="Area2D8" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 725.442, 284.145 )
[node name="Area2D10" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 420.661, 330.179 )
[node name="Area2D12" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 547.653, 430.186 )
[node name="Area2D14" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 122.23, 457.171 )
[node name="Area2D16" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 249.222, 557.178 )
[node name="Area2D18" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 660.359, 444.472 )
[node name="Area2D19" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 901.644, 373.039 )
[node name="Area2D20" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 787.351, 544.478 )
[node name="Area2D9" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 660.036, 115.278 )
[node name="Area2D11" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 355.255, 161.312 )
[node name="Area2D13" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 482.247, 261.319 )
[node name="Area2D15" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 56.8237, 288.304 )
[node name="Area2D17" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 183.816, 388.311 )
[node name="Area2D21" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 594.953, 275.605 )
[node name="Area2D22" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 836.238, 204.172 )
[node name="Area2D23" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 721.945, 375.611 )
[node name="Area2D24" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 696.901, 221.117 )
[node name="Area2D25" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 392.12, 267.151 )
[node name="Area2D26" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 519.112, 367.158 )
[node name="Area2D27" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 93.689, 394.143 )
[node name="Area2D28" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 220.681, 494.15 )
[node name="Area2D29" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 631.818, 381.444 )
[node name="Area2D30" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 873.103, 310.011 )
[node name="Area2D31" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 758.81, 481.45 )
[node name="Area2D32" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 639.819, 9.43819 )
[node name="Area2D33" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 335.038, 55.4722 )
[node name="Area2D34" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 462.03, 155.479 )
[node name="Area2D35" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 36.6071, 182.464 )
[node name="Area2D36" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 163.599, 282.471 )
[node name="Area2D37" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 574.736, 169.765 )
[node name="Area2D38" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 816.021, 98.3322 )
[node name="Area2D39" parent="Area2D" instance=ExtResource( 2 )]
position = Vector2( 701.728, 269.771 )
[node name="CharacterBody2D" type="Node2D" parent="."]
[node name="CharacterBody2D" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 90.4819, 302.4 )
[node name="KinematicBody2D2" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 380.142, 465.25 )
[node name="KinematicBody2D3" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 333.423, 131.54 )
[node name="KinematicBody2D4" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 509.622, 242.332 )
[node name="KinematicBody2D5" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 914.078, 76.812 )
[node name="KinematicBody2D6" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 251.025, 329.752 )
[node name="KinematicBody2D7" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 540.685, 492.602 )
[node name="KinematicBody2D8" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 493.966, 158.892 )
[node name="KinematicBody2D9" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 670.165, 269.684 )
[node name="KinematicBody2D10" parent="CharacterBody2D" instance=ExtResource( 3 )]
position = Vector2( 926.288, 135.628 )
[node name="StaticBody2D" type="Node2D" parent="."]
position = Vector2( 73.6327, 117.071 )
[node name="StaticBody2D" parent="StaticBody2D" instance=ExtResource( 4 )]
[node name="StaticBody2D2" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 171.12, 267.286 )
[node name="StaticBody2D3" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 618.011, -2.82837 )
[node name="StaticBody2D4" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 793.374, 120.208 )
[node name="StaticBody2D6" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 68.974, 216.436 )
[node name="StaticBody2D7" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 246.087, 431.281 )
[node name="StaticBody2D8" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 686.985, 213.607 )
[node name="StaticBody2D9" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 862.348, 336.644 )
[node name="StaticBody2D5" parent="StaticBody2D" instance=ExtResource( 4 )]
position = Vector2( 704.278, 296.985 )
[node name="RigidDynamicBody2D" type="Node2D" parent="."]
[node name="RigidDynamicBody2D" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 178.191, 120.915 )
[node name="RigidBody2D2" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 192.874, 313.132 )
[node name="RigidBody2D3" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 386.426, 210.35 )
[node name="RigidBody2D4" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 374.412, 43.4946 )
[node name="RigidBody2D5" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 609.344, 331.82 )
[node name="RigidBody2D6" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 756.177, 187.657 )
[node name="RigidBody2D7" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 754.842, 43.4946 )
[node name="RigidBody2D8" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 490.543, 544.06 )
[node name="RigidBody2D9" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 490.543, 544.06 )
[node name="RigidBody2D10" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 282.873, 201.928 )
[node name="RigidBody2D11" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 281.538, 57.7651 )
[node name="RigidBody2D12" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 45.7064, 532.859 )
[node name="RigidBody2D13" parent="RigidDynamicBody2D" instance=ExtResource( 5 )]
position = Vector2( 45.7064, 532.859 )
[node name="Barriers" type="Node2D" parent="."]
[node name="Corner" type="StaticBody2D" parent="Barriers"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Barriers/Corner"]
position = Vector2( 7.93701, 317.48 )
rotation = 1.5708
shape = SubResource( 1 )
[node name="Corner2" type="StaticBody2D" parent="Barriers"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Barriers/Corner2"]
position = Vector2( 1017.52, 365.102 )
rotation = 1.5708
shape = SubResource( 1 )
[node name="Corner3" type="StaticBody2D" parent="Barriers"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Barriers/Corner3"]
position = Vector2( 503.206, -19.0488 )
shape = SubResource( 1 )
[node name="Corner4" type="StaticBody2D" parent="Barriers"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Barriers/Corner4"]
position = Vector2( 492.094, 576.227 )
shape = SubResource( 1 )

22
Physics/2D/RigidBody2D.gd Normal file
View File

@ -0,0 +1,22 @@
extends RigidDynamicBody2D
var move_vector: Vector2 = Vector2(1, 1)
var speed: float = 1000.0
func _ready():
pass
func _process(delta):
#position += Vector2(move_vector.x * delta * speed,move_vector.y * delta * speed)
if position.y > Autoload.screen_size.y:
move_vector.y = -1
elif position.y < 0:
move_vector.y = 1
elif position.x > Autoload.screen_size.x:
move_vector.x = -1
elif position.x < 0:
move_vector.x = 1
apply_impulse(move_vector, Vector2(0, 1))

View File

@ -0,0 +1,16 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://Physics/2D/RigidBody2D.gd" type="Script" id=1]
[ext_resource path="res://icon.png" type="Texture2D" id=2]
[node name="RigidDynamicBody2D" type="RigidDynamicBody2D"]
gravity_scale = 0.1
script = ExtResource( 1 )
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PackedVector2Array( -2.29324, -15.2017, -12.0322, 4.46353, 8.38219, 7.64743 )
[node name="Sprite2D" type="Sprite2D" parent="."]
modulate = Color( 0.47451, 0, 0.427451, 1 )
rotation = 0.792379
texture = ExtResource( 2 )

View File

@ -0,0 +1,21 @@
extends StaticBody2D
var move_vector: Vector2 = Vector2(1, 1)
var speed: float = 1000.0
func _ready():
pass
func _process(delta):
position += Vector2(move_vector.x * delta * speed, move_vector.y * delta * speed)
if position.y > Autoload.screen_size.y:
move_vector.y = -1
elif position.y < 0:
move_vector.y = 1
elif position.x > Autoload.screen_size.x:
move_vector.x = -1
elif position.x < 0:
move_vector.x = 1

View File

@ -0,0 +1,15 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://icon.png" type="Texture2D" id=1]
[ext_resource path="res://Physics/2D/StaticBody2D.gd" type="Script" id=2]
[node name="StaticBody2D" type="StaticBody2D"]
script = ExtResource( 2 )
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PackedVector2Array( -0.566719, -5.64549, -7.24092, 1.19557, -2.06841, 8.20348, 5.60692, 5.20009, 4.10522, -5.14492 )
[node name="Sprite2D" type="Sprite2D" parent="."]
modulate = Color( 0, 1, 1, 0.584314 )
rotation = 0.270526
texture = ExtResource( 1 )

266
Physics/3D/Physics3D.tscn Normal file
View File

@ -0,0 +1,266 @@
[gd_scene load_steps=11 format=2]
[ext_resource path="res://icon.png" type="Texture2D" id=1]
[ext_resource path="res://Physics/3D/StaticArena.gd" type="Script" id=2]
[ext_resource path="res://Physics/3D/RigidBody3D.tscn" type="PackedScene" id=3]
[sub_resource type="PhysicsMaterial" id=1]
friction = 0.89
rough = true
[sub_resource type="StandardMaterial3D" id=2]
albedo_color = Color( 1, 1, 1, 0.521569 )
albedo_texture = ExtResource( 1 )
metallic = 1.0
metallic_specular = 0.86
metallic_texture = ExtResource( 1 )
[sub_resource type="BoxShape3D" id=3]
extents = Vector3( 50, 2, 50 )
[sub_resource type="StandardMaterial3D" id=4]
params_diffuse_mode = 1
albedo_texture = ExtResource( 1 )
metallic = 0.8
[sub_resource type="BoxShape3D" id=5]
extents = Vector3( 50, 20, 5 )
[sub_resource type="BoxShape3D" id=6]
extents = Vector3( 11.8794, 1.37845, 22.281 )
[sub_resource type="BoxShape3D" id=7]
extents = Vector3( 11.8794, 1.37845, 22.281 )
[node name="Physics3D" type="Node3D"]
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D( 1, 0, 0, 0, -0.959707, 0.281002, 0, -0.281002, -0.959707, 0, 35.3705, 0 )
light_energy = 1.45
[node name="StaticArena" type="Node3D" parent="."]
script = ExtResource( 2 )
[node name="StaticBody3D" type="StaticBody3D" parent="StaticArena"]
collision_layer = 2147483651
collision_mask = 279045
physics_material_override = SubResource( 1 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody3D"]
width = 100.0
height = 4.32824
depth = 100.0
material = SubResource( 2 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody3D"]
shape = SubResource( 3 )
[node name="StaticBody2" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18.1689, 1.64214 )
collision_layer = 2147483651
collision_mask = 279045
physics_material_override = SubResource( 1 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody2"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -46.5124 )
width = 100.0
height = 40.0
depth = 10.0
material = SubResource( 4 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody2"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -46.709 )
shape = SubResource( 5 )
[node name="StaticBody3" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18.1689, 91.732 )
collision_layer = 2147483651
collision_mask = 279045
physics_material_override = SubResource( 1 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody3"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -46.5124 )
width = 100.0
height = 40.0
depth = 10.0
material = SubResource( 4 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody3"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -46.709 )
shape = SubResource( 5 )
[node name="StaticBody4" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( -1.62921e-07, 0, -1, 0, 1, 0, 1, 0, -1.62921e-07, -1.90218, 18.1689, 0.572887 )
collision_layer = 2147483651
collision_mask = 279045
physics_material_override = SubResource( 1 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody4"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.13509, -46.5124 )
width = 100.0
height = 40.0
depth = 10.0
material = SubResource( 4 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody4"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -46.709 )
shape = SubResource( 5 )
[node name="StaticBody5" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( -1.62921e-07, 0, -1, 0, 1, 0, 1, 0, -1.62921e-07, -92.1931, 18.8845, 0.814518 )
collision_layer = 2147483651
collision_mask = 279045
physics_material_override = SubResource( 1 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody5"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -46.5124 )
width = 100.0
height = 40.0
depth = 10.0
material = SubResource( 4 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody5"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -46.709 )
shape = SubResource( 5 )
[node name="StaticBody6" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( 0.998532, 0.013617, -0.0524264, 0, 0.967885, 0.251394, 0.054166, -0.251025, 0.966464, -16.8315, 7.76313, 0 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody6"]
shape = SubResource( 6 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody6"]
width = 23.9394
depth = 44.6359
[node name="StaticBody7" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( -0.638995, 0.193375, -0.744507, 0, 0.967885, 0.251394, 0.769211, 0.16064, -0.618474, 10.0702, 7.03413, 0 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody7"]
transform = Transform3D( 1, -9.31323e-10, 0, 0, 1, 1.49012e-08, 3.72529e-09, 1.49012e-08, 1, 0, 0, 0 )
shape = SubResource( 7 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody7"]
width = 23.9394
depth = 44.6359
[node name="StaticBody8" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( -0.314953, 0.2386, -0.918626, 0, 0.967885, 0.251394, 0.949107, 0.0791774, -0.304838, 10.0702, 7.03413, 24.278 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody8"]
transform = Transform3D( 1, -9.31323e-10, 0, 0, 1, 1.49012e-08, 3.72529e-09, 1.49012e-08, 1, 0, 0, 0 )
shape = SubResource( 7 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody8"]
width = 23.9394
depth = 44.6359
[node name="StaticBody9" type="StaticBody3D" parent="StaticArena"]
transform = Transform3D( 0.289683, -0.599318, 0.746259, -0.123608, -0.796586, -0.591753, 0.949107, 0.0791774, -0.304838, 10.0702, 0.940654, -25.555 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticArena/StaticBody9"]
transform = Transform3D( 1, 7.45058e-09, 0, 1.49012e-08, 1, 4.84288e-08, 0, -3.1665e-08, 1, 0, 0, 0 )
shape = SubResource( 7 )
[node name="CSGBox3D" type="CSGBox3D" parent="StaticArena/StaticBody9"]
width = 23.9394
depth = 44.6359
[node name="Objects" type="Node3D" parent="."]
[node name="RigidDynamicBody3D" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -8.50424, 17.1047, 14.7363 )
[node name="RigidBody2" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 3.7864, 12.6031, 19.1751 )
[node name="RigidBody3" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -16.9896, 10.6319, 28.8764 )
[node name="RigidBody4" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -26.0866, 12.6031, -18.3703 )
[node name="RigidBody5" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 22.2505, 12.6031, -20.7732 )
[node name="RigidBody6" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 24.085, 12.6031, 8.2937 )
[node name="RigidBody7" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 18.9278, 12.6031, 23.4173 )
[node name="RigidBody8" parent="Objects" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -3.85186, 24.8548, -9.87658 )
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D( 0.922114, 0.23703, -0.305815, 0.0163102, 0.765871, 0.642787, 0.386575, -0.597711, 0.702354, -25.392, 55.117, 39.851 )
current = true
far = 200.0
[node name="Joints" type="Node3D" parent="."]
[node name="Cone" type="Node3D" parent="Joints"]
[node name="RigidBody2" parent="Joints/Cone" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 6.73046, 77.026 )
gravity_scale = -3.0
[node name="RigidDynamicBody3D" parent="Joints/Cone" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 15.3482, 19.1751 )
[node name="ConeTwistJoint3D" type="ConeTwistJoint3D" parent="Joints/Cone"]
nodes/node_a = NodePath("../RigidDynamicBody3D")
nodes/node_b = NodePath("../RigidBody2")
[node name="Generic" type="Node3D" parent="Joints"]
[node name="RigidDynamicBody3D" parent="Joints/Generic" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 33.1278, 67.0796 )
gravity_scale = -3.0
[node name="RigidBody2" parent="Joints/Generic" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 33.1278, -0.445078 )
[node name="Generic6DOFJoint3D" type="Generic6DOFJoint3D" parent="Joints/Generic"]
nodes/node_a = NodePath("../RigidDynamicBody3D")
nodes/node_b = NodePath("../RigidBody2")
[node name="Hinge" type="Node3D" parent="Joints"]
[node name="RigidDynamicBody3D" parent="Joints/Hinge" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 18.6153, 33.1278, 59.2096 )
gravity_scale = -3.0
[node name="RigidBody2" parent="Joints/Hinge" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8.17695, 33.1278, 19.1751 )
[node name="HingeJoint3D" type="HingeJoint3D" parent="Joints/Hinge"]
nodes/node_a = NodePath("../RigidDynamicBody3D")
nodes/node_b = NodePath("../RigidBody2")
[node name="Pin" type="Node3D" parent="Joints"]
[node name="RigidDynamicBody3D" parent="Joints/Pin" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 4.83369, 116.28 )
gravity_scale = -3.0
[node name="RigidBody2" parent="Joints/Pin" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 18.4589, 10.7729 )
[node name="PinJoint3D" type="PinJoint3D" parent="Joints/Pin"]
nodes/node_a = NodePath("../RigidDynamicBody3D")
nodes/node_b = NodePath("../RigidBody2")
[node name="Slider" type="Node3D" parent="Joints"]
[node name="RigidDynamicBody3D" parent="Joints/Slider" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 17.7427, 19.1751 )
gravity_scale = -3.0
[node name="RigidBody2" parent="Joints/Slider" instance=ExtResource( 3 )]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -33.3355, 16.2845, 19.1751 )
[node name="SliderJoint3D" type="SliderJoint3D" parent="Joints/Slider"]
nodes/node_a = NodePath("../RigidDynamicBody3D")
nodes/node_b = NodePath("../RigidBody2")
linear_motion/softness = 1.43

View File

@ -0,0 +1,6 @@
extends RigidDynamicBody3D
func _physics_process(delta: float) -> void:
add_constant_force(Vector3(0, 4 * delta, 0), Vector3(0, 0, 0))
pass

View File

@ -0,0 +1,18 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://Physics/3D/RigidBody3D.gd" type="Script" id=1]
[sub_resource type="SphereShape3D" id=1]
[node name="RigidDynamicBody3D" type="RigidDynamicBody3D"]
transform = Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, -23.2888, 33.1278, 19.1751 )
gravity_scale = 5.0
continuous_cd = true
linear_velocity = Vector3( 0, 5, 0 )
script = ExtResource( 1 )
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D( 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0 )
shape = SubResource( 1 )
[node name="CSGSphere3D" type="CSGSphere3D" parent="CollisionShape3D"]

View File

@ -0,0 +1,5 @@
extends Node3D
func _process(delta):
rotate(Vector3(0, 1, 0).normalized(), 2 * delta)

View File

@ -1,7 +1,7 @@
# Godot regression test project # Godot regression test project
This repository contains project which is used to find regressions in Godot. This repository contains project which is used to find regressions in Godot.
It aims to check as much as possible functions and states, be easy in maintain and provide reproducible results. It aims to check as much as possible functions and states, be easy in maintain and provide quite reproducible results.
## Basic Informations ## Basic Informations
This project contains a few different scenes and `Start.tscn`(default one) which opens every other scene. This project contains a few different scenes and `Start.tscn`(default one) which opens every other scene.
@ -50,18 +50,19 @@ A scene that will probably give people a hard time quite often is `FunctionExecu
This is a fuzzer, but with removed ability to use random argument values (the arguments are identical every time it is run). This is a fuzzer, but with removed ability to use random argument values (the arguments are identical every time it is run).
When the engine crashes, in logs usually will be something like this: When the engine crashes, in logs usually will be something like this:
``` ```
#################### SkeletonModification2DPhysicalBones #################### #################### LineEdit ####################
SkeletonModification2DPhysicalBones.set_physical_bone_node
Parameters [100, ] LineEdit._text_changed --- executing with 0 parameters []
ERROR: Joint index out of range! GDSCRIPT CODE: LineEdit.new()._text_changed()
at: set_physical_bone_node (scene/resources/skeleton_modification_2d_physicalbones.cpp:259)
SkeletonModification2DPhysicalBones.get_physical_bone_node LineEdit._toggle_draw_caret --- executing with 0 parameters []
Parameters [100] GDSCRIPT CODE: LineEdit.new()._toggle_draw_caret()
ERROR: Joint index out of range!
at: get_physical_bone_node (scene/resources/skeleton_modification_2d_physicalbones.cpp:265) LineEdit.set_align --- executing with 1 parameters [100]
SkeletonModification2DPhysicalBones.fetch_physical_bones GDSCRIPT CODE: LineEdit.new().set_align(100)
Parameters [] ERROR: set_align: Index (int)p_align = 100 is out of bounds (4 = 4).
scene/resources/skeleton_modification_2d_physicalbones.cpp:186:2: runtime error: member access within null pointer of type 'struct SkeletonModificationStack2D' At: scene/gui/line_edit.cpp:592.
scene/resources/line_edit.cpp:186:2: runtime error: member access within null pointer of type 'struct LineEdit'
handle_crash: Program crashed with signal 11 handle_crash: Program crashed with signal 11
Dumping the backtrace. Please include this when reporting the bug on godotengine/godot/issues Dumping the backtrace. Please include this when reporting the bug on godotengine/godot/issues
[1] bin/godot.linuxbsd.tools.64s() [0x1e697d8] (/home/runner/work/godot/godot/platform/linuxbsd/crash_handler_linuxbsd.cpp:54) [1] bin/godot.linuxbsd.tools.64s() [0x1e697d8] (/home/runner/work/godot/godot/platform/linuxbsd/crash_handler_linuxbsd.cpp:54)
@ -70,24 +71,24 @@ Dumping the backtrace. Please include this when reporting the bug on godotengine
There are some interesting things to discuss here. There are some interesting things to discuss here.
This line shows what class we are testing now This line shows what class we are testing now
``` ```
#################### SkeletonModification2DPhysicalBones #################### #################### LineEdit ####################
``` ```
which method which method
``` ```
SkeletonModification2DPhysicalBones.set_physical_bone_node LineEdit.set_align
``` ```
and which parameters (here are two arguments - `100`, \` \`(empty string)) and which parameters
``` ```
Parameters [100, ] --- executing with 1 parameters [100]
``` ```
To make testing easier, each object is created from scratch and by looking at the class definition in Godot - `set_physical_bone_node(int, String)` we can create an expression that is executed on this line: Next you can see GDScript command which is executed and you can copy it and test manually in Godot
``` ```
SkeletonModification2DPhysicalBones.new().set_physical_bone_node(100,"") GDSCRIPT CODE: LineEdit.new()._toggle_draw_caret()
``` ```
Then you can see errors caused by invalid arguments, which you can ignore if they don't cause other crashes/leaks etc. Then you can see errors caused by invalid arguments, which you can ignore if they don't cause other crashes/leaks etc.
``` ```
ERROR: Joint index out of range! ERROR: set_align: Index (int)p_align = 100 is out of bounds (4 = 4).
at: get_physical_bone_node (scene/resources/skeleton_modification_2d_physicalbones.cpp:265) At: scene/gui/line_edit.cpp:592.
``` ```
At the end we can see Godot's crash log with additional information that tried to use null pointer incorrectly: At the end we can see Godot's crash log with additional information that tried to use null pointer incorrectly:
``` ```
@ -97,14 +98,14 @@ Dumping the backtrace. Please include this when reporting the bug on godotengine
[1] bin/godot.linuxbsd.tools.64s() [0x1e697d8] (/home/runner/work/godot/godot/platform/linuxbsd/crash_handler_linuxbsd.cpp:54) [1] bin/godot.linuxbsd.tools.64s() [0x1e697d8] (/home/runner/work/godot/godot/platform/linuxbsd/crash_handler_linuxbsd.cpp:54)
[2] /lib/x86_64-linux-gnu/libc.so.6(+0x46210) [0x7fd1ca5b0210] (??:0) [2] /lib/x86_64-linux-gnu/libc.so.6(+0x46210) [0x7fd1ca5b0210] (??:0)
``` ```
we can assume that this is caused by calling the function immediately before the crash: In most situations, the latest executed function/created object is responsible for crash
``` ```
SkeletonModification2DPhysicalBones.fetch_physical_bones LineEdit.set_align --- executing with 1 parameters [100]
Parameters [] GDSCRIPT CODE: LineEdit.new().set_align(100)
``` ```
We can test this by running a function in Godot that looks like this(just add `.new()` after class name and fill function arguments from `Parameters`): So we can just take GDScript code from above, copy it into Godot and test project, which should crash engine
``` ```
SkeletonModification2DPhysicalBones.new().fetch_physical_bones() LineEdit.new().set_align(100)
``` ```
## Nodes ## Nodes
@ -115,24 +116,18 @@ It is used to catch early very obvious and easy to reproduce bugs.
This is more advanced variation of Nodes scene. This is more advanced variation of Nodes scene.
In random order adds, remove and move in scene tree nodes. It may not sound spectacular, but it sometimes allows you to find bugs that are hard to detect. In random order adds, remove and move in scene tree nodes. It may not sound spectacular, but it sometimes allows you to find bugs that are hard to detect.
## CreatingAllThings
This scene creates, prints and removes object.
Can be used to quicly check if classes don't crash when executing simple commands on them.
## Others ## Others
Scenes like `Physics2D.tscn` or `Lights3D.tscn` are normal scenes with specific types of nodes. They are only used to manually check visual differences between different Godot versions. Scenes like `Physics2D.tscn` or `Lights3D.tscn` are normal scenes with specific types of nodes. They are only used to manually check visual differences between different Godot versions.
![Physics](https://user-images.githubusercontent.com/41945903/115050994-9da8a100-9edc-11eb-99f6-9375ef917be1.png) ![Physics](https://user-images.githubusercontent.com/41945903/115050994-9da8a100-9edc-11eb-99f6-9375ef917be1.png)
## TODO
- Add physics test - currently blocked by several crashes - https://github.com/godotengine/godot/issues/47440
## 4.0 version limitations
ReparentingDeleting is in 4.0 only Reparenting - bug https://github.com/godotengine/godot/issues/45471
Some scenes available in 3.x branch, but due freezes and long loading times are disabled.
## Epilepsy Warning ## Epilepsy Warning
Due using by project a lot of functions from each type of Node, screen may flicker, images and objects may change randomly color and size which may lead some users to health problems. Due using by project a lot of functions from each type of Node, screen may flicker, images and objects may change randomly color and size which may lead some users to health problems.
## Problems with project ## Problems with project
The project should not cause too many problems in CI when adding and removing features in Godot, since it don't uses too much functions but for example removing a base type e.g. `TYPE_INT` or changes in GDScript(e.g. changing `instance` to `instantiate`) can mess it up. The project should not cause too many problems in CI when adding and removing features in Godot, since it don't uses too much functions but for example removing a base type e.g. `TYPE_INT` or changes in GDScript(e.g. changing `instance` to `instantiate`) can mess it up.
If you have problem with this project e.g. in CI, just ping me -> @qarmin <- and after that I will try help to fix issues which you have with it or add exception to project.

View File

@ -1,96 +1,118 @@
extends Node extends Node
var number_of_nodes : int = 0 # Script first adds nodes to scene, then choose some random nodes and reparents
# them or delete and replace with new ones
# This is not really reproducible, but crashes find by this tool should be quite easy to recreate
var collected_nodes : Array = [] ## Algorithm
var disabled_classes : Array = [
"NavigationAgent2D", "NavigationAgent3D","GPUParticlesCollisionHeightField",
"ReflectionProbe",# Cause errors, not sure about it
# Creating them is really slow in Godot 4.0
"ColorPicker",
"FileDialog",
"ColorPickerButton",
"PhysicalSkyMaterial",
"ProceduralSkyMaterial"
] # Just add name of any class if cause problems
func collect() -> void:
var classes : Array = ClassDB.get_class_list()
classes.sort()
for name_of_class in classes:
if ClassDB.is_parent_class(name_of_class,"Node"):
if name_of_class.find("Editor") != -1: # We don't want to test editor nodes
continue
if disabled_classes.has(name_of_class): # Class is disabled
continue
if ClassDB.can_instantiate(name_of_class): # Only instantable nodes can be used
collected_nodes.append(name_of_class)
func _ready() -> void:
seed(405)
collect()
number_of_nodes = max(collected_nodes.size(),11) # Use at least all nodes, or more if you want(168 is probably number nodes)
for i in range(number_of_nodes):
var index = i
if i >= collected_nodes.size(): # Wrap values
index = i % collected_nodes.size()
var child : Node = Autoload.get_instance_from_name(collected_nodes[index])
child.set_name("Special Node " + str(i))
add_child(child)
## It is quite easy algorithm to reparent and delete items
# - Add multiple nodes to scene # - Add multiple nodes to scene
# - Set name to each # - Set name to each
# - In process # - In _process
# - Get random node # - Get random node
# - Remove its parent # - Detach it from its parent
# - Play with a russian roulette # - Play with a russian roulette:
# - If node will be deleted, be sure to get list of its all children and then # - If node will be deleted, be sure to get list of its all children and then
# replace all with new nodes(change also name) and old remove with queue_free() # replace all with new nodes(change also name) and old remove with queue_free()
# - Get another random node # - Get another random node
# - If nodes are the same, add node to root one(cannot set self as self parent) and repeat steps # - If nodes are the same, add node to root one(cannot set self as self parent) and repeat steps
# - If second node is child of first, add first node to root one(prevents from memory leaks due invalid reparenting) # - If second node is child of first, add first node to root one(prevents from memory leaks due invalid reparenting)
# - At the end add first random node as child of second # - At the end add first random node as child of second
var number_of_nodes: int = 0
# Collected nodes
var collected_nodes: Array = []
# Disabled nodes which won't be used
var disabled_classes: Array = [
"NavigationAgent2D",
"NavigationAgent3D",
"GPUParticlesCollisionHeightField",
"ReflectionProbe", # Cause errors, not sure about it
# Creating them is really slow in Godot 4.0
"ColorPicker",
"FileDialog",
"ColorPickerButton",
"PhysicalSkyMaterial",
"ProceduralSkyMaterial"
]
var debug_enabled: bool = false
func collect() -> void:
var classes: Array = ClassDB.get_class_list()
classes.sort()
for name_of_class in classes:
if ClassDB.is_parent_class(name_of_class, "Node"):
if name_of_class.find("Editor") != -1: # We don't want to test editor nodes
continue
if disabled_classes.has(name_of_class): # Class is disabled
continue
if ClassDB.can_instantiate(name_of_class): # Only instantable nodes can be used
collected_nodes.append(name_of_class)
if debug_enabled:
var to_print: String = "DEBUG: List of classes used in ReparentingDeleting scene:\n"
to_print += "DEBUG: ["
for index in range(classes.size()):
to_print += '"' + classes[index] + '"'
if index != classes.size() - 1:
to_print += ", "
print(to_print)
func _ready() -> void:
seed(405)
collect()
number_of_nodes = max(collected_nodes.size(), 200) # Use at least all nodes, or more if you want(168 is probably number of all nodes)
for i in range(number_of_nodes):
var index = i
if i >= collected_nodes.size(): # Wrap values
index = i % collected_nodes.size()
var child: Node = ClassDB.instantiate(collected_nodes[index])
child.set_name("Special Node " + str(i))
add_child(child)
func _process(delta: float) -> void: func _process(delta: float) -> void:
assert(Performance.get_monitor(Performance.OBJECT_ORPHAN_NODE_COUNT) == 0) # Don't work good with running more than 1 this scene # assert(Performance.get_monitor(Performance.OBJECT_ORPHAN_NODE_COUNT) == 0) # Don't work good when instancing more than 1 scene, because node queued for deleting
var choosen_node : Node var choosen_node: Node
var parent_of_node : Node var parent_of_node: Node
for i in range(5): for i in range(5):
var number : String = "Special Node " + str(randi() % number_of_nodes) var number: String = "Special Node " + str(randi() % number_of_nodes)
choosen_node = find_node(number,true,false) choosen_node = find_node(number, true, false)
parent_of_node = choosen_node.get_parent() parent_of_node = choosen_node.get_parent()
var random_node = find_node("Special Node " + str(randi() % number_of_nodes),true,false) var random_node = find_node("Special Node " + str(randi() % number_of_nodes), true, false)
parent_of_node.remove_child(choosen_node) parent_of_node.remove_child(choosen_node)
# if randi() % 6 == 0: # 16% chance to remove node with children if randi() % 6 == 0: # 16% chance to remove node with children
# var names_to_remove : Array = find_all_special_children_names(choosen_node) var names_to_remove: Array = find_all_special_children_names(choosen_node)
# for name_to_remove in names_to_remove: for name_to_remove in names_to_remove:
# var node : Node = Autoload.get_instance_from_name(collected_nodes[randi() % collected_nodes.size()]) var node: Node = ClassDB.instantiate(collected_nodes[randi() % collected_nodes.size()])
# node.set_name(name_to_remove) node.set_name(name_to_remove)
# add_child(node) add_child(node)
# choosen_node.queue_free() choosen_node.queue_free()
# continue continue
if choosen_node.find_node(random_node.get_name(), true, false) != null: # Cannot set as node parent one of its child
if choosen_node.find_node(random_node.get_name(),true,false) != null: # Cannot set as node parent one of its child
add_child(choosen_node) add_child(choosen_node)
continue continue
if choosen_node == random_node: # Do not reparent node to self if choosen_node == random_node: # Do not reparent node to self
add_child(choosen_node) add_child(choosen_node)
continue continue
random_node.add_child(choosen_node) random_node.add_child(choosen_node)
# Finds recusivelly all child nodes which are not internal
func find_all_special_children_names(node : Node) -> Array: # Finds recusivelly all child nodes which will be also removed to be able to add
var array : Array = [] # exactly same number of nodes in replacement.
func find_all_special_children_names(node: Node) -> Array:
var array: Array = []
array.append(node.get_name()) array.append(node.get_name())
for child in node.get_children(): for child in node.get_children():
if String(child.get_name()).begins_with("Special Node"): if String(child.get_name()).begins_with("Special Node"):
array.append_array(find_all_special_children_names(child)) array.append_array(find_all_special_children_names(child))
return array return array

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://bko71to5pvsix"] [gd_scene load_steps=2 format=2]
[ext_resource type="Script" path="res://ReparentingDeleting/ReparentingDeleting.gd" id="1"] [ext_resource path="res://ReparentingDeleting/ReparentingDeleting.gd" type="Script" id=1]
[node name="ReparentingDeleting" type="Node"] [node name="ReparentingDeleting" type="Node"]
script = ExtResource( "1" ) script = ExtResource( 1 )

View File

@ -8,13 +8,17 @@ var array_with_time_to_change: Array = []
func _ready(): func _ready():
Autoload.can_be_closed = false
for i in Autoload.alone_steps.size() + 1: for i in Autoload.alone_steps.size() + 1:
array_with_time_to_change.append(Time.get_ticks_msec() + i * Autoload.time_for_each_step) array_with_time_to_change.append(Autoload.time_object.get_ticks_msec() + i * Autoload.time_for_each_step)
func _process(_delta): func _process(_delta):
if current_scene < Autoload.alone_steps.size() - 1 && Time.get_ticks_msec() > array_with_time_to_change[current_scene + 1]: if current_scene < Autoload.alone_steps.size() - 1 && Autoload.time_object.get_ticks_msec() > array_with_time_to_change[current_scene + 1]:
current_scene += 1 current_scene += 1
if current_scene == Autoload.alone_steps.size() - 1:
Autoload.can_be_closed = true
for child in get_children(): for child in get_children():
child.queue_free() child.queue_free()

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=2 format=3 uid="uid://bi6b75cfmqj4r"] [gd_scene load_steps=2 format=3 uid="uid://c1k8u3yl82xm4"]
[ext_resource type="Script" path="res://Start.gd" id="1"] [ext_resource type="Script" path="res://Start.gd" id="1"]

View File

@ -8,22 +8,18 @@ export_filter="all_resources"
include_filter="" include_filter=""
exclude_filter="" exclude_filter=""
export_path="" export_path=""
encryption_include_filters="" patch_list=PoolStringArray( )
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=1 script_export_mode=1
script_encryption_key="" script_encryption_key=""
[preset.0.options] [preset.0.options]
custom_template/debug="PATH_TO_CHANGE"
custom_template/release=""
binary_format/64_bits=true
binary_format/embed_pck=false
texture_format/bptc=false texture_format/bptc=false
texture_format/s3tc=true texture_format/s3tc=true
texture_format/etc=false texture_format/etc=false
texture_format/etc2=false texture_format/etc2=false
texture_format/no_bptc_fallbacks=true texture_format/no_bptc_fallbacks=true
binary_format/64_bits=true
binary_format/embed_pck=false
custom_template/release=""
custom_template/debug="PATH_TO_CHANGE"

View File

@ -2,7 +2,7 @@
importer="texture" importer="texture"
type="StreamTexture2D" type="StreamTexture2D"
uid="uid://bp1jqfv4eumxi" uid="uid://bkhft4ksf6bm8"
path.s3tc="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.s3tc.stex" path.s3tc="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.s3tc.stex"
path.etc2="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.etc2.stex" path.etc2="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.etc2.stex"
metadata={ metadata={
@ -24,7 +24,7 @@ compress/bptc_ldr=0
compress/normal_map=0 compress/normal_map=0
compress/channel_pack=0 compress/channel_pack=0
compress/streamed=false compress/streamed=false
mipmaps/generate=true mipmaps/generate=false
mipmaps/limit=-1 mipmaps/limit=-1
roughness/mode=0 roughness/mode=0
roughness/src_normal="" roughness/src_normal=""
@ -33,5 +33,5 @@ process/premult_alpha=false
process/normal_map_invert_y=false process/normal_map_invert_y=false
process/HDR_as_SRGB=false process/HDR_as_SRGB=false
process/size_limit=0 process/size_limit=0
detect_3d/compress_to=0 detect_3d/compress_to=1
svg/scale=1.0 svg/scale=1.0

View File

@ -6,12 +6,13 @@
; [section] ; section goes between [] ; [section] ; section goes between []
; param=value ; assign values to parameters ; param=value ; assign values to parameters
config_version=4 config_version=5
[application] [application]
run/main_scene="res://Start.tscn" run/main_scene="res://Start.tscn"
config/icon="res://icon.png" config/icon="res://icon.png"
config/features=PackedStringArray("4.0")
[autoload] [autoload]