class_name PersonStateRecord extends RefCounted const SCHEMA_VERSION := 1 var data: Dictionary func _init(record_data: Dictionary = {}) -> void: data = record_data.duplicate(true) static func create_at_location( person_id: StringName, display_name: String, role_id: StringName, polity_id: StringName, home_location_id: StringName, address: SpatialAddress, history_event_ids: Array = [] ) -> PersonStateRecord: return _create( person_id, display_name, role_id, polity_id, home_location_id, address, &"", history_event_ids ) static func create_in_group( person_id: StringName, display_name: String, role_id: StringName, polity_id: StringName, home_location_id: StringName, mobile_group_id: StringName, history_event_ids: Array = [] ) -> PersonStateRecord: return _create( person_id, display_name, role_id, polity_id, home_location_id, null, mobile_group_id, history_event_ids ) static func _create( person_id: StringName, display_name: String, role_id: StringName, polity_id: StringName, home_location_id: StringName, address: Variant, mobile_group_id: StringName, history_event_ids: Array ) -> PersonStateRecord: var normalized_address: Variant = null if address != null: normalized_address = RegionalStateSupport.normalize_address(address) var normalized_history: Variant = RegionalStateSupport.normalize_history_event_ids( history_event_ids ) if normalized_history == null or (address != null and normalized_address == null): return null var record := ( PersonStateRecord . new( { "schema_version": SCHEMA_VERSION, "person_id": String(person_id), "display_name": display_name, "role_id": String(role_id), "polity_id": String(polity_id), "home_location_id": String(home_location_id), "location_address": normalized_address, "mobile_group_id": String(mobile_group_id), "history_event_ids": normalized_history, } ) ) return record if record.is_valid() else null static func from_dictionary(record_data: Dictionary) -> PersonStateRecord: if int(record_data.get("schema_version", -1)) != SCHEMA_VERSION: return null if not ( record_data . has_all( [ "person_id", "display_name", "role_id", "polity_id", "home_location_id", "location_address", "mobile_group_id", "history_event_ids", ] ) ): return null if ( ( record_data["location_address"] != null and not record_data["location_address"] is Dictionary ) or not record_data["history_event_ids"] is Array ): return null return _create( StringName(record_data["person_id"]), String(record_data["display_name"]), StringName(record_data["role_id"]), StringName(record_data["polity_id"]), StringName(record_data["home_location_id"]), record_data["location_address"], StringName(record_data["mobile_group_id"]), record_data["history_event_ids"] ) func is_valid() -> bool: return ( not get_person_id().is_empty() and not get_display_name().is_empty() and not get_role_id().is_empty() and not get_polity_id().is_empty() and not get_home_location_id().is_empty() and (is_at_location() != is_in_mobile_group()) ) func get_person_id() -> StringName: return StringName(data["person_id"]) func get_display_name() -> String: return String(data["display_name"]) func get_role_id() -> StringName: return StringName(data["role_id"]) func get_polity_id() -> StringName: return StringName(data["polity_id"]) func get_home_location_id() -> StringName: return StringName(data["home_location_id"]) func is_at_location() -> bool: return data["location_address"] is Dictionary and get_mobile_group_id().is_empty() func is_in_mobile_group() -> bool: return data["location_address"] == null and not get_mobile_group_id().is_empty() func get_location_address() -> SpatialAddress: return RegionalStateSupport.address_from_data(data["location_address"]) func get_mobile_group_id() -> StringName: return StringName(data["mobile_group_id"]) func get_history_event_ids() -> Array[int]: return RegionalStateSupport.copy_int_array(data["history_event_ids"]) func to_dictionary() -> Dictionary: return data.duplicate(true)