mirror of
https://github.com/Relintai/regression-test-project.git
synced 2024-11-12 10:25:30 +01:00
Clean 3.x branch (#65)
This commit is contained in:
parent
e59d9cb011
commit
1aff26a273
13
.github/workflows/required.yml
vendored
13
.github/workflows/required.yml
vendored
@ -27,6 +27,7 @@ jobs:
|
||||
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
|
||||
xvfb wget2 unzip python scons git
|
||||
|
||||
# Allows to test project with precompiled binaries
|
||||
# - name: Download Godot
|
||||
# run: |
|
||||
# wget2 https://downloads.tuxfamily.org/godotengine/3.2.4/beta1/Godot_v3.2.4-beta1_x11.64.zip
|
||||
@ -63,11 +64,11 @@ jobs:
|
||||
|
||||
- name: Test project
|
||||
run: |
|
||||
DRI_PRIME=0 xvfb-run ./godot.x11.tools.64s 60 --audio-driver Dummy --video-driver GLES3 --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
|
||||
DRI_PRIME=0 xvfb-run ./godot.x11.tools.64s 180 --audio-driver Dummy --video-driver GLES3 --path $(pwd) 2>&1 | tee sanitizers_log.txt || true
|
||||
misc/check_ci_log.py sanitizers_log.txt
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ github.job }}
|
||||
path: godot.x11.tools.64s
|
||||
retention-days: 14
|
||||
# - uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: ${{ github.job }}
|
||||
# path: godot.x11.tools.64s
|
||||
# retention-days: 14
|
||||
|
@ -20,21 +20,22 @@ const alone_steps: Array = [
|
||||
"res://Nodes/Nodes.tscn",
|
||||
"res://Physics/2D/Physics2D.tscn",
|
||||
"res://Physics/3D/Physics3D.tscn",
|
||||
"res://ReparentingDeleting/ReparentingDeleting.tscn",
|
||||
"res://AutomaticBugs/FunctionExecutor.tscn", # Only runs
|
||||
# "res://ReparentingDeleting/ReparentingDeleting.tscn", Not always reproducible
|
||||
"res://AutomaticBugs/FunctionExecutor.tscn", # Only need to run once
|
||||
]
|
||||
|
||||
var time_object : Object
|
||||
var time_object: Object
|
||||
|
||||
|
||||
func _init():
|
||||
# Workaround for Time/OS breaking change - https://github.com/godotengine/godot/pull/54056
|
||||
if ClassDB.class_exists("_Time"):
|
||||
time_object = ClassDB.instance("_Time")
|
||||
elif ClassDB.class_exists("Time"):
|
||||
time_object = ClassDB.instance("Time")
|
||||
else:
|
||||
time_object = ClassDB.instance("_OS")
|
||||
|
||||
|
||||
|
||||
start_time = time_object.get_ticks_msec()
|
||||
|
||||
# In case when user doesn't provide time
|
||||
@ -45,13 +46,13 @@ func _init():
|
||||
time_to_show = int(argument.to_float() * 1000)
|
||||
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.")
|
||||
break # We only need to take first argument
|
||||
break # We only need to take first numeric argument
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
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:
|
||||
print("Test is running now " + str(int(time_to_print_next_time / 1000)) + " seconds")
|
||||
time_to_print_next_time += PRINT_TIME_EVERY_MILISECONDS
|
||||
@ -59,6 +60,7 @@ func _process(delta: float) -> void:
|
||||
if current_run_time > time_to_show && can_be_closed:
|
||||
print("######################## Ending test ########################")
|
||||
get_tree().quit()
|
||||
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
time_object.free()
|
||||
|
@ -1,71 +1,61 @@
|
||||
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
|
||||
|
||||
# Globablly disabled functions for all classes
|
||||
var function_exceptions : Array = [
|
||||
"get_packet", # TODO
|
||||
"_gui_input", # TODO probably missing cherrypick #GH 47636
|
||||
"_input",
|
||||
"_unhandled_input",
|
||||
"_unhandled_key_input",
|
||||
"connect_to_signal", # Should be chrrypicked
|
||||
|
||||
var function_exceptions: Array = [
|
||||
# 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
|
||||
"_submenu_timeout", # GH 45981
|
||||
"_thread_done", #GH 46000
|
||||
"generate", #GH 46001
|
||||
"_proximity_group_broadcast", #GH 46002
|
||||
"_direct_state_changed", #GH 46003
|
||||
"create_from", #GH 46004
|
||||
"create_from_blend_shape", #GH 46004
|
||||
"append_from", #GH 46004
|
||||
"_set_tile_data", #GH 46015
|
||||
"get", #GH 46019
|
||||
"instance_has", #GH 46020
|
||||
"get_var", #GH 46096
|
||||
"set_script", #GH 46120
|
||||
"getvar", #GH 46019
|
||||
"get_available_chars", #GH 46118
|
||||
"open_midi_inputs", #GH 46183
|
||||
"set_icon", #GH 46189
|
||||
"get_latin_keyboard_variant", #GH TODO Memory Leak
|
||||
"set_editor_hint", #GH 46252
|
||||
"get_item_at_position", #TODO hard to find
|
||||
"set_probe_data", #GH 46570
|
||||
"_range_click_timeout", #GH 46648
|
||||
"get_indexed", #GH 46019
|
||||
"add_vertex", #GH 47066
|
||||
"create_client", # TODO, strange memory leak
|
||||
"create_shape_owner", #47135
|
||||
"shape_owner_get_owner", #47135
|
||||
|
||||
"get_bind_bone", #GH 47358
|
||||
"get_bind_name", #GH 47358
|
||||
"get_bind_pose", #GH 47358
|
||||
|
||||
# TODO Check this later
|
||||
"get_packet", # TODO
|
||||
"_gui_input", # TODO probably missing cherrypick #GH 47636
|
||||
"_input",
|
||||
"_unhandled_input",
|
||||
"_unhandled_key_input",
|
||||
"connect_to_signal", # Should be chrrypicked
|
||||
"_editor_settings_changed", # GH 45979
|
||||
"_submenu_timeout", # GH 45981
|
||||
"_thread_done", #GH 46000
|
||||
"generate", #GH 46001
|
||||
"_proximity_group_broadcast", #GH 46002
|
||||
"_direct_state_changed", #GH 46003
|
||||
"create_from", #GH 46004
|
||||
"create_from_blend_shape", #GH 46004
|
||||
"append_from", #GH 46004
|
||||
"_set_tile_data", #GH 46015
|
||||
"get", #GH 46019
|
||||
"instance_has", #GH 46020
|
||||
"get_var", #GH 46096
|
||||
"set_script", #GH 46120
|
||||
"getvar", #GH 46019
|
||||
"get_available_chars", #GH 46118
|
||||
"open_midi_inputs", #GH 46183
|
||||
"set_icon", #GH 46189
|
||||
"get_latin_keyboard_variant", #GH TODO Memory Leak
|
||||
"set_editor_hint", #GH 46252
|
||||
"get_item_at_position", #TODO hard to find
|
||||
"set_probe_data", #GH 46570
|
||||
"_range_click_timeout", #GH 46648
|
||||
"get_indexed", #GH 46019
|
||||
"add_vertex", #GH 47066
|
||||
"create_client", # TODO, strange memory leak
|
||||
"create_shape_owner", #47135
|
||||
"shape_owner_get_owner", #47135
|
||||
"get_bind_bone", #GH 47358
|
||||
"get_bind_name", #GH 47358
|
||||
"get_bind_pose", #GH 47358
|
||||
# Not worth using
|
||||
"propagate_notification",
|
||||
"notification",
|
||||
|
||||
# TODO Adds big spam when i>100 - look for possiblity to
|
||||
# TODO Adds big spam when i>100 - look for possiblity to
|
||||
"add_sphere",
|
||||
"_update_inputs", # Cause big spam with add_input
|
||||
# Spam when i~1000 - change to specific
|
||||
"_update_inputs", # Cause big spam with add_input
|
||||
# Spam when i~1000 - change to specific
|
||||
"update_bitmask_region",
|
||||
"set_enabled_inputs",
|
||||
|
||||
# Slow Function
|
||||
"_update_sky",
|
||||
|
||||
# Undo/Redo function which doesn't provide enough information about types of objects, probably due vararg(variable size argument)
|
||||
"add_do_method",
|
||||
"add_undo_method",
|
||||
|
||||
# Do not save files and create files and folders
|
||||
"pck_start",
|
||||
"save",
|
||||
@ -84,19 +74,16 @@ var function_exceptions : Array = [
|
||||
"open_encrypted",
|
||||
"open_encrypted_with_pass",
|
||||
"open_compressed",
|
||||
|
||||
# Do not warp mouse
|
||||
"warp_mouse",
|
||||
"warp_mouse_position",
|
||||
|
||||
# OS
|
||||
"kill",
|
||||
"shell_open",
|
||||
"execute",
|
||||
"delay_usec",
|
||||
"delay_msec",
|
||||
"alert", # Stupid alert window opens
|
||||
|
||||
"alert", # Stupid alert window opens
|
||||
# Godot Freeze
|
||||
"wait_to_finish",
|
||||
"accept_stream",
|
||||
@ -105,12 +92,8 @@ var function_exceptions : Array = [
|
||||
"wait",
|
||||
"debug_bake",
|
||||
"bake",
|
||||
|
||||
"_create", # TODO Check
|
||||
|
||||
|
||||
"set_gizmo", # Stupid function, needs as parameter an object which can't be instanced # TODO, create issue to hide it
|
||||
|
||||
"_create", # TODO Check
|
||||
"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_stray_nodes",
|
||||
@ -118,7 +101,6 @@ var function_exceptions : Array = [
|
||||
"print_all_textures_by_size",
|
||||
"print_all_resources",
|
||||
"print_resources_in_use",
|
||||
|
||||
# Do not call other functions
|
||||
"_call_function",
|
||||
"call",
|
||||
@ -126,7 +108,6 @@ var function_exceptions : Array = [
|
||||
"callv",
|
||||
# Looks like a bug in FuncRef, probably but not needed, because it call other functions
|
||||
"call_func",
|
||||
|
||||
# Too dangerous, because add, mix and remove randomly nodes and objects
|
||||
"replace_by",
|
||||
"create_instance",
|
||||
@ -149,13 +130,12 @@ var function_exceptions : Array = [
|
||||
"add_sibling",
|
||||
]
|
||||
|
||||
# Globally disabled classes which causes bugs or are very hard to us
|
||||
var disabled_classes : Array = [
|
||||
"ProjectSettings", # Don't mess with project settings, because they can broke entire your workflow
|
||||
"EditorSettings", # Also don't mess with editor settings
|
||||
"_OS", # This may sometimes crash compositor, but it should be tested manually sometimes
|
||||
"GDScript", # Broke script
|
||||
|
||||
# Globally disabled classes which causes bugs or are very hard to use properly
|
||||
var disabled_classes: Array = [
|
||||
"ProjectSettings", # Don't mess with project settings, because they can broke entire your workflow
|
||||
"EditorSettings", # Also don't mess with editor settings
|
||||
"_OS", # This may sometimes crash compositor, but it should be tested manually sometimes
|
||||
"GDScript", # Broke scripts
|
||||
# This classes have problems with static/non static methods
|
||||
"PhysicsDirectSpaceState",
|
||||
"Physics2DDirectSpaceState",
|
||||
@ -170,54 +150,79 @@ var disabled_classes : Array = [
|
||||
"NavigationAgent2D",
|
||||
"NavigationAgent",
|
||||
|
||||
# Only one class - JavaClass returns Null when using JavaClass.new().get_class
|
||||
# Only one class - JavaClass returns Null when using JavaClass.new().get_class()
|
||||
"JavaClass",
|
||||
|
||||
# Just don't use these because they are not normal things
|
||||
# Just don't use these because they are not normal things
|
||||
"_Thread",
|
||||
"_Semaphore",
|
||||
"_Mutex",
|
||||
]
|
||||
|
||||
|
||||
# Checks if function can be executed
|
||||
# Looks at its arguments an
|
||||
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
|
||||
if method_data["flags"] == method_data["flags"] | METHOD_FLAG_VIRTUAL:
|
||||
return false
|
||||
if method_data["flags"] == method_data["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
|
||||
|
||||
|
||||
for arg in method_data["args"]:
|
||||
var name_of_class : String = arg["class_name"]
|
||||
var name_of_class: String = arg["class_name"]
|
||||
if name_of_class.empty():
|
||||
continue
|
||||
if name_of_class in disabled_classes:
|
||||
return false
|
||||
if name_of_class.find("Server") != -1 && ClassDB.class_exists(name_of_class) && !ClassDB.is_parent_class(name_of_class,"Reference"):
|
||||
|
||||
if !ClassDB.class_exists(name_of_class):
|
||||
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, "Reference"):
|
||||
return false
|
||||
|
||||
if name_of_class.find("Editor") != -1 || name_of_class.find("SkinReference") != -1:
|
||||
return false
|
||||
|
||||
|
||||
# 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
|
||||
var t : int = arg["type"]
|
||||
if !(t == TYPE_NIL || 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_INT_ARRAY || t == TYPE_NODE_PATH || t == TYPE_OBJECT || t == TYPE_PLANE || t == TYPE_QUAT || t == TYPE_RAW_ARRAY || t == TYPE_REAL || t == TYPE_REAL_ARRAY || t == TYPE_RECT2 || t == TYPE_RID || t == TYPE_STRING || t == TYPE_TRANSFORM || t == TYPE_TRANSFORM2D || t == TYPE_VECTOR2 || t == TYPE_VECTOR2_ARRAY || t == TYPE_VECTOR3 || t == TYPE_VECTOR3_ARRAY):
|
||||
print("----------------------------------------------------------- TODO - MISSING TYPE, ADD SUPPORT IT") # Add assert here to get info which type is missing
|
||||
var t: int = arg["type"]
|
||||
if !(
|
||||
t == TYPE_NIL
|
||||
|| 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_INT_ARRAY
|
||||
|| t == TYPE_NODE_PATH
|
||||
|| t == TYPE_OBJECT
|
||||
|| t == TYPE_PLANE
|
||||
|| t == TYPE_QUAT
|
||||
|| t == TYPE_RAW_ARRAY
|
||||
|| t == TYPE_REAL
|
||||
|| t == TYPE_REAL_ARRAY
|
||||
|| t == TYPE_RECT2
|
||||
|| t == TYPE_RID
|
||||
|| t == TYPE_STRING
|
||||
|| t == TYPE_TRANSFORM
|
||||
|| t == TYPE_TRANSFORM2D
|
||||
|| t == TYPE_VECTOR2
|
||||
|| t == TYPE_VECTOR2_ARRAY
|
||||
|| t == TYPE_VECTOR3
|
||||
|| t == TYPE_VECTOR3_ARRAY
|
||||
):
|
||||
print("----------------------------------------------------------- TODO - MISSING TYPE, ADD SUPPORT IT") # Add assert here to get info which type is missing
|
||||
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
|
||||
|
||||
func remove_disabled_methods(method_list : Array, exceptions : Array) -> void:
|
||||
|
||||
# Removes disabled methods from classes
|
||||
func remove_disabled_methods(method_list: Array, exceptions: Array) -> void:
|
||||
for exception in exceptions:
|
||||
var index: int = -1
|
||||
for method_index in range(method_list.size()):
|
||||
@ -227,35 +232,30 @@ func remove_disabled_methods(method_list : Array, exceptions : Array) -> void:
|
||||
if index != -1:
|
||||
method_list.remove(index)
|
||||
|
||||
|
||||
# Return all available classes which can be used
|
||||
func get_list_of_available_classes(must_be_instantable : bool = true) -> Array:
|
||||
var full_class_list : Array = Array(ClassDB.get_class_list())
|
||||
var classes : Array = []
|
||||
func get_list_of_available_classes(must_be_instantable: bool = true) -> Array:
|
||||
var full_class_list: Array = Array(ClassDB.get_class_list())
|
||||
var classes: Array = []
|
||||
full_class_list.sort()
|
||||
var c = 0
|
||||
# var rr = 0
|
||||
for name_of_class in full_class_list:
|
||||
# rr += 1
|
||||
if name_of_class in disabled_classes:
|
||||
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
|
||||
if regression_test_project:
|
||||
if !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "Reference"):
|
||||
continue
|
||||
if !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "Reference"):
|
||||
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 && !ClassDB.is_parent_class(name_of_class,"Reference"):
|
||||
continue
|
||||
if name_of_class.find("Editor") != -1 && regression_test_project:
|
||||
continue
|
||||
|
||||
|
||||
if !must_be_instantable || ClassDB.can_instance(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.")
|
||||
return classes
|
||||
|
@ -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)
|
||||
### - print info if needed to console
|
||||
### - execute function with parameters
|
||||
### - removes all objects/nodes to prevent memory leak
|
||||
|
||||
var debug_print: bool = true
|
||||
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:
|
||||
if BasicData.regression_test_project:
|
||||
ValueCreator.random = false # Results in RegressionTestProject must be always reproducible
|
||||
else:
|
||||
ValueCreator.random = true
|
||||
|
||||
ValueCreator.number = 100
|
||||
ValueCreator.should_be_always_valid = false
|
||||
|
||||
if BasicData.regression_test_project:
|
||||
tests_all_functions()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if !BasicData.regression_test_project:
|
||||
tests_all_functions()
|
||||
if exiting:
|
||||
get_tree().quit()
|
||||
tests_all_functions()
|
||||
|
||||
|
||||
# Test all functions
|
||||
@ -39,7 +26,7 @@ func tests_all_functions() -> void:
|
||||
for name_of_class in BasicData.get_list_of_available_classes():
|
||||
if debug_print:
|
||||
print("\n#################### " + name_of_class + " ####################")
|
||||
|
||||
|
||||
var object: Object = ClassDB.instance(name_of_class)
|
||||
assert(object != null, "Object must be instantable")
|
||||
if add_to_tree:
|
||||
@ -50,50 +37,49 @@ func tests_all_functions() -> void:
|
||||
# Removes excluded methods
|
||||
BasicData.remove_disabled_methods(method_list, BasicData.function_exceptions)
|
||||
|
||||
for _i in range(1):
|
||||
for method_data in method_list:
|
||||
if !BasicData.check_if_is_allowed(method_data):
|
||||
continue
|
||||
for method_data in method_list:
|
||||
if !BasicData.check_if_is_allowed(method_data):
|
||||
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:
|
||||
var to_print: String = "GDSCRIPT CODE: "
|
||||
if (
|
||||
ClassDB.is_parent_class(name_of_class, "Object")
|
||||
&& !ClassDB.is_parent_class(name_of_class, "Node")
|
||||
&& !ClassDB.is_parent_class(name_of_class, "Reference")
|
||||
&& !ClassDB.class_has_method(name_of_class, "new")
|
||||
):
|
||||
to_print += "ClassDB.instance(\"" + name_of_class + "\")." + method_data["name"] + "("
|
||||
else:
|
||||
to_print += name_of_class.trim_prefix("_") + ".new()." + method_data["name"] + "("
|
||||
if debug_print:
|
||||
var to_print: String = "GDSCRIPT CODE: "
|
||||
if (
|
||||
ClassDB.is_parent_class(name_of_class, "Object")
|
||||
&& !ClassDB.is_parent_class(name_of_class, "Node")
|
||||
&& !ClassDB.is_parent_class(name_of_class, "Reference")
|
||||
&& !ClassDB.class_has_method(name_of_class, "new")
|
||||
):
|
||||
to_print += 'ClassDB.instance("' + name_of_class + '").' + method_data["name"] + "("
|
||||
else:
|
||||
to_print += name_of_class.trim_prefix("_") + ".new()." + method_data["name"] + "("
|
||||
|
||||
for i in arguments.size():
|
||||
to_print += ParseArgumentType.return_gdscript_code_which_run_this_object(arguments[i])
|
||||
if i != arguments.size() - 1:
|
||||
to_print += ", "
|
||||
to_print += ")"
|
||||
print(to_print)
|
||||
for i in arguments.size():
|
||||
to_print += ParseArgumentType.return_gdscript_code_which_run_this_object(arguments[i])
|
||||
if i != arguments.size() - 1:
|
||||
to_print += ", "
|
||||
to_print += ")"
|
||||
print(to_print)
|
||||
|
||||
object.callv(method_data["name"], arguments)
|
||||
object.callv(method_data["name"], arguments)
|
||||
|
||||
for argument in arguments:
|
||||
if argument is Node:
|
||||
argument.queue_free()
|
||||
elif argument is Object && !(argument is Reference):
|
||||
argument.free()
|
||||
for argument in arguments:
|
||||
if argument is Node:
|
||||
argument.queue_free()
|
||||
elif argument is Object && !(argument is Reference):
|
||||
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 Reference):
|
||||
object.free()
|
||||
|
||||
object = ClassDB.instance(name_of_class)
|
||||
if add_to_tree:
|
||||
if object is Node:
|
||||
object.queue_free()
|
||||
elif object is Object && !(object is Reference):
|
||||
object.free()
|
||||
|
||||
object = ClassDB.instance(name_of_class)
|
||||
if add_to_tree:
|
||||
if object is Node:
|
||||
add_child(object)
|
||||
add_child(object)
|
||||
|
||||
if object is Node:
|
||||
object.queue_free()
|
||||
|
@ -1,124 +1,5 @@
|
||||
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 create_gdscript_arguments(arguments: Array) -> Array:
|
||||
var argument_array: Array = []
|
||||
|
||||
var counter = 0
|
||||
for argument in arguments:
|
||||
counter += 1
|
||||
var sa: SingleArgument = SingleArgument.new()
|
||||
sa.name = "variable" + str(counter)
|
||||
match argument["type"]:
|
||||
TYPE_NIL: # Looks that this means VARIANT not null
|
||||
sa.type = "Variant"
|
||||
sa.value = "false"
|
||||
TYPE_AABB:
|
||||
sa.type = "AABB"
|
||||
sa.value = ValueCreator.get_aabb_string()
|
||||
TYPE_ARRAY:
|
||||
sa.type = "Array"
|
||||
sa.value = "[]"
|
||||
TYPE_BASIS:
|
||||
sa.type = "Basis"
|
||||
sa.value = ValueCreator.get_basis_string()
|
||||
TYPE_BOOL:
|
||||
sa.type = "bool"
|
||||
sa.value = ValueCreator.get_bool_string().to_lower()
|
||||
TYPE_COLOR:
|
||||
sa.type = "Color"
|
||||
sa.value = ValueCreator.get_color_string()
|
||||
TYPE_COLOR_ARRAY:
|
||||
sa.type = "PoolColorArray"
|
||||
sa.value = "PoolColorArray([])"
|
||||
TYPE_DICTIONARY:
|
||||
sa.type = "Dictionary"
|
||||
sa.value = "{}" # TODO Why not all use ValueCreator?
|
||||
TYPE_INT:
|
||||
sa.type = "int"
|
||||
sa.value = ValueCreator.get_int_string()
|
||||
TYPE_INT_ARRAY:
|
||||
sa.type = "PoolIntArray"
|
||||
sa.value = "PoolIntArray([])"
|
||||
TYPE_NODE_PATH:
|
||||
sa.type = "NodePath"
|
||||
sa.value = "NodePath(\".\")"
|
||||
TYPE_OBJECT:
|
||||
sa.type = ValueCreator.get_object_string(argument["class_name"])
|
||||
sa.value = sa.type + ".new()"
|
||||
|
||||
sa.is_object = true
|
||||
if ClassDB.is_parent_class(sa.type, "Node"):
|
||||
sa.is_only_node = true
|
||||
elif ClassDB.is_parent_class(sa.type, "Reference"):
|
||||
sa.is_only_reference = true
|
||||
else:
|
||||
sa.is_only_object = true
|
||||
|
||||
TYPE_PLANE:
|
||||
sa.type = "Plane"
|
||||
sa.value = ValueCreator.get_plane_string()
|
||||
TYPE_QUAT:
|
||||
sa.type = "Quat"
|
||||
sa.value = ValueCreator.get_quat_string()
|
||||
TYPE_RAW_ARRAY:
|
||||
sa.type = "PoolByteArray"
|
||||
sa.value = "PoolByteArray([])"
|
||||
TYPE_REAL:
|
||||
sa.type = "float"
|
||||
sa.value = ValueCreator.get_float_string()
|
||||
TYPE_REAL_ARRAY:
|
||||
sa.type = "PoolRealArray"
|
||||
sa.value = "PoolRealArray([])"
|
||||
TYPE_RECT2:
|
||||
sa.type = "Rect2"
|
||||
sa.value = ValueCreator.get_rect2_string()
|
||||
TYPE_RID:
|
||||
sa.type = "RID"
|
||||
sa.value = "RID()"
|
||||
TYPE_STRING:
|
||||
sa.type = "String"
|
||||
sa.value = ValueCreator.get_string_string()
|
||||
TYPE_STRING_ARRAY:
|
||||
sa.type = "PoolStringArray"
|
||||
sa.value = "PoolStringArray([])"
|
||||
TYPE_TRANSFORM:
|
||||
sa.type = "Transform"
|
||||
sa.value = ValueCreator.get_transform_string()
|
||||
TYPE_TRANSFORM2D:
|
||||
sa.type = "Transform2D"
|
||||
sa.value = ValueCreator.get_transform2D_string()
|
||||
TYPE_VECTOR2:
|
||||
sa.type = "Vector2"
|
||||
sa.value = ValueCreator.get_vector2_string()
|
||||
TYPE_VECTOR2_ARRAY:
|
||||
sa.type = "PoolVector2Array"
|
||||
sa.value = "PoolVector2Array([])"
|
||||
TYPE_VECTOR3:
|
||||
sa.type = "Vector3"
|
||||
sa.value = ValueCreator.get_vector3_string()
|
||||
TYPE_VECTOR3_ARRAY:
|
||||
sa.type = "PoolVector3Array"
|
||||
sa.value = "PoolVector3Array([])"
|
||||
_:
|
||||
assert(false, "Missing type, needs to be added to project")
|
||||
argument_array.append(sa)
|
||||
|
||||
return argument_array
|
||||
|
||||
|
||||
func parse_and_return_objects(method_data: Dictionary, name_of_class: String, debug_print: bool = false) -> Array:
|
||||
var arguments_array: Array = []
|
||||
@ -126,21 +7,7 @@ func parse_and_return_objects(method_data: Dictionary, name_of_class: String, de
|
||||
for argument in method_data["args"]:
|
||||
match argument.type:
|
||||
TYPE_NIL: # Looks that this means VARIANT not null
|
||||
if ValueCreator.random == false:
|
||||
arguments_array.push_back(false)
|
||||
else:
|
||||
if randi() % 3:
|
||||
arguments_array.push_back(ValueCreator.get_array())
|
||||
elif randi() % 3:
|
||||
arguments_array.push_back(ValueCreator.get_object("Object"))
|
||||
elif randi() % 3:
|
||||
arguments_array.push_back(ValueCreator.get_dictionary())
|
||||
elif randi() % 3:
|
||||
arguments_array.push_back(ValueCreator.get_string())
|
||||
elif randi() % 3:
|
||||
arguments_array.push_back(ValueCreator.get_int())
|
||||
else:
|
||||
arguments_array.push_back(ValueCreator.get_basis())
|
||||
arguments_array.push_back(false)
|
||||
TYPE_AABB:
|
||||
arguments_array.push_back(ValueCreator.get_aabb())
|
||||
TYPE_ARRAY:
|
||||
@ -162,13 +29,9 @@ func parse_and_return_objects(method_data: Dictionary, name_of_class: String, de
|
||||
TYPE_NODE_PATH:
|
||||
arguments_array.push_back(ValueCreator.get_nodepath())
|
||||
TYPE_OBJECT:
|
||||
if ValueCreator.random && randi() % 2:
|
||||
arguments_array.push_back(null)
|
||||
else:
|
||||
var obj: Object = ValueCreator.get_object(argument["class_name"])
|
||||
arguments_array.push_back(obj)
|
||||
assert(obj != null, "Failed to create an object of type " + argument["class_name"])
|
||||
|
||||
var obj: Object = ValueCreator.get_object(argument["class_name"])
|
||||
arguments_array.push_back(obj)
|
||||
assert(obj != null, "Failed to create an object of type " + argument["class_name"])
|
||||
TYPE_PLANE:
|
||||
arguments_array.push_back(ValueCreator.get_plane())
|
||||
TYPE_QUAT:
|
||||
@ -292,7 +155,7 @@ func return_gdscript_code_which_run_this_object(data) -> String:
|
||||
&& !ClassDB.is_parent_class(name_of_class, "Reference")
|
||||
&& !ClassDB.class_has_method(name_of_class, "new")
|
||||
):
|
||||
return_string += "ClassDB.instance(\"" + name_of_class + "\")"
|
||||
return_string += 'ClassDB.instance("' + name_of_class + '")'
|
||||
else:
|
||||
return_string = name_of_class.trim_prefix("_")
|
||||
return_string += ".new()"
|
||||
@ -342,7 +205,7 @@ func return_gdscript_code_which_run_this_object(data) -> String:
|
||||
TYPE_RID:
|
||||
return_string = "RID()"
|
||||
TYPE_STRING:
|
||||
return_string = "\"" + data + "\""
|
||||
return_string = '"' + data + '"'
|
||||
TYPE_STRING_ARRAY:
|
||||
return_string = "PoolStringArray(["
|
||||
for i in data.size():
|
||||
|
@ -3,9 +3,6 @@ extends Node
|
||||
# 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 max_array_size: int = 15
|
||||
|
||||
|
||||
@ -14,246 +11,87 @@ func _ready() -> void:
|
||||
|
||||
|
||||
func get_int() -> int:
|
||||
if random:
|
||||
if int(number) == 0:
|
||||
return 0
|
||||
return (randi() % int(number)) - int(number / 2.0)
|
||||
else:
|
||||
return int(number)
|
||||
return int(number)
|
||||
|
||||
|
||||
func get_int_string() -> String:
|
||||
if random:
|
||||
if int(number) == 0:
|
||||
return "0"
|
||||
return "(randi() % int(number)) - int(number / 2.0)".replace("number", str(number))
|
||||
else:
|
||||
return str(int(number))
|
||||
return str(int(number))
|
||||
|
||||
|
||||
func get_float() -> float:
|
||||
if random:
|
||||
return (randf() * number) - (number / 2.0)
|
||||
else:
|
||||
return number
|
||||
return number
|
||||
|
||||
|
||||
func get_float_string() -> String:
|
||||
if random:
|
||||
return "(randf() * number) - (number / 2.0)".replace("number", str(number))
|
||||
else:
|
||||
return str(number)
|
||||
return str(number)
|
||||
|
||||
|
||||
func get_bool() -> bool:
|
||||
if random:
|
||||
if number < 2:
|
||||
return bool()
|
||||
return bool(randi() % 2)
|
||||
else:
|
||||
return bool()
|
||||
return bool()
|
||||
|
||||
|
||||
func get_bool_string() -> String:
|
||||
if random:
|
||||
if number < 2:
|
||||
return str(bool())
|
||||
return "bool(randi() % 2)"
|
||||
else:
|
||||
return str(bool())
|
||||
return str(bool())
|
||||
|
||||
|
||||
func get_vector2() -> Vector2:
|
||||
if random:
|
||||
if randi() % 2:
|
||||
return Vector2(get_float(), get_float()).normalized()
|
||||
return Vector2(get_float(), get_float())
|
||||
|
||||
|
||||
func get_vector2_string() -> String:
|
||||
if random:
|
||||
if randi() % 2:
|
||||
return "Vector2(" + get_float_string() + ", " + get_float_string() + ").normalized()"
|
||||
return "Vector2(" + get_float_string() + ", " + get_float_string() + ")"
|
||||
|
||||
|
||||
func get_vector2_string_csharp() -> String:
|
||||
if random:
|
||||
if randi() % 2:
|
||||
return "new Vector2(" + get_float_string() + ", " + get_float_string() + ").Normalized()"
|
||||
return "new Vector2(" + get_float_string() + ", " + get_float_string() + ")"
|
||||
|
||||
|
||||
func get_vector3() -> Vector3:
|
||||
if random:
|
||||
if randi() % 2:
|
||||
return Vector3(get_float(), get_float(), get_float()).normalized()
|
||||
return Vector3(get_float(), get_float(), get_float())
|
||||
|
||||
|
||||
func get_vector3_string() -> String:
|
||||
if random:
|
||||
if randi() % 2:
|
||||
return "Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ").normalized()"
|
||||
return "Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
|
||||
|
||||
|
||||
func get_vector3_string_csharp() -> String:
|
||||
if random:
|
||||
if randi() % 2:
|
||||
return "new Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ").Normalized()"
|
||||
return "new Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
|
||||
|
||||
|
||||
func get_aabb() -> AABB:
|
||||
return AABB(get_vector3(), get_vector3())
|
||||
|
||||
|
||||
func get_aabb_string() -> String:
|
||||
return "AABB(" + get_vector3_string() + ", " + get_vector3_string() + ")"
|
||||
|
||||
|
||||
func get_aabb_string_csharp() -> String:
|
||||
return "new AABB(" + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ")"
|
||||
|
||||
|
||||
func get_transform() -> Transform:
|
||||
return Transform(get_vector3(), get_vector3(), get_vector3(), get_vector3())
|
||||
|
||||
|
||||
func get_transform_string() -> String:
|
||||
return "Transform(" + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ")"
|
||||
|
||||
|
||||
func get_transform_string_csharp() -> String:
|
||||
return "new Transform(" + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ", " + get_vector3_string() + ")"
|
||||
|
||||
|
||||
func get_transform2D() -> Transform2D:
|
||||
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_transform2D_string_csharp() -> String:
|
||||
return "new Transform2D(" + get_vector2_string_csharp() + ", " + get_vector2_string_csharp() + ", " + get_vector2_string_csharp() + ")"
|
||||
|
||||
|
||||
func get_plane() -> Plane:
|
||||
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_plane_string_csharp() -> String:
|
||||
return "new Plane(" + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ")"
|
||||
|
||||
|
||||
func get_quat() -> Quat:
|
||||
return Quat(get_vector3())
|
||||
|
||||
|
||||
func get_quat_string() -> String:
|
||||
return "Quat(" + get_vector3_string() + ")"
|
||||
|
||||
|
||||
func get_quat_string_csharp() -> String:
|
||||
return "new Quat(" + get_vector3_string_csharp() + ")"
|
||||
|
||||
|
||||
func get_basis() -> Basis:
|
||||
return Basis(get_vector3())
|
||||
|
||||
|
||||
func get_basis_string() -> String:
|
||||
return "Basis(" + get_vector3_string() + ")"
|
||||
|
||||
|
||||
func get_basis_string_csharp() -> String:
|
||||
return "new Basis(" + get_vector3_string_csharp() + ")"
|
||||
|
||||
|
||||
func get_rect2() -> Rect2:
|
||||
return Rect2(get_vector2(), get_vector2())
|
||||
|
||||
|
||||
func get_rect2_string() -> String:
|
||||
return "Rect2(" + get_vector2_string() + ", " + get_vector2_string() + ")"
|
||||
|
||||
|
||||
func get_rect2_string_csharp() -> String:
|
||||
return "new Rect2(" + get_vector2_string_csharp() + ", " + get_vector2_string_csharp() + ")"
|
||||
|
||||
|
||||
func get_color() -> Color:
|
||||
return Color(get_float(), get_float(), get_float())
|
||||
|
||||
|
||||
func get_color_string() -> String:
|
||||
return "Color(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
|
||||
|
||||
|
||||
func get_color_string_csharp() -> String:
|
||||
return "new Color(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
|
||||
|
||||
|
||||
# TODO
|
||||
func get_string() -> String:
|
||||
if random:
|
||||
if randi() % 2 == 0:
|
||||
return String(".")
|
||||
else:
|
||||
return str(randi())
|
||||
return String()
|
||||
|
||||
|
||||
func get_string_string() -> String:
|
||||
if random:
|
||||
if randi() % 3 == 0:
|
||||
return "\".\""
|
||||
elif randi() % 3 == 0:
|
||||
return "\"\""
|
||||
else:
|
||||
return "str(randi() / 100)"
|
||||
return "\"\""
|
||||
|
||||
|
||||
# TODO
|
||||
func get_nodepath() -> NodePath:
|
||||
return NodePath(get_string())
|
||||
|
||||
|
||||
# TODO
|
||||
func get_nodepath_string_csharp() -> String:
|
||||
return "new NodePath(\".\")"
|
||||
|
||||
|
||||
# TODO
|
||||
func get_array() -> Array:
|
||||
var array: Array = []
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
if random && randi() % 2:
|
||||
array.append(randi() % 100)
|
||||
else:
|
||||
array.append([])
|
||||
return Array([])
|
||||
|
||||
|
||||
func get_dictionary() -> Dictionary:
|
||||
if random:
|
||||
if randi() % 2:
|
||||
return Dictionary({"roman": 22, 22: 25, BoxShape.new(): BoxShape.new()})
|
||||
return Dictionary({})
|
||||
|
||||
|
||||
func get_pool_string_array() -> PoolStringArray:
|
||||
var array: Array = []
|
||||
if random && randi() % 2:
|
||||
return PoolStringArray(array)
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
array.append(get_string())
|
||||
return PoolStringArray(array)
|
||||
@ -261,8 +99,6 @@ func get_pool_string_array() -> PoolStringArray:
|
||||
|
||||
func get_pool_int_array() -> PoolIntArray:
|
||||
var array: Array = []
|
||||
if random && randi() % 2:
|
||||
return PoolIntArray(array)
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
array.append(get_int())
|
||||
return PoolIntArray(array)
|
||||
@ -270,8 +106,6 @@ func get_pool_int_array() -> PoolIntArray:
|
||||
|
||||
func get_pool_byte_array() -> PoolByteArray:
|
||||
var array: Array = []
|
||||
if random && randi() % 2:
|
||||
return PoolByteArray(array)
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
array.append(get_int())
|
||||
return PoolByteArray(array)
|
||||
@ -279,8 +113,6 @@ func get_pool_byte_array() -> PoolByteArray:
|
||||
|
||||
func get_pool_real_array() -> PoolRealArray:
|
||||
var array: Array = []
|
||||
if random && randi() % 2:
|
||||
return PoolRealArray(array)
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
array.append(get_float())
|
||||
return PoolRealArray(array)
|
||||
@ -288,8 +120,6 @@ func get_pool_real_array() -> PoolRealArray:
|
||||
|
||||
func get_pool_vector2_array() -> PoolVector2Array:
|
||||
var array: Array = []
|
||||
if random && randi() % 2:
|
||||
return PoolVector2Array(array)
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
array.append(get_vector2())
|
||||
return PoolVector2Array(array)
|
||||
@ -297,8 +127,6 @@ func get_pool_vector2_array() -> PoolVector2Array:
|
||||
|
||||
func get_pool_vector3_array() -> PoolVector3Array:
|
||||
var array: Array = []
|
||||
if random && randi() % 2:
|
||||
return PoolVector3Array(array)
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
array.append(get_vector3())
|
||||
return PoolVector3Array(array)
|
||||
@ -306,8 +134,6 @@ func get_pool_vector3_array() -> PoolVector3Array:
|
||||
|
||||
func get_pool_color_array() -> PoolColorArray:
|
||||
var array: Array = []
|
||||
if random && randi() % 2:
|
||||
return PoolColorArray(array)
|
||||
for _i in range(int(min(max_array_size, number))):
|
||||
array.append(get_color())
|
||||
return PoolColorArray(array)
|
||||
@ -315,144 +141,18 @@ func get_pool_color_array() -> PoolColorArray:
|
||||
|
||||
func get_object(object_name: String) -> Object:
|
||||
assert(ClassDB.class_exists(object_name), "Class " + object_name + " doesn't exists.")
|
||||
if object_name == "PhysicsDirectSpaceState" || object_name == "Physics2DDirectSpaceState":
|
||||
return BoxShape.new()
|
||||
# if object_name == "PhysicsDirectSpaceState" || object_name == "Physics2DDirectSpaceState":
|
||||
# return BoxShape.new()
|
||||
|
||||
var a = 0
|
||||
if random:
|
||||
var classes = ClassDB.get_inheriters_from_class("Node") + ClassDB.get_inheriters_from_class("Reference")
|
||||
|
||||
if object_name == "Object":
|
||||
while true:
|
||||
var choosen_class: String = classes[randi() % classes.size()]
|
||||
if (
|
||||
ClassDB.can_instance(choosen_class)
|
||||
&& (ClassDB.is_parent_class(choosen_class, "Node") || ClassDB.is_parent_class(choosen_class, "Reference"))
|
||||
&& !(choosen_class in BasicData.disabled_classes)
|
||||
):
|
||||
return ClassDB.instance(choosen_class)
|
||||
|
||||
if ClassDB.is_parent_class(object_name, "Node") || ClassDB.is_parent_class(object_name, "Reference"):
|
||||
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_instance(object_name) && object_name in BasicData.disabled_classes:
|
||||
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for " + object_name)
|
||||
|
||||
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 " + object_name)
|
||||
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
|
||||
if ClassDB.can_instance(choosen_class) && !(choosen_class in BasicData.disabled_classes):
|
||||
return ClassDB.instance(choosen_class)
|
||||
else:
|
||||
while true:
|
||||
a += 1
|
||||
if a > 50:
|
||||
assert(false, "Cannot find proper instantable child for " + object_name)
|
||||
var choosen_class: String = classes[randi() % classes.size()]
|
||||
if ClassDB.can_instance(choosen_class) && !ClassDB.is_parent_class(choosen_class, object_name) && !(choosen_class in BasicData.disabled_classes):
|
||||
return ClassDB.instance(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_instance(object_name) && object_name in BasicData.disabled_classes:
|
||||
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for " + object_name)
|
||||
|
||||
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 " + object_name)
|
||||
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
|
||||
if ClassDB.can_instance(choosen_class) && !(choosen_class in BasicData.disabled_classes):
|
||||
return ClassDB.instance(choosen_class)
|
||||
|
||||
if ClassDB.can_instance(object_name): # E.g. Texture is not instantable or shouldn't be, but LargeTexture is
|
||||
return ClassDB.instance(object_name)
|
||||
else:
|
||||
if ClassDB.can_instance(object_name): # E.g. Texture is not instantable or shouldn't be, but LargeTexture is
|
||||
return ClassDB.instance(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 " + object_name) # 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_instance(i) && (ClassDB.is_parent_class(i, "Node") || ClassDB.is_parent_class(i, "Reference")):
|
||||
return ClassDB.instance(i)
|
||||
assert(false, "Cannot find proper instantable child for " + object_name)
|
||||
|
||||
# Checking for children 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 " + object_name) # 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_instance(i) && (ClassDB.is_parent_class(i, "Node") || ClassDB.is_parent_class(i, "Reference")):
|
||||
return ClassDB.instance(i)
|
||||
assert(false, "Cannot find proper instantable child for " + object_name)
|
||||
return BoxShape.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")
|
||||
|
||||
if object_name == "Object":
|
||||
while true:
|
||||
var choosen_class: String = classes[randi() % classes.size()]
|
||||
if ClassDB.can_instance(choosen_class) && (ClassDB.is_parent_class(choosen_class, "Node") || ClassDB.is_parent_class(choosen_class, "Reference")):
|
||||
return choosen_class
|
||||
|
||||
if ClassDB.is_parent_class(object_name, "Node") || ClassDB.is_parent_class(object_name, "Reference"):
|
||||
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_instance(object_name):
|
||||
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for " + object_name)
|
||||
|
||||
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 " + object_name)
|
||||
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
|
||||
if ClassDB.can_instance(choosen_class):
|
||||
return choosen_class
|
||||
else:
|
||||
while true:
|
||||
a += 1
|
||||
if a > 30:
|
||||
assert(false, "Cannot find proper instantable child for " + object_name)
|
||||
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_instance(object_name) && object_name in BasicData.disabled_classes:
|
||||
assert(to_use_classes.size() > 0, "Cannot find proper instantable child for " + object_name)
|
||||
|
||||
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 " + object_name)
|
||||
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
|
||||
if ClassDB.can_instance(choosen_class) && !(choosen_class in BasicData.disabled_classes):
|
||||
return choosen_class
|
||||
|
||||
else:
|
||||
if ClassDB.can_instance(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 " + object_name) # 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_instance(i) && (ClassDB.is_parent_class(i, "Node") || ClassDB.is_parent_class(i, "Reference")):
|
||||
return i
|
||||
assert(false, "Cannot find proper instantable child for " + object_name)
|
||||
|
||||
assert(false, "Cannot find proper instantable child for " + object_name)
|
||||
return "BoxMesh"
|
||||
|
@ -1,30 +1,32 @@
|
||||
extends Node2D
|
||||
|
||||
var available_classes : Array = []
|
||||
var exeptions : Array = ["SceneTree", "EditorSettings", "ProjectSettings"]
|
||||
var available_classes: Array = []
|
||||
var exeptions: Array = ["SceneTree", "EditorSettings", "ProjectSettings"]
|
||||
|
||||
|
||||
func _ready():
|
||||
var cl : Array = Array(ClassDB.get_class_list())
|
||||
var cl: Array = Array(ClassDB.get_class_list())
|
||||
cl.sort()
|
||||
for name_of_class in cl:
|
||||
if !ClassDB.can_instance(name_of_class):
|
||||
continue
|
||||
if name_of_class in exeptions:
|
||||
continue
|
||||
if name_of_class.to_lower().find("server") != -1:
|
||||
continue
|
||||
|
||||
print("########### " + name_of_class)
|
||||
print("GDSCRIPT CODE: var thing = ClassDB.instance(\"" + name_of_class + "\")")
|
||||
print("GDSCRIPT CODE: str(" + name_of_class + ")")
|
||||
|
||||
var thing = ClassDB.instance(name_of_class)
|
||||
str(thing)
|
||||
|
||||
if thing is Node:
|
||||
print("GDSCRIPT CODE: thing.queue_free()")
|
||||
thing.queue_free()
|
||||
elif thing is Object && !(thing is Reference):
|
||||
print("GDSCRIPT CODE: thing.free()")
|
||||
thing.free()
|
||||
|
||||
# Repeat 3 times, to be sure that code don't crash in unreleated function
|
||||
for _i in range(3):
|
||||
if !ClassDB.can_instance(name_of_class):
|
||||
continue
|
||||
if name_of_class in exeptions:
|
||||
continue
|
||||
if name_of_class.to_lower().find("server") != -1:
|
||||
continue
|
||||
|
||||
print("########### " + name_of_class)
|
||||
print('GDSCRIPT CODE: var thing = ClassDB.instance("' + name_of_class + '")')
|
||||
print("GDSCRIPT CODE: str(" + name_of_class + ")")
|
||||
|
||||
var thing = ClassDB.instance(name_of_class)
|
||||
str(thing)
|
||||
|
||||
if thing is Node:
|
||||
print("GDSCRIPT CODE: thing.queue_free()")
|
||||
thing.queue_free()
|
||||
elif thing is Object && !(thing is Reference):
|
||||
print("GDSCRIPT CODE: thing.free()")
|
||||
thing.free()
|
||||
|
@ -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/'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@ func collect() -> void:
|
||||
var to_print: String = "DEBUG: List of classes used in Nodes scene:\n"
|
||||
to_print += "DEBUG: ["
|
||||
for index in range(classes.size()):
|
||||
to_print += "\"" + classes[index] + "\""
|
||||
to_print += '"' + classes[index] + '"'
|
||||
if index != classes.size() - 1:
|
||||
to_print += ", "
|
||||
print(to_print)
|
||||
|
@ -1,5 +1,6 @@
|
||||
extends RigidBody
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
add_force(Vector3(0,4 * delta ,0),Vector3(0,0,0))
|
||||
add_force(Vector3(0, 4 * delta, 0), Vector3(0, 0, 0))
|
||||
pass
|
||||
|
17
README.md
17
README.md
@ -1,7 +1,7 @@
|
||||
# Godot regression test project
|
||||
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
|
||||
This project contains a few different scenes and `Start.tscn`(default one) which opens every other scene.
|
||||
@ -116,25 +116,18 @@ It is used to catch early very obvious and easy to reproduce bugs.
|
||||
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.
|
||||
|
||||
## 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
|
||||
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)
|
||||
|
||||
## 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(mostly Vulkan fault).
|
||||
Some patches are applied to e.g. handle rename `OS` -> `Platform` or `Transform` -> `Transform3D`
|
||||
|
||||
## 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.
|
||||
|
||||
## 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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@ extends Node
|
||||
|
||||
# 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
|
||||
|
||||
## Algorithm
|
||||
# - Add multiple nodes to scene
|
||||
@ -45,7 +46,7 @@ func collect() -> void:
|
||||
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] + "\""
|
||||
to_print += '"' + classes[index] + '"'
|
||||
if index != classes.size() - 1:
|
||||
to_print += ", "
|
||||
print(to_print)
|
||||
|
Loading…
Reference in New Issue
Block a user