-
Notifications
You must be signed in to change notification settings - Fork 60
/
resource_collection.gd
128 lines (92 loc) · 3.17 KB
/
resource_collection.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
tool
class_name ResourceCollection
extends Resource
# author: xdgamestudios
# license: MIT
# description:
# An abstract base class for data structures that store Resource objects.
# Uses a key-value store, but can also append items.
const SETUP_PREFIX = "setup/"
const DATA_PREFIX = "data/"
const EMPTY_ENTRY = "[ Empty ]"
var _type: Script = null
var _type_readonly: bool = false
var _class_type: ClassType = ClassType.new()
func clear() -> void:
assert(false)
func get_base_type() -> Script:
return _type
func set_base_type(p_type: Script) -> void:
if _type == p_type:
return
_type = p_type
property_list_changed_notify()
func is_type_readonly() -> bool:
return _type_readonly
func set_type_readonly(read_only: bool) -> void:
if _type_readonly == read_only:
return
_type_readonly = read_only
property_list_changed_notify()
func _get(p_property: String):
match p_property.trim_prefix(SETUP_PREFIX):
"base_type":
return _type
return null
func _set(p_property: String, p_value) -> bool:
match p_property.trim_prefix(SETUP_PREFIX):
"base_type":
if _type != p_value:
_type = p_value
property_list_changed_notify()
return true
return false
func _get_property_list() -> Array:
var list := []
list += _export_setup_group()
if not _type:
return list
list += _export_data_group()
return list
# Append an element to the collection.
#warning-ignore:unused_argument
func _add_element(p_script: Script) -> void:
assert(false)
# Refresh the data upon type change.
func _refresh_data() -> void:
assert(false)
# Export properties within the 'data' group.
func _export_data_group() -> Array:
return [ PropertyInfoFactory.new_editor_only(DATA_PREFIX + "dropdown").to_dict() ]
# Export properties within the 'setup' group.
func _export_setup_group() -> Array:
return [ PropertyInfoFactory.new_resource(SETUP_PREFIX + "base_type", "Script").to_dict() ] if not _type_readonly else []
# Injects controls to the EditorInspectorPlugin.
func _parse_property(p_plugin: EditorInspectorPlugin, p_pinfo: PropertyInfo) -> bool:
match p_pinfo.name.trim_prefix(DATA_PREFIX):
"dropdown":
var elements = _find_inheritors()
var control = InspectorControls.new_dropdown_appender(elements, self, "_on_dropdown_selector_selected")
p_plugin.add_custom_control(control)
return true
return false
func _instantiate_script(p_script: Script) -> Resource:
var res: Resource = null
if ClassDB.is_parent_class(p_script.get_instance_base_type(), "Resource"):
push_warning("Must assign non-Script Resource instances. Auto-instantiating the given Resource script.")
res = p_script.new()
else:
push_error("Must assign non-Script Resource instances. Fallback error: cannot auto-instantiate non-Resource scripts into ResourceCollection.")
return res
func _find_inheritors() -> Dictionary:
_class_type.res = _type
var list = _class_type.get_deep_inheritors_list()
var type_map = _class_type.get_deep_type_map()
var inheritors = { }
for a_name in list:
inheritors[a_name] = load(type_map[a_name].path)
return inheritors
func _on_dropdown_selector_selected(dropdown_selector):
var script = dropdown_selector.get_selected_meta()
_add_element(script)
property_list_changed_notify()