first commit

This commit is contained in:
Beyhan Oğur
2026-09-03 04:45:36 +03:00
commit d5f52cc3d3
1038 changed files with 169579 additions and 0 deletions
@@ -0,0 +1,378 @@
# Cross-Platform Considerations
<cite>
**Referenced Files in This Document**
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
- [WPFDispatcher.cs](file://ClassicAssist/WPFDispatcher.cs)
- [WPFUIInvoker.cs](file://ClassicAssist/WPFUIInvoker.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
- [NativeMethods.cs](file://ClassicAssist.Shared/Misc/NativeMethods.cs)
- [ClassicAssist.Avalonia.csproj](file://ClassicAssist.Avalonia/ClassicAssist.Avalonia.csproj)
- [ClassicAssist.csproj](file://ClassicAssist/ClassicAssist.csproj)
</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)
## Introduction
This document explains the cross-platform implementation strategy for ClassicAssist.Avalonia, focusing on how platform-specific functionality is abstracted and resolved at runtime. It covers:
- Platform abstraction layer design using interfaces such as IDispatcher and IUIInvoker
- Platform detection and conditional compilation strategies
- File system abstraction, path handling, and configuration management
- Threading model differences across Windows, macOS, and Linux
- Native interop considerations for platform-specific APIs
- Deployment, packaging, and build configurations
- Performance optimization techniques per target platform and .NET runtime behavior
## Project Structure
The project separates shared logic from UI implementations:
- Shared abstractions and platform detection live in ClassicAssist.Shared
- Avalonia-based UI and its platform-specific dispatching live in ClassicAssist.Avalonia
- WPF-based UI and its platform-specific dispatching live in ClassicAssist (legacy)
```mermaid
graph TB
subgraph "Shared"
A["IDispatcher.cs"]
B["IUIInvoker.cs"]
C["PlatformDetector.cs"]
D["NativeMethods.cs"]
end
subgraph "Avalonia UI"
E["AvaloniaDispatcher.cs"]
F["AvaloniaUIInvoker.cs"]
G["Engine.cs"]
H["Program.cs"]
I["App.axaml.cs"]
end
subgraph "WPF UI (Legacy)"
J["WPFDispatcher.cs"]
K["WPFUIInvoker.cs"]
end
A --> E
B --> F
C --> G
D --> G
E --> G
F --> G
H --> G
I --> G
A --> J
B --> K
```
**Diagram sources**
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
- [WPFDispatcher.cs](file://ClassicAssist/WPFDispatcher.cs)
- [WPFUIInvoker.cs](file://ClassicAssist/WPFUIInvoker.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
- [NativeMethods.cs](file://ClassicAssist.Shared/Misc/NativeMethods.cs)
**Section sources**
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
- [WPFDispatcher.cs](file://ClassicAssist/WPFDispatcher.cs)
- [WPFUIInvoker.cs](file://ClassicAssist/WPFUIInvoker.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
- [NativeMethods.cs](file://ClassicAssist.Shared/Misc/NativeMethods.cs)
## Core Components
- IDispatcher: Abstraction for scheduling work onto the UI thread. Implementations exist for Avalonia and WPF to ensure UI updates are marshaled correctly on each platform.
- IUIInvoker: Abstraction for UI-level operations that require platform-specific calls (e.g., message boxes, window interactions). Implementations encapsulate platform details behind a common interface.
- PlatformDetector: Provides runtime OS detection used by engine initialization and feature toggles.
- Engine (Avalonia): Bootstraps the application, resolves dispatcher and invoker, initializes services, and starts the UI loop.
- Program and App: Entry points that configure the Avalonia application lifecycle and resolve DI or static services.
Key responsibilities:
- Decouple UI threading and UI invocation from core logic
- Centralize platform detection and native interop usage
- Provide consistent initialization across platforms
**Section sources**
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
- [WPFDispatcher.cs](file://ClassicAssist/WPFDispatcher.cs)
- [WPFUIInvoker.cs](file://ClassicAssist/WPFUIInvoker.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
## Architecture Overview
The architecture uses an inversion-of-control pattern where the shared core depends only on interfaces. The UI layer provides concrete implementations selected at startup.
```mermaid
classDiagram
class IDispatcher {
+Invoke(action) void
+BeginInvoke(action) void
}
class IUIInvoker {
+ShowMessage(text) void
+OpenFile() string
+SaveFile(data) bool
}
class AvaloniaDispatcher
class AvaloniaUIInvoker
class WPFDispatcher
class WPFUIInvoker
IDispatcher <|.. AvaloniaDispatcher
IDispatcher <|.. WPFDispatcher
IUIInvoker <|.. AvaloniaUIInvoker
IUIInvoker <|.. WPFUIInvoker
```
**Diagram sources**
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
- [WPFDispatcher.cs](file://ClassicAssist/WPFDispatcher.cs)
- [WPFUIInvoker.cs](file://ClassicAssist/WPFUIInvoker.cs)
## Detailed Component Analysis
### Dispatcher Abstraction and Implementations
Purpose:
- Ensure all UI-related work runs on the correct UI thread regardless of platform.
- Provide BeginInvoke and Invoke semantics compatible with Avalonia and WPF.
Design:
- IDispatcher defines the contract.
- AvaloniaDispatcher implements it using Avalonia’s dispatcher primitives.
- WPFDispatcher implements it using WPF’s dispatcher primitives.
```mermaid
sequenceDiagram
participant Core as "Core Logic"
participant Disp as "IDispatcher"
participant Impl as "AvaloniaDispatcher"
participant UI as "Avalonia UI Thread"
Core->>Disp : "Invoke(updateUI)"
Disp->>Impl : "Dispatch call"
Impl->>UI : "Marshal to UI thread"
UI-->>Core : "Update completed"
```
**Diagram sources**
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
**Section sources**
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [WPFDispatcher.cs](file://ClassicAssist/WPFDispatcher.cs)
### UI Invoker Abstraction and Implementations
Purpose:
- Encapsulate UI operations that differ between platforms (message boxes, file dialogs, window behaviors).
- Keep core logic free of platform-specific UI code.
Design:
- IUIInvoker defines the contract.
- AvaloniaUIInvoker and WPFUIInvoker implement platform-specific calls.
```mermaid
sequenceDiagram
participant Core as "Core Logic"
participant Inv as "IUIInvoker"
participant Impl as "AvaloniaUIInvoker"
participant OS as "OS Dialogs"
Core->>Inv : "ShowMessage(text)"
Inv->>Impl : "Forward to platform impl"
Impl->>OS : "Invoke native dialog"
OS-->>Impl : "Result"
Impl-->>Core : "Return"
```
**Diagram sources**
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
- [WPFUIInvoker.cs](file://ClassicAssist/WPFUIInvoker.cs)
**Section sources**
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
- [WPFUIInvoker.cs](file://ClassicAssist/WPFUIInvoker.cs)
### Platform Detection and Conditional Compilation
Purpose:
- Detect runtime OS to enable/disable features or choose paths/configurations.
- Support compile-time flags for platform-specific builds.
Behavior:
- PlatformDetector exposes OS information consumed by Engine and other components.
- Build targets may use conditional compilation to include/exclude platform-specific assets or code paths.
```mermaid
flowchart TD
Start(["Application Start"]) --> Detect["Detect OS via PlatformDetector"]
Detect --> IsWindows{"Is Windows?"}
IsWindows --> |Yes| WinPath["Use Windows paths and settings"]
IsWindows --> |No| IsMac{"Is macOS?"}
IsMac --> |Yes| MacPath["Use macOS paths and settings"]
IsMac --> |No| LinuxPath["Use Linux paths and settings"]
WinPath --> Init["Initialize services"]
MacPath --> Init
LinuxPath --> Init
Init --> End(["Ready"])
```
**Diagram sources**
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
**Section sources**
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
### File System Abstraction and Path Handling
Guidelines:
- Use platform-aware path utilities to construct directories and files consistently.
- Prefer environment variables and well-known locations for user data and configuration.
- Normalize separators and handle case sensitivity differences on Linux/macOS.
Recommendations:
- Centralize path resolution in a small helper module that wraps System.IO and Environment APIs.
- Abstract read/write operations behind simple methods to allow mocking in tests.
[No sources needed since this section provides general guidance]
### Configuration Management
Guidelines:
- Store user preferences in platform-appropriate locations (e.g., Application Data on Windows, ~/Library on macOS, ~/.config on Linux).
- Serialize settings to JSON or XML; validate schema on load.
- Provide defaults and migration helpers when configuration formats change.
[No sources needed since this section provides general guidance]
### Threading Model Differences
- Windows: WPF uses a single-threaded apartment model for UI threads; Avalonia uses a different threading model based on its rendering backend.
- macOS: Avalonia integrates with Cocoa; ensure UI updates occur on the main run loop thread.
- Linux: Avalonia uses X11/Wayland backends; marshal UI updates appropriately.
Best practices:
- Always route UI updates through IDispatcher.
- Avoid blocking the UI thread; offload long-running tasks to background threads.
- Be mindful of synchronization primitives and avoid deadlocks when crossing UI boundaries.
[No sources needed since this section provides general guidance]
### Native Interop Considerations
- Use P/Invoke sparingly and wrap calls in safe abstractions.
- Guard calls with PlatformDetector checks to avoid unsupported scenarios.
- Handle exceptions from native calls and map them to user-friendly messages via IUIInvoker.
- Consider loading native libraries conditionally based on OS and architecture.
**Section sources**
- [NativeMethods.cs](file://ClassicAssist.Shared/Misc/NativeMethods.cs)
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
### Application Bootstrap and Service Resolution
Flow:
- Program sets up the Avalonia application.
- App configures resources and resolves services.
- Engine initializes platform detection, dispatcher, invoker, and core subsystems.
```mermaid
sequenceDiagram
participant Proc as "Program.cs"
participant App as "App.axaml.cs"
participant Eng as "Engine.cs"
participant Det as "PlatformDetector.cs"
participant Disp as "IDispatcher"
participant Inv as "IUIInvoker"
Proc->>App : "Create and configure Avalonia app"
App->>Eng : "Initialize engine"
Eng->>Det : "Detect OS"
Eng->>Disp : "Resolve dispatcher"
Eng->>Inv : "Resolve UI invoker"
Eng-->>Proc : "Start UI loop"
```
**Diagram sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
- [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs)
- [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs)
**Section sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
## Dependency Analysis
High-level dependencies:
- ClassicAssist.Avalonia depends on ClassicAssist.Shared for abstractions and platform detection.
- ClassicAssist (WPF) also depends on ClassicAssist.Shared but provides WPF-specific implementations.
- Both UI projects depend on their respective UI frameworks (Avalonia vs WPF).
```mermaid
graph LR
Shared["ClassicAssist.Shared"]
Avalonia["ClassicAssist.Avalonia"]
WPF["ClassicAssist (WPF)"]
Shared --> Avalonia
Shared --> WPF
```
**Diagram sources**
- [ClassicAssist.Avalonia.csproj](file://ClassicAssist.Avalonia/ClassicAssist.Avalonia.csproj)
- [ClassicAssist.csproj](file://ClassicAssist/ClassicAssist.csproj)
**Section sources**
- [ClassicAssist.Avalonia.csproj](file://ClassicAssist.Avalonia/ClassicAssist.Avalonia.csproj)
- [ClassicAssist.csproj](file://ClassicAssist/ClassicAssist.csproj)
## Performance Considerations
- UI Threading: Minimize work on the UI thread; batch updates and coalesce frequent changes.
- Rendering: On macOS and Linux, prefer vector graphics and avoid heavy bitmap operations on the UI thread.
- I/O: Use asynchronous file operations and cache frequently accessed data.
- GC Pressure: Reuse buffers and objects where possible; avoid allocations in hot loops.
- Native Calls: Batch native calls and reduce marshaling overhead by passing arrays instead of scalars.
- Runtime: On .NET 6+, leverage modern runtime optimizations and consider ReadyToRun for faster cold starts.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and remedies:
- UI not updating: Ensure all UI modifications go through IDispatcher.
- Crashes on native calls: Wrap P/Invoke in try/catch and verify OS/arch compatibility before calling.
- Incorrect paths: Validate path construction with PlatformDetector and normalize separators.
- Deadlocks: Review cross-thread synchronization and avoid nested UI locks.
**Section sources**
- [NativeMethods.cs](file://ClassicAssist.Shared/Misc/NativeMethods.cs)
- [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)
## Conclusion
ClassicAssist.Avalonia achieves cross-platform consistency by isolating platform-specific concerns behind clear interfaces (IDispatcher, IUIInvoker), centralizing platform detection, and providing targeted implementations per UI framework. This design simplifies maintenance, enables testing, and supports future platform additions while preserving performance and reliability across Windows, macOS, and Linux.