Files
TheTree_mock/scripts/events/event_instance.gd

152 lines
4.8 KiB
GDScript

class_name EventInstance
extends RefCounted
enum State {
QUEUED,
RUNNING,
WAITING_CHOICE,
COMPLETED,
CANCELLED,
EXPIRED,
ERROR,
INTERRUPTED,
}
var event_instance_id: StringName = &""
var source_event_id: StringName = &""
var resolved_event_id: StringName = &""
var actor_ids: Array[StringName] = []
var priority := 0
var created_at := 0
var expires_at := -1
var foreground := true
var state: State = State.QUEUED
var deduplication_key: StringName = &""
var context: Dictionary = {}
var presentation_mode: StringName = &"FULL"
var choice_instance_id: StringName = &""
var selected_choice_id: StringName = &""
var reserved_costs: Dictionary = {}
var failure_reason := ""
var retry_count := 0
func configure(
p_instance_id: StringName,
p_source_event_id: StringName,
p_resolved_event_id: StringName,
p_actor_ids: Array,
p_priority: int,
p_created_at: int,
p_expires_at: int,
p_foreground: bool,
p_deduplication_key: StringName,
p_context: Dictionary = {},
presentation: StringName = &"FULL"
) -> EventInstance:
event_instance_id = p_instance_id
source_event_id = p_source_event_id
resolved_event_id = p_resolved_event_id
actor_ids = _sorted_unique_names(p_actor_ids)
priority = p_priority
created_at = maxi(p_created_at, 0)
expires_at = p_expires_at
foreground = p_foreground
deduplication_key = p_deduplication_key
context = p_context.duplicate(true)
presentation_mode = presentation
return self
func is_valid() -> bool:
if event_instance_id.is_empty() or source_event_id.is_empty() or resolved_event_id.is_empty():
return false
if created_at < 0 or (expires_at >= 0 and expires_at < created_at):
return false
if state < State.QUEUED or state > State.INTERRUPTED:
return false
return true
func is_terminal() -> bool:
return state in [State.COMPLETED, State.CANCELLED, State.EXPIRED, State.ERROR]
func create_snapshot() -> Dictionary:
return {
&"event_instance_id": String(event_instance_id),
&"source_event_id": String(source_event_id),
&"resolved_event_id": String(resolved_event_id),
&"actor_ids": _names_to_strings(actor_ids),
&"priority": priority,
&"created_at": created_at,
&"expires_at": expires_at,
&"foreground": foreground,
&"state": State.keys()[state],
&"deduplication_key": String(deduplication_key),
&"context": context.duplicate(true),
&"presentation_mode": String(presentation_mode),
&"choice_instance_id": String(choice_instance_id),
&"selected_choice_id": String(selected_choice_id),
&"reserved_costs": reserved_costs.duplicate(true),
&"failure_reason": failure_reason,
&"retry_count": retry_count,
}
static func from_snapshot(snapshot: Dictionary) -> EventInstance:
var instance := EventInstance.new().configure(
StringName(_value(snapshot, &"event_instance_id", &"")),
StringName(_value(snapshot, &"source_event_id", &"")),
StringName(_value(snapshot, &"resolved_event_id", &"")),
_array(_value(snapshot, &"actor_ids", [])),
int(_value(snapshot, &"priority", 0)),
int(_value(snapshot, &"created_at", 0)),
int(_value(snapshot, &"expires_at", -1)),
bool(_value(snapshot, &"foreground", true)),
StringName(_value(snapshot, &"deduplication_key", &"")),
_dictionary(_value(snapshot, &"context", {})),
StringName(_value(snapshot, &"presentation_mode", &"FULL"))
)
var state_name := String(_value(snapshot, &"state", "QUEUED")).to_upper()
var state_index := State.keys().find(state_name)
instance.state = (state_index if state_index >= 0 else State.ERROR) as State
instance.choice_instance_id = StringName(_value(snapshot, &"choice_instance_id", &""))
instance.selected_choice_id = StringName(_value(snapshot, &"selected_choice_id", &""))
instance.reserved_costs = _dictionary(_value(snapshot, &"reserved_costs", {})).duplicate(true)
instance.failure_reason = String(_value(snapshot, &"failure_reason", ""))
instance.retry_count = maxi(int(_value(snapshot, &"retry_count", 0)), 0)
return instance
static func _sorted_unique_names(raw_value: Variant) -> Array[StringName]:
var result: Array[StringName] = []
if raw_value is Array:
for raw_entry: Variant in raw_value:
var entry := StringName(raw_entry)
if not entry.is_empty() and not result.has(entry):
result.append(entry)
result.sort_custom(func(a: StringName, b: StringName) -> bool: return String(a) < String(b))
return result
static func _names_to_strings(values: Array[StringName]) -> Array[String]:
var result: Array[String] = []
for value: StringName in values:
result.append(String(value))
return result
static func _value(source: Dictionary, key: StringName, fallback: Variant) -> Variant:
if source.has(key):
return source[key]
return source.get(String(key), fallback)
static func _array(value: Variant) -> Array:
return value if value is Array else []
static func _dictionary(value: Variant) -> Dictionary:
return value if value is Dictionary else {}