Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove skill UUID #283

Merged
merged 5 commits into from
Nov 7, 2024
Merged

Remove skill UUID #283

merged 5 commits into from
Nov 7, 2024

Conversation

codaishin
Copy link
Owner

@codaishin codaishin commented Nov 7, 2024

Treat skills as normal assets and load them through providing paths to the .skill files instead of an artificial uuid.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a custom asset loader for handling various asset types.
    • Added a trait for registering custom assets, enhancing asset management capabilities.
    • Implemented a new procedural macro for skill asset handling.
  • Improvements

    • Enhanced error handling for asset loading processes, providing clearer error messages.
    • Simplified inventory management by transitioning to handle types for skills.
    • Streamlined skill asset management within the quickbar icon retrieval system.
    • Updated skill definitions to remove unnecessary identifiers, simplifying data structures.
  • Bug Fixes

    • Resolved issues with duplicate skill entries in dropdown menus.
  • Tests

    • Added new tests to ensure unique skills are listed correctly and validate the new asset management features.
  • Chores

    • Updated dependencies and streamlined code for better maintainability.

Copy link

coderabbitai bot commented Nov 7, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

This pull request introduces several changes across multiple files, primarily enhancing the asset loading and management systems within a Bevy application. Key modifications include the introduction of a CustomAssetLoader for handling custom assets, updates to error handling in asset loading processes, and the addition of new traits and methods for registering custom assets. The register_item_view_for method in the App struct has been modified to include additional conditions for asset loading states. Various type adjustments have been made to improve type safety and flexibility, particularly in how skills and assets are referenced.

Changes

File Path Change Summary
src/plugins/items/src/lib.rs Modified register_item_view_for method to include checks for DependencyResolveProgress.
src/plugins/loading/src/asset_loader.rs Added CustomAssetLoader struct with methods for loading custom assets and handling errors.
src/plugins/loading/src/folder_asset_loader.rs Added Display and Error trait implementations for LoadError enum, enhancing error handling.
src/plugins/loading/src/lib.rs Added module declaration for asset_loader.
src/plugins/loading/src/traits.rs Added new module register_custom_assets.
src/plugins/loading/src/traits/register_custom_assets.rs Introduced RegisterCustomAssets trait with a method for registering custom assets.
src/plugins/loading/src/traits/register_custom_assets/app.rs Implemented RegisterCustomAssets for App struct.
src/plugins/loading/src/traits/register_custom_folder_assets.rs Renamed type parameter in register_custom_folder_assets method.
src/plugins/loading/src/traits/register_custom_folder_assets/app.rs Updated asset registration logic in register_custom_folder_assets.
src/plugins/macros/Cargo.toml Updated syn dependency version from 1.0 to 2.0.
src/plugins/macros/src/lib.rs Added new procedural macro skill_asset for handling skill assets.
src/plugins/menu/src/lib.rs Updated panel_container_states function to simplify type signature.
src/plugins/menu/src/systems/dropdown/insert_skill_select_dropdown.rs Added logic to ensure unique skills in dropdowns and a new test for this functionality.
src/plugins/menu/src/systems/items/swap/equipped_items.rs Updated Slots and SkillItemContent structures to use Handle<Skill>.
src/plugins/menu/src/systems/items/swap/inventory_items.rs Changed Inventory<Skill> to Inventory for greater flexibility.
src/plugins/menu/src/systems/update_panels/get_quickbar_icons.rs Modified to include access to skill assets for icon retrieval.
src/plugins/skills/Cargo.toml Changed macros.workspace dependency from [dev-dependencies] to [dependencies].
src/plugins/skills/src/bundles.rs Updated ComboBundle and Loadout structures to use new types for combos and slots.
src/plugins/skills/src/components/inventory.rs Added default type parameter for Inventory to use Handle<Skill>.
src/plugins/skills/src/components/slots.rs Changed Slots struct to use Handle<Skill> and updated trait implementations accordingly.
src/plugins/skills/src/item.rs Updated SkillItem and SkillItemContent to use Handle<Skill>.
src/plugins/skills/src/lib.rs Removed inventory and skill_combo_load methods; updated asset loading in get_loadout and get_inventory.
src/plugins/skills/src/skills.rs Removed SkillId from Skill struct, simplifying its interface.
src/plugins/skills/src/skills/skill_data.rs Removed SkillId from SkillData struct.
src/plugins/skills/src/systems.rs Removed public module declaration for uuid_to_skill.
src/plugins/skills/src/systems/enqueue.rs Updated enqueue functions to use Handle<Skill> instead of Skill.
src/plugins/skills/src/systems/equip.rs Changed Slots references to use Handle<Skill>.
src/plugins/skills/src/systems/uuid_to_skill.rs Deleted file containing UUID to skill mapping logic.
src/plugins/skills/src/systems/visualize_slot_items.rs Simplified instantiation of Slots and updated tests for consistency.
assets/skills/force_shield.skill Removed the "id" field from the skill definition.
assets/skills/gravity_well.skill Removed the "id" field from the skill definition.
assets/skills/shoot_hand_gun.skill Removed the "id" field from the skill definition.
src/plugins/skills/src/components/combo_node.rs Removed TryMap trait and associated methods from ComboNode.
src/plugins/skills/src/traits.rs Removed TryMap trait.

Possibly related PRs

  • Refine load dependencies #279: Modifications to the Cargo.toml file to include a new internal dependency, indirectly relating to loading processes.
  • add loading screen #281: Introduces a loading screen and modifies the MenuPlugin to manage asset loading and dependency resolution states, directly relevant to the changes in the register_item_view_for method.

"In the realm of code where rabbits play,
New assets and loaders brighten the day.
With skills and slots now handled with grace,
Our Bevy app hops to a new place!
So let’s cheer for changes, both big and small,
For in this code garden, we flourish for all!" 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (24)
src/plugins/loading/src/traits/register_custom_assets.rs (1)

9-12: Consider using more generic type parameter names.

The generic parameter TSkill suggests this trait is specific to skills, but it appears to be a general-purpose custom asset loader. This could limit its perceived reusability for other asset types.

Consider renaming the type parameters for better clarity:

-	fn register_custom_assets<TSkill, TDto>(&mut self) -> &mut Self
+	fn register_custom_assets<TAsset, TDto>(&mut self) -> &mut Self
 	where
-		TSkill: Asset + LoadFrom<TDto> + Clone + Debug,
+		TAsset: Asset + LoadFrom<TDto> + Clone + Debug,
 		for<'a> TDto: Deserialize<'a> + AssetFileExtensions + Sync + Send + 'static;

This change would:

  • Better reflect the generic nature of the trait
  • Make it more obvious that this can be used for any custom asset type
  • Align with the PR's goal of treating skills as standard assets
src/plugins/loading/src/traits/register_custom_folder_assets.rs (1)

13-16: LGTM! Good improvement in type parameter naming.

The renaming from TSkill to TAsset is a positive change that:

  • Makes the trait more generic and reusable
  • Better reflects that this is a general-purpose asset registration mechanism
  • Aligns with the architectural goal of treating skills as standard assets

This change supports a more maintainable asset management system by:

  • Removing special-case handling of skills
  • Enabling consistent path-based asset loading
  • Making the codebase more modular and reusable
src/plugins/loading/src/traits/register_custom_assets/app.rs (1)

13-22: Add documentation to explain usage and requirements.

The implementation looks solid and aligns well with the PR objective of treating skills as standard assets. However, it would benefit from documentation explaining:

  • Purpose and typical use cases
  • Requirements for TAsset and TDto types
  • Example usage with a simple asset type

Add doc comments like this:

+/// Registers custom assets with their corresponding DTO types for loading.
+///
+/// # Type Parameters
+/// * `TAsset` - The asset type to register
+/// * `TDto` - The DTO type used for deserializing the asset
+///
+/// # Example
+/// ```rust
+/// use bevy::prelude::*;
+/// 
+/// #[derive(Asset, Clone, Debug)]
+/// struct CustomAsset { /* ... */ }
+/// 
+/// #[derive(Deserialize)]
+/// struct CustomDto { /* ... */ }
+/// 
+/// impl LoadFrom<CustomDto> for CustomAsset { /* ... */ }
+/// impl AssetFileExtensions for CustomDto { /* ... */ }
+/// 
+/// app.register_custom_assets::<CustomAsset, CustomDto>();
+/// ```
 impl RegisterCustomAssets for App {
src/plugins/skills/src/bundles.rs (1)

Line range hint 1-70: Great architectural improvement moving to asset-based skill management.

This transition to treating skills as assets brings several benefits:

  1. Leverages Bevy's built-in asset management system
  2. Enables hot-reloading capabilities
  3. Provides better resource management and memory safety
  4. Simplifies skill loading and unloading
src/plugins/skills/src/skills/skill_data.rs (1)

Line range hint 15-23: Consider adding documentation for the SkillData struct.

The struct definition is clean and properly aligns with treating skills as standard assets. However, adding documentation would improve maintainability by explaining the purpose of each field and their relationships.

Consider adding documentation like this:

+/// Represents the serializable data structure for a skill asset.
+/// This struct is used to load skill definitions from .skill files.
 #[derive(Serialize, Deserialize, Debug)]
 pub(crate) struct SkillData {
+    /// The display name of the skill
     name: String,
+    /// The time required to cast this skill
     cast_time: DurationData,
+    /// Animation configuration for the skill
     animate: AnimateData,
+    /// Runtime behavior configuration
     behavior: RunSkillBehaviorData,
+    /// Set of item types that can use this skill
     is_usable_with: HashSet<SkillItemType>,
+    /// Optional path to the skill's icon asset
     icon: Option<Path>,
 }
src/plugins/skills/src/item.rs (2)

21-24: Excellent refactor to use Bevy's asset system.

The change from direct Skill types to Handle<Skill> aligns with Bevy's asset management patterns and the PR's objective to treat skills as standard assets. This modification:

  • Improves resource management through Bevy's asset system
  • Enables loading skills from files rather than using UUIDs
  • Maintains type safety through Bevy's handle system

Consider documenting the following patterns in your team's guidelines:

  1. Use Handle<T> for all asset references
  2. Load assets through Bevy's asset system
  3. Reference assets by path instead of UUID

Also applies to: 24-28


Asset system setup for skills needs implementation

The verification reveals missing critical asset system components for skills:

  • No asset loader implementation for Skill type
  • No asset type registration in the plugin setup
  • Missing error handling for asset loading events
  • Undefined skill asset serialization format

While asset_server.load() is being used to load skills, the supporting infrastructure is not in place, which could lead to runtime failures.

Required implementations:

  • Asset loader implementation for Skill
  • Asset type registration in plugin setup
  • Asset loading error handling system
  • Proper serialization format definition
🔗 Analysis chain

Line range hint 21-28: Verify asset loading setup.

Since skills are now treated as assets, ensure proper asset loading infrastructure is in place.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the asset system setup for skills

# Test 1: Check if a custom asset loader for skills is registered
echo "Checking for skill asset loader registration..."
rg -l "impl AssetLoader for.*Skill" 

# Test 2: Check if asset loading error handling is implemented
echo "Checking for asset loading error handling..."
rg "LoadState|AssetEvent.*Skill"

# Test 3: Verify skill file extension registration
echo "Checking for skill file extension registration..."
rg "add_asset::<Skill>|register_asset_reflect::<Skill>"

Length of output: 1701


Script:

#!/bin/bash
# Let's check for skill-related asset setup in a more comprehensive way

# Check for skill asset registration in plugin setup
echo "Checking for skill asset registration in plugin setup..."
rg -A 5 "impl Plugin.*Skill|struct SkillPlugin"

# Check for any asset loading related to skills
echo "Checking for skill asset loading..."
rg -A 3 "load.*Skill|Skill.*load"

# Check for asset server usage with skills
echo "Checking asset server usage with skills..."
rg -A 3 "AssetServer.*Skill|asset_server.*skill"

# Check for RON file handling for skills (common asset format in Bevy)
echo "Checking for RON file handling..."
fd -e ron --exec grep -l "Skill"

Length of output: 2548


Script:

#!/bin/bash
# Let's check for the skill_asset macro and asset registration

# Check for skill_asset macro definition
echo "Checking for skill_asset macro definition..."
rg "macro_rules!.*skill_asset"

# Check for asset registration in the plugin setup
echo "Checking for asset type registration..."
rg -A 5 "app.add_asset|app.register_asset_source|app.register_type::<Skill>"

# Check for the Skill type definition and its serialization
echo "Checking Skill type definition..."
ast-grep --pattern 'struct Skill {
  $$$
}'

