105 lines
2.9 KiB
GDScript
105 lines
2.9 KiB
GDScript
class_name EntityPresentationSnapshot
|
|
extends RefCounted
|
|
|
|
## Immutable renderer input for one session-local world entity visual.
|
|
## Gameplay authority, identity allocation and asset selection remain external.
|
|
|
|
const CONTRACT_VERSION := 1
|
|
const SCRIPT_PATH := "res://src/render/entities/entity_presentation_snapshot.gd"
|
|
const ENTITY_ID_SCRIPT := preload("res://src/domain/identity/entity_id.gd")
|
|
const GODOT_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/godot_world_position.gd")
|
|
|
|
var is_valid: bool:
|
|
get:
|
|
return _failure_code.is_empty()
|
|
|
|
var failure_code: StringName:
|
|
get:
|
|
return _failure_code
|
|
|
|
var entity_id: RefCounted:
|
|
get:
|
|
return _entity_id
|
|
|
|
var world_position: RefCounted:
|
|
get:
|
|
return _world_position
|
|
|
|
var visual_scene_path: String:
|
|
get:
|
|
return _visual_scene_path
|
|
|
|
var yaw_radians: float:
|
|
get:
|
|
return _yaw_radians
|
|
|
|
var uniform_scale: float:
|
|
get:
|
|
return _uniform_scale
|
|
|
|
var is_visible: bool:
|
|
get:
|
|
return _is_visible
|
|
|
|
var _failure_code: StringName
|
|
var _entity_id: RefCounted
|
|
var _world_position: RefCounted
|
|
var _visual_scene_path: String
|
|
var _yaw_radians: float
|
|
var _uniform_scale: float
|
|
var _is_visible: bool
|
|
|
|
|
|
## Creates a version-1 full visual snapshot. Invalid values remain inspectable and
|
|
## are rejected without scene mutation by the facade/presenter.
|
|
static func create(
|
|
entity_id_value: RefCounted,
|
|
world_position_value: RefCounted,
|
|
visual_scene_path_value: String,
|
|
yaw_radians_value: float = 0.0,
|
|
uniform_scale_value: float = 1.0,
|
|
is_visible_value: bool = true
|
|
) -> RefCounted:
|
|
return load(SCRIPT_PATH).new(
|
|
entity_id_value,
|
|
world_position_value,
|
|
visual_scene_path_value,
|
|
yaw_radians_value,
|
|
uniform_scale_value,
|
|
is_visible_value
|
|
)
|
|
|
|
|
|
func _init(
|
|
entity_id_value: RefCounted,
|
|
world_position_value: RefCounted,
|
|
visual_scene_path_value: String,
|
|
yaw_radians_value: float,
|
|
uniform_scale_value: float,
|
|
is_visible_value: bool
|
|
) -> void:
|
|
_entity_id = entity_id_value
|
|
_world_position = world_position_value
|
|
_visual_scene_path = visual_scene_path_value.strip_edges()
|
|
_yaw_radians = yaw_radians_value
|
|
_uniform_scale = uniform_scale_value
|
|
_is_visible = is_visible_value
|
|
_failure_code = _validate()
|
|
|
|
|
|
func _validate() -> StringName:
|
|
if _entity_id == null or _entity_id.get_script() != ENTITY_ID_SCRIPT or not bool(_entity_id.call("is_valid")):
|
|
return &"entity_presentation_invalid_entity_id"
|
|
if _world_position == null or _world_position.get_script() != GODOT_WORLD_POSITION_SCRIPT:
|
|
return &"entity_presentation_invalid_world_position"
|
|
for coordinate_name in [&"x_units", &"y_units", &"z_units"]:
|
|
if not is_finite(float(_world_position.get(coordinate_name))):
|
|
return &"entity_presentation_position_not_finite"
|
|
if _visual_scene_path.is_empty():
|
|
return &"entity_presentation_visual_path_empty"
|
|
if not is_finite(_yaw_radians):
|
|
return &"entity_presentation_yaw_not_finite"
|
|
if not is_finite(_uniform_scale) or _uniform_scale <= 0.0:
|
|
return &"entity_presentation_scale_invalid"
|
|
return &""
|