Files
gamedev-the-steward/simulation/commands/TransactionalActionEffectCommitter.gd
2026-08-12 22:29:46 +02:00

57 lines
1.9 KiB
GDScript

class_name TransactionalActionEffectCommitter
extends RefCounted
const REASON_INVALID_PLAN := &"invalid_effect_plan"
const REASON_INVALID_CONTEXT := &"invalid_commit_context"
const REASON_NOT_IMPLEMENTED := &"effect_committer_not_implemented"
const REASON_INVALID_RESULT := &"invalid_commit_result"
# This is the single public commit boundary. Implementations override only
# _commit_whole_plan, apply every operation within one authority transaction,
# and return success only after that transaction records its exact event IDs.
# Any failure result promises that all partial writes were rolled back.
func commit(plan: ActionEffectPlan, commit_context: Dictionary = {}) -> ActionEffectCommitResult:
if plan == null or not plan.is_valid():
return (
ActionEffectCommitResult
. rollback_safe_failure(
REASON_INVALID_PLAN,
"Effect plan is missing or invalid",
[&"commit_rejected_before_authority", &"no_mutation_attempted"],
)
)
if not ActionEffectPlan.is_primitive_record(commit_context):
return (
ActionEffectCommitResult
. rollback_safe_failure(
REASON_INVALID_CONTEXT,
"Commit context must contain only primitive values",
[&"commit_rejected_before_authority", &"no_mutation_attempted"],
)
)
var result := _commit_whole_plan(plan, commit_context.duplicate(true))
if result == null or not result.is_valid():
return (
ActionEffectCommitResult
. rollback_safe_failure(
REASON_INVALID_RESULT,
"Atomic committer returned an invalid result",
[&"commit_result_invalid", &"rollback_required"],
)
)
return result
func _commit_whole_plan(
_plan: ActionEffectPlan, _commit_context: Dictionary
) -> ActionEffectCommitResult:
return (
ActionEffectCommitResult
. rollback_safe_failure(
REASON_NOT_IMPLEMENTED,
"No authoritative action-effect committer is configured",
[&"commit_not_implemented", &"no_mutation_attempted"],
)
)