Files
game-cards/addons/gut/scratch/get_info.gd
2026-05-29 09:16:10 +08:00

546 lines
17 KiB
GDScript

# ##############################################################################
# This is a script I used to poke around script and method properties. It's
# not supposed to be a "real" tool but it has a lot of examples in it and has
# come in handy numerous times.
#
# Feel free to use whatever you find in here for your own purposes.
# ##############################################################################
extends SceneTree
const DOUBLE_ME_PATH = 'res://test/resources/doubler_test_objects/double_me.gd'
var DoubleMe = load(DOUBLE_ME_PATH)
var DoubleMeScene = load('res://test/resources/doubler_test_objects/double_me_scene.tscn')
var SetGetTestNode = load('res://test/resources/test_assert_setget_test_objects/test_node.gd')
# const INNER_CLASSES_PATH = 'res://test/resources/doubler_test_objects/inner_classes.gd'
# var InnerClasses = load(INNER_CLASSES_PATH)
var json = JSON.new()
var _strutils = load('res://addons/gut/strutils.gd').new()
const DEFAULT_ARGS = 'default_args'
const NAME = 'name'
const ARGS = 'args'
var PROPERTY_USAGES = {
'PROPERTY_USAGE_NONE' : PROPERTY_USAGE_NONE,
'PROPERTY_USAGE_STORAGE' : PROPERTY_USAGE_STORAGE,
'PROPERTY_USAGE_EDITOR' : PROPERTY_USAGE_EDITOR,
'PROPERTY_USAGE_INTERNAL' : PROPERTY_USAGE_INTERNAL,
'PROPERTY_USAGE_CHECKABLE' : PROPERTY_USAGE_CHECKABLE,
'PROPERTY_USAGE_CHECKED' : PROPERTY_USAGE_CHECKED,
'PROPERTY_USAGE_GROUP' : PROPERTY_USAGE_GROUP,
'PROPERTY_USAGE_CATEGORY' : PROPERTY_USAGE_CATEGORY,
'PROPERTY_USAGE_SUBGROUP' : PROPERTY_USAGE_SUBGROUP,
'PROPERTY_USAGE_CLASS_IS_BITFIELD' : PROPERTY_USAGE_CLASS_IS_BITFIELD,
'PROPERTY_USAGE_NO_INSTANCE_STATE' : PROPERTY_USAGE_NO_INSTANCE_STATE,
'PROPERTY_USAGE_RESTART_IF_CHANGED' : PROPERTY_USAGE_RESTART_IF_CHANGED,
'PROPERTY_USAGE_SCRIPT_VARIABLE' : PROPERTY_USAGE_SCRIPT_VARIABLE,
'PROPERTY_USAGE_STORE_IF_NULL' : PROPERTY_USAGE_STORE_IF_NULL,
'PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED' : PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED,
'PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE' : PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE,
'PROPERTY_USAGE_CLASS_IS_ENUM' : PROPERTY_USAGE_CLASS_IS_ENUM,
'PROPERTY_USAGE_NIL_IS_VARIANT' : PROPERTY_USAGE_NIL_IS_VARIANT,
'PROPERTY_USAGE_ARRAY' : PROPERTY_USAGE_ARRAY,
'PROPERTY_USAGE_ALWAYS_DUPLICATE' : PROPERTY_USAGE_ALWAYS_DUPLICATE,
'PROPERTY_USAGE_NEVER_DUPLICATE' : PROPERTY_USAGE_NEVER_DUPLICATE,
'PROPERTY_USAGE_HIGH_END_GFX' : PROPERTY_USAGE_HIGH_END_GFX,
'PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT' : PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT,
'PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT' : PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT,
'PROPERTY_USAGE_KEYING_INCREMENTS' : PROPERTY_USAGE_KEYING_INCREMENTS,
'PROPERTY_USAGE_DEFERRED_SET_RESOURCE' : PROPERTY_USAGE_DEFERRED_SET_RESOURCE,
'PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT' : PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT,
'PROPERTY_USAGE_EDITOR_BASIC_SETTING' : PROPERTY_USAGE_EDITOR_BASIC_SETTING,
'PROPERTY_USAGE_READ_ONLY' : PROPERTY_USAGE_READ_ONLY,
'PROPERTY_USAGE_SECRET' : PROPERTY_USAGE_SECRET,
'PROPERTY_USAGE_DEFAULT' : PROPERTY_USAGE_DEFAULT,
'PROPERTY_USAGE_NO_EDITOR' : PROPERTY_USAGE_NO_EDITOR,
}
class HasSomeInners:
signal look_at_me_now
const WHATEVER = 'maaaaaan'
class Inner1:
extends 'res://addons/gut/test.gd'
var a = 'b'
class Inner2:
var b = 'a'
class Inner2_a:
extends 'res://addons/gut/test.gd'
class Inner2_b:
var foo = 'bar'
class Inner3:
extends GutInternalTester
class ExtendsInner1:
extends Inner1
class ExtendsNode2D:
extends Node2D
static var static_foo := "static foo"
static func a_static_func():
return true
var local_foo := "local foo"
func my_function(some_string : String, defaulted_node : Node = null):
return 7
func get_position():
return Vector2(0, 0)
func _input(event):
print(event)
class SimpleObject:
var a = 'a'
class ExtendsAnInnerClassElsewhere:
extends 'res://test/resources/doubler_test_objects/inner_classes.gd'.InnerB
func foobar():
return 'foobar'
func get_methods_by_flag(obj):
var methods_by_flags = {}
var methods = obj.get_method_list()
for i in range(methods.size()):
var flag = methods[i]['flags']
var name = methods[i]['name']
if(methods_by_flags.has(flag)):
methods_by_flags[flag].append(name)
else:
methods_by_flags[flag] = [name]
return methods_by_flags
func print_methods_by_flags(methods_by_flags):
for flag in methods_by_flags:
for i in range(methods_by_flags[flag].size()):
print(flag, ": ", methods_by_flags[flag][i])
var total = 0
for flag in methods_by_flags:
if(methods_by_flags[flag].size() > 0):
print("-- ", flag, " (", methods_by_flags[flag].size(), ") --")
total += methods_by_flags[flag].size()
print("Total: ", total)
func print_methods_with_defaults(thing):
print('------------------------------------------------------------------')
print('--- Methods (object) ---')
print('------------------------------------------------------------------')
var methods = thing.get_method_list()
for m in methods:
if(m.default_args.size() > 0):
print(m.name)
pp(m, ' ')
print('------------------------------------------------------------------')
print('--- Methods (script) ---')
print('------------------------------------------------------------------')
methods = thing.get_script_method_list()
for m in methods:
print(m.name)
pp(m, ' ')
func print_methods_with_flags(obj, flags, print_all = true):
var methods = obj.get_method_list()
for i in range(methods.size()):
var mflags = methods[i]['flags']
if(is_flagged(mflags, flags)):
print(methods[i]['name'], ':', mflags)
print_method_flags(mflags, print_all)
func print_methods_named(obj, name):
var methods = obj.get_method_list()
for i in range(methods.size()):
if(methods[i]['name'] == name):
print(methods[i]['name'], ':')
print_method_flags(methods[i]['flags'], false)
func subtract_dictionary(sub_this, from_this):
var result = {}
for key in sub_this:
if(from_this.has(key)):
result[key] = []
for value in from_this[key]:
var index = sub_this[key].find(value)
if(index == -1):
result[key].append(value)
return result
func is_flagged(mask, index):
return mask & index != 0
func print_flag(name, flags, flag, print_all=true):
var is_set = is_flagged(flags, flag)
if(print_all or is_set):
print(name,'(', flag, ') = ', is_set)
func print_method_flags(flags, print_all=true):
print_flag(' normal', flags, METHOD_FLAG_NORMAL, print_all)
print_flag(' editor', flags, METHOD_FLAG_EDITOR, print_all)
print_flag(' const', flags, METHOD_FLAG_CONST, print_all)
print_flag(' virtual', flags, METHOD_FLAG_VIRTUAL, print_all)
print_flag(' vararg', flags, METHOD_FLAG_VARARG, print_all)
print_flag(' static', flags, METHOD_FLAG_STATIC, print_all)
print_flag(' core', flags, METHOD_FLAG_OBJECT_CORE, print_all)
print_flag(' default', flags, METHOD_FLAGS_DEFAULT, print_all)
func print_method_info(obj):
var methods = obj.get_method_list()
for i in range(methods.size()):
print(methods[i]['name'], ' ', methods[i]['flags'])
# if(methods[i]['default_args'].size() > 0):
# print(" *** here be defaults ***")
print_method_flags(methods[i]['flags'], false)
# if(methods[i]['flags'] == 65):
# for key in methods[i]:
# if(key == 'args'):
# print(' args:')
# for argname in range(methods[i][key].size()):
# print(' ', methods[i][key][argname]['name'], ': ', methods[i][key][argname])
# else:
# print(' ', key, ': ', methods[i][key])
func get_defaults_and_types(method_meta):
var text = ""
text += method_meta[NAME] + "\n"
for i in range(method_meta[DEFAULT_ARGS].size()):
var arg_index = method_meta[ARGS].size() - (method_meta[DEFAULT_ARGS].size() - i)
text += str(' ', method_meta[ARGS][arg_index][NAME])
text += str('(type=', method_meta[ARGS][arg_index]['type'], ")")
text += str(' = ', method_meta[DEFAULT_ARGS][i], "\n")
# text += str(' ', method_meta[ARGS][arg_index]['usage'], "\n")
return text
func class_db_stuff():
print(ClassDB.class_exists('Node2D'))
# print('category = ', ClassDB.('Node2D'))
# print(str(JSON.print(ClassDB.class_get_method_list('Node2D'), ' ')))
# print(ClassDB.class_get_integer_constant_list('Node2D'))
print(ClassDB.get_class_list())
func does_inherit_from_test(thing):
var base_script = thing.get_base_script()
var to_return = false
print(' *base_script = ', base_script)
if(base_script != null):
var base_path = base_script.get_path()
print(' *base_path = ', base_path)
if(base_path == 'res://addons/gut/test.gd'):
to_return = true
else:
to_return = does_inherit_from_test(base_script)
return to_return
func print_other_info(loaded, msg = '', indent=''):
print(indent, '--------------------- ', msg, ' ---------------------')
print(indent, loaded)
var base_script_path = 'NO base script'
if(loaded.has_method('get_base_script')):
if(loaded.get_base_script() != null):
base_script_path = str('"', loaded.get_base_script().get_path(), '"')
else:
base_script_path = 'Null base script'
print(indent, 'base_script path ', base_script_path)
print(indent, 'class ', loaded.get_class())
print(indent, 'instance base type ', loaded.get_instance_base_type())
print(indent, 'instance_id ', loaded.get_instance_id())
print(indent, 'meta_list ', loaded.get_meta_list())
print(indent, 'name ', loaded.get_name())
print(indent, 'path ', loaded.get_path())
print(indent, 'resource local to scene ', loaded.resource_local_to_scene)
print(indent, 'resource name ', loaded.resource_name)
print(indent, 'resource path ', loaded.resource_path)
print(indent, 'RID ', loaded.get_rid())
print(indent, 'script ', loaded.get_script())
print()
print(loaded.get_script_property_list())
print_properties(loaded.get_property_list(), loaded)
var const_map = loaded.new().get_script().get_script_constant_map()
# if(const_map.size() > 0):
print(indent, '--- Constants ---')
for key in const_map:
var thing = const_map[key]
print(indent, key, ' = ', thing)
if(typeof(thing) == TYPE_OBJECT):
print_other_info(thing, key, indent + ' ')
# print(' ', 'meta ', thing.get_meta_list())
# print(' ', 'class ', thing.get_class())
# print(' ', 'path ', thing.get_path())
# var base_script = thing.get_base_script()
# print(' ', 'base script ', base_script)
# if(base_script != null):
# print(' ', 'base id ', base_script.get_instance_id())
# print(' ', 'base path ', base_script.get_path() )
# print(' ', 'base type ', thing.get_instance_base_type())
# print(' ', 'can instantiate ', thing.can_instantiate())
# print(' ', 'id ', thing.get_instance_id())
# print(' ', 'is test ', does_inherit_from_test(thing))
func print_inner_test_classes(loaded, from=null):
# print('path = ', loaded.get_path())
# if(loaded.get_base_script() != null):
# print('base = ', loaded.get_base_script().get_path())
# else:
# print('base = ')
var const_map = loaded.get_script_constant_map()
for key in const_map:
var thing = const_map[key]
if(typeof(thing) == TYPE_OBJECT):
print('Class ', key, ':')
if(does_inherit_from_test(thing)):
print(' is a test class')
else:
print(' noooooooooope')
var next_from
if(from == null):
next_from = key
else:
next_from = str(from, '/', key)
print_inner_test_classes(thing, next_from)
else:
print('CONST ', key, ' = ', thing)
func print_script_methods():
var script = load('res://tests_4_0/test_print.gd')
var methods = script.get_script_method_list()
for i in range(methods.size()):
print(methods[i]['name'])
pp(methods[i])
func print_methods(methods, print_all_meta = false):
var methods_by_name = {}
var method_names = []
for method in methods:
methods_by_name[method.name] = method
method_names.append(method.name)
method_names.sort()
for m_name in method_names:
print(m_name)
if(print_all_meta):
pp(methods_by_name[m_name], ' ')
func print_properties(props, thing, print_all_meta=false):
for i in range(props.size()):
var prop_name = props[i].name
var prop_value = thing.get(props[i].name)
var print_value = str(prop_value)
if(print_value.length() > 100):
print_value = print_value.substr(0, 97) + '...'
elif(print_value == ''):
print_value = 'EMPTY'
print(prop_name, ' = ', print_value)
if(print_all_meta):
print(' ', props[i])
print_property_usage(props[i])
func print_property_usage(prop):
for key in PROPERTY_USAGES:
var flag = PROPERTY_USAGES[key]
if(prop.usage & flag):
print('- ', key, ' ', flag)
func print_script_info(thing):
print('path = ', thing.get_path())
print('--- Methods (script) ---')
print_methods(thing.get_script_method_list(), true)
print('--- Properties (script) ---')
var props = thing.get_script_property_list()
print_properties(props, thing, true)
print('--- Constants ---')
pp(thing.get_script_constant_map())
print('--- Signals ---')
var sigs = thing.get_signal_list()
for sig in sigs:
print(sig['name'])
print(' ', sig)
func print_all_info(thing):
print('path = ', thing.get_path())
print('--- Methods (object) ---')
print_methods(thing.get_method_list(), true)
print('--- Methods (script) ---')
print_methods(thing.get_script_method_list(), true)
print('--- Properties (object) ---')
var props = thing.get_property_list()
print_properties(props, thing)
print('--- Properties (script) ---')
props = thing.get_script_property_list()
print_properties(props, thing, true)
print('--- Constants ---')
print_inner_test_classes(thing)
print('--- Signals ---')
var sigs = thing.get_signal_list()
for sig in sigs:
print(sig['name'])
print(' ', sig)
func print_class_db_class_list():
var list = ClassDB.get_class_list()
list.sort()
print("\n".join(list))
func pp(dict, indent=''):
var text = json.stringify(dict, ' ')
text = _strutils.indent_text(text, 1, indent)
print(text)
func has_script_method(Class):
var methods = Class.get_script_method_list()
func print_inner_classes(loaded, parent=''):
var const_map = loaded.get_script_constant_map()
for key in const_map:
var thing = const_map[key]
if(typeof(thing) == TYPE_OBJECT):
print(parent, key, ': ', thing)
print_inner_classes(thing, key + '.')
func print_inner_class_path(loaded):
pass
func print_scene_info(scene):
pp(scene._bundled)
var state = scene.get_state()
print('state = ', state)
print('nodes = ', state.get_node_count())
for i in range(state.get_node_count()):
print(i, '. ', state.get_node_name(i))
print(' type ', state.get_node_type(i))
print(' node index ', state.get_node_index(i))
print(' #props ', state.get_node_property_count(i))
print(' is placehodler ', state.is_node_instance_placeholder(i))
print(' node path ', state.get_node_path(i))
print(' groups ', state.get_node_groups(i))
print(" properties:")
for j in range(state.get_node_property_count(i)):
var n = state.get_node_property_name(i, j)
var v = state.get_node_property_value(i, j)
print(' - ', n, ' = ', v)
func get_scene_script_object(scene):
return GutUtils.get_scene_script_object(scene)
func _init():
# var TestScene = load('res://test/resources/Issue436Scene.tscn')
# print_scene_info(TestScene)
# var inst = TestScene.instantiate()
# print_all_info(inst.get_script())
print_script_info(ExtendsNode2D)
# print_methods_with_flags(ExtendsNode2D.new(), METHOD_FLAG_VARARG, false)
# print_methods_with_flags(ExtendsNode2D.new(), METHOD_FLAG_OBJECT_CORE, false)
# print_methods_named(ExtendsNode2D.new(), '_input')
# print_methods_named(ExtendsNode2D.new(), '_notification')
# print_methods_named(ExtendsNode2D.new(), '_to_string')
# print_methods_named(ExtendsNode2D.new(), 'get_script')
# print_methods_named(ExtendsNode2D.new(), 'has_method')
# print_methods_named(ExtendsNode2D.new(), 'print_orphan_nodes')
# pp(Button.new().get_method_list())
# print_other_info(GutDoubleTestInnerClasses)
# print("---------------\n\n\n\n-------------------")
# print_other_info(GutDoubleTestInnerClasses.InnerA)
# class_db_stuff()
# print_all_info(DoubleMeScene)
# var TestScene = load('res://test/resources/doubler_test_objects/double_me_scene.tscn')
# print_scene_info(TestScene)
# print(get_scene_script_object(TestScene))
# var ThatInnerClassScript = load('res://test/resources/doubler_test_objects/inner_classes.gd')
# print_other_info(HasSomeInners, 'HasSomeInners')
# print_other_info(HasSomeInners.Inner2.Inner2_a, 'Inner2_a')
# print_inner_classes(ThatInnerClassScript)
# print_other_info(ThatInnerClassScript, 'ThatInnerClassScript')
# print_other_info(ThatInnerClassScript.AnotherInnerA, 'AnotherInnerA')
# print_all_info(ThatInnerClassScript.AnotherInnerA)
# print_all_info(ExtendsAnInnerClassElsewhere)
# print_all_info(DoubleMe)
# print_class_db_class_list()
# print_all_info(GutTest)
# var WithDefaults = load('res://test/resources/doubler_test_objects/double_default_parameters.gd')
# print_methods_with_defaults(WithDefaults)
# print_other_info(GutTest)
# print_all_info(SetGetTestNode)
# print(SetGetTestNode.has_method('has_setter_setter'))
# var inst = SetGetTestNode.new()
# print(inst.has_method('has_setter_setter'))
# print(inst.has_method('@has_setter_setter'))
# print(inst.has_method('@has_getter_getter'))
quit()