60 lines
2.0 KiB
Rust
60 lines
2.0 KiB
Rust
//! 剧情领域事件。
|
|
//!
|
|
//! 事件只表达 story session 已经发生的领域事实;是否写入 SpacetimeDB event table 或
|
|
//! 映射成 HTTP/SSE 输出,由外层 adapter 决定。
|
|
|
|
use crate::domain::StorySessionSnapshot;
|
|
use serde::{Deserialize, Serialize};
|
|
use shared_kernel::build_prefixed_seed_id;
|
|
#[cfg(feature = "spacetime-types")]
|
|
use spacetimedb::SpacetimeType;
|
|
|
|
/// 剧情事件 ID 的稳定前缀。
|
|
pub const STORY_EVENT_ID_PREFIX: &str = "storyevt_";
|
|
|
|
/// 剧情事件类型,当前覆盖开局和续写两条最小主链。
|
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum StoryEventKind {
|
|
SessionStarted,
|
|
StoryContinued,
|
|
}
|
|
|
|
impl StoryEventKind {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Self::SessionStarted => "session_started",
|
|
Self::StoryContinued => "story_continued",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct StoryEventSnapshot {
|
|
pub event_id: String,
|
|
pub story_session_id: String,
|
|
pub event_kind: StoryEventKind,
|
|
pub narrative_text: String,
|
|
pub choice_function_id: Option<String>,
|
|
pub created_at_micros: i64,
|
|
}
|
|
|
|
pub fn build_story_started_event(snapshot: &StorySessionSnapshot) -> StoryEventSnapshot {
|
|
StoryEventSnapshot {
|
|
event_id: generate_story_event_id(snapshot.created_at_micros),
|
|
story_session_id: snapshot.story_session_id.clone(),
|
|
event_kind: StoryEventKind::SessionStarted,
|
|
narrative_text: snapshot
|
|
.opening_summary
|
|
.clone()
|
|
.unwrap_or_else(|| snapshot.initial_prompt.clone()),
|
|
choice_function_id: None,
|
|
created_at_micros: snapshot.created_at_micros,
|
|
}
|
|
}
|
|
|
|
pub fn generate_story_event_id(seed_micros: i64) -> String {
|
|
build_prefixed_seed_id(STORY_EVENT_ID_PREFIX, seed_micros)
|
|
}
|