Skip to main content

khora_data/render/
editor_view.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! `EditorViewportOverride` — fallback view consumed by [`RenderFlow`] when
16//! no active scene `Camera` exists.
17//!
18//! Tools that drive their own camera outside the ECS (the editor in
19//! Editing mode, headless screenshot tools, …) write the desired
20//! [`ExtractedView`] here once per frame **before** the scheduler runs.
21//! `RenderFlow` reads it during `project()` and appends it to
22//! `RenderWorld.views` if the world produced none of its own.
23//!
24//! The type is intentionally generic — it lives in the data layer so that
25//! [`RenderFlow`] does not need to know about any editor crate.
26//!
27//! [`RenderFlow`]: crate::flow::RenderFlow
28
29use std::sync::{Arc, RwLock};
30
31use super::ExtractedView;
32
33/// Shared, mutable per-frame view override.
34///
35/// Cloning shares the inner state — every `Arc` clone observes the same
36/// override.
37#[derive(Clone, Default)]
38pub struct EditorViewportOverride(Arc<RwLock<Option<ExtractedView>>>);
39
40impl EditorViewportOverride {
41    /// Creates a new, empty override.
42    pub fn new() -> Self {
43        Self::default()
44    }
45
46    /// Replaces the current override view (or clears it with `None`).
47    pub fn set(&self, view: Option<ExtractedView>) {
48        if let Ok(mut slot) = self.0.write() {
49            *slot = view;
50        }
51    }
52
53    /// Returns the current override view, if any.
54    pub fn get(&self) -> Option<ExtractedView> {
55        self.0.read().ok().and_then(|slot| slot.clone())
56    }
57
58    /// Clears the current override.
59    pub fn clear(&self) {
60        self.set(None);
61    }
62}