Added array properties, automatic property wrappers and titles to entities.
This commit is contained in:
parent
0cb9feffe2
commit
47fbd56b9a
@ -2,12 +2,129 @@ extends Reference
|
|||||||
|
|
||||||
class_name GDB_Entity
|
class_name GDB_Entity
|
||||||
|
|
||||||
|
var _title := ""
|
||||||
|
var _title_property : Object = null
|
||||||
var _properties := [].duplicate()
|
var _properties := [].duplicate()
|
||||||
var _property_ids := [].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 #
|
# 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:
|
func get_properties() -> Array:
|
||||||
return _properties
|
return _properties
|
||||||
|
|
||||||
@ -67,6 +184,14 @@ func find_property(property : Object) -> int:
|
|||||||
func find_property_by_id(id : String) -> int:
|
func find_property_by_id(id : String) -> int:
|
||||||
return _property_ids.find(id)
|
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 stuff #
|
||||||
################
|
################
|
||||||
@ -74,8 +199,62 @@ static func is_valid_entity(object : Object) -> bool:
|
|||||||
return object != null \
|
return object != null \
|
||||||
&& object.has_method("get_properties")
|
&& 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 #
|
# signals #
|
||||||
###########
|
###########
|
||||||
|
signal entity_title_changed()
|
||||||
signal property_added(index)
|
signal property_added(index)
|
||||||
signal property_removed(index, property)
|
signal property_removed(index, property)
|
||||||
|
@ -3,12 +3,19 @@ extends Reference
|
|||||||
class_name GDB_Property
|
class_name GDB_Property
|
||||||
|
|
||||||
# special types
|
# special types
|
||||||
const TYPE_HEADER = -1
|
const TYPE_HEADER = -1
|
||||||
|
const TYPE_ENTITY = -2
|
||||||
|
const TYPE_PROPERTY = -3
|
||||||
|
|
||||||
|
const FLAG_READONLY = (1 << 0) # the user should not be able to change this
|
||||||
|
const FLAG_HIDDEN = (1 << 1) # completely hidden from UI
|
||||||
|
|
||||||
var _name := ""
|
var _name := ""
|
||||||
var _icon : Texture = null
|
var _icon : Texture = null
|
||||||
var _value = null
|
var _value = null
|
||||||
var _type := TYPE_INT
|
var _type := TYPE_INT#
|
||||||
|
var _content_type := TYPE_NIL
|
||||||
|
var _flags := 0
|
||||||
|
|
||||||
################
|
################
|
||||||
# overridables #
|
# overridables #
|
||||||
@ -43,7 +50,23 @@ func get_type() -> int:
|
|||||||
func set_type(type : int) -> void:
|
func set_type(type : int) -> void:
|
||||||
if type != _type:
|
if type != _type:
|
||||||
_type = type
|
_type = type
|
||||||
emit_signal("type_changed")
|
emit_signal("type_changed")
|
||||||
|
|
||||||
|
func get_content_type() -> int:
|
||||||
|
return _content_type
|
||||||
|
|
||||||
|
func set_content_type(type : int) -> void:
|
||||||
|
if type != _content_type:
|
||||||
|
_content_type = type
|
||||||
|
emit_signal("type_changed")
|
||||||
|
|
||||||
|
func get_flags() -> int:
|
||||||
|
return _flags
|
||||||
|
|
||||||
|
func set_flags(flags : int) -> void:
|
||||||
|
if flags != _flags:
|
||||||
|
_flags = flags
|
||||||
|
emit_signal("flags_changed")
|
||||||
|
|
||||||
################
|
################
|
||||||
# static stuff #
|
# static stuff #
|
||||||
@ -55,12 +78,13 @@ static func is_valid_property(object : Object) -> bool:
|
|||||||
&& object.has_method("get_type")
|
&& object.has_method("get_type")
|
||||||
|
|
||||||
static func get_prop_icon(property : Object) -> Texture:
|
static func get_prop_icon(property : Object) -> Texture:
|
||||||
var icon : Texture = null
|
return __get_prop_optional(property, "icon")
|
||||||
if property.has_method("get_icon"):
|
|
||||||
icon = property.get_icon() as Texture
|
static func get_prop_flags(property : Object) -> int:
|
||||||
else:
|
return __get_prop_optional(property, "flags", 0)
|
||||||
icon = property.get("icon") as Texture
|
|
||||||
return icon
|
static func get_prop_content_type(property : Object) -> int:
|
||||||
|
return __get_prop_optional(property, "content_type", TYPE_NIL)
|
||||||
|
|
||||||
static func is_prop_value_valid(property : Object, value) -> bool:
|
static func is_prop_value_valid(property : Object, value) -> bool:
|
||||||
if property.has_method("is_value_valud"):
|
if property.has_method("is_value_valud"):
|
||||||
@ -69,12 +93,16 @@ static func is_prop_value_valid(property : Object, value) -> bool:
|
|||||||
match property.get_type():
|
match property.get_type():
|
||||||
TYPE_HEADER:
|
TYPE_HEADER:
|
||||||
return false
|
return false
|
||||||
|
TYPE_BOOL:
|
||||||
|
return value is bool
|
||||||
TYPE_INT:
|
TYPE_INT:
|
||||||
return value is int
|
return value is int
|
||||||
TYPE_REAL:
|
TYPE_REAL:
|
||||||
return value is float
|
return value is float
|
||||||
TYPE_STRING:
|
TYPE_STRING:
|
||||||
return value is String
|
return value is String
|
||||||
|
TYPE_ARRAY:
|
||||||
|
return value is Array
|
||||||
_: # TODO: more default checks
|
_: # TODO: more default checks
|
||||||
return true
|
return true
|
||||||
|
|
||||||
@ -83,6 +111,16 @@ static func get_prop_value_as_string(property : Object) -> String:
|
|||||||
return property.get_value_as_string()
|
return property.get_value_as_string()
|
||||||
return str(property.get_value())
|
return str(property.get_value())
|
||||||
|
|
||||||
|
static func __get_prop_optional(property : Object, name : String, default = null):
|
||||||
|
var value = default
|
||||||
|
if property.has_method("get_" + name):
|
||||||
|
value = property.call("get_" + name)
|
||||||
|
else:
|
||||||
|
var val = property.get(name)
|
||||||
|
if typeof(default) == TYPE_NIL || typeof(val) == typeof(default):
|
||||||
|
value = val
|
||||||
|
return value
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# signals #
|
# signals #
|
||||||
###########
|
###########
|
||||||
@ -90,3 +128,6 @@ signal name_changed()
|
|||||||
signal icon_changed()
|
signal icon_changed()
|
||||||
signal value_changed()
|
signal value_changed()
|
||||||
signal type_changed()
|
signal type_changed()
|
||||||
|
signal flags_changed()
|
||||||
|
signal value_added(value)
|
||||||
|
signal value_removed(value)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user