Repository: bevyengine/bevy
File: crates/bevy_asset/src/processor/mod.rs (Rust)

Code before:
impl AssetProcessorData {
    /// Initializes a new [`AssetProcessorData`] using the given [`AssetSources`].
    pub fn new(source: AssetSources) -> Self {
        let (mut finished_sender, finished_receiver) = async_broadcast::broadcast(1);
        let (mut initialized_sender, initialized_receiver) = async_broadcast::broadcast(1);
        // allow overflow on these "one slot" channels to allow receivers to retrieve the "latest" state, and to allow senders to
        // not block if there was older state present.
        finished_sender.set_overflow(true);
        initialized_sender.set_overflow(true);

        AssetProcessorData {
            sources: source,
            finished_sender,
            finished_receiver,
            initialized_sender,
            initialized_receiver,
            state: async_lock::RwLock::new(ProcessorState::Initializing),
            log_factory: Mutex::new(Some(Box::new(FileTransactionLogFactory::default()))),
            log: Default::default(),
            processors: Default::default(),
            asset_infos: Default::default(),
            default_processors: Default::default(),
        }
    }

    /// Sets the transaction log factory prior to processing being started.
    pub fn set_log_factory(
        &self,
        factory: Box<dyn ProcessorTransactionLogFactory>,
    ) -> Result<(), SetTransactionLogFactoryError> {
        let mut log_factory = self
            .log_factory
            .lock()
            .unwrap_or_else(PoisonError::into_inner);
        if log_factory.is_none() {
            // This indicates the asset processor has already started, so setting the factory does
            // nothing here.
            return Err(SetTransactionLogFactoryError::AlreadyInUse);
        }

        *log_factory = Some(factory);
        Ok(())
    }

    /// Returns a future that will not finish until the path has been processed.
    pub async fn wait_until_processed(&self, path: AssetPath<'static>) -> ProcessStatus {
        self.wait_until_initialized().await;
        let mut receiver = {
            let infos = self.asset_infos.write().await;
            let info = infos.get(&path);
            match info {

Review comment (bug):
```suggestion
    /// Replaces the default transaction log factory. If this is called after asset processing has begun in the `Startup` schedule, it will fail and return `SetTransactionLogFactoryError::AlreadyInUse`.
```
just a nit, but I think this could be clearer.

Code after:
impl AssetProcessorData {
    /// Initializes a new [`AssetProcessorData`] using the given [`AssetSources`].
    pub fn new(source: AssetSources) -> Self {
        let (mut finished_sender, finished_receiver) = async_broadcast::broadcast(1);
        let (mut initialized_sender, initialized_receiver) = async_broadcast::broadcast(1);
        // allow overflow on these "one slot" channels to allow receivers to retrieve the "latest" state, and to allow senders to
        // not block if there was older state present.
        finished_sender.set_overflow(true);
        initialized_sender.set_overflow(true);

        AssetProcessorData {
            sources: source,
            finished_sender,
            finished_receiver,
            initialized_sender,
            initialized_receiver,
            state: async_lock::RwLock::new(ProcessorState::Initializing),
            log_factory: Mutex::new(Some(Box::new(FileTransactionLogFactory::default()))),
            log: Default::default(),
            processors: Default::default(),
            asset_infos: Default::default(),
            default_processors: Default::default(),
        }
    }

    /// Sets the transaction log factory for the processor.
    ///
    /// If this is called after asset processing has begun (in the `Startup` schedule), it will
    /// return an error. If not called, the default transaction log will be used.
    pub fn set_log_factory(
        &self,
        factory: Box<dyn ProcessorTransactionLogFactory>,
    ) -> Result<(), SetTransactionLogFactoryError> {
        let mut log_factory = self
            .log_factory
            .lock()
            .unwrap_or_else(PoisonError::into_inner);
        if log_factory.is_none() {
            // This indicates the asset processor has already started, so setting the factory does
            // nothing here.
            return Err(SetTransactionLogFactoryError::AlreadyInUse);
        }

        *log_factory = Some(factory);
        Ok(())
    }

    /// Returns a future that will not finish until the path has been processed.
    pub async fn wait_until_processed(&self, path: AssetPath<'static>) -> ProcessStatus {
        self.wait_until_initialized().await;
        let mut receiver = {