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

Code before:
    async fn remove(
        &mut self,
        asset_path: &AssetPath<'static>,
    ) -> Option<Arc<async_lock::RwLock<()>>> {
        let info = self.infos.remove(asset_path)?;
        if let Some(processed_info) = info.processed_info {
            self.clear_dependencies(asset_path, processed_info);
        }
        // Tell all listeners this asset does not exist
        info.status_sender
            .broadcast(ProcessStatus::NonExistent)
            .await
            .unwrap();
        if !info.dependents.is_empty() {
            error!(
                    "The asset at {asset_path} was removed, but it had assets that depend on it to be processed. Consider updating the path in the following assets: {:?}",
                    info.dependents
                );
            self.non_existent_dependents
                .insert(asset_path.clone(), info.dependents);
        }

        Some(info.file_transaction_lock)
    }

    /// Remove the info for the given path. This should only happen if an asset's source is
    /// removed/non-existent. Returns the transaction locks for the old and new assets respectively.
    async fn rename(
        &mut self,
        old: &AssetPath<'static>,
        new: &AssetPath<'static>,
        new_task_sender: &async_channel::Sender<(AssetSourceId<'static>, PathBuf)>,
    ) -> Option<(Arc<async_lock::RwLock<()>>, Arc<async_lock::RwLock<()>>)> {
        let mut info = self.infos.remove(old)?;
        if !info.dependents.is_empty() {
            // TODO: We can't currently ensure "moved" folders with relative paths aren't broken because AssetPath
            // doesn't distinguish between absolute and relative paths. We have "erased" relativeness. In the short term,
            // we could do "remove everything in a folder and re-add", but that requires full rebuilds / destroying the cache.
            // If processors / loaders could enumerate dependencies, we could check if the new deps line up with a rename.
            // If deps encoded "relativeness" as part of loading, that would also work (this seems like the right call).
            // TODO: it would be nice to log an error here for dependents that aren't also being moved + fixed.
            // (see the remove impl).
            error!(
                    "The asset at {old} was removed, but it had assets that depend on it to be processed. Consider updating the path in the following assets: {:?}",
                    info.dependents
                );
            self.non_existent_dependents
                .insert(old.clone(), core::mem::take(&mut info.dependents));
        }
        if let Some(processed_info) = &info.processed_info {
            // Update "dependent" lists for this asset's "process dependencies" to use new path.

Review comment (suggestion):
If I’m understanding this function correctly, maybe the comment text should be something like:
```suggestion
    /// Remove the info for the given old path, and get or create the info for the given new path, moving over
    /// any relevant fields from the old path to this new path. Update dependents of the old path to the new path.
    /// Returns the transaction locks for the old and new assets respectively, or None if the old asset path does not exist.
```

Code after:
    /// path does not exist.
    async fn remove(
        &mut self,
        asset_path: &AssetPath<'static>,
    ) -> Option<Arc<async_lock::RwLock<()>>> {
        let info = self.infos.remove(asset_path)?;
        if let Some(processed_info) = info.processed_info {
            self.clear_dependencies(asset_path, processed_info);
        }
        // Tell all listeners this asset does not exist
        info.status_sender
            .broadcast(ProcessStatus::NonExistent)
            .await
            .unwrap();
        if !info.dependents.is_empty() {
            error!(
                    "The asset at {asset_path} was removed, but it had assets that depend on it to be processed. Consider updating the path in the following assets: {:?}",
                    info.dependents
                );
            self.non_existent_dependents
                .insert(asset_path.clone(), info.dependents);
        }

        Some(info.file_transaction_lock)
    }

    /// Remove the info for the old path, and move over its info to the new path. This should only
    /// happen if an asset's source is removed/non-existent. Returns the transaction locks for the
    /// old and new assets respectively, or [`None`] if the old path does not exist.
    async fn rename(
        &mut self,
        old: &AssetPath<'static>,
        new: &AssetPath<'static>,
        new_task_sender: &async_channel::Sender<(AssetSourceId<'static>, PathBuf)>,
    ) -> Option<(Arc<async_lock::RwLock<()>>, Arc<async_lock::RwLock<()>>)> {
        let mut info = self.infos.remove(old)?;
        if !info.dependents.is_empty() {
            // TODO: We can't currently ensure "moved" folders with relative paths aren't broken because AssetPath
            // doesn't distinguish between absolute and relative paths. We have "erased" relativeness. In the short term,
            // we could do "remove everything in a folder and re-add", but that requires full rebuilds / destroying the cache.
            // If processors / loaders could enumerate dependencies, we could check if the new deps line up with a rename.
            // If deps encoded "relativeness" as part of loading, that would also work (this seems like the right call).
            // TODO: it would be nice to log an error here for dependents that aren't also being moved + fixed.
            // (see the remove impl).
            error!(
                    "The asset at {old} was removed, but it had assets that depend on it to be processed. Consider updating the path in the following assets: {:?}",
                    info.dependents
                );
            self.non_existent_dependents
                .insert(old.clone(), core::mem::take(&mut info.dependents));
        }