Files
ClassicAssist.Avalonia/.qoder/repowiki/en/content/Macro System/Custom Command Development.md
T
Beyhan Oğur d5f52cc3d3 first commit
2026-09-03 04:45:36 +03:00

402 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Custom Command Development
<cite>
**Referenced Files in This Document**
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [ParameterType.cs](file://ClassicAssist.Shared/Data/Macros/ParameterType.cs)
- [CommandsDisplayAttribute.cs](file://ClassicAssist.Shared/Data/Macros/CommandsDisplayAttribute.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [ConsumeCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/ConsumeCommands.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [ActionCommands.cs](file://ClassicAssist.Shared/Data/Macros/Commands/ActionCommands.cs)
- [MainCommands.cs](file://ClassicAssist.Shared/Data/Macros/Commands/MainCommands.cs)
- [MacroEntry.cs](file://ClassicAssist.Shared/Data/Macros/MacroEntry.cs)
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
- [UseOnceList.cs](file://ClassicAssist.Shared/Data/Macros/UseOnceList.cs)
- [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
</cite>
## Table of Contents
1. [Introduction](#introduction)
2. [Project Structure](#project-structure)
3. [Core Components](#core-components)
4. [Architecture Overview](#architecture-overview)
5. [Detailed Component Analysis](#detailed-component-analysis)
6. [Dependency Analysis](#dependency-analysis)
7. [Performance Considerations](#performance-considerations)
8. [Troubleshooting Guide](#troubleshooting-guide)
9. [Conclusion](#conclusion)
10. [Appendices](#appendices)
## Introduction
This document explains how to create custom macro commands for ClassicAssist.Avalonia, focusing on the command registration system using attributes and interfaces, parameter validation and conversion mechanisms, error handling patterns, and the command lifecycle from initialization through execution to cleanup. It also covers advanced topics such as asynchronous execution, command composition, inter-command communication, testing strategies, debugging techniques, performance optimization, and guidelines for distribution and version compatibility.
## Project Structure
The macro command system is primarily implemented in the shared layer and exposed to the Avalonia UI layer at runtime. Key areas include:
- Macro command definitions and invoker infrastructure
- Hotkey command attribute-based registration
- Display and help metadata for IntelliSense and documentation generation
- Managers that orchestrate discovery, parsing, and execution
```mermaid
graph TB
subgraph "Shared Layer"
MI["MacroInvoker.cs"]
MM["MacroManager.cs"]
ME["MacroEntry.cs"]
PT["ParameterType.cs"]
CDA["CommandsDisplayAttribute.cs"]
HCA["HotkeyCommandAttribute.cs"]
HC["HotkeyCommand.cs"]
HM["HotkeyManager.cs"]
CM["CommandsManager.cs"]
SMW["SystemMessageTextWriter.cs"]
UOL["UseOnceList.cs"]
end
subgraph "Avalonia Layer"
ENG["Engine.cs"]
APP["App.axaml.cs"]
end
ENG --> MM
ENG --> HM
HM --> HCA
HM --> HC
MM --> MI
MM --> ME
MM --> PT
MM --> CDA
MM --> SMW
MM --> UOL
ENG --> CM
```
**Diagram sources**
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroEntry.cs](file://ClassicAssist.Shared/Data/Macros/MacroEntry.cs)
- [ParameterType.cs](file://ClassicAssist.Shared/Data/Macros/ParameterType.cs)
- [CommandsDisplayAttribute.cs](file://ClassicAssist.Shared/Data/Macros/CommandsDisplayAttribute.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs)
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
- [UseOnceList.cs](file://ClassicAssist.Shared/Data/Macros/UseOnceList.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
**Section sources**
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
## Core Components
- MacroInvoker: Provides the runtime context and execution pipeline for macro commands, including parameter resolution and output routing.
- MacroManager: Discovers and manages macro commands, integrates with display attributes for help and IntelliSense, and coordinates invocation.
- ParameterType: Defines supported parameter types and conversion rules used by the macro system.
- CommandsDisplayAttribute: Supplies metadata (name, description, see-also) for documentation and help generation.
- HotkeyCommandAttribute and HotkeyCommand: Attribute-driven registration and base class for hotkey-invoked commands.
- SystemMessageTextWriter: Bridges command outputs into the application’s message system.
- UseOnceList: Utility for tracking one-time usage or state across command runs.
These components collectively enable a declarative approach to defining commands, robust parameter handling, and consistent user feedback.
**Section sources**
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [ParameterType.cs](file://ClassicAssist.Shared/Data/Macros/ParameterType.cs)
- [CommandsDisplayAttribute.cs](file://ClassicAssist.Shared/Data/Macros/CommandsDisplayAttribute.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
- [UseOnceList.cs](file://ClassicAssist.Shared/Data/Macros/UseOnceList.cs)
## Architecture Overview
The command architecture separates concerns between discovery, registration, invocation, and presentation:
- Discovery and Registration: Attributes annotate command classes; managers scan assemblies and register commands.
- Invocation Pipeline: The macro engine resolves parameters, validates inputs, converts types, executes logic, and routes output.
- Presentation and Help: Display attributes feed documentation and IntelliSense providers.
```mermaid
sequenceDiagram
participant User as "User"
participant UI as "Avalonia App"
participant Engine as "Engine.cs"
participant HM as "HotkeyManager.cs"
participant MM as "MacroManager.cs"
participant Inv as "MacroInvoker.cs"
participant Cmd as "YourCustomCommand"
participant Out as "SystemMessageTextWriter.cs"
User->>UI : Trigger command (macro/hotkey)
UI->>Engine : Request execution
Engine->>HM : Resolve hotkey/command mapping
HM-->>Engine : Command reference
Engine->>MM : Invoke command with arguments
MM->>Inv : Prepare execution context
Inv->>Cmd : Execute(commandArgs)
Cmd->>Out : Write status/messages
Out-->>UI : Render messages
Inv-->>MM : Result/status
MM-->>Engine : Completion
Engine-->>UI : Update UI/state
```
**Diagram sources**
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
## Detailed Component Analysis
### Command Registration via Attributes and Interfaces
- HotkeyCommandAttribute: Declares a command’s identity and metadata for hotkey binding and discovery.
- HotkeyCommand: Base class providing common behavior for hotkey-invoked commands.
- CommandsDisplayAttribute: Adds name, description, and related commands for help and IntelliSense.
```mermaid
classDiagram
class HotkeyCommand {
+Execute(args)
+OnInitialize()
+OnCleanup()
}
class HotkeyCommandAttribute {
+Name
+Description
}
class CommandsDisplayAttribute {
+Name
+Description
+SeeAlso
}
class YourCustomCommand {
+Execute(args)
}
HotkeyCommand <|-- YourCustomCommand
HotkeyCommandAttribute ..> HotkeyCommand : "annotates"
CommandsDisplayAttribute ..> YourCustomCommand : "documents"
```
**Diagram sources**
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [CommandsDisplayAttribute.cs](file://ClassicAssist.Shared/Data/Macros/CommandsDisplayAttribute.cs)
**Section sources**
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [CommandsDisplayAttribute.cs](file://ClassicAssist.Shared/Data/Macros/CommandsDisplayAttribute.cs)
### Parameter Validation and Conversion
- ParameterType enumerates supported input types and guides conversion during invocation.
- MacroInvoker orchestrates argument parsing, type conversion, and validation before calling command logic.
- Commands can leverage built-in conversions and provide clear error messages when inputs are invalid.
```mermaid
flowchart TD
Start(["Parse Arguments"]) --> Validate["Validate Required Parameters"]
Validate --> Valid{"All Valid?"}
Valid --> |No| Error["Return Error Message"]
Valid --> |Yes| Convert["Convert Types Using ParameterType"]
Convert --> Check["Check Constraints/Ranges"]
Check --> OK{"Constraints Met?"}
OK --> |No| Error
OK --> |Yes| Proceed["Proceed to Execution"]
Error --> End(["Exit"])
Proceed --> End
```
**Diagram sources**
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [ParameterType.cs](file://ClassicAssist.Shared/Data/Macros/ParameterType.cs)
**Section sources**
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [ParameterType.cs](file://ClassicAssist.Shared/Data/Macros/ParameterType.cs)
### Error Handling Patterns
- Commands should produce user-friendly messages via the system message writer.
- Use structured errors where possible and avoid swallowing exceptions.
- Centralized writers ensure consistent formatting and localization support.
```mermaid
flowchart TD
Entry(["Command Entry"]) --> TryBlock["Try Block"]
TryBlock --> Success{"Success?"}
Success --> |Yes| Done(["Return Status"])
Success --> |No| Catch["Catch Exception"]
Catch --> Format["Format Error Message"]
Format --> Write["Write via SystemMessageTextWriter"]
Write --> Done
```
**Diagram sources**
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
**Section sources**
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
### Command Lifecycle
- Initialization: Setup resources, caches, or one-time lists.
- Execution Context: Access parsed parameters and environment state.
- Cleanup: Release resources, reset transient state.
```mermaid
stateDiagram-v2
[*] --> Initialized
Initialized --> Executing : "Invoke"
Executing --> Completed : "Success"
Executing --> Failed : "Error"
Completed --> [*]
Failed --> [*]
```
[No sources needed since this diagram shows conceptual lifecycle, not actual code structure]
### Asynchronous Command Execution
- For long-running operations, prefer asynchronous patterns to keep the UI responsive.
- Ensure thread safety when accessing shared state and marshal UI updates appropriately.
- Provide cancellation tokens where applicable to allow users to abort operations.
[No sources needed since this section provides general guidance]
### Command Composition and Inter-Command Communication
- Compose complex workflows by invoking other commands programmatically.
- Use shared state or event-like mechanisms for inter-command communication.
- Maintain clear contracts for parameters and return values to avoid coupling.
[No sources needed since this section provides general guidance]
### Step-by-Step Example: Building a Complex Custom Command
1. Define a new command class inheriting from the appropriate base (e.g., HotkeyCommand).
2. Annotate the class with display attributes for name, description, and related commands.
3. Implement parameter parsing and validation using the provided parameter types.
4. Add error handling and write messages via the system message writer.
5. If needed, implement initialization and cleanup hooks.
6. Register the command via the attribute-driven discovery mechanism.
7. Test locally by triggering the command through macros or hotkeys.
8. Generate help and IntelliSense data using the display attributes.
[No sources needed since this section provides general guidance]
### Documentation Generation and IntelliSense Support
- CommandsDisplayAttribute supplies metadata consumed by help generators and IDE integrations.
- Keep descriptions concise and accurate; use SeeAlso to link related commands.
- Ensure consistent naming conventions to improve discoverability.
**Section sources**
- [CommandsDisplayAttribute.cs](file://ClassicAssist.Shared/Data/Macros/CommandsDisplayAttribute.cs)
### Testing Strategies for Custom Commands
- Unit tests: Validate parameter parsing, conversion, and error paths without UI.
- Integration tests: Simulate macro invocations and verify side effects and messages.
- Mock external dependencies (network, game state) to isolate command logic.
- Use deterministic inputs and assertions on outputs and state changes.
[No sources needed since this section provides general guidance]
### Debugging Techniques
- Enable verbose logging within commands to trace execution flow.
- Use the system message writer to surface diagnostic information.
- Leverage breakpoints and conditional logs for complex flows.
- Reproduce issues with minimal macro scripts to isolate problems.
[No sources needed since this section provides general guidance]
### Performance Optimization
- Avoid heavy work on the UI thread; offload to background tasks.
- Cache expensive lookups and reuse objects where safe.
- Minimize allocations in tight loops and batch operations.
- Profile frequently executed commands to identify bottlenecks.
[No sources needed since this section provides general guidance]
### Distribution and Version Compatibility Management
- Package commands as separate modules or plugins if supported by the host.
- Clearly declare required versions of ClassicAssist core libraries.
- Use semantic versioning and migration notes for breaking changes.
- Provide fallbacks or feature flags for older versions.
[No sources needed since this section provides general guidance]
## Dependency Analysis
The following diagram highlights key dependencies among command-related components and their role in the lifecycle.
```mermaid
graph LR
HCA["HotkeyCommandAttribute.cs"] --> HM["HotkeyManager.cs"]
HC["HotkeyCommand.cs"] --> HM
CDA["CommandsDisplayAttribute.cs"] --> MM["MacroManager.cs"]
MM --> MI["MacroInvoker.cs"]
MI --> PT["ParameterType.cs"]
MI --> SMW["SystemMessageTextWriter.cs"]
MM --> ME["MacroEntry.cs"]
MM --> UOL["UseOnceList.cs"]
ENG["Engine.cs"] --> HM
ENG --> MM
```
**Diagram sources**
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [CommandsDisplayAttribute.cs](file://ClassicAssist.Shared/Data/Macros/CommandsDisplayAttribute.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [ParameterType.cs](file://ClassicAssist.Shared/Data/Macros/ParameterType.cs)
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
- [MacroEntry.cs](file://ClassicAssist.Shared/Data/Macros/MacroEntry.cs)
- [UseOnceList.cs](file://ClassicAssist.Shared/Data/Macros/UseOnceList.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
**Section sources**
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
## Performance Considerations
- Prefer asynchronous execution for I/O-bound operations to maintain responsiveness.
- Reuse computed results and avoid redundant checks inside hot paths.
- Limit UI updates to necessary moments; batch updates when possible.
- Monitor memory usage and release resources promptly in cleanup phases.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and resolutions:
- Command not discovered: Verify attributes are correctly applied and assembly scanning includes your module.
- Parameter conversion failures: Confirm parameter names and types match expected formats; add explicit validation messages.
- No output shown: Ensure messages are written via the system message writer and UI is subscribed to updates.
- Threading anomalies: Avoid direct UI access from background threads; marshal updates to the UI dispatcher.
**Section sources**
- [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
## Conclusion
By leveraging attribute-driven registration, robust parameter handling, and consistent error reporting, you can build reliable and user-friendly macro commands in ClassicAssist.Avalonia. Follow the lifecycle best practices, adopt asynchronous patterns where appropriate, and use the provided metadata attributes to enhance documentation and IntelliSense. With careful testing and performance tuning, your commands will integrate seamlessly and deliver a great user experience.
## Appendices
### Reference Examples (Built-in Commands)
Explore existing implementations to understand patterns and conventions:
- ConsumeCommands: Demonstrates consumption-style commands and parameter handling.
- MovementCommands: Shows movement-related actions and state interactions.
- ActionCommands: Illustrates action-oriented commands and messaging.
- MainCommands: Provides examples of core functionality integration.
**Section sources**
- [ConsumeCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/ConsumeCommands.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [ActionCommands.cs](file://ClassicAssist.Shared/Data/Macros/Commands/ActionCommands.cs)
- [MainCommands.cs](file://ClassicAssist.Shared/Data/Macros/Commands/MainCommands.cs)