molgfx_render/engine/session.rs
1//! Complete render-session persistence for reproducible figures.
2//!
3//! Core scene manifests intentionally remain independent from GPU presentation
4//! state. This envelope joins the scene description to the camera and ordered
5//! render profile without copying caller-owned structure or volume data.
6
7use super::RenderProfile;
8use crate::error::RenderError;
9use molgfx_core::{Scene, SceneDescription, SceneDescriptionSources};
10use molgfx_math::Camera;
11use serde::{Deserialize, Serialize};
12
13/// A reproducible figure/session envelope.
14#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
15pub struct RenderSession {
16 /// Schema version of this presentation envelope.
17 pub schema: u16,
18 /// Core scene composition and source fingerprints.
19 pub scene: SceneDescription,
20 /// Camera state used for the frame.
21 pub camera: Camera,
22 /// Ordered, weighted presentation modules.
23 pub profile: RenderProfile,
24}
25
26impl RenderSession {
27 /// Current session-envelope schema.
28 pub const SCHEMA: u16 = 1;
29
30 /// Captures scene composition without copying caller-owned source data.
31 #[must_use]
32 pub fn new(scene: &Scene, camera: Camera, profile: RenderProfile) -> Self {
33 Self {
34 schema: Self::SCHEMA,
35 scene: scene.describe(),
36 camera,
37 profile,
38 }
39 }
40
41 /// Encodes the complete session as stable pretty JSON.
42 ///
43 /// # Errors
44 ///
45 /// Returns [`RenderError::SessionEncoding`] when serialization fails.
46 pub fn to_json(&self) -> Result<String, RenderError> {
47 serde_json::to_string_pretty(self).map_err(|error| RenderError::SessionEncoding {
48 summary: error.to_string(),
49 })
50 }
51
52 /// Decodes and validates a session envelope without loading sources.
53 ///
54 /// # Errors
55 ///
56 /// Returns [`RenderError::SessionEncoding`] for malformed JSON or an
57 /// unsupported session schema.
58 pub fn from_json(source: &str) -> Result<Self, RenderError> {
59 let session: Self =
60 serde_json::from_str(source).map_err(|error| RenderError::SessionEncoding {
61 summary: error.to_string(),
62 })?;
63 if session.schema != Self::SCHEMA {
64 return Err(RenderError::SessionEncoding {
65 summary: format!(
66 "unsupported render session schema; expected {}",
67 Self::SCHEMA
68 ),
69 });
70 }
71 Ok(session)
72 }
73
74 /// Rehydrates the core scene from the caller's source allocations.
75 ///
76 /// # Errors
77 ///
78 /// Returns the core validation error when a source fingerprint, handle or
79 /// scene-owned payload does not match the session.
80 pub fn restore(
81 &self,
82 sources: SceneDescriptionSources<'_>,
83 ) -> Result<(Scene, Camera, RenderProfile), molgfx_core::CoreError> {
84 let scene = Scene::from_description(&self.scene, sources)?;
85 Ok((scene, self.camera, self.profile.clone()))
86 }
87}
88
89#[cfg(test)]
90#[path = "session_tests.rs"]
91mod tests;