112 lines
2.6 KiB
GDScript
112 lines
2.6 KiB
GDScript
class_name ConversationActStateRecord
|
|
extends RefCounted
|
|
|
|
const SCHEMA_VERSION := 1
|
|
const MAX_TOPICS := 8
|
|
|
|
var data: Dictionary
|
|
|
|
|
|
func _init(record_data: Dictionary = {}) -> void:
|
|
data = record_data.duplicate(true)
|
|
|
|
|
|
static func create(
|
|
act_id: int,
|
|
tick: int,
|
|
speaker: WorldEntityRef,
|
|
listener: WorldEntityRef,
|
|
intent_id: StringName,
|
|
topic_ids: Array[StringName] = []
|
|
) -> ConversationActStateRecord:
|
|
if (
|
|
act_id < 0
|
|
or tick < 0
|
|
or speaker == null
|
|
or listener == null
|
|
or not speaker.is_valid()
|
|
or not listener.is_valid()
|
|
or speaker.equals(listener)
|
|
or not ConversationIntentIds.is_supported(intent_id)
|
|
or topic_ids.size() > MAX_TOPICS
|
|
):
|
|
return null
|
|
var normalized_topics: Array[String] = []
|
|
var seen: Dictionary = {}
|
|
for topic_id in topic_ids:
|
|
if topic_id.is_empty() or seen.has(topic_id):
|
|
return null
|
|
seen[topic_id] = true
|
|
normalized_topics.append(String(topic_id))
|
|
return (
|
|
ConversationActStateRecord
|
|
. new(
|
|
{
|
|
"schema_version": SCHEMA_VERSION,
|
|
"act_id": act_id,
|
|
"tick": tick,
|
|
"speaker": speaker.to_dictionary(),
|
|
"listener": listener.to_dictionary(),
|
|
"intent_id": String(intent_id),
|
|
"topic_ids": normalized_topics,
|
|
}
|
|
)
|
|
)
|
|
|
|
|
|
static func from_dictionary(record_data: Dictionary) -> ConversationActStateRecord:
|
|
if (
|
|
int(record_data.get("schema_version", -1)) != SCHEMA_VERSION
|
|
or not record_data.has_all(
|
|
["act_id", "tick", "speaker", "listener", "intent_id", "topic_ids"]
|
|
)
|
|
or not record_data["speaker"] is Dictionary
|
|
or not record_data["listener"] is Dictionary
|
|
or not record_data["topic_ids"] is Array
|
|
):
|
|
return null
|
|
var topics: Array[StringName] = []
|
|
for topic in record_data["topic_ids"]:
|
|
if not topic is String and not topic is StringName:
|
|
return null
|
|
topics.append(StringName(topic))
|
|
return create(
|
|
int(record_data["act_id"]),
|
|
int(record_data["tick"]),
|
|
WorldEntityRef.from_dictionary(record_data["speaker"]),
|
|
WorldEntityRef.from_dictionary(record_data["listener"]),
|
|
StringName(record_data["intent_id"]),
|
|
topics
|
|
)
|
|
|
|
|
|
func get_act_id() -> int:
|
|
return int(data["act_id"])
|
|
|
|
|
|
func get_tick() -> int:
|
|
return int(data["tick"])
|
|
|
|
|
|
func get_speaker() -> WorldEntityRef:
|
|
return WorldEntityRef.from_dictionary(data["speaker"])
|
|
|
|
|
|
func get_listener() -> WorldEntityRef:
|
|
return WorldEntityRef.from_dictionary(data["listener"])
|
|
|
|
|
|
func get_intent_id() -> StringName:
|
|
return StringName(data["intent_id"])
|
|
|
|
|
|
func get_topic_ids() -> Array[StringName]:
|
|
var result: Array[StringName] = []
|
|
for topic in data["topic_ids"]:
|
|
result.append(StringName(topic))
|
|
return result
|
|
|
|
|
|
func to_dictionary() -> Dictionary:
|
|
return data.duplicate(true)
|