134 lines
3.6 KiB
GDScript
134 lines
3.6 KiB
GDScript
class_name DataFieldValue
|
|
extends Resource
|
|
|
|
enum DataFieldType {
|
|
TEXT,
|
|
MULTILINE_TEXT,
|
|
NUMBER,
|
|
BOOL,
|
|
FORMULA,
|
|
LIST,
|
|
REFERENCE_SINGLE,
|
|
REFERENCE_LIST
|
|
}
|
|
|
|
@export var field_type: DataFieldType
|
|
@export var value: Variant
|
|
|
|
# --- TYPE STRING MAPPING ---
|
|
|
|
static func _type_to_string(t: DataFieldType) -> String:
|
|
match t:
|
|
DataFieldType.TEXT: return "Text"
|
|
DataFieldType.MULTILINE_TEXT: return "MultiText"
|
|
DataFieldType.NUMBER: return "Number"
|
|
DataFieldType.BOOL: return "Boolean"
|
|
DataFieldType.FORMULA: return "Formula"
|
|
DataFieldType.LIST: return "List"
|
|
DataFieldType.REFERENCE_SINGLE: return "RefSingle"
|
|
DataFieldType.REFERENCE_LIST: return "RefList"
|
|
_: return str(int(t))
|
|
|
|
static func _string_to_type(s: String) -> DataFieldType:
|
|
match s:
|
|
"Text": return DataFieldType.TEXT
|
|
"MultiText": return DataFieldType.MULTILINE_TEXT
|
|
"Number": return DataFieldType.NUMBER
|
|
"Boolean": return DataFieldType.BOOL
|
|
"Formula": return DataFieldType.FORMULA
|
|
"List": return DataFieldType.LIST
|
|
"RefSingle": return DataFieldType.REFERENCE_SINGLE
|
|
"RefList": return DataFieldType.REFERENCE_LIST
|
|
_: return DataFieldType.TEXT
|
|
|
|
# --- COMPLEX VALUE ACCESS ---
|
|
|
|
func get_concrete_value() -> Variant:
|
|
match field_type:
|
|
DataFieldType.FORMULA:
|
|
return value as FormulaValue
|
|
DataFieldType.LIST, DataFieldType.REFERENCE_LIST:
|
|
return value as ListValue
|
|
_:
|
|
return value
|
|
|
|
# --- SERIALIZATION HELPERS ---
|
|
|
|
static func _envelope_variant(v: Variant) -> Dictionary:
|
|
return {
|
|
"_kind": "gd-variant-b64",
|
|
"data": Marshalls.raw_to_base64(var_to_bytes(v))
|
|
}
|
|
|
|
static func _deenvelope_variant(d: Dictionary) -> Variant:
|
|
var raw: PackedByteArray = Marshalls.base64_to_raw(d.get("data", ""))
|
|
return bytes_to_var(raw)
|
|
|
|
static func _serialize_list_value(v: Variant) -> Array:
|
|
if v is Array:
|
|
var out: Array = []
|
|
for item in v:
|
|
if item is Dictionary or item is Array or item is String or item is int or item is float or item is bool or item == null:
|
|
out.append(item)
|
|
else:
|
|
out.append(_envelope_variant(item))
|
|
return out
|
|
return []
|
|
|
|
static func _deserialize_list_value(a: Array) -> Array:
|
|
var out: Array = []
|
|
for item in a:
|
|
if item is Dictionary and item.get("_kind") == "gd-variant-b64":
|
|
out.append(_deenvelope_variant(item))
|
|
else:
|
|
out.append(item)
|
|
return out
|
|
|
|
# --- SERIALIZE/DESERIALIZE VALUE ---
|
|
|
|
static func serialize_value(p_field_type: DataFieldType, v: Variant) -> Variant:
|
|
match p_field_type:
|
|
DataFieldType.TEXT, DataFieldType.MULTILINE_TEXT:
|
|
return str(v)
|
|
DataFieldType.NUMBER:
|
|
if v is int or v is float:
|
|
return v
|
|
var s := str(v)
|
|
if s.find(".") >= 0:
|
|
return float(s)
|
|
else:
|
|
return int(s)
|
|
DataFieldType.BOOL:
|
|
return bool(v)
|
|
_:
|
|
if v is Dictionary or v is Array or v is String or v is int or v is float or v is bool or v == null:
|
|
return v
|
|
return _envelope_variant(v)
|
|
|
|
static func deserialize_value(p_field_type: DataFieldType, raw: Variant) -> Variant:
|
|
match p_field_type:
|
|
DataFieldType.TEXT, DataFieldType.MULTILINE_TEXT:
|
|
return str(raw)
|
|
DataFieldType.NUMBER:
|
|
return raw if (raw is float or raw is int) else float(str(raw))
|
|
DataFieldType.BOOL:
|
|
return bool(raw)
|
|
_:
|
|
if raw is Dictionary and raw.get("_kind") == "gd-variant-b64":
|
|
return _deenvelope_variant(raw)
|
|
return raw
|
|
|
|
# --- DICT CONVERSION ---
|
|
|
|
func to_dict() -> Dictionary:
|
|
return {
|
|
"field_type": _type_to_string(field_type),
|
|
"value": serialize_value(field_type, value)
|
|
}
|
|
|
|
static func from_dict(d: Dictionary) -> DataFieldValue:
|
|
var inst := DataFieldValue.new()
|
|
inst.field_type = _string_to_type(d.get("field_type", "Text"))
|
|
inst.value = deserialize_value(inst.field_type, d.get("value"))
|
|
return inst
|