From 94048a0c8f442c144889cd30d880ca3064bcd1b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= <41945903+qarmin@users.noreply.github.com> Date: Tue, 18 May 2021 06:56:35 +0200 Subject: [PATCH] Implement better printing about executing nodes (#49) --- AutomaticBugs/BasicData.gd | 110 ++++--- AutomaticBugs/FunctionExecutor.gd | 61 ++-- AutomaticBugs/ParseArgumentType.gd | 452 ++++++++++++++++++----------- AutomaticBugs/ValueCreator.gd | 195 ++++++++----- Start.gd | 23 +- 5 files changed, 501 insertions(+), 340 deletions(-) diff --git a/AutomaticBugs/BasicData.gd b/AutomaticBugs/BasicData.gd index 6a046ed..7a5d620 100644 --- a/AutomaticBugs/BasicData.gd +++ b/AutomaticBugs/BasicData.gd @@ -2,11 +2,11 @@ extends Node var regression_test_project : bool = true # Set it to true in RegressionTestProject -# Contains info about disabled classes -# Also allows to get list of available classes +### Contains info about disabled classes and allows to take info about allowed methods +# Globablly disabled functions for all classes var function_exceptions : Array = [ - #GODOT 4.0 + # GODOT 4.0 "create_from_image", "set_point_position", "connect", # OTHER THINGS @@ -31,21 +31,21 @@ var function_exceptions : Array = [ "set_texture", "_activate", "add_node", #GH 46012 + "set_peering_bit_terrain", #GH 48799 + "get_peering_bit_terrain", - - "_set_user_data", "get_packet", # TODO - "create_from_mesh", + "_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 - "connect_to_signal", # GH 47572 - "set_config_file", # GH 45997 - "class_get_property", # GH 47573 - "class_set_property", # GH 47573 + #"connect_to_signal", # GH 47572 "_editor_settings_changed",# GH 45979 "_submenu_timeout", # GH 45981 - "_gui_input", # GH 45998 - "_unhandled_key_input", # GH 45998 "_thread_done", #GH 46000 "generate", #GH 46001 "_proximity_group_broadcast", #GH 46002 @@ -53,13 +53,10 @@ var function_exceptions : Array = [ "create_from", #GH 46004 "create_from_blend_shape", #GH 46004 "append_from", #GH 46004 - "_unhandled_input", # TODO - "_input", # TODO "_set_tile_data", #GH 46015 "get", #GH 46019 "instance_has", #GH 46020 "get_var", #GH 46096 - "force_drag", #GH 46114 "set_script", #GH 46120 "getvar", #GH 46019 "get_available_chars", #GH 46118 @@ -69,22 +66,16 @@ var function_exceptions : Array = [ "set_editor_hint", #GH 46252 "get_item_at_position", #TODO hard to find "set_probe_data", #GH 46570 - "_range_click_timeout", - "draw", #GH 46648 + "_range_click_timeout", #GH 46648 "get_indexed", #GH 46019 - "_vp_input", # TODO - "_vp_unhandled_input", # TODO - "remove_joy_mapping", #GH 46754 - "add_joy_mapping", #GH 46754 "add_vertex", #GH 47066 "create_client", # TODO, strange memory leak "create_shape_owner", #47135 "shape_owner_get_owner", #47135 - "collide", #GH 46137 - "collide_and_get_contacts", #GH 46137 - "collide_with_motion", #GH 46137 - "collide_with_motion_and_get_contacts", #GH 46137 + "get_bind_bone", #GH 47358 + "get_bind_name", #GH 47358 + "get_bind_pose", #GH 47358 # TODO Check this later "propagate_notification", @@ -186,13 +177,8 @@ var function_exceptions : Array = [ "add_child_below_node", "add_sibling", ] -var exported : Array = [ - "get_bind_bone", - "get_bind_name", - "get_bind_pose", -] -# Used only in ValueCreator +# 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 @@ -208,6 +194,7 @@ var disabled_classes : Array = [ "InputDefault", "IP_Unix", "JNISingleton", + "JavaClass", # Godot 4.0 Leaks, crashes etc. "World3D", @@ -217,11 +204,10 @@ var disabled_classes : Array = [ "Image", "GIProbe", - # Just don't use these because they are not normal things "_Thread", "_Semaphore", - "_Mutex", + "_Mutex", # Creating them is really slow in Godot 4.0 @@ -230,26 +216,14 @@ var disabled_classes : Array = [ "ColorPickerButton", "PhysicalSkyMaterial", "ProceduralSkyMaterial" - ] -# GH 47358 -func _init(): - function_exceptions.append_array(exported) - # Checks if function can be executed -# Looks at its arguments an func check_if_is_allowed(method_data : Dictionary) -> bool: - # Function is virtual, 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: return false - - # Function is vararg, so we just skip it - if method_data.get("flags") == method_data.get("flags") | 128: - return false - - # Function is static, so we just skip it - if method_data.get("flags") == method_data.get("flags") | 256: + if method_data.get("flags") == method_data.get("flags") | 128: # VARARG TODO, Godot issue, add missing flag binding return false for arg in method_data.get("args"): @@ -260,34 +234,48 @@ func check_if_is_allowed(method_data : Dictionary) -> bool: return false if name_of_class.find("Server") != -1 && ClassDB.class_exists(name_of_class) && !ClassDB.is_parent_class(name_of_class,"Reference"): return false - if name_of_class.find("Editor") != -1: # TODO not sure about it + # Editor stuff usually aren't good choice for arhuments + 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 + # In case of adding new type, this prevents from crashing due not recognizing this type + var t : int = arg.get("type") + + 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_QUAT|| 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_TRANSFORM|| 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") 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 - - # In case of adding new type, this prevents from crashing due not recognizing this type - var t : int = arg.get("type") - if t == TYPE_CALLABLE: - return false - elif !(t == TYPE_NIL|| 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_QUAT|| 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_TRANSFORM|| 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") - return false - return true -# Return all available classes to instance and test +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()): + if method_list[method_index].get("name") == exception: + index = method_index + break + 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 = [] full_class_list.sort() var c = 0 - var rr = 0 +# var rr = 0 for name_of_class in full_class_list: - rr += 1 +# rr += 1 if name_of_class in disabled_classes: continue @@ -301,7 +289,7 @@ func get_list_of_available_classes(must_be_instantable : bool = true) -> Array: if name_of_class.find("Server") != -1 && !ClassDB.is_parent_class(name_of_class,"Reference"): continue - if name_of_class.find("Editor") != -1: # TODO not sure about it + if name_of_class.find("Editor") != -1 && regression_test_project: continue diff --git a/AutomaticBugs/FunctionExecutor.gd b/AutomaticBugs/FunctionExecutor.gd index 3233602..90d3e73 100644 --- a/AutomaticBugs/FunctionExecutor.gd +++ b/AutomaticBugs/FunctionExecutor.gd @@ -1,18 +1,32 @@ extends Node -# Execute every object function +### Script: +### - takes all available classes +### - checks if method is allowed +### - 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 var debug_print: bool = true var add_to_tree: bool = false # Adds nodes to tree, freeze godot when removing a lot of nodes var use_parent_methods: bool = false # Allows Node2D use Node methods etc. - it is a little slow option which rarely shows var use_always_new_object: bool = true # Don't allow to "remeber" other function effects -var exiting: bool = true +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() @@ -23,33 +37,45 @@ func _process(_delta: float) -> void: # Test all functions 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: if object is Node: add_child(object) var method_list: Array = ClassDB.class_get_method_list(name_of_class, !use_parent_methods) - ## Exception - for exception in BasicData.function_exceptions: - var index: int = -1 - for method_index in range(method_list.size()): - if method_list[method_index].get("name") == exception: - index = method_index - break - if index != -1: - method_list.remove(index) + # Removes excluded methods + BasicData.remove_disabled_methods(method_list, BasicData.function_exceptions) - if debug_print: - print("#################### " + name_of_class +" ####################") for _i in range(1): for method_data in method_list: if !BasicData.check_if_is_allowed(method_data): continue - if debug_print: - print(name_of_class + "." + method_data.get("name")) + 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.get("name") + "(" + else: + to_print += name_of_class.trim_prefix("_") + ".new()." + method_data.get("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) - var arguments: Array = ParseArgumentType.parse_and_return_objects(method_data, debug_print) object.callv(method_data.get("name"), arguments) for argument in arguments: @@ -59,7 +85,6 @@ func tests_all_functions() -> void: argument.free() if use_always_new_object: - assert(object != null, "Object must be instantable") if object is Node: object.queue_free() elif object is Object && !(object is Reference): diff --git a/AutomaticBugs/ParseArgumentType.gd b/AutomaticBugs/ParseArgumentType.gd index f26124c..5935e93 100644 --- a/AutomaticBugs/ParseArgumentType.gd +++ b/AutomaticBugs/ParseArgumentType.gd @@ -1,7 +1,9 @@ extends Node -# Parse arguments and return needed info/objects etc. +### 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 @@ -12,144 +14,12 @@ class SingleArgument: var is_only_node: bool = false # Needs to be removed with .queue_free() -func create_gdscript_arguments(arguments: Array) -> Array: - var argument_array: Array = [] - - ValueCreator.number = 10 - ValueCreator.random = true - ValueCreator.should_be_always_valid = true # DO NOT CHANGE, BECAUSE NON VALID VALUES WILL SHOW GDSCRIPT ERRORS! - - var counter = 0 - for argument in arguments: - var typ = argument.get("type") - counter += 1 - var sa: SingleArgument = SingleArgument.new() - sa.name = "variable" + str(counter) - if typ == TYPE_NIL: # Looks that this means VARIANT not null - sa.type = "Variant" - sa.value = "false" - elif typ ==TYPE_AABB: - sa.type = "AABB" - sa.value = ValueCreator.get_aabb_string() - elif typ ==TYPE_ARRAY: - sa.type = "Array" - sa.value = "[]" - elif typ ==TYPE_BASIS: - sa.type = "Basis" - sa.value = ValueCreator.get_basis_string() - elif typ ==TYPE_BOOL: - sa.type = "bool" - sa.value = ValueCreator.get_bool_string().to_lower() - elif typ ==TYPE_COLOR: - sa.type = "Color" - sa.value = ValueCreator.get_color_string() - elif typ ==TYPE_COLOR_ARRAY: - sa.type = "PackedColorArray" - sa.value = "PackedColorArray([])" - elif typ ==TYPE_DICTIONARY: - sa.type = "Dictionary" - sa.value = "{}" # TODO Why not all use ValueCreator? - elif typ ==TYPE_INT: - sa.type = "int" - sa.value = ValueCreator.get_int_string() - elif typ ==TYPE_INT32_ARRAY: - sa.type = "PackedInt32Array" - sa.value = "PackedInt32Array([])" - elif typ ==TYPE_INT64_ARRAY: - sa.type = "PackedInt64Array" - sa.value = "PackedInt64Array([])" - elif typ ==TYPE_NODE_PATH: - sa.type = "NodePath" - sa.value = "NodePath(\".\")" - elif typ ==TYPE_OBJECT: - sa.type = ValueCreator.get_object_string(argument.get("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 - elif typ ==TYPE_PLANE: - sa.type = "Plane" - sa.value = ValueCreator.get_plane_string() - elif typ ==TYPE_QUAT: - sa.type = "Quat" - sa.value = ValueCreator.get_quat_string() - elif typ ==TYPE_RAW_ARRAY: - sa.type = "PackedByteArray" - sa.value = "PackedByteArray([])" - elif typ ==TYPE_FLOAT: - sa.type = "float" - sa.value = ValueCreator.get_float_string() - elif typ ==TYPE_FLOAT32_ARRAY: - sa.type = "PackedFloat32Array" - sa.value = "PackedFloat32Array([])" - elif typ ==TYPE_FLOAT64_ARRAY: - sa.type = "PackedFloat64Array" - sa.value = "PackedFloat64Array([])" - elif typ ==TYPE_RECT2: - sa.type = "Rect2" - sa.value = ValueCreator.get_rect2_string() - elif typ ==TYPE_RID: - sa.type = "RID" - sa.value = "RID()" - elif typ ==TYPE_STRING: - sa.type = "String" - sa.value = ValueCreator.get_string_string() - elif typ ==TYPE_STRING_NAME: - sa.type = "StringName" - sa.value = StringName(ValueCreator.get_string_string()) - elif typ ==TYPE_STRING_ARRAY: - sa.type = "PackedStringArray" - sa.value = "PackedStringArray([])" - elif typ ==TYPE_TRANSFORM: - sa.type = "Transform" - sa.value = ValueCreator.get_transform_string() - elif typ ==TYPE_TRANSFORM2D: - sa.type = "Transform2D" - sa.value = ValueCreator.get_transform2D_string() - elif typ ==TYPE_VECTOR2: - sa.type = "Vector2" - sa.value = ValueCreator.get_vector2_string() - elif typ ==TYPE_VECTOR2_ARRAY: - sa.type = "PackedVector2Array" - sa.value = "PackedVector2Array([])" - elif typ ==TYPE_VECTOR2I: - sa.type = "Vector2i" - sa.value = ValueCreator.get_vector2i_string() - elif typ ==TYPE_VECTOR3: - sa.type = "Vector3" - sa.value = ValueCreator.get_vector3_string() - elif typ ==TYPE_VECTOR3_ARRAY: - sa.type = "PackedVector3Array" - sa.value = "PackedVector3Array([])" - elif typ ==TYPE_VECTOR3I: - sa.type = "Vector3i" - sa.value = ValueCreator.get_vector3i_string() - elif typ ==TYPE_RECT2I: - sa.type = "Rect2i" - sa.value = ValueCreator.get_rect2i_string() - elif typ ==TYPE_CALLABLE: - sa.type= "Callable" - sa.value = """Callable(BoxMesh.new(),StringName("a"))""" - else: - print("Missing " + str(argument) ) - assert(false) # Missed some types, add it - - argument_array.append(sa) - - return argument_array - - -func parse_and_return_objects(method_data: Dictionary, debug_print: bool = false) -> Array: - var arguments_array: Array = [] +func parse_and_return_objects(method_data: Dictionary, name_of_class: String, debug_print: bool = false) -> Array: + var arguments_array: Array = Array([]) if BasicData.regression_test_project: ValueCreator.number = 100 - ValueCreator.random = false # Results in RegressionTestProject must be always reproducible + ValueCreator.random = false # Results in RegressionTestProject must be always reproducible else: ValueCreator.number = 1000 ValueCreator.random = true @@ -157,80 +27,310 @@ func parse_and_return_objects(method_data: Dictionary, debug_print: bool = false for argument in method_data.get("args"): var type = argument.get("type") - if type == TYPE_NIL: # Looks that this means VARIANT not null - arguments_array.push_back(false) # TODO Add some randomization + if type == TYPE_NIL: # Looks that this means VARIANT not null + arguments_array.push_back(false) # TODO Add some randomization # assert(false) - elif type == TYPE_MAX: - assert(false) elif type == TYPE_AABB: - arguments_array.push_back(ValueCreator.get_aabb()) + arguments_array.push_back(ValueCreator.get_aabb()) elif type == TYPE_ARRAY: - arguments_array.push_back(ValueCreator.get_array()) + arguments_array.push_back(ValueCreator.get_array()) elif type == TYPE_BASIS: - arguments_array.push_back(ValueCreator.get_basis()) + arguments_array.push_back(ValueCreator.get_basis()) elif type == TYPE_BOOL: - arguments_array.push_back(ValueCreator.get_bool()) + arguments_array.push_back(ValueCreator.get_bool()) elif type == TYPE_COLOR: - arguments_array.push_back(ValueCreator.get_color()) + arguments_array.push_back(ValueCreator.get_color()) elif type == TYPE_COLOR_ARRAY: - arguments_array.push_back(PackedColorArray([])) + arguments_array.push_back(PackedColorArray([])) elif type == TYPE_DICTIONARY: - arguments_array.push_back(ValueCreator.get_dictionary()) + arguments_array.push_back(ValueCreator.get_dictionary()) elif type == TYPE_INT: - arguments_array.push_back(ValueCreator.get_int()) + arguments_array.push_back(ValueCreator.get_int()) elif type == TYPE_INT32_ARRAY: - arguments_array.push_back(PackedInt32Array([])) + arguments_array.push_back(PackedInt32Array([])) elif type == TYPE_INT64_ARRAY: - arguments_array.push_back(PackedInt64Array([])) + arguments_array.push_back(PackedInt64Array([])) elif type == TYPE_NODE_PATH: - arguments_array.push_back(ValueCreator.get_nodepath()) + arguments_array.push_back(ValueCreator.get_nodepath()) elif type == TYPE_OBJECT: - arguments_array.push_back(ValueCreator.get_object(argument.get("class_name"))) + arguments_array.push_back(ValueCreator.get_object(argument.get("class_name"))) elif type == TYPE_PLANE: - arguments_array.push_back(ValueCreator.get_plane()) + arguments_array.push_back(ValueCreator.get_plane()) elif type == TYPE_QUAT: - arguments_array.push_back(ValueCreator.get_quat()) + arguments_array.push_back(ValueCreator.get_quat()) elif type == TYPE_RAW_ARRAY: - arguments_array.push_back(PackedByteArray([])) + arguments_array.push_back(PackedByteArray([])) elif type == TYPE_FLOAT: - arguments_array.push_back(ValueCreator.get_float()) + arguments_array.push_back(ValueCreator.get_float()) elif type == TYPE_FLOAT32_ARRAY: - arguments_array.push_back(PackedFloat32Array([])) + arguments_array.push_back(PackedFloat32Array([])) elif type == TYPE_FLOAT64_ARRAY: - arguments_array.push_back(PackedFloat64Array([])) + arguments_array.push_back(PackedFloat64Array([])) elif type == TYPE_RECT2: - arguments_array.push_back(ValueCreator.get_rect2()) + arguments_array.push_back(ValueCreator.get_rect2()) elif type == TYPE_RECT2I: - arguments_array.push_back(ValueCreator.get_rect2i()) + arguments_array.push_back(ValueCreator.get_rect2i()) elif type == TYPE_RID: - arguments_array.push_back(RID()) + arguments_array.push_back(RID()) elif type == TYPE_STRING: - arguments_array.push_back(ValueCreator.get_string()) + arguments_array.push_back(ValueCreator.get_string()) elif type == TYPE_STRING_NAME: - arguments_array.push_back(StringName(ValueCreator.get_string())) + arguments_array.push_back(StringName(ValueCreator.get_string())) elif type == TYPE_STRING_ARRAY: - arguments_array.push_back(PackedStringArray([])) + arguments_array.push_back(PackedStringArray([])) elif type == TYPE_TRANSFORM: - arguments_array.push_back(ValueCreator.get_transform()) + arguments_array.push_back(ValueCreator.get_transform()) elif type == TYPE_TRANSFORM2D: - arguments_array.push_back(ValueCreator.get_transform2D()) + arguments_array.push_back(ValueCreator.get_transform2D()) elif type == TYPE_VECTOR2: - arguments_array.push_back(ValueCreator.get_vector2()) + arguments_array.push_back(ValueCreator.get_vector2()) elif type == TYPE_VECTOR2I: - arguments_array.push_back(ValueCreator.get_vector2i()) + arguments_array.push_back(ValueCreator.get_vector2i()) elif type == TYPE_VECTOR2_ARRAY: - arguments_array.push_back(PackedVector2Array([])) + arguments_array.push_back(PackedVector2Array([])) elif type == TYPE_VECTOR3: - arguments_array.push_back(ValueCreator.get_vector3()) + arguments_array.push_back(ValueCreator.get_vector3()) elif type == TYPE_VECTOR3I: - arguments_array.push_back(ValueCreator.get_vector3i()) + arguments_array.push_back(ValueCreator.get_vector3i()) elif type == TYPE_VECTOR3_ARRAY: - arguments_array.push_back(PackedVector3Array([])) - elif type== TYPE_CALLABLE: - arguments_array.push_back(Callable(BoxMesh.new(),"Rar")) + arguments_array.push_back(PackedVector3Array([])) + elif type == TYPE_CALLABLE: + arguments_array.push_back(Callable(BoxMesh.new(), "Rar")) else: - assert(false) # Missed some types, add it + assert(false) # Missed some types, add it +# assert(is_instance_valid(arguments_array) == true) if debug_print: - print("Parameters " + str(arguments_array)) + print("\n" + name_of_class + "." + method_data.get("name") + " --- executing with " + str(arguments_array.size()) + " parameters " + str(arguments_array)) return arguments_array + + +func return_gdscript_code_which_run_this_object(data) -> String: + var return_string: String = "" + + var type = typeof(data) + + if type == TYPE_NIL: # Looks that this means VARIANT not null + return_string = "null" + #assert("false", "This is even possible?") + elif type == TYPE_AABB: + return_string = "AABB(" + return_string += return_gdscript_code_which_run_this_object(data.position) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.size) + return_string += ")" + elif type == TYPE_ARRAY: + return_string = "Array([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_BASIS: + return_string = "Basis(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.z) + return_string += ")" + elif type == TYPE_BOOL: + if data == true: + return_string = "true" + else: + return_string = "false" + elif type == TYPE_COLOR: + return_string = "Color(" + return_string += return_gdscript_code_which_run_this_object(data.r) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.g) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.b) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.a) + return_string += ")" + elif type == TYPE_COLOR_ARRAY: + return_string = "PoolColorArray([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_DICTIONARY: + return_string = "{" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data.keys()[i]) + return_string += " : " + return_string += return_gdscript_code_which_run_this_object(data.values()[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "}" + elif type == TYPE_INT: + return_string = str(data) + elif type == TYPE_INT32_ARRAY: + return_string = "PoolInt32Array([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_INT64_ARRAY: + return_string = "PoolInt64Array([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_NODE_PATH: + return_string = "NodePath(" + return_string += return_gdscript_code_which_run_this_object(str(data)) + return_string += ")" + elif type == TYPE_OBJECT: + if data == null: + return_string = "null" + else: + var name_of_class: String = data.get_class() + 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") + ): + return_string += "ClassDB.instance(\"" + name_of_class + "\")" + else: + return_string = name_of_class.trim_prefix("_") + return_string += ".new()" + + elif type == TYPE_PLANE: + return_string = "Plane(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.z) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.d) + return_string += ")" + elif type == TYPE_QUAT: + return_string = "Quat(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.z) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.w) + return_string += ")" + elif type == TYPE_RAW_ARRAY: + return_string = "PoolByteArray([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_FLOAT: + return_string = str(data) + elif type == TYPE_FLOAT32_ARRAY: + return_string = "PoolFloat32Array([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_FLOAT64_ARRAY: + return_string = "PoolFloat64Array([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_RECT2: + return_string = "Rect2(" + return_string += return_gdscript_code_which_run_this_object(data.position) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.size) + return_string += ")" + elif type == TYPE_RECT2I: + return_string = "Rect2i(" + return_string += return_gdscript_code_which_run_this_object(data.position) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.size) + return_string += ")" + elif type == TYPE_RID: + return_string = "RID()" + elif type == TYPE_STRING: + return_string = "\"" + data + "\"" + elif type == TYPE_STRING_ARRAY: + return_string = "PackedStringArray([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_TRANSFORM: + return_string = "Transform(" + return_string += return_gdscript_code_which_run_this_object(data.basis) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.origin) + return_string += ")" + elif type == TYPE_TRANSFORM2D: + return_string = "Transform2D(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.origin) + return_string += ")" + elif type == TYPE_VECTOR2: + return_string = "Vector2(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ")" + elif type == TYPE_VECTOR2I: + return_string = "Vector2i(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ")" + elif type == TYPE_VECTOR2_ARRAY: + return_string = "PoolVector2Array([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_VECTOR3: + return_string = "Vector3(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.z) + return_string += ")" + elif type == TYPE_VECTOR3I: + return_string = "Vector3i(" + return_string += return_gdscript_code_which_run_this_object(data.x) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.y) + return_string += ", " + return_string += return_gdscript_code_which_run_this_object(data.z) + return_string += ")" + elif type == TYPE_STRING_NAME: + return_string = "StringName(" + return_string += return_gdscript_code_which_run_this_object(str(data)) + return_string += ")" + elif type == TYPE_VECTOR3_ARRAY: + return_string = "PoolVector3Array([" + for i in data.size(): + return_string += return_gdscript_code_which_run_this_object(data[i]) + if i != data.size() - 1: + return_string += ", " + return_string += "])" + elif type == TYPE_CALLABLE: + return_string = "Callable(BoxMesh.new(),\"\")" + else: + print(type) + assert(false, "Missing type, needs to be added to project") + + return return_string diff --git a/AutomaticBugs/ValueCreator.gd b/AutomaticBugs/ValueCreator.gd index 38a65d0..cf953c7 100644 --- a/AutomaticBugs/ValueCreator.gd +++ b/AutomaticBugs/ValueCreator.gd @@ -7,6 +7,7 @@ var should_be_always_valid: bool = true # Generate only valid values e.g. to No var max_array_size: int = 15 + func _ready() -> void: randomize() @@ -18,27 +19,31 @@ func get_int() -> int: return (randi() % int(number)) - int(number / 2.0) else: 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)) + return "(randi() % int(number)) - int(number / 2.0)".replace("number", str(number)) else: return str(int(number)) + func get_float() -> float: if random: return (randf() * number) - (number / 2.0) else: return number - + + func get_float_string() -> String: if random: return "(randf() * number) - (number / 2.0)".replace("number", str(number)) else: return str(number) + func get_bool() -> bool: if random: if number < 2: @@ -46,7 +51,8 @@ func get_bool() -> bool: return bool(randi() % 2) else: return bool() - + + func get_bool_string() -> String: if random: if number < 2: @@ -55,84 +61,110 @@ func get_bool_string() -> String: else: return str(bool()) + func get_vector2() -> Vector2: return Vector2(get_float(), get_float()) - + + func get_vector2i() -> Vector2i: 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: - return Vector3(get_float(),get_float(),get_float()) - + return Vector3(get_float(), get_float(), get_float()) + + 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() + ")" - + 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: - 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_transform() -> Transform: - return Transform(get_vector3(),get_vector3(),get_vector3(),get_vector3()) - + 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_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() + ")" - + return "Transform2D(" + get_vector2_string() + ", " + get_vector2_string() + ", " + get_vector2_string() + ")" + 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() + ")" - + return "Plane(" + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ")" + + func get_quat() -> Quat: return Quat(get_vector3()) - + + func get_quat_string() -> String: return "Quat(" + get_vector3_string() + ")" - + + func get_basis() -> Basis: return Basis(get_vector3()) - + + func get_basis_string() -> String: return "Basis(" + get_vector3_string() + ")" - + + func get_rect2() -> Rect2: return Rect2(get_vector2(), get_vector2()) - + + func get_rect2i() -> Rect2i: return Rect2i(get_vector2i(), get_vector2i()) - + + func get_rect2_string() -> String: - return "Rect2(" + get_vector2_string() + ", " + get_vector2_string()+ ")" - + return "Rect2(" + get_vector2_string() + ", " + get_vector2_string() + ")" + + func get_rect2i_string() -> String: - return "Rect2i(" + get_vector2i_string() + ", " + get_vector2i_string()+ ")" - + return "Rect2i(" + get_vector2i_string() + ", " + get_vector2i_string() + ")" + + 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() + ")" + return "Color(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")" + # TODO func get_string() -> String: @@ -142,7 +174,8 @@ func get_string() -> String: else: return str(randi()) return String() - + + func get_string_string() -> String: if random: if randi() % 2 == 0: @@ -150,78 +183,92 @@ func get_string_string() -> String: else: return "\"randi())\"" return "\"\"" + + # TODO func get_nodepath() -> NodePath: return NodePath(get_string()) + + # TODO func get_array() -> Array: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append([]) return Array([]) + + # TODO func get_dictionary() -> Dictionary: return Dictionary({}) - - + + func get_Packed_string_array() -> PackedStringArray: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_string()) return PackedStringArray(array) - + + func get_Packed_int32_array() -> PackedInt32Array: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_int()) return PackedInt32Array(array) - + + func get_Packed_int64_array() -> PackedInt32Array: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_int()) return PackedInt32Array(array) - + + func get_Packed_byte_array() -> PackedByteArray: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_int()) return PackedByteArray(array) - + + func get_Packed_float32_array() -> PackedFloat32Array: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_float()) return PackedFloat32Array(array) - + + func get_Packed_float64_array() -> PackedFloat64Array: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_float()) return PackedFloat64Array(array) - + + func get_Packed_vector2_array() -> PackedVector2Array: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_vector2()) return PackedVector2Array(array) - + + func get_Packed_vector3_array() -> PackedVector3Array: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_vector3()) return PackedVector3Array(array) - + + func get_Packed_color_array() -> PackedColorArray: - var array : Array = [] - for _i in range(int(min(max_array_size,number))): + var array: Array = [] + for _i in range(int(min(max_array_size, number))): array.append(get_color()) return PackedColorArray(array) func get_object(object_name: String) -> Object: assert(ClassDB.class_exists(object_name), "Class doesn't exists.") - if object_name == "PhysicsDirectSpaceState3D" || object_name == "PhysicsDirectSpaceState2D" : + if object_name == "PhysicsDirectSpaceState3D" || object_name == "PhysicsDirectSpaceState2D": return BoxShape3D.new() var a = 0 diff --git a/Start.gd b/Start.gd index 27fc105..6e6b203 100644 --- a/Start.gd +++ b/Start.gd @@ -1,25 +1,26 @@ extends Control -var current_scene : int = -1 -var time_to_switch : int -const NUMBER_OF_INSTANCES : int = 1 # Use more than 1 to stress test, 1 should be optimal for casual CI +var current_scene: int = -1 +var time_to_switch: int +const NUMBER_OF_INSTANCES: int = 1 # Use more than 1 to stress test, 1 should be optimal for casual CI + +var array_with_time_to_change: Array = [] -var array_with_time_to_change : Array = [] func _ready(): for i in Autoload.alone_steps.size() + 1: array_with_time_to_change.append(Autoload.os.get_ticks_msec() + i * Autoload.time_for_each_step) + func _process(_delta): if current_scene < Autoload.alone_steps.size() - 1 && Autoload.os.get_ticks_msec() > array_with_time_to_change[current_scene + 1]: current_scene += 1 - + for child in get_children(): child.queue_free() - - print("Changed scene to " + Autoload.alone_steps[current_scene]) - - for _i in range(NUMBER_OF_INSTANCES): - var scene : Node = load(Autoload.alone_steps[current_scene]).instance() - add_child(scene) + print("Changed scene to " + Autoload.alone_steps[current_scene]) + + for _i in range(NUMBER_OF_INSTANCES): + var scene: Node = load(Autoload.alone_steps[current_scene]).instance() + add_child(scene)