# Check for asset loading error handling systems
echo "Checking for asset loading systems..."
rg -A 5 "fn.*system.*asset.*skill|AssetEvent<Skill>"

Length of output: 562

src/plugins/macros/src/lib.rs (2)

113-133: LGTM! The macro implementation is solid but could be more robust.

The macro successfully implements compile-time validation of skill assets, aligning well with the PR's objective of moving to path-based skill loading.

Consider these improvements:

  1. Make paths configurable through environment variables or build configuration
  2. Add validation for the skill name to ensure it contains only valid filename characters
  3. Use std::path::PathBuf for cross-platform path handling

Example implementation for path handling:

let asset_path = PathBuf::from("skills")
    .join(format!("{}.skill", literal.value()));
let path = PathBuf::from("assets")
    .join(&asset_path);

125-127: Enhance error messages with more context.

The error message could be more helpful by including the attempted path and suggesting possible solutions.

-			compile_error!("No skill with that name found in `assets/skills/`")
+			compile_error!(concat!(
+				"Skill file not found: `", #path, "`\n",
+				"Make sure the skill file exists in the assets/skills directory ",
+				"and has a .skill extension"
+			))
src/plugins/menu/src/systems/items/swap/inventory_items.rs (1)

60-61: Maintain consistency in type annotations.

Most test cases use type inference, but line 168 explicitly specifies Inventory::<Handle<Skill>>. Consider using the same pattern as other tests for consistency:

-				Inventory::<Handle<Skill>>::new([]),
+				Inventory::new([]),

Also applies to: 79-79, 103-103, 115-115, 136-136, 148-148, 168-168

src/plugins/menu/src/systems/items/swap/equipped_items.rs (1)

Line range hint 94-163: Consider reducing test data duplication.

The test data setup could be simplified by extracting common test fixtures.

Consider creating helper functions:

fn create_test_skill_item(name: &str, item_type: SkillItemType) -> SkillItem {
    SkillItem {
        name,
        content: SkillItemContent::<Handle<Skill>> {
            item_type,
            ..default()
        },
    }
}
src/plugins/skills/src/systems/visualize_slot_items.rs (1)

163-166: LGTM: Comprehensive test coverage maintained

The slot initialization changes maintain good test coverage across various scenarios. Consider adding a test case for handling invalid asset handles to verify error handling behavior with the new asset-based approach.

Example test case to consider:

#[test]
fn visualize_item_with_invalid_handle() {
    let mut app = setup();
    let invalid_handle = Handle::<Skill>::default();
    let item = SkillItem {
        content: SkillItemContent::<Handle<Skill>> {
            render: Renderer::default(),
            skill: invalid_handle,
            ..default()
        },
        ..default()
    };
    // Test visualization behavior with invalid handle
}

Also applies to: 185-196, 214-214

src/plugins/skills/src/components/slots.rs (2)

Line range hint 33-39: Consider enhancing error handling for skill handle retrieval.

While the implementation is correct, consider making the error cases more explicit by returning a Result instead of Option. This would help distinguish between "slot not found" and "skill not set" cases.

