261 lines
7.5 KiB
GDScript
261 lines
7.5 KiB
GDScript
extends Reference
|
|
|
|
class_name GDB_Entity
|
|
|
|
var _title := ""
|
|
var _title_property : Object = null
|
|
var _properties := [].duplicate()
|
|
var _property_ids := [].duplicate()
|
|
|
|
class _CommonWrapperProperty extends GDB_Property:
|
|
var object : WeakRef
|
|
func _init(object_ : Object, val, sig_name := "", flags := 0) -> void:
|
|
self.object = weakref(object_)
|
|
.set_type(typeof(val))
|
|
.set_value(val)
|
|
.set_flags(flags)
|
|
|
|
if sig_name != "":
|
|
object_.connect(sig_name, self, "_on_object_value_changed")
|
|
|
|
func _on_object_value_changed(p0 = null, p1 = null, p2 = null, p3 = null) -> void:
|
|
var obj : Object = self.object.get_ref()
|
|
if obj: # shouldn't actually be null, who called the handler then?
|
|
_value = obj.get(self.member)
|
|
emit_signal("value_changed")
|
|
|
|
class _WrapperProperty extends _CommonWrapperProperty:
|
|
var member : String
|
|
|
|
func _init(object_ : Object, member_ : String, sig_name : String, flags : int) \
|
|
.(object_, object_.get(member), sig_name, flags) -> void:
|
|
self.member = member_
|
|
.set_name(member_.capitalize())
|
|
|
|
func get_value():
|
|
var obj : Object = self.object.get_ref()
|
|
if obj:
|
|
return obj.get(self.member)
|
|
return .get_value()
|
|
|
|
func set_value(value) -> void:
|
|
var obj : Object = self.object.get_ref()
|
|
if obj:
|
|
obj.set(self.member, value)
|
|
.set_value(obj.get(self.member))
|
|
else:
|
|
.set_value(value)
|
|
|
|
class _ArrayWrapperProperty extends _WrapperProperty:
|
|
func _init(object_ : Object, member_ : String, sig_name_added : String, sig_name_removed : String, flags : int) \
|
|
.(object_, member_, "", flags) -> void:
|
|
if sig_name_added != "":
|
|
object_.connect(sig_name_added, self, "_on_object_value_added")
|
|
if sig_name_removed != "":
|
|
object_.connect(sig_name_added, self, "_on_object_value_removed")
|
|
|
|
func _on_object_value_added(value, p0 = null, p1 = null, p2 = null, p3 = null) -> void:
|
|
var obj : Object = self.object.get_ref()
|
|
if obj:
|
|
_value = obj.get(self.member)
|
|
emit_signal("value_changed")
|
|
emit_signal("value_added", value)
|
|
|
|
func _on_object_value_removed(value, p0 = null, p1 = null, p2 = null, p3 = null) -> void:
|
|
var obj : Object = self.object.get_ref()
|
|
if obj:
|
|
_value = obj.get(self.member)
|
|
emit_signal("value_changed")
|
|
emit_signal("value_removed", value)
|
|
|
|
class _GetSetWrapperProperty extends _CommonWrapperProperty:
|
|
var getter := ""
|
|
var setter := ""
|
|
|
|
func _init(object_ : Object, getter_ : String, setter_ := "", sig_name := "", flags := 0) \
|
|
.(object_, object.call(getter_), sig_name, flags) -> void:
|
|
self.getter = getter_
|
|
self.setter = setter_
|
|
|
|
func get_value():
|
|
var obj : Object = self.object.get_ref()
|
|
if obj:
|
|
return obj.call(self.getter)
|
|
return .get_value()
|
|
|
|
func set_value(value) -> void:
|
|
if !self.setter:
|
|
return
|
|
var obj : Object = self.object.get_ref()
|
|
if obj:
|
|
obj.call(self.setter, value)
|
|
.set_value(obj.call(self.getter))
|
|
else:
|
|
.set_value(value)
|
|
|
|
################
|
|
# public stuff #
|
|
################
|
|
func get_title() -> String:
|
|
return _title
|
|
|
|
func set_title(title : String) -> void:
|
|
if _title_property:
|
|
# title and title_property are mutually exclusive
|
|
GDBUtility.disconnect_all(_title_property, self)
|
|
_title_property = null
|
|
|
|
__set_title(title)
|
|
|
|
func set_title_property(property : Object) -> void:
|
|
if property.get_type() != TYPE_STRING:
|
|
printerr("Title property must be string.")
|
|
return
|
|
|
|
if _title_property == property:
|
|
return
|
|
|
|
if _title_property:
|
|
GDBUtility.disconnect_all(_title_property, self)
|
|
|
|
_title_property = property
|
|
var new_title := ""
|
|
if _title_property:
|
|
new_title = _title_property.get_value()
|
|
GDBUtility.try_connect(_title_property, "value_changed", self, "_on_title_property_value_changed")
|
|
__set_title(new_title)
|
|
|
|
func get_properties() -> Array:
|
|
return _properties
|
|
|
|
func get_property_ids() -> Array:
|
|
return _property_ids
|
|
|
|
func get_property(index : int) -> Object:
|
|
if index < 0 || index >= _properties.size():
|
|
return null
|
|
return _properties[index]
|
|
|
|
func get_property_id(index : int) -> String:
|
|
if index < 0 || index >= _property_ids.size():
|
|
return ""
|
|
return _property_ids[index]
|
|
|
|
func get_property_by_id(id : String) -> Object:
|
|
return get_property(find_property_by_id(id))
|
|
|
|
func add_property(id : String, property : Object, index := -1) -> void:
|
|
if !GDB_Property.is_valid_property(property):
|
|
printerr("GDB_Entity: attempted to add invalid property.")
|
|
return
|
|
|
|
if find_property(property) >= 0:
|
|
return
|
|
|
|
if find_property_by_id(id) >= 0:
|
|
printerr("GDB_Entity: duplicate property id")
|
|
return
|
|
|
|
if index < 0:
|
|
index = _properties.size()
|
|
index = min(index, _properties.size())
|
|
_properties.insert(index, property)
|
|
_property_ids.insert(index, id)
|
|
emit_signal("property_added", index)
|
|
|
|
func remove_property(property : Object) -> bool:
|
|
var index := find_property(property)
|
|
if index < 0:
|
|
return false
|
|
|
|
_properties.remove(index)
|
|
_property_ids.remove(index)
|
|
emit_signal("property_removed", index, property)
|
|
return true
|
|
|
|
func remove_property_at(index : int) -> bool:
|
|
if index < 0 || index >= _properties.size():
|
|
return false
|
|
return remove_property(_properties[index])
|
|
|
|
func find_property(property : Object) -> int:
|
|
return _properties.find(property)
|
|
|
|
func find_property_by_id(id : String) -> int:
|
|
return _property_ids.find(id)
|
|
|
|
#################
|
|
# private stuff #
|
|
#################
|
|
func __set_title(title : String) -> void:
|
|
if title != _title:
|
|
_title = title
|
|
emit_signal("entity_title_changed")
|
|
|
|
################
|
|
# static stuff #
|
|
################
|
|
static func is_valid_entity(object : Object) -> bool:
|
|
return object != null \
|
|
&& object.has_method("get_properties")
|
|
|
|
static func make_property(object : Object, member : String, sig_name := "", flags := 0) -> GDB_Property:
|
|
return _WrapperProperty.new(object, member, sig_name, flags)
|
|
|
|
static func make_getset_property(object : Object, getter : String, setter := "", sig_name := "", flags := 0) -> GDB_Property:
|
|
return _GetSetWrapperProperty.new(object, getter, setter, sig_name, flags)
|
|
|
|
static func make_array_property(object : Object, member : String, sig_name_added := "", sig_name_removed := "", array_type := TYPE_NIL, flags := 0) -> GDB_Property:
|
|
var prop := _ArrayWrapperProperty.new(object, member, sig_name_added, sig_name_removed, flags)
|
|
prop.set_content_type(array_type)
|
|
return prop
|
|
|
|
static func make_entity_title_property(entity : Object) -> Object:
|
|
var property : Object
|
|
if entity.has_method("get_title_property"):
|
|
property = entity.get_title_property()
|
|
if property:
|
|
return property
|
|
if entity.get("title") is String:
|
|
var sig_name := ""
|
|
if entity.has_signal("title_changed"):
|
|
sig_name = "title_changed"
|
|
return make_property(entity, "title", sig_name)
|
|
if entity.has_method("get_title"):
|
|
var setter := ""
|
|
var sig_name := ""
|
|
var flags := 0
|
|
if entity.has_method("set_title"):
|
|
setter = "set_title"
|
|
else:
|
|
flags |= GDB_Property.FLAG_READONLY
|
|
if entity.has_signal("title_changed"):
|
|
sig_name = "title_changed"
|
|
return make_getset_property(entity, "get_title", setter, sig_name, flags)
|
|
return null
|
|
|
|
|
|
static func get_entity_property_ids(entity : Object) -> Array:
|
|
return __get_entity_optional(entity, "property_ids", [])
|
|
|
|
#################
|
|
# private stuff #
|
|
#################
|
|
static func __get_entity_optional(entity : Object, name : String, default = null):
|
|
return GDB_Property.__get_prop_optional(entity, name, default) # why write this twice?
|
|
|
|
############
|
|
# handlers #
|
|
############
|
|
func _on_title_property_value_changed() -> void:
|
|
if !_title_property: # should exist
|
|
return
|
|
__set_title(_title_property.get_value())
|
|
|
|
###########
|
|
# signals #
|
|
###########
|
|
signal entity_title_changed()
|
|
signal property_added(index)
|
|
signal property_removed(index, property)
|