Skip to main content

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;