-impl GetRef<SlotKey, Handle<Skill>> for Slots {
-    fn get(&self, key: &SlotKey) -> Option<&Handle<Skill>> {
-        let item: &SkillItem = self.get(key)?;
-        item.content.skill.as_ref()
-    }
+impl GetRef<SlotKey, Handle<Skill>> for Slots {
+    fn get(&self, key: &SlotKey) -> Result<Option<&Handle<Skill>>, SlotError> {
+        let item = self.get(key).ok_or(SlotError::SlotNotFound)?;
+        Ok(item.content.skill.as_ref())
+    }
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum SlotError {
+    #[error("slot not found")]
+    SlotNotFound,
+}

138-154: Consider adding more edge cases to handle-based skill tests.

While the basic handle retrieval test is good, consider adding tests for:

  • Retrieving a handle from an empty slot
  • Retrieving a handle from a slot with an item but no skill
  • Clone behavior of handles in slots

Example test case:

#[test]
fn get_skill_handle_from_empty_slot() {
    let slots = Slots::<Handle<Skill>>::default();
    assert_eq!(None, slots.get(&SlotKey::BottomHand(Side::Right)));
}
src/plugins/skills/src/systems/equip.rs (2)

Line range hint 1-106: Add documentation to explain the system's purpose and requirements.

Consider adding documentation to explain:

  • The purpose of the equip_item system
  • The relationship between Slots, SkillItem, and Handle<Skill>
  • Requirements for the generic type parameters

Example documentation:

/// System for equipping skill items into slots.
/// 
/// # Type Parameters
/// - `TContainer`: Component storing pending swap operations
/// - `TInnerKey`: Inner key type for the swap controller
/// - `TSwaps`: Component indicating active swap operations
///
/// # Component Requirements
/// - Entity must have `Slots<Handle<Skill>>`, `TContainer`, and `TSwaps` components
pub fn equip_item<TContainer, TInnerKey, TSwaps>(...

Line range hint 152-309: Consider organizing tests into sub-modules by functionality.

The test cases cover different aspects of the system. Consider organizing them into sub-modules for better clarity:

#[cfg(test)]
mod tests {
    // ... test setup code ...

    mod slot_operations {
        #[test]
        fn set_swap_in_item() { ... }
        
        #[test]
        fn set_swap_out_item() { ... }
    }

    mod error_handling {
        #[test]
        fn try_again_error_when_slot_not_found() { ... }
        
        #[test]
        fn return_error_when_slot_not_found() { ... }
    }

    mod cleanup {
        #[test]
        fn remove_swap_component_when_empty() { ... }
        
        #[test]
        fn do_not_remove_swap_component_when_not_empty() { ... }
    }
}
src/plugins/menu/src/systems/dropdown/insert_skill_select_dropdown.rs (1)

43-57: Consider optimizing duplicate detection.

The current implementation uses Vec::contains for duplicate detection which has O(n) complexity, making the overall filtering O(n²). Consider using a HashSet for O(1) duplicate checking:

-	let mut seen = Vec::new();
+	let mut seen = HashSet::new();
 	let skills = skills
 		.iter()
 		.filter(|(_, skill)| {
 			if !skill.is_usable_with.contains(&item.content.item_type) {
 				return false;
 			}
-			if seen.contains(skill) {
+			if !seen.insert(skill) {
 				return false;
 			}
-
-			seen.push(skill);
 			true
 		})
src/plugins/menu/src/systems/update_panels/get_quickbar_icons.rs (1)

145-157: Consider extracting test data setup into helper functions.

While the test setup is functional, consider extracting the skill asset creation logic into a separate helper function to improve test maintainability and reusability. This would make it easier to create different test scenarios and reduce duplication across tests.

Example refactor:

fn create_test_skill(assets: &mut Assets<Skill>, icon: Option<Handle<Image>>) -> Handle<Skill> {
    let handle = new_handle();
    assets.insert(
        handle.id(),
        Skill {
            icon,
            ..default()
        },
    );
    handle
}

Also applies to: 175-190

src/plugins/loading/src/asset_loader.rs (2)

13-21: Simplify lifetime annotations in the read function

The explicit lifetime annotations in the read function can be omitted for cleaner code since Rust's lifetime elision rules can infer them.

Apply this diff to simplify the function:

-    async fn read<'a>(
-        reader: &'a mut Reader<'_>,
-        buffer: &'a mut Vec<u8>,
-    ) -> Result<&'a str, ReadError> {
+    async fn read(
+        reader: &mut Reader<'_>,
+        buffer: &mut Vec<u8>,
+    ) -> Result<&str, ReadError> {
         reader.read_to_end(buffer).await.map_err(ReadError::IO)?;
         from_utf8(buffer).map_err(ReadError::ParseChars)
     }

44-62: Simplify error handling in the load function using the ? operator

The error handling logic can be made more concise by leveraging the ? operator to propagate errors, enhancing readability.

Apply this diff to refactor the code:

         let buffer = &mut vec![];

-        let dto = match Self::read(reader, buffer).await {
-            Err(ReadError::IO(err)) => return Err(LoadError::IO(err)),
-            Err(ReadError::ParseChars(err)) => return Err(LoadError::ParseChars(err)),
-            Ok(str) => serde_json::from_str(str),
-        };
-
-        match dto {
-            Ok(dto) => Ok(TAsset::load_from(dto, context)),
-            Err(err) => Err(LoadError::ParseObject(err)),
-        }
+        let str = Self::read(reader, buffer).await.map_err(|e| match e {
+            ReadError::IO(err) => LoadError::IO(err),
+            ReadError::ParseChars(err) => LoadError::ParseChars(err),
+        })?;
+        let dto: TDto = serde_json::from_str(str).map_err(LoadError::ParseObject)?;
+        Ok(TAsset::load_from(dto, context))

Explanation:

  • Use map_err with the ? operator to handle errors from Self::read.
  • Apply the same pattern to handle errors from serde_json::from_str.
  • Return the final result directly, reducing nested control flow.
src/plugins/skills/src/lib.rs (4)

102-104: Refactor to reduce duplication in equip_item system calls

The equip_item system is registered twice with similar type parameters, differing only in the order of InventoryKey and SlotKey. Consider creating a more generic implementation or combining these calls to reduce code duplication and improve maintainability.

You could define a helper function or generic system that abstracts over the key types.


154-154: Unnecessary use of as_ref() on AssetServer

The AssetServer resource implements Deref, so you can use it directly without calling as_ref(). Removing as_ref() simplifies the code.

Apply this diff to simplify the code:

-        let asset_server = asset_server.as_ref();

And use asset_server directly in subsequent calls.


184-184: Refactor to reduce duplication when loading skill assets in get_loadout

Multiple SkillItem instances load the same skill assets using asset_server.load(skill_asset!(...)). To reduce repetition and improve performance, consider loading each unique skill asset once and reusing the Handle<Skill>.

Refactor example:

// At the beginning of `get_loadout`
let shoot_hand_gun_skill = asset_server.load(skill_asset!("shoot_hand_gun"));
let force_shield_skill = asset_server.load(skill_asset!("force_shield"));

// In your SkillItems
skill: Some(shoot_hand_gun_skill.clone()),

skill: Some(force_shield_skill.clone()),

Also applies to: 198-198, 212-212, 226-226


243-243: Refactor to reduce duplication when loading skill assets in get_inventory

Similar to get_loadout, multiple SkillItem instances in get_inventory load the "shoot_hand_gun" asset. Load this asset once and reuse the handle to avoid redundancy.

Refactor example:

// At the beginning of `get_inventory`
let shoot_hand_gun_skill = asset_server.load(skill_asset!("shoot_hand_gun"));

// In your SkillItems
skill: Some(shoot_hand_gun_skill.clone()),

Also applies to: 254-254, 265-265

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 4abdedc and 1f19300.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (29)
  • src/plugins/items/src/lib.rs (1 hunks)
  • src/plugins/loading/src/asset_loader.rs (1 hunks)
  • src/plugins/loading/src/folder_asset_loader.rs (1 hunks)
  • src/plugins/loading/src/lib.rs (1 hunks)
  • src/plugins/loading/src/traits.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_assets.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_assets/app.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_folder_assets.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_folder_assets/app.rs (2 hunks)
  • src/plugins/macros/Cargo.toml (1 hunks)
  • src/plugins/macros/src/lib.rs (1 hunks)
  • src/plugins/menu/src/lib.rs (1 hunks)
  • src/plugins/menu/src/systems/dropdown/insert_skill_select_dropdown.rs (2 hunks)
  • src/plugins/menu/src/systems/items/swap/equipped_items.rs (5 hunks)
  • src/plugins/menu/src/systems/items/swap/inventory_items.rs (8 hunks)
  • src/plugins/menu/src/systems/update_panels/get_quickbar_icons.rs (13 hunks)
  • src/plugins/skills/Cargo.toml (1 hunks)
  • src/plugins/skills/src/bundles.rs (3 hunks)
  • src/plugins/skills/src/components/inventory.rs (1 hunks)
  • src/plugins/skills/src/components/slots.rs (6 hunks)
  • src/plugins/skills/src/item.rs (2 hunks)
  • src/plugins/skills/src/lib.rs (11 hunks)
  • src/plugins/skills/src/skills.rs (0 hunks)
  • src/plugins/skills/src/skills/skill_data.rs (1 hunks)
  • src/plugins/skills/src/systems.rs (0 hunks)
  • src/plugins/skills/src/systems/enqueue.rs (8 hunks)
  • src/plugins/skills/src/systems/equip.rs (7 hunks)
  • src/plugins/skills/src/systems/uuid_to_skill.rs (0 hunks)
  • src/plugins/skills/src/systems/visualize_slot_items.rs (6 hunks)
💤 Files with no reviewable changes (3)
  • src/plugins/skills/src/skills.rs
  • src/plugins/skills/src/systems.rs
  • src/plugins/skills/src/systems/uuid_to_skill.rs
🔇 Additional comments (66)
src/plugins/macros/Cargo.toml (2)

10-11: Verify quote compatibility with syn 2.0.

While syn has been updated to 2.0, quote remains at 1.0. Let's verify that this combination is supported.

#!/bin/bash
# Description: Check for potential compatibility issues between syn 2.0 and quote 1.0

# Test: Look for patterns where syn and quote are used together
rg -A 3 'use quote|quote!'

10-10: Verify proc macro compatibility with syn 2.0.

The update to syn 2.0 is appropriate, but as this is a major version bump, ensure all proc macros in this crate are compatible with the new version.

✅ Verification successful

Based on the shell script results, I can now generate the final response:

Proc macros are compatible with syn 2.0

The codebase uses straightforward syn features that are well-supported in syn 2.0:

  • Basic parsing with parse_macro_input and parse
  • Common types: DeriveInput, Data, Fields, Ident, Type, Lit
  • Simple pattern matching on literals
  • Integration with quote 1.0 for code generation

All these features have maintained compatibility in syn 2.0, and the usage patterns in the macros are standard and stable.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential compatibility issues with syn 2.0

# Test: Look for proc macro definitions that might need updates
ast-grep --pattern 'proc_macro'

# Test: Look for syn usage patterns that might need updates
rg -A 3 'use syn::|syn::'

Length of output: 3138

src/plugins/loading/src/traits.rs (1)

6-6: LGTM! Well-organized module addition.

The new register_custom_assets module is a good addition that aligns with the PR's objective of improving asset handling. It maintains good code organization by following the existing module naming pattern and alphabetical ordering.

src/plugins/loading/src/traits/register_custom_assets.rs (3)

1-6: LGTM! Well-organized imports.

The imports are minimal and purposeful, properly supporting the trait's requirements.


8-9: LGTM! Clear and well-designed trait interface.

The trait provides a fluent interface for registering custom assets, with method chaining support via &mut self return type.


10-12: LGTM! Well-defined trait bounds.

The trait bounds are comprehensive and ensure:

  • Type safety through Asset trait
  • Custom loading behavior via LoadFrom
  • Thread safety with Sync + Send
  • Proper serialization support
src/plugins/skills/Cargo.toml (1)

18-18: LGTM! Dependency change aligns with the new skill asset system.

The movement of macros from dev-dependencies to main dependencies is appropriate, as it will be used for production code in the new skill asset loading system.

Let's verify the workspace setup:

✅ Verification successful

Workspace configuration and dependency change verified successfully

The change is correctly implemented:

  • macros is properly referenced as a workspace dependency in the skills package
  • The workspace setup is valid with appropriate dependency management
  • Moving macros to main dependencies aligns with its production use in the new skill asset system
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the workspace configuration and macros dependency

# Test 1: Check if this is part of a workspace by looking for root Cargo.toml
echo "Checking workspace setup..."
if ! [ -f "Cargo.toml" ]; then
    echo "Error: No root Cargo.toml found"
    exit 1
fi

# Test 2: Verify macros package exists in workspace
echo "Verifying macros package..."
rg -l "name = \"macros\"" "src/plugins/macros/Cargo.toml"

Length of output: 239


Script:

#!/bin/bash
# Let's verify the workspace configuration in detail

# Check if macros is properly defined in workspace members
echo "=== Checking workspace members ==="
rg "members.*plugins.*macros" Cargo.toml

# Verify macros package version in workspace dependencies
echo -e "\n=== Checking workspace dependencies ==="
rg "^\[workspace\.dependencies\]" -A 10 Cargo.toml

# Check the actual macros dependency in skills Cargo.toml
echo -e "\n=== Checking skills package dependency ==="
cat src/plugins/skills/Cargo.toml

Length of output: 1101

src/plugins/loading/src/traits/register_custom_assets/app.rs (2)

1-11: LGTM! Well-organized imports.

The imports are properly organized and provide all necessary components for the custom asset registration implementation.


19-21: Verify error handling in asset initialization.

The implementation chains init_asset and register_asset_loader without explicit error handling. Let's verify how errors are handled in the underlying Bevy system.

✅ Verification successful

Error handling is properly implemented in the asset loading system

The implementation has comprehensive error handling:

  1. CustomAssetLoader implements proper error handling through the LoadError type which handles:

    • IO errors during file reading
    • Character parsing errors for UTF-8 content
    • JSON parsing errors for the asset data
  2. The chained methods work as expected:

    • init_asset is a Bevy framework method that sets up the asset type
    • register_asset_loader adds the loader with proper error propagation
    • Errors are properly propagated through the Result type in the loader's implementation

The error handling implementation is thorough and follows Bevy's asset system design patterns, making the original concern unwarranted.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for error handling patterns in Bevy's asset initialization
# and registration to understand the default behavior

# Look for error handling in Bevy's AssetApp trait implementation
rg -A 5 "init_asset.*where" 

# Look for error handling in CustomAssetLoader implementation
ast-grep --pattern 'impl AssetLoader for CustomAssetLoader<$_, $_> {
  $$$
  fn load($_, $_, $_, $_) -> $_ {
    $$$
  }
  $$$
}'

Length of output: 161


Script:

#!/bin/bash
# Let's search for the implementation and usage patterns more broadly

# Search for init_asset implementation
rg -A 10 "fn init_asset"

# Search for CustomAssetLoader implementation
rg -A 15 "impl.*CustomAssetLoader"

# Search for register_asset_loader implementation
rg -A 10 "fn register_asset_loader"

# Look for any Result or error handling patterns in related files
rg -A 5 "Result|Error" src/plugins/loading/

Length of output: 23888

src/plugins/loading/src/lib.rs (1)

5-5: LGTM! The new module declaration aligns with the PR objectives.

The addition of the asset_loader module with crate-level visibility is well-structured and supports the transition to treating skills as standard assets.

Let's verify the integration of the new asset loader:

✅ Verification successful

Let me gather more information about how the new asset loader is being used.


Let me check one final aspect to understand how the new CustomAssetLoader is integrated with skills.


The new asset_loader module is well-implemented and properly integrated

The verification shows that:

  • The CustomAssetLoader follows the same pattern as FolderAssetLoader with proper implementation of AssetLoader trait
  • It's correctly used through the register_custom_assets trait for loading assets including skills
  • The implementation is generic and type-safe, using TAsset and TDto to handle various asset types
  • The module's crate-level visibility is appropriate as it's used internally by the loading plugin
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation and usage of the new asset_loader module

# Test 1: Check if the asset_loader module is properly implemented
echo "Checking asset_loader implementation..."
rg -p "impl.*AssetLoader" src/plugins/loading/src/asset_loader.rs

# Test 2: Verify that the new asset loader is used for skills
echo "Checking skill asset loading usage..."
rg -p "CustomAssetLoader.*skill" .

# Test 3: Compare with folder_asset_loader to ensure consistent patterns
echo "Comparing with folder_asset_loader..."
rg -p "impl.*AssetLoader" src/plugins/loading/src/folder_asset_loader.rs

Length of output: 826


Script:

#!/bin/bash
# Check the implementation details and usage of CustomAssetLoader
echo "Checking CustomAssetLoader implementation and usage..."
rg -p "use.*CustomAssetLoader|struct.*CustomAssetLoader" .

# Check how the asset loader is registered in the plugin
echo "Checking asset loader registration..."
rg -p "app\.add_asset_loader|register_asset_loader" .

# Look for skill-related asset type definitions
echo "Checking skill asset type definitions..."
rg -p "struct.*Skill|enum.*Skill" .

Length of output: 5060


Script:

#!/bin/bash
# Check the registration of skill assets
echo "Checking skill asset registration..."
rg -p "RegisterCustomAssets.*Skill|register_custom_assets.*Skill" .

# Check the asset_loader.rs file content
echo "Checking asset_loader.rs content..."
cat src/plugins/loading/src/asset_loader.rs

# Check the plugin setup
echo "Checking LoadingPlugin setup..."
cat src/plugins/loading/src/lib.rs

Length of output: 3156

src/plugins/skills/src/bundles.rs (3)

3-3: LGTM: Import changes align with the PR objective.

The new imports support the transition to handling skills as standard assets.

Also applies to: 11-11


35-35: LGTM: Proper implementation of Bevy asset handling.

The transition to Handle<Skill> is the correct approach for handling skills as assets in Bevy. This change:

  • Ensures proper asset lifecycle management
  • Maintains type safety
  • Aligns with Bevy's asset handling patterns

Also applies to: 41-41


20-20: Verify the impact of removing with_predefined_combos.

The type change from ComboNode<SkillId> to Combos aligns with treating skills as assets. However, let's verify that the removal of with_predefined_combos doesn't break existing code.

✅ Verification successful

Removal of with_predefined_combos is safe

The codebase only uses ComboBundle::with_timeout() for initialization, as seen in src/plugins/skills/src/lib.rs. The removed with_predefined_combos method was not used anywhere, making its removal safe. The type change from ComboNode<SkillId> to Combos is properly supported by the remaining initialization pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for any remaining usage of the removed method
# Expect: No results, as the method should not be used anymore

# Test: Search for direct method calls
rg "with_predefined_combos" 

# Test: Search for ComboBundle initialization patterns that might have used this method
ast-grep --pattern 'ComboBundle { $$$' 

Length of output: 68


Script:

#!/bin/bash
# Let's try a broader search to understand the usage patterns of ComboBundle

# Search for ComboBundle usage patterns
rg "ComboBundle" -A 3

# Search for any test files that might use ComboBundle
fd "test.*\.rs" --exec rg "ComboBundle" -A 3 {}

# Look for any struct definitions or implementations related to ComboBundle
ast-grep --pattern 'struct ComboBundle'
ast-grep --pattern 'impl $$ for ComboBundle'

Length of output: 1262

src/plugins/skills/src/skills/skill_data.rs (3)

Line range hint 5-13: LGTM! Clean and well-organized imports.

The imports are properly structured and align well with the transition to treating skills as standard assets.


Line range hint 25-29: LGTM! Proper asset file extension configuration.

The implementation correctly specifies the .skill extension, supporting the transition to file-based skill assets.


Line range hint 31-45: Consider adding error handling for asset loading.

While the implementation is correct, it might benefit from more robust error handling for asset loading failures.

Let's verify how asset loading errors are handled in the codebase:

Consider wrapping the asset loading in a Result to handle potential failures:

 impl LoadFrom<SkillData> for Skill {
     fn load_from<TLoadAsset: LoadAsset>(
         skill_data: SkillData,
         asset_server: &mut TLoadAsset,
-    ) -> Self {
+    ) -> Result<Self, Box<dyn std::error::Error>> {
+        let icon = if let Some(icon_path) = skill_data.icon {
+            Some(asset_server.load_asset(icon_path))
+        } else {
+            None
+        };
+
         Self {
             name: skill_data.name,
             cast_time: Duration::from(skill_data.cast_time),
             animate: skill_data.animate.into(),
             behavior: skill_data.behavior.into(),
             is_usable_with: skill_data.is_usable_with,
-            icon: skill_data.icon.map(|icon| asset_server.load_asset(icon)),
+            icon,
         }
     }
 }
src/plugins/skills/src/item.rs (1)

12-12: LGTM: Required import for Bevy's handle types.

The addition of Bevy's prelude import is necessary for using Handle<T> type.

src/plugins/items/src/lib.rs (2)

57-58: LGTM: Asset loading conditions are properly handled.

The addition of checks for both AssetLoadProgress and DependencyResolveProgress ensures that visualization commands only run when all assets are fully loaded and dependencies are resolved. This is essential for treating skills as standard assets.


60-60: Verify if sequential execution is necessary.

Adding .chain() forces the systems to run sequentially instead of in parallel. While this might be necessary for dependency ordering, it could impact performance.

Let's check if there are any explicit dependencies between these systems:

If there are no explicit dependencies between these systems, consider removing .chain() to allow parallel execution for better performance.

✅ Verification successful

Sequential execution appears necessary for dependency handling

The .chain() usage is justified here because:

  • The systems are running in the Update stage and involve asset loading and dependency resolution
  • The second system (VisualizeCommands::apply) explicitly runs with conditions checking DependencyResolveProgress
  • The sequential ordering ensures that visualization tracking is completed before commands are applied, which is important for dependency resolution

The performance impact of sequential execution is an acceptable trade-off for maintaining correct dependency handling in this case.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Look for system dependencies or shared component access that would require sequential execution

# Search for component access patterns in the Visualizer and VisualizeCommands implementations
ast-grep --pattern 'impl Visualizer<$_, $_> {
  $$$
}'

ast-grep --pattern 'impl VisualizeCommands<$_, $_> {
  $$$
}'

