//! Public types for resolved Storybook entities //! //! These types represent fully resolved, validated entities after the //! resolution pipeline completes. Unlike the AST types which represent //! raw parsed syntax, these types: //! - Have all cross-references resolved //! - Have all overrides applied //! - Have passed semantic validation //! - Are ready for consumption by the game engine use std::collections::HashMap; use crate::syntax::ast::{ BehaviorNode, Participant, ProseBlock, Span, Time, Transition, Value, }; /// A fully resolved Storybook project #[derive(Debug, Clone)] pub struct ResolvedFile { pub declarations: Vec, } /// A resolved top-level declaration #[derive(Debug, Clone)] pub enum ResolvedDeclaration { Character(ResolvedCharacter), Template(ResolvedTemplate), LifeArc(ResolvedLifeArc), Schedule(ResolvedSchedule), Behavior(ResolvedBehavior), Institution(ResolvedInstitution), Relationship(ResolvedRelationship), Location(ResolvedLocation), Species(ResolvedSpecies), Enum(ResolvedEnum), } /// A character with all templates applied and references resolved #[derive(Debug, Clone, PartialEq)] pub struct ResolvedCharacter { pub name: String, pub species: Option, pub fields: HashMap, pub prose_blocks: HashMap, pub span: Span, } /// A template definition (before instantiation) #[derive(Debug, Clone, PartialEq)] pub struct ResolvedTemplate { pub name: String, pub fields: HashMap, pub span: Span, } /// A life arc with validated state transitions #[derive(Debug, Clone, PartialEq)] pub struct ResolvedLifeArc { pub name: String, pub states: Vec, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub struct ResolvedArcState { pub name: String, pub transitions: Vec, pub span: Span, } /// A schedule with validated non-overlapping blocks #[derive(Debug, Clone, PartialEq)] pub struct ResolvedSchedule { pub name: String, pub blocks: Vec, pub span: Span, } #[derive(Debug, Clone, PartialEq)] pub struct ResolvedScheduleBlock { pub activity: String, pub start: Time, pub end: Time, pub span: Span, } /// A behavior tree with validated actions #[derive(Debug, Clone, PartialEq)] pub struct ResolvedBehavior { pub name: String, pub root: BehaviorNode, pub span: Span, } /// An institution with resolved member references #[derive(Debug, Clone, PartialEq)] pub struct ResolvedInstitution { pub name: String, pub fields: HashMap, pub span: Span, } /// A bidirectional relationship with merged self/other blocks #[derive(Debug, Clone, PartialEq)] pub struct ResolvedRelationship { pub name: String, pub participants: Vec, pub fields: HashMap, pub span: Span, } /// A location definition #[derive(Debug, Clone, PartialEq)] pub struct ResolvedLocation { pub name: String, pub fields: HashMap, pub span: Span, } /// A species definition #[derive(Debug, Clone, PartialEq)] pub struct ResolvedSpecies { pub name: String, pub fields: HashMap, pub span: Span, } /// An enum definition with variants #[derive(Debug, Clone, PartialEq)] pub struct ResolvedEnum { pub name: String, pub variants: Vec, pub span: Span, } impl ResolvedFile { /// Get all characters in the file pub fn characters(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Character(c) => Some(c), | _ => None, }) } /// Get all relationships in the file pub fn relationships(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Relationship(r) => Some(r), | _ => None, }) } /// Get all institutions in the file pub fn institutions(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Institution(i) => Some(i), | _ => None, }) } /// Get all schedules in the file pub fn schedules(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Schedule(s) => Some(s), | _ => None, }) } /// Get all behavior trees in the file pub fn behaviors(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Behavior(b) => Some(b), | _ => None, }) } /// Get all life arcs in the file pub fn life_arcs(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::LifeArc(la) => Some(la), | _ => None, }) } /// Get all locations in the file pub fn locations(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Location(l) => Some(l), | _ => None, }) } /// Get all species in the file pub fn species(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Species(s) => Some(s), | _ => None, }) } /// Get all enums in the file pub fn enums(&self) -> impl Iterator { self.declarations.iter().filter_map(|decl| match decl { | ResolvedDeclaration::Enum(e) => Some(e), | _ => None, }) } /// Find a character by name pub fn find_character(&self, name: &str) -> Option<&ResolvedCharacter> { self.characters().find(|c| c.name == name) } /// Find a relationship by name pub fn find_relationship(&self, name: &str) -> Option<&ResolvedRelationship> { self.relationships().find(|r| r.name == name) } /// Find an institution by name pub fn find_institution(&self, name: &str) -> Option<&ResolvedInstitution> { self.institutions().find(|i| i.name == name) } }