Files
room_glitch/core/runtime/scenario_validator.gd

212 lines
3.7 KiB
GDScript

class_name ScenarioValidator
static func validate(
scenario: ScenarioDefinition
) -> ValidationResult:
var result := ValidationResult.new()
if scenario == null:
result.add_error("Scenario is null.")
return result
if scenario.assignments.is_empty():
result.add_error(
"Scenario has no cabinet assignments."
)
return result
var seen_cabinets: Dictionary = {}
for assignment in scenario.assignments:
_validate_assignment(
assignment,
seen_cabinets,
result
)
return result
static func _validate_assignment(
assignment: ScenarioAssignment,
seen_cabinets: Dictionary,
result: ValidationResult
) -> void:
if assignment == null:
result.add_error(
"Scenario contains a null assignment."
)
return
if assignment.cabinet == null:
result.add_error(
"An assignment has no cabinet."
)
return
var cabinet := assignment.cabinet
var cabinet_id := cabinet.cabinet_id
if cabinet_id == &"":
result.add_error(
"A cabinet has no cabinet_id."
)
if seen_cabinets.has(cabinet_id):
result.add_error(
"Cabinet '%s' appears more than once."
% cabinet_id
)
else:
seen_cabinets[cabinet_id] = true
if assignment.game == null:
result.add_error(
"Cabinet '%s' has no game assigned."
% cabinet_id
)
return
var game := assignment.game
if game.game_id == &"":
result.add_error(
"Cabinet '%s' has a game with no game_id."
% cabinet_id
)
if game.scene == null:
result.add_error(
"Game '%s' has no scene assigned."
% game.game_id
)
if not game.can_run_on(cabinet):
result.add_error(
"Game '%s' cannot run on cabinet '%s'."
% [
game.game_id,
cabinet_id
]
)
if cabinet.hardware_config == null:
result.add_error(
"Cabinet '%s' has no HardwareConfig."
% cabinet_id
)
return
_validate_event_mappings(
assignment,
result
)
static func _validate_event_mappings(
assignment: ScenarioAssignment,
result: ValidationResult
) -> void:
var cabinet := assignment.cabinet
var cabinet_id := cabinet.cabinet_id
var hardware := cabinet.hardware_config
var game:= assignment.game
_validate_game_events(
game,
result
)
for mapping in assignment.event_mappings:
if mapping == null:
result.add_warning(
"Cabinet '%s' contains a null event mapping."
% cabinet_id
)
continue
if mapping.game_event == &"":
result.add_warning(
"Cabinet '%s' has a mapping with no game event."
% cabinet_id
)
else:
if not game.has_event(
mapping.game_event
):
result.add_error(
(
"Game '%s' does not define event '%s' "
+ "used by cabinet '%s'."
)
% [
game.game_id,
mapping.game_event,
cabinet_id
]
)
if mapping.hardware_actions.is_empty():
result.add_warning(
"Event '%s' on cabinet '%s' has no actions."
% [
mapping.game_event,
cabinet_id
]
)
for action_id in mapping.hardware_actions:
if not hardware.has_action(action_id):
result.add_error(
"Cabinet '%s': event '%s' references unknown hardware action '%s'."
% [
cabinet_id,
mapping.game_event,
action_id
]
)
static func _validate_game_events(
game: GameDefinition,
result: ValidationResult
) -> void:
var seen_events: Dictionary = {}
for event in game.events:
if event == null:
result.add_warning(
"Game '%s' contains a null event definition."
% game.game_id
)
continue
if event.event_id == &"":
result.add_error(
"Game '%s' contains an event with no event_id."
% game.game_id
)
continue
if seen_events.has(
event.event_id
):
result.add_error(
"Game '%s' defines event '%s' more than once."
% [
game.game_id,
event.event_id
]
)
else:
seen_events[
event.event_id
] = true