Length of output: 120


Script:

#!/bin/bash
# Let's try a different approach to find the systems and their dependencies

# First, let's find the context around where .chain() is used
rg -B 10 -A 5 "\.chain\(\)" src/plugins/items/src/lib.rs

# Also search for any system definitions or app.add_systems calls
rg "add_systems|fn \w+_system" src/plugins/items/src/lib.rs

Length of output: 550


Script:

#!/bin/bash
# Let's look for the implementation of these systems to understand their dependencies

# Search for Visualizer's track_in_self_and_children implementation
ast-grep --pattern 'fn track_in_self_and_children<$_>($$$) {
  $$$
}'

# Search for VisualizeCommands::apply implementation
ast-grep --pattern 'fn apply($$$) {
  $$$
}'

# Look for any shared component access or dependencies
rg "Query|ResMut|Res" src/plugins/items/src/lib.rs

Length of output: 361

src/plugins/loading/src/traits/register_custom_folder_assets/app.rs (2)

16-17: LGTM: New imports support asset registration changes.

The added imports for RegisterCustomAssets and RegisterLoadTracking align well with the PR's objective of standardizing asset handling.


36-39: LGTM: Enhanced asset registration system.

The changes improve asset handling by:

  1. Using register_custom_assets for more sophisticated asset registration with DTO support
  2. Implementing AliveAssets<TAsset> for better asset lifecycle management

Let's verify the integration of these changes:

✅ Verification successful

Changes are consistent with the codebase implementation

The verification confirms:

  1. RegisterCustomAssets trait is properly implemented for App with consistent DTO support and asset loading patterns
  2. AliveAssets<TAsset> is well-integrated across the codebase:
    • Defined as a resource with proper HashSet implementation
    • Used consistently in load tracking and folder asset registration
    • Integrated with systems for mapping load results
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of RegisterCustomAssets trait and AliveAssets
# across the codebase to ensure consistent implementation

# Check for other implementations of RegisterCustomAssets
echo "Checking RegisterCustomAssets implementations..."
ast-grep --pattern 'impl RegisterCustomAssets for $TYPE {
  $$$
}'

# Look for AliveAssets usage patterns
echo "Checking AliveAssets usage patterns..."
rg "AliveAssets<.*>" -A 3

Length of output: 3781

src/plugins/macros/src/lib.rs (1)

113-133: Verify the macro usage and directory structure.

Let's ensure the codebase is prepared for this change.

✅ Verification successful

Macro implementation aligns with codebase usage and directory structure

The verification confirms:

  • The assets/skills directory exists with .skill files
  • All skill files referenced in macro usages (shoot_hand_gun.skill, force_shield.skill) are present in the directory
  • The macro is used consistently in src/plugins/skills/src/lib.rs for loading skill assets
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the macro usage and directory structure

# Test 1: Check if the skills directory exists
if [ ! -d "assets/skills" ]; then
    echo "Warning: assets/skills directory does not exist"
fi

# Test 2: Find all .skill files
echo "Existing skill files:"
fd -e skill . assets/skills

# Test 3: Find usage of the skill_asset macro
echo "Macro usage:"
rg "skill_asset!\(" -A 2

Length of output: 1749

src/plugins/loading/src/folder_asset_loader.rs (1)

Line range hint 1-138: LGTM! Well-structured asset loading implementation.

The implementation provides a robust error handling system that aligns well with the PR objective of treating skills as standard assets. The code is well-organized and follows Rust best practices.

src/plugins/menu/src/systems/items/swap/inventory_items.rs (3)

9-9: LGTM! Import changes align with asset-based skill handling.

The changes to use a generic Inventory type and add Handle support are consistent with treating skills as standard assets.

Also applies to: 14-14, 49-52


Line range hint 18-45: LGTM! System implementation remains robust with generic inventory.

The core swap functionality is preserved while benefiting from the more flexible inventory type.


Line range hint 1-180: Verify consistent adoption of asset-based skill handling.

Let's ensure all inventory usages have been updated to use the new pattern consistently across the codebase.

✅ Verification successful

Based on the comprehensive search results, I can now provide a final response:

Asset-based skill handling has been consistently implemented.

The codebase shows consistent usage of Handle<Skill> across all inventory-related components and systems:

  • The base type definition Inventory<TSkill = Handle<Skill>> correctly defaults to using Handle<Skill>
  • All test cases and implementations consistently use Handle<Skill> when instantiating SkillItem and Inventory
  • No instances of direct Skill usage were found in inventory contexts
  • The type system enforces this pattern through generic constraints and default type parameters
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of Inventory<Skill> or inconsistent patterns

# Test 1: Look for old Inventory<Skill> pattern
echo "Checking for old Inventory<Skill> pattern..."
rg "Inventory<Skill>"

# Test 2: Look for potential SkillItem usage without Handle
echo "Checking for SkillItem usage without Handle..."
rg "SkillItem(?!<Handle<Skill>)" --type rust

# Test 3: Verify all inventory-related tests follow the new pattern
echo "Checking inventory test patterns..."
ast-grep --pattern 'fn $test_name() {
  $$$
  Inventory::<$type>::new($$$)
  $$$
}'

Length of output: 679


Script:

#!/bin/bash
# Let's try a different approach with simpler patterns

# Check for SkillItem usage patterns
echo "Checking SkillItem usage patterns..."
rg "SkillItem" -A 2 --type rust

# Check Inventory type declarations and usages
echo "Checking Inventory type declarations and usages..."
rg "Inventory::" --type rust

# Look for skill-related type parameters
echo "Checking skill-related generic type parameters..."
rg "Inventory<" --type rust

Length of output: 54925

src/plugins/menu/src/systems/items/swap/equipped_items.rs (3)

Line range hint 1-93: LGTM! Main implementation is type-safe and robust.

The system implementation correctly handles the type changes while maintaining its core functionality. The error handling and cleanup processes are well-implemented.


Line range hint 94-114: LGTM! Type changes are consistent with asset-based approach.

The update to use Handle<Skill> aligns with treating skills as standard assets.


Line range hint 1-207: Verify complete migration from UUID to asset-based skill identification.

The changes look good, but let's verify that no UUID-based skill identification remains in related files.

✅ Verification successful

Let me check the context of those UUID references to ensure they're not problematic.


No issues found - UUID usage is only in test fixtures

The UUID references found are exclusively in test code where they're used to create deterministic test handles. The actual implementation correctly uses Bevy's asset system with Handle<Skill>. The migration from UUID to asset-based skill identification is complete.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining UUID references in skill-related files
rg -i "uuid.*skill|skill.*uuid" --type rust

# Search for old Skill type usage without Handle
ast-grep --pattern 'Slots::<Skill>'
ast-grep --pattern 'SkillItemContent::<Skill>'

Length of output: 474


Script:

#!/bin/bash
# Get context around the UUID references
rg -B 5 -A 5 "uuid.*skill|skill.*uuid" --type rust

# Check if these are test fixtures
fd "get_quickbar_icons" -t f -x cat {}

Length of output: 9537

src/plugins/skills/src/components/inventory.rs (3)

4-4: LGTM: Import changes align with asset-based skill handling.

The addition of skills::Skill and bevy::prelude::* imports supports the transition to treating skills as Bevy assets.

Also applies to: 7-7


Line range hint 15-201: LGTM: Robust implementation with comprehensive test coverage.

The existing implementation is well-designed:

  • Type-generic implementations ensure compatibility with the new Handle<Skill> type
  • Comprehensive test coverage using mock types validates the behavior
  • No implementation changes were needed, demonstrating good initial design

13-13: Verify the impact of the default type parameter change.

The modification to use Handle<Skill> as the default type parameter aligns with the PR objective of treating skills as assets. However, we should verify that all existing inventory usages are compatible with this change.

✅ Verification successful

Based on the search results, I can now generate the final response:

The default type parameter change is safe and all usages are compatible

All existing usages of Inventory in the codebase are either:

  • Using the default type parameter implicitly
  • Explicitly using Handle<Skill> as the type parameter
  • Part of generic implementations that are type-agnostic

The change aligns perfectly with the existing codebase, particularly evident in:

  • src/plugins/menu/src/systems/items/swap/inventory_items.rs where Inventory is explicitly used with Handle<Skill>
  • src/plugins/skills/src/lib.rs where the type is used as Inventory<Handle<Skill>>
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for direct Inventory type usage to ensure compatibility with new default type parameter

# Test 1: Look for explicit Inventory type usage that might need adjustment
rg "Inventory<" --type rust

# Test 2: Look for inventory instantiation patterns
rg "Inventory::new" --type rust -A 2

Length of output: 2931

src/plugins/skills/src/systems/visualize_slot_items.rs (3)

84-85: LGTM: Type parameter simplification

The removal of explicit type parameter Slots::<Skill>::new in favor of Slots::new is a good simplification that aligns with treating skills as standard assets. The type inference works correctly here.


128-131: LGTM: Consistent type parameter simplification

The simplification is consistently applied in the multi-item test case while maintaining comprehensive test coverage for multiple slot scenarios.


152-152: Verify consistent Handle usage across the codebase

The change to SkillItemContent::<Handle<Skill>> aligns with treating skills as assets. Let's verify this pattern is consistently applied.

Also applies to: 188-188

✅ Verification successful

Let me gather more information about the SkillItemContent type definition to understand if it's generic and how it's being used.


No issues found - type parameter usage is correct

The SkillItemContent is already defined as a generic struct with a default type parameter Handle<Skill>: struct SkillItemContent<TSkill = Handle<Skill>>. The explicit type annotation in the reviewed code SkillItemContent::<Handle<Skill>> is redundant but valid since it matches the default type parameter. The rest of the codebase mostly relies on the default type parameter, which is why we see many usages without explicit type annotation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining direct Skill usage that should be Handle<Skill>
rg "SkillItemContent[^<]" --type rust

# Search for the new pattern to confirm consistent usage
rg "SkillItemContent::<Handle<Skill>>" --type rust

Length of output: 6215


Script:

#!/bin/bash
# Find the definition of SkillItemContent
ast-grep --pattern 'struct SkillItemContent'

# Look for type parameters or where clauses
rg "SkillItemContent" -B2 -A2 --type rust src/plugins/skills/src/item.rs

Length of output: 969

src/plugins/skills/src/components/slots.rs (3)

7-7: LGTM! Import change aligns with Bevy conventions.

The switch to bevy::prelude::* follows Bevy's recommended practices for importing common traits and types.


11-13: Well-designed change to handle-based skill references!

The modification to use Handle<Skill> as the default type parameter is a good architectural decision because:

  • It aligns with Bevy's asset management system
  • Handles are lightweight references, improving performance
  • The generic type parameter maintains flexibility while providing a sensible default

12-12: Verify consistent handle usage across the codebase.

Let's ensure that all skill references have been updated to use handles consistently.

✅ Verification successful

Based on the search results, I can now generate the final response since I have enough information to verify the handle usage consistency.

Handle usage is correctly implemented across the codebase

The codebase consistently uses Handle<Skill> as the default type parameter in all relevant places:

  • Default slot container: Slots<TSkill = Handle<Skill>>
  • Default inventory container: Inventory<TSkill = Handle<Skill>>
  • Default skill item: SkillItem<TSkill = Handle<Skill>>

The direct Skill usages found are appropriate as they are for:

  • Asset type definitions
  • Struct implementations
  • Test code
  • Internal type aliases
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any direct Skill usage that should be Handle<Skill>
# Expect: All skill references should use Handle<Skill> except in asset definitions

# Search for direct Skill usage
rg --type rust "Skill[^<]" --glob "!**/asset*.rs"

# Search for Handle<Skill> usage to compare
rg --type rust "Handle<Skill>" 

Length of output: 162376

src/plugins/skills/src/systems/equip.rs (1)

Line range hint 1-309: Changes align well with PR objectives.

The transition from direct Skill references to Handle<Skill> aligns with the goal of treating skills as standard assets. The implementation:

  • Properly uses Bevy's asset handling patterns
  • Maintains existing functionality
  • Includes comprehensive test coverage
src/plugins/menu/src/lib.rs (1)

277-277: LGTM! Verify asset loading implementation.

The simplified type signature aligns with the PR objective to treat skills as standard assets. However, let's verify the asset loading implementation.

✅ Verification successful

Based on the search results, I can now provide a definitive response about the change to panel_container_states. The code shows that Inventory is a type alias defined in src/plugins/skills/src/components/inventory.rs as:

pub type Inventory<TSkill = Handle<Skill>> = Collection<Option<SkillItem<TSkill>>>;

The change to remove the explicit <Skill> type parameter is correct because:

  1. The type alias already has a default type parameter Handle<Skill>
  2. The codebase consistently uses this default throughout (as seen in the test cases and implementations)
  3. The change aligns with treating skills as standard assets loaded via paths

The type simplification is safe and correct.

The asset loading is properly handled through the default type parameter and Bevy's asset system.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the Inventory type implementation and asset loading
# Look for the Inventory type definition and any asset loading related code

# Search for Inventory type definition
echo "=== Inventory Type Definition ==="
rg --type rust "struct Inventory" -A 5

# Search for asset loading implementations
echo "=== Asset Loading Implementation ==="
rg --type rust "impl.*AssetLoader.*Skill" -A 10

Length of output: 1545


Script:

#!/bin/bash
# Let's search for Inventory type and related asset loading implementations with broader patterns

# Search for Inventory type and its implementation
echo "=== Inventory Type and Implementation ==="
rg --type rust "^(pub )?struct Inventory|^impl.*Inventory" -A 5

# Search for skill-related asset loading code with broader patterns
echo "=== Skill Asset Loading ==="
rg --type rust "(load|Load).*Skill|Skill.*[Aa]sset" -A 5

# Search for inventory-related systems and asset handling
echo "=== Inventory Systems and Asset Handling ==="
rg --type rust "fn.*inventory.*asset|system.*inventory.*asset" -A 5

Length of output: 9283


Script:

#!/bin/bash
# Let's find the Inventory struct definition and its generic implementation

# Search for Inventory struct definition
echo "=== Inventory Struct Definition ==="
rg --type rust -p "struct Inventory\s*(<[^>]+>)?\s*\{" -A 10

# Search for the specific file where the change was made to understand the context better
echo "=== Context Around the Changed Line ==="
rg --type rust -p "panel_container_states.*Inventory" -B 5 -A 5 src/plugins/menu/src/lib.rs

# Look for skill item related types
echo "=== Skill Item Types ==="
rg --type rust "SkillItem|SkillItemContent" -A 5

Length of output: 86617

src/plugins/menu/src/systems/dropdown/insert_skill_select_dropdown.rs (2)

184-262: LGTM! Well-structured test for skill deduplication.

The test effectively validates the deduplication functionality by:

  1. Setting up test data with duplicate skills
  2. Verifying that only unique skills appear in the dropdown
  3. Following consistent test patterns

Line range hint 1-262: Verify alignment with PR objective of removing skill UUIDs.

While the deduplication changes are valuable, please verify how this file's changes contribute to the PR's main objective of treating skills as standard assets and removing UUIDs.

src/plugins/menu/src/systems/update_panels/get_quickbar_icons.rs (3)

Line range hint 21-34: LGTM: Clean transition to asset-based skill handling.

The addition of the skills resource and its integration into the system aligns well with the PR's objective of treating skills as standard assets. The changes maintain the system's core functionality while adopting a more standardized approach to asset management.


73-81: LGTM: Robust asset retrieval implementation.

The helper function's adaptation to use asset handles is well-implemented, maintaining proper error handling through the Option chain and preserving lifetime constraints.


198-201: LGTM: Comprehensive test coverage maintained.

The test cases have been properly adapted to the new asset-based approach while maintaining thorough coverage of all scenarios. The modifications preserve the original behavioral verification while accommodating the new implementation.

Also applies to: 227-235, 250-253, 279-282, 305-308, 341-344, 377-378

src/plugins/loading/src/asset_loader.rs (2)

9-11: Good use of PhantomData for type safety

The phantom_data field correctly utilizes PhantomData to maintain type information without storing actual data.


31-39: Trait bounds and implementations are appropriate

The implementation of the AssetLoader trait with the specified associated types and trait bounds is correct and aligns with the requirements for custom asset loading in Bevy.

src/plugins/skills/src/systems/enqueue.rs (12)

7-9: Add necessary imports for Assets and Handle

The addition of Assets and Handle imports from bevy::asset is appropriate for managing asset resources and skill handles in the system.


14-14: Update TSlots generic to use Handle<Skill>

Changing TSlots to GetRef<SlotKey, Handle<Skill>> ensures that slots now store skill handles rather than direct Skill instances. This aligns with the new asset loading strategy and improves memory efficiency.


20-20: Inject skills resource into enqueue function

Adding skills: Res<Assets<Skill>> to the function parameters allows access to the skill assets, enabling the retrieval of Skill instances from their handles.


24-24: Pass skills resource to enqueue_new_skills function

Including &skills in the call to enqueue_new_skills ensures that the function has the necessary resources to resolve skill handles to actual skills.


29-34: Modify enqueue_new_skills to accept skills

The enqueue_new_skills function now accepts skills: &Assets<Skill>>, enabling it to retrieve Skill instances using the handles provided by slots.


36-36: Pass skills to enqueue_new_skill

Passing skills to enqueue_new_skill allows for the resolution of skill handles within the function.


40-45: Update enqueue_new_skill to handle skill handles and assets

By accepting skills: &Assets<Skill>> and updating the generics to use Handle<Skill>, the function can now retrieve the actual Skill instances needed for enqueueing.


116-116: Update _Skills struct to store Handle<Skill>

Changing _Skills to hold a HashMap<SlotKey, Handle<Skill>> reflects the shift to using handles for skill management, which improves consistency with the asset system.


118-119: Adjust GetRef implementation for _Skills

The get method now returns Option<&Handle<Skill>>, allowing retrieval of skill handles that can be resolved to actual skills elsewhere.


144-146: Verify skill insertion into Assets<Skill> in setup function

Inserting skills using skill_assets.insert(id, skill) may not align with Bevy's standard asset management practices, which typically auto-generate asset IDs.

Please confirm that manually assigning AssetId when inserting into Assets<Skill> is appropriate. If not, consider using the add method, which returns a Handle<Skill>:

-for (id, skill) in skills {
-    skill_assets.insert(id, skill);
+for (_, skill) in skills {
+    skill_assets.add(skill);
 }

This approach leverages Bevy's asset system to manage asset IDs automatically.

Also applies to: 148-154


193-195: Ensure correct handle usage in enqueue_skill_from_skills test

In the test, verify that the handle's ID corresponds to the skill inserted into Assets<Skill>. Using handle.id() assumes that the handle's ID matches the asset's ID in Assets<Skill>.

Consider obtaining the handle from skill_assets.add(skill) to ensure consistency.

Also applies to: 200-204


229-229: Tests correctly initialize with empty skills where appropriate

In the prime_skill, prime_skill_matching_with_key, and prime_all_in_queue tests, initializing the app with empty skills is suitable, as these tests focus on the queuing and priming logic rather than skill retrieval.

Also applies to: 247-247, 275-275

src/plugins/skills/src/lib.rs (7)

48-48: Import of skill_asset macro is appropriate

The addition of use macros::skill_asset; correctly brings the skill_asset! macro into scope for use in asset loading.


51-51: Proper import of skill-related types

The line use skills::{skill_data::SkillData, QueuedSkill, RunSkillBehavior, Skill}; imports the necessary types for skill execution and data handling, ensuring they're available in this module.


146-150: Addition of asset_server parameter to set_player_items function

Including asset_server: Res<AssetServer> in the parameters allows the function to load assets, aligning with the need to pass asset_server to get_inventory and get_loadout.


159-160: Passing asset_server to helper functions

The asset_server is appropriately passed to Self::get_inventory and Self::get_loadout, enabling these functions to load assets as needed.


166-166: Definition of get_loadout with asset_server parameter

The get_loadout function now accepts asset_server: &AssetServer, which is necessary for loading skill assets.


234-234: Definition of get_inventory with asset_server parameter

The get_inventory function now accepts asset_server: &AssetServer, which allows it to load skill assets properly.


275-275: Usage of ComboBundle::with_timeout is appropriate

The call to ComboBundle::with_timeout(timeout) correctly initializes the combo bundle with the specified timeout duration.

src/plugins/macros/src/lib.rs Show resolved Hide resolved
src/plugins/loading/src/folder_asset_loader.rs Outdated Show resolved Hide resolved
src/plugins/skills/src/systems/enqueue.rs Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (15)
src/plugins/loading/src/asset_loader.rs (1)

31-63: LGTM! Consider adding documentation for the asset loading workflow.

The implementation is robust with comprehensive error handling. To improve maintainability, consider adding documentation explaining:

  • The expected format of the JSON data
  • The relationship between TAsset and TDto
  • Examples of typical usage patterns

Add documentation like this:

+/// A generic asset loader that loads assets from JSON files.
+/// 
+/// # Type Parameters
+/// 
+/// * `TAsset` - The final asset type that will be loaded into the game
+/// * `TDto` - The intermediate DTO type that the JSON deserializes into
+/// 
+/// # Example JSON Format
+/// 
+/// ```json
+/// {
+///   // Fields matching TDto structure
+/// }
+/// ```
 impl<TAsset, TDto> AssetLoader for CustomAssetLoader<TAsset, TDto>
src/plugins/skills/src/components/inventory.rs (3)

Line range hint 17-27: Document the auto-expansion behavior.

The GetMut implementation automatically expands the inventory when accessing an out-of-range index. While this behavior is tested, it would be helpful to document this important detail in the implementation comments.

Add documentation above the impl block:

+/// Provides mutable access to inventory items.
+/// The inventory automatically expands with None values when accessing an out-of-range index.
 impl GetMut<InventoryKey, Option<SkillItem>> for Inventory {

29-34: Consider using vec::resize_with for better performance.

The current implementation uses a loop to push items individually. For better performance with large expansions, consider using Vec::resize_with.

 fn fill(inventory: &mut Vec<Option<SkillItem>>, inventory_key: usize) {
-    let fill_len = inventory_key - inventory.len() + 1;
-    for _ in 0..fill_len {
-        inventory.push(None);
-    }
+    inventory.resize_with(inventory_key + 1, || None);
 }

Line range hint 36-124: Consider adding a stress test for large expansions.

The current tests cover the basic functionality well, but consider adding a test case for large index values to ensure performance characteristics are acceptable.

Add a test like this:

#[test]
fn get_item_mut_large_expansion() {
    let mut inventory = Inventory::new([]);
    let large_index = 10000;
    
    // This should not cause performance issues
    inventory.get_mut(&InventoryKey(large_index));
    
    assert_eq!(inventory.0.len(), large_index + 1);
    assert!(inventory.0.iter().all(|item| item.is_none()));
}
src/plugins/skills/src/components/slots.rs (1)

28-35: Consider enhancing error handling in skill handle retrieval.

The current implementation silently returns None when either the slot is empty or the skill handle is missing. Consider adding logging or error context to help diagnose issues during development.

 impl GetRef<SlotKey, Handle<Skill>> for Slots {
     fn get(&self, key: &SlotKey) -> Option<&Handle<Skill>> {
-        let item: &SkillItem = self.get(key)?;
-
-        item.content.skill.as_ref()
+        let item: &SkillItem = self.get(key).or_else(|| {
+            debug!("No skill item found in slot: {:?}", key);
+            None
+        })?;
+        
+        item.content.skill.as_ref().or_else(|| {
+            debug!("Skill item found but no skill handle present: {:?}", item);
+            None
+        })
     }
 }
src/plugins/macros/src/lib.rs (1)

124-128: Consider enhancing the error message with the actual path.

The error message could be more helpful by including the constructed path that was not found.

-			compile_error!("No skill with that name found in `assets/skills/`")
+			compile_error!(concat!("No skill found at `", #path, "`"))
src/plugins/loading/src/folder_asset_loader.rs (1)

119-127: Consider adding documentation for error handling.

The Error trait implementation is well-structured and maintains proper error chains. Consider adding documentation to explain the error hierarchy and how errors propagate through the asset loading system.

Add documentation above the implementation:

+/// Implements std::error::Error for LoadError, maintaining the error chain
+/// through the source() method. This allows tracking the original cause of
+/// failures during asset loading.
 impl Error for LoadError {
src/plugins/skills/src/systems/enqueue.rs (3)

14-28: LGTM: System parameter changes follow Bevy's best practices.

The addition of skills: Res<Assets<Skill>> parameter and its usage follows Bevy's recommended patterns for asset access in systems. This ensures efficient read-only access to skill assets across the system.

Consider adding error logging when skills cannot be accessed, as this could help diagnose asset loading issues in production.


40-54: Consider enhancing error handling for skill asset retrieval.

While the code correctly handles skill asset retrieval, it silently fails when a skill cannot be found. This could make debugging difficult in production.

Consider adding debug logging when skill retrieval fails:

 fn enqueue_new_skill<TSlots: GetRef<SlotKey, Handle<Skill>>, TQueue: Enqueue<(Skill, SlotKey)>>(
     key: &SlotKey,
     queue: &mut TQueue,
     slots: &TSlots,
     skills: &Assets<Skill>,
 ) {
     let Some(skill) = slots.get(key).cloned() else {
+        debug!("No skill handle found for slot key: {:?}", key);
         return;
     };
     let Some(skill) = skills.get(&skill).cloned() else {
+        debug!("Failed to load skill asset: {:?}", skill);
         return;
     };

Line range hint 144-295: LGTM: Test changes properly cover asset-based skill handling.

The test setup and cases correctly handle the new asset-based approach. The mock implementations and assertions are appropriate.

Consider adding these test cases to improve coverage:

  1. Attempting to enqueue a skill with an invalid handle
  2. Attempting to enqueue a skill that exists in slots but not in assets
  3. Testing concurrent access to skill assets from multiple systems
src/plugins/skills/src/lib.rs (1)

Line range hint 166-232: Consider extracting common SkillItemContent creation logic.

While the asset loading implementation is correct, there's repeated code for creating similar SkillItemContent structures for plasma pistols. Consider extracting this into a helper function.

Example refactor:

fn create_pistol_item(name: &str, asset_server: &AssetServer) -> SkillItem {
    SkillItem {
        name,
        content: SkillItemContent {
            render: Renderer {
                model: ModelRender::Hand(AssetModel::Path("models/pistol.glb")),
                essence: EssenceRender::StandardMaterial,
            },
            skill: Some(asset_server.load(skill_asset!("shoot_hand_gun"))),
            item_type: SkillItemType::Pistol,
        },
    }
}
src/plugins/menu/src/systems/dropdown/insert_skill_select_dropdown.rs (2)

43-57: LGTM! Consider using HashSet for seen skills.

The implementation correctly prevents duplicate skills in the dropdown. However, since we're only checking for containment, using a HashSet instead of a Vec for seen could be more efficient, especially with a large number of skills.

-    let mut seen = Vec::new();
+    let mut seen = HashSet::new();
     let skills = skills
         .iter()
         .filter(|(_, skill)| {
             if !skill.is_usable_with.contains(&item.content.item_type) {
                 return false;
             }
-            if seen.contains(skill) {
+            if !seen.insert(skill) {
                 return false;
             }
-
-            seen.push(skill);
             true
         })

184-262: Consider improving test clarity and efficiency.

While the test correctly verifies skill deduplication, consider these improvements:

  1. Rename the test to be more specific, e.g., test_dropdown_deduplicates_identical_skills
  2. Simplify the test by using just one duplicate skill instead of including an additional unique skill
  3. Add a comment explaining that the duplicate skills are intentional for testing deduplication
-    fn list_unique_skills() {
+    fn test_dropdown_deduplicates_identical_skills() {
+        // Create two identical skills to verify deduplication
         let image_b = new_handle();
         let skills = [
-            Skill {
-                name: "skill a".to_owned(),
-                is_usable_with: HashSet::from([SkillItemType::Pistol]),
-                icon: Some(image_a.clone()),
-                ..default()
-            },
             Skill {
                 name: "skill b".to_owned(),
                 is_usable_with: HashSet::from([SkillItemType::Pistol, SkillItemType::Bracer]),
                 icon: Some(image_b.clone()),
                 ..default()
             },
             Skill {
                 name: "skill b".to_owned(),
                 is_usable_with: HashSet::from([SkillItemType::Pistol, SkillItemType::Bracer]),
                 icon: Some(image_b.clone()),
                 ..default()
             },
         ];
src/plugins/skills/src/components/combo_node.rs (2)

Line range hint 22-24: Consider adding documentation for the ComboNode struct.

While the implementation is solid, adding documentation comments (///) would improve code maintainability by explaining:

  • The purpose of the ComboNode structure
  • The relationship between skills and nodes
  • The significance of ordering in the combo system
+/// A tree structure representing skill combinations where each node contains a skill and its possible follow-up skills.
+/// The order of combinations is preserved using OrderedHashMap to maintain consistent combo sequences.
 #[derive(Component, Clone, PartialEq, Debug)]
 pub struct ComboNode<TSkill = Skill>(OrderedHashMap<SlotKey, (TSkill, ComboNode<TSkill>)>);

Line range hint 302-303: Consider adding tests for asset path-based skill loading.

With the transition from UUID to asset-based skill identification, consider adding test cases that verify:

  • Loading skills from valid asset paths
  • Handling of invalid asset paths
  • Path resolution edge cases
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 1f19300 and 3c8acae.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (34)
  • assets/skills/force_shield.skill (0 hunks)
  • assets/skills/gravity_well.skill (0 hunks)
  • assets/skills/shoot_hand_gun.skill (0 hunks)
  • src/plugins/items/src/lib.rs (1 hunks)
  • src/plugins/loading/src/asset_loader.rs (1 hunks)
  • src/plugins/loading/src/folder_asset_loader.rs (1 hunks)
  • src/plugins/loading/src/lib.rs (1 hunks)
  • src/plugins/loading/src/traits.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_assets.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_assets/app.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_folder_assets.rs (1 hunks)
  • src/plugins/loading/src/traits/register_custom_folder_assets/app.rs (2 hunks)
  • src/plugins/macros/Cargo.toml (1 hunks)
  • src/plugins/macros/src/lib.rs (1 hunks)
  • src/plugins/menu/src/lib.rs (1 hunks)
  • src/plugins/menu/src/systems/dropdown/insert_skill_select_dropdown.rs (2 hunks)
  • src/plugins/menu/src/systems/items/swap/equipped_items.rs (5 hunks)
  • src/plugins/menu/src/systems/items/swap/inventory_items.rs (8 hunks)
  • src/plugins/menu/src/systems/update_panels/get_quickbar_icons.rs (13 hunks)
  • src/plugins/skills/Cargo.toml (1 hunks)
  • src/plugins/skills/src/bundles.rs (3 hunks)
  • src/plugins/skills/src/components/combo_node.rs (1 hunks)
  • src/plugins/skills/src/components/inventory.rs (6 hunks)
  • src/plugins/skills/src/components/slots.rs (4 hunks)
  • src/plugins/skills/src/item.rs (2 hunks)
  • src/plugins/skills/src/lib.rs (11 hunks)
  • src/plugins/skills/src/skills.rs (0 hunks)
  • src/plugins/skills/src/skills/skill_data.rs (1 hunks)
  • src/plugins/skills/src/systems.rs (0 hunks)
  • src/plugins/skills/src/systems/enqueue.rs (8 hunks)
  • src/plugins/skills/src/systems/equip.rs (7 hunks)
  • src/plugins/skills/src/systems/uuid_to_skill.rs (0 hunks)
  • src/plugins/skills/src/systems/visualize_slot_items.rs (6 hunks)
  • src/plugins/skills/src/traits.rs (0 hunks)
💤 Files with no reviewable changes (7)
  • assets/skills/force_shield.skill
  • assets/skills/gravity_well.skill
  • assets/skills/shoot_hand_gun.skill
  • src/plugins/skills/src/skills.rs
  • src/plugins/skills/src/systems.rs
  • src/plugins/skills/src/systems/uuid_to_skill.rs
  • src/plugins/skills/src/traits.rs
🚧 Files skipped from review as they are similar to previous changes (17)
  • src/plugins/items/src/lib.rs
  • src/plugins/loading/src/lib.rs
  • src/plugins/loading/src/traits.rs
  • src/plugins/loading/src/traits/register_custom_assets.rs
  • src/plugins/loading/src/traits/register_custom_assets/app.rs
  • src/plugins/loading/src/traits/register_custom_folder_assets.rs
  • src/plugins/loading/src/traits/register_custom_folder_assets/app.rs
  • src/plugins/macros/Cargo.toml
  • src/plugins/menu/src/lib.rs
  • src/plugins/menu/src/systems/items/swap/equipped_items.rs
  • src/plugins/menu/src/systems/items/swap/inventory_items.rs
  • src/plugins/menu/src/systems/update_panels/get_quickbar_icons.rs
  • src/plugins/skills/Cargo.toml
  • src/plugins/skills/src/item.rs
  • src/plugins/skills/src/skills/skill_data.rs
  • src/plugins/skills/src/systems/equip.rs
  • src/plugins/skills/src/systems/visualize_slot_items.rs
🧰 Additional context used
📓 Learnings (1)
src/plugins/macros/src/lib.rs (1)
Learnt from: codaishin
PR: codaishin/project-zyheeda-bevy#283
File: src/plugins/macros/src/lib.rs:115-119
Timestamp: 2024-11-07T18:10:42.156Z
Learning: In the `skill_asset` macro in `src/plugins/macros/src/lib.rs`, skill names do not require additional input validation beyond checking that the corresponding skill file exists.
🔇 Additional comments (22)
src/plugins/loading/src/asset_loader.rs (3)

1-11: LGTM! Well-structured imports and type definition.

The imports are minimal and well-organized. The struct definition correctly uses PhantomData for zero-sized type parameters and has appropriate crate-level visibility.


23-29: LGTM! Correct Default implementation.

The implementation follows Rust idioms for PhantomData initialization.


31-63: Verify the asset loading implementation usage.

Let's verify how this loader is being used in the codebase, particularly for skill assets.

✅ Verification successful

Let me gather more specific information about the skill asset implementation and usage.


Based on the gathered information, I can now provide the final response:

The asset loading implementation is correctly used and integrated

The verification shows that:

  • SkillData properly implements AssetFileExtensions with the ".skill" extension
  • Skill correctly implements LoadFrom<SkillData> with proper asset conversion
  • The custom asset loader is properly integrated through the registration system
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all asset registrations and skill-related asset types

echo "Searching for asset registrations using CustomAssetLoader..."
rg -l "CustomAssetLoader" --type rust

echo -e "\nSearching for skill asset type definitions..."
ast-grep --pattern 'struct $name:ident {
  $$$
}
where
  $$$
  Asset $$$
  $$$'

echo -e "\nSearching for skill file extensions..."
rg "asset_file_extensions" --type rust -A 2

Length of output: 3577


Script:

#!/bin/bash
# Find skill asset implementation and registration
echo "Searching for skill asset implementation..."
rg -A 10 "impl.*Asset.*Skill" --type rust

echo -e "\nSearching for skill asset registration..."
rg -A 5 "register_custom_asset.*Skill" --type rust

echo -e "\nSearching for SkillData struct definition..."
ast-grep --pattern 'struct SkillData {
  $$$
}'

echo -e "\nLooking for LoadFrom implementation for skills..."
ast-grep --pattern 'impl LoadFrom<$_> for $_ {
  $$$
}'

Length of output: 4605

src/plugins/skills/src/components/inventory.rs (1)

8-8: LGTM: Type simplification aligns with PR objectives.

The removal of the generic type parameter from Inventory aligns well with treating skills as standard assets, making the code more straightforward.

Let's verify this change doesn't break any existing usages:

✅ Verification successful

Based on the search results, I can now generate the final response since we have comprehensive information about the Inventory type usage across the codebase:

Verified: Type simplification is safe and consistent

The removal of the generic type parameter from Inventory is safe as all usages across the codebase consistently use it with Option<SkillItem>. The change aligns with treating skills as standard assets and maintains compatibility with all existing implementations:

  • All imports and usages in menu systems
  • Trait implementations for GetRef and GetMut
  • Integration with game state management
  • Swap and inventory management systems
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining generic Inventory usage that might need updating
rg "Inventory<" --type rust

Length of output: 29


Script:

#!/bin/bash
# Let's try a broader search to find all usages of Inventory type
rg "Inventory" --type rust -B 2 -A 2

# Also search for any imports of the Inventory type
rg "use.*Inventory" --type rust

Length of output: 32575

src/plugins/skills/src/components/slots.rs (2)

1-7: LGTM! Clean struct definition with appropriate trait derivations.

The simplified Slots struct without generic parameters aligns well with the PR's objective of treating skills as standard assets. The use of HashMap provides efficient slot-based storage with O(1) access time.


Line range hint 37-125: Consider adding tests for edge cases.

While the current test coverage is good, consider adding tests for these scenarios:

  • Empty slots (HashMap entry with Some(None))
  • Invalid skill handles
  • Multiple slots with various states

Let's check if these cases are tested elsewhere:

src/plugins/macros/src/lib.rs (1)

113-133: LGTM! The implementation aligns with the PR objectives.

The macro correctly implements the new approach of treating skills as standard assets, with appropriate validation and error handling.

src/plugins/loading/src/folder_asset_loader.rs (2)

107-117: LGTM! Well-implemented error messages.

The Display implementation provides clear, user-friendly error messages for each error type. This implementation effectively addresses the previous review comment about enhancing error handling.


107-127: Verify error handling in skill loading code.

Let's ensure that skill loading code properly handles these error cases.

✅ Verification successful

Let me gather more information about the error handling implementation and usage.


Based on the extensive search results, I can now provide a definitive response about the error handling implementation:

Error handling is properly implemented and consistent with asset loading system

The error handling implementation in LoadError is well integrated with Bevy's asset loading system and properly handles all error cases:

  1. The error types are used consistently throughout the codebase:

    • LoadError::IO for file reading errors
    • LoadError::ParseChars for character encoding errors
    • LoadError::ParseObject for JSON parsing errors
  2. The implementation is used by both the custom asset loader (CustomAssetLoader) and folder asset loader (FolderAssetLoader) to handle skill loading and other assets in a consistent way.

  3. The error handling integrates with Bevy's asset system through:

    • Proper implementation of Error and Display traits
    • Integration with LoadResult enum that wraps assets and errors
    • Consistent error propagation through the asset loading pipeline
  4. The error handling is actively used by the skill loading system through the register_custom_folder_assets functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if skill loading code properly handles LoadError cases

# Search for skill loading code that might use this error handling
rg -l "\.skill'?" | xargs rg "LoadResult|LoadError" -B 2 -A 2

# Look for any custom error handling in skill-related files
rg -l "skill" | xargs rg "impl.*Error" -B 2 -A 2

Length of output: 1509


Script:

#!/bin/bash
# Search for LoadError usage in the codebase
rg "LoadError" -B 2 -A 2

# Search for skill asset loading implementation
ast-grep --pattern 'impl $_ for $_ {
  $$$
  load($$$) {
    $$$
  }
  $$$
}'

# Check for any asset loading related traits and their implementations
rg "Asset|Loader" -B 2 -A 2

Length of output: 213541

src/plugins/skills/src/systems/enqueue.rs (1)

7-14: LGTM: Import changes and type signatures align with asset-based approach.

The changes correctly introduce the necessary Bevy asset types and update the generic parameter to use Handle<Skill>, aligning with the PR's objective to treat skills as standard assets.

src/plugins/skills/src/lib.rs (5)

48-48: LGTM: Import changes align with asset-based skill management.

The changes to imports reflect the transition from UUID-based to asset-based skill management, which aligns with the PR objectives.

Also applies to: 51-51


102-104: LGTM: Simplified equip_item system registration.

The removal of SkillId generics simplifies the system registration while maintaining the functionality.


146-154: LGTM: Proper asset server injection.

The addition of the asset server parameter follows Bevy's dependency injection patterns and enables proper asset loading.


271-275: LGTM: Simplified combo system.

The combo system has been simplified to only maintain timeout functionality, which aligns with the PR's objective of streamlining skill management.


Line range hint 234-269: Verify asset paths exist.

The implementation correctly uses asset loading, but we should verify that all referenced skill assets exist in the project.

✅ Verification successful

Let me verify the model assets as well since they are also referenced in the code.


All referenced assets exist in the project

The verification confirms that:

  • The skill asset shoot_hand_gun.skill exists at assets/skills/shoot_hand_gun.skill
  • The model asset pistol.glb exists at assets/models/pistol.glb
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all referenced skill assets exist
# Extract skill asset paths and check if they exist

# Search for skill_asset! macro usage and verify the paths
rg --no-filename 'skill_asset!\("([^"]+)"\)' -or '$1' | while read -r path; do
    echo "Checking for skill asset: $path"
    fd -e skill "$path"
done

Length of output: 1244


Script:

#!/bin/bash
# Check if the referenced model files exist
fd -e glb "pistol.glb"

Length of output: 47

src/plugins/skills/src/components/combo_node.rs (2)

8-8: LGTM! Import changes align with PR objectives.

The removal of the TryMap trait from imports is consistent with the goal of treating skills as standard assets, simplifying the skill handling system.


Line range hint 1-1000: Verify complete removal of UUID references.

Let's ensure there are no remaining UUID references in the codebase that might affect this implementation.

✅ Verification successful

The search results show that all UUID references in the codebase are related to asset handling (Bevy's asset system) and UI components, not for skill identification. The UUIDs are being used appropriately for:

  1. Asset handles in the Bevy engine (images, meshes, scenes)
  2. UI components (fonts, icons)
  3. Resource management and caching
  4. Animation system

There are no UUID references in the skill system implementation or the combo system, confirming that the changes align with removing UUID-based skill identification while maintaining proper asset handling where needed.

Changes verified: UUID usage properly confined to asset management.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining UUID references in skill-related code
echo "Checking for UUID references in skill-related code..."
rg -i "uuid" --type rust

Length of output: 6489

src/plugins/skills/src/bundles.rs (5)

3-3: Addition of combos::Combos Import

Including combos::Combos in the import statements ensures that the Combos type is available for use in the ComboBundle struct.


11-11: Addition of item::SkillItem Import

The import of item::SkillItem provides access to the SkillItem type used within the Loadout struct.


20-20: Update combos Field in ComboBundle Struct

The combos: Combos field in the ComboBundle struct initializes the combos component, aligning with the updated design to manage combos without SkillId.


35-35: Simplify slot_definition Field in Loadout Struct

Changing the slot_definition field to Slots simplifies slot management by removing unnecessary generic parameters, enhancing code readability and maintainability.


40-40: Update new Method Signature in Loadout

The new method's parameter type is updated from Option<SkillItem<SkillId>> to Option<SkillItem>, reflecting the removal of SkillId and streamlining the API.

Please verify that all instances of SkillItem<SkillId> have been updated throughout the codebase to prevent type mismatches.

Run the following script to confirm that there are no remaining references to SkillItem<SkillId>:

✅ Verification successful

Based on the comprehensive search results, I can now generate the final response:

No Type Mismatches Found - SkillItem Usage is Consistent

The codebase shows that SkillItem is consistently used without the SkillId generic parameter. The type is defined as pub type SkillItem = Item<SkillItemContent<Handle<Skill>>> in src/plugins/skills/src/item.rs and all usages across the codebase follow this definition. The change in the new method signature is consistent with the rest of the implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for any remaining usage of `SkillItem<SkillId>` in the codebase

# Test: Find instances of `SkillItem<SkillId>`. Expect: No matches
rg -F 'SkillItem<SkillId>'

Length of output: 28


Script:

#!/bin/bash
# Let's try a more comprehensive search approach

# 1. Search for SkillItem type usage patterns
rg "SkillItem\s*<" --type rust

# 2. Look for SkillId type usage
rg "SkillId" --type rust -A 2 -B 2

# 3. Find the SkillItem type definition to understand its structure
rg "struct\s+SkillItem" --type rust -A 5

Length of output: 435


Script:

#!/bin/bash
# Let's examine the actual usage of SkillItem in the codebase

# 1. Search for SkillItem (without generic parameter) to see current usage
rg "\bSkillItem\b" --type rust -A 2 -B 2

# 2. Look at the bundles.rs file to understand the context better
cat src/plugins/skills/src/bundles.rs

# 3. Look for any type aliases or uses of SkillItem
rg "type.*SkillItem" --type rust
rg "use.*SkillItem" --type rust

Length of output: 51248

src/plugins/loading/src/asset_loader.rs Show resolved Hide resolved
@codaishin codaishin merged commit bae590e into master Nov 7, 2024
3 checks passed
@codaishin codaishin deleted the remove-skill-uuid branch November 7, 2024 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant