bevy_simple_screenshot 0.1.2

A plug-and-play screenshot library for Bevy 0.17+ with ring-buffered capture and automatic saving
//! ScreenshotBufferPlugin implementation.

use bevy::prelude::*;
use crossbeam_channel::bounded;

use crate::buffer::ScreenshotBufferManager;
use crate::capture::{
    detect_shutdown, handle_screenshot_captured, process_screenshot_requests,
    update_render_readiness, RenderReadiness, ScreenshotRequest, ScreenshotRequestReceiver,
    ScreenshotRequestSender, ShutdownState,
};
use crate::config::ScreenshotConfig;
use crate::save::{spawn_save_thread, SaveTaskSender};

/// Plugin that adds screenshot buffering capabilities to a Bevy app.
pub struct ScreenshotBufferPlugin {
    config: ScreenshotConfig,
}

impl ScreenshotBufferPlugin {
    /// Create a new plugin that loads configuration from screenshots.toml.
    pub fn new() -> Self {
        Self {
            config: ScreenshotConfig::load(),
        }
    }

    /// Create a new plugin with the provided configuration.
    pub fn with_config(config: ScreenshotConfig) -> Self {
        Self { config }
    }
}

impl Default for ScreenshotBufferPlugin {
    fn default() -> Self {
        Self::new()
    }
}

impl Plugin for ScreenshotBufferPlugin {
    fn build(&self, app: &mut App) {
        // Channel capacity for screenshot requests (bounded to prevent memory issues)
        const REQUEST_CHANNEL_CAPACITY: usize = 32;
        // Channel capacity for save tasks (larger to handle burst captures)
        const SAVE_CHANNEL_CAPACITY: usize = 64;

        // Create request channel
        let (request_tx, request_rx) = bounded::<ScreenshotRequest>(REQUEST_CHANNEL_CAPACITY);

        // Create save channel
        let (save_tx, save_rx) = bounded(SAVE_CHANNEL_CAPACITY);

        // Spawn background save thread
        let config_clone = self.config.clone();
        let save_thread_handle = spawn_save_thread(save_rx, config_clone);

        // Register resources and systems
        app.insert_resource(save_thread_handle)
            .insert_resource(ScreenshotRequestSender(request_tx))
            .insert_resource(ScreenshotRequestReceiver(request_rx))
            .insert_resource(SaveTaskSender(save_tx))
            .insert_resource(ScreenshotBufferManager::new(self.config.clone()))
            .insert_resource(RenderReadiness::default())
            .insert_resource(ShutdownState::default())
            .add_message::<ScreenshotRequest>()
            // Update render readiness early in the frame
            .add_systems(First, update_render_readiness)
            // Detect shutdown events
            .add_systems(Last, detect_shutdown)
            // Process screenshot requests in Update
            .add_systems(Update, process_screenshot_requests)
            .add_observer(handle_screenshot_captured);
    }
}