# Architecture Overview This document describes the high-level architecture and design of CppLab IDE. Now, keep in mind that everything shown here is just the gist of what I did. I do plan on putting a proper diagram here once my exams are over but for now, I just wanted a pretty wiki with some basic diagram, and here it is. Now, this is mostly for documenting purposes but if you want to understand what was I thinking, making an IDE for C/C++ in Python, well, this is a good place to start. ## System Architecture CppLab IDE follows a layered architecture with clear separation of concerns: ``` ┌─────────────────────────────────────────────────────────────┐ │ User Interface Layer │ │ (PyQt6 - MainWindow, Dialogs, Widgets) │ ├─────────────────────────────────────────────────────────────┤ │ Application Logic Layer │ │ (Project Management, File Management, Settings) │ ├─────────────────────────────────────────────────────────────┤ │ Build & Execution Layer │ │ (Async BuildWorker, Toolchain Management, Compiler) │ ├─────────────────────────────────────────────────────────────┤ │ Data Persistence Layer │ │ (JSON Config Files, Settings Storage) │ └─────────────────────────────────────────────────────────────┘ ``` ## Directory Structure ``` CppLabEngine/ ├── src/cpplab/ # Main application package │ ├── __init__.py # Package init with version │ ├── main.py # Application entry point │ ├── app.py # MainWindow class (1000+ lines) │ ├── dialogs.py # Project dialogs (NewProject, etc.) │ ├── settings.py # Settings data model and persistence │ ├── settings_dialog.py # Settings UI dialog │ │ │ ├── ui/ # Qt Designer UI files │ │ ├── MainWindow.ui │ │ └── NewProjectDialog.ui │ │ │ ├── widgets/ # Custom Qt widgets │ │ ├── code_editor.py # Syntax-highlighted editor │ │ ├── project_explorer.py # File tree view │ │ └── output_panel.py # Build output display │ │ │ └── core/ # Core business logic │ ├── project_config.py # Project data model │ ├── toolchains.py # Compiler configuration │ └── builder.py # Build system (500+ lines) │ ├── compilers/ # Bundled MinGW toolchains │ ├── mingw32/ # 32-bit (graphics.h) │ └── mingw64/ # 64-bit (OpenMP) │ ├── docs/ # Offline documentation ├── examples/ # Sample projects ├── tests/ # Unit and integration tests └── tools/ # Build and release scripts └── build_release.py ``` ## Core Components ### 1. MainWindow (app.py) **Responsibilities:** - Central application controller - UI event handling and routing - State management (current project, open files) - Async build coordination **Key Attributes:** ```python self.current_project: Optional[ProjectConfig] # Active project self.toolchains: dict # MinGW toolchains self.open_editors: dict[str, CodeEditor] # Open file editors self.build_in_progress: bool # Async build state self.settings: AppSettings # User preferences ``` **Key Methods:** - `start_build_task()` - Initiate async builds - `on_build_finished()` - Handle build completion - `build_current()` / `run_current()` - Build/run workflows - `apply_settings()` - Apply theme and font changes ### 2. BuildWorker (app.py) **Responsibilities:** - Execute compilation in background thread - Emit progress signals to UI - Handle build errors gracefully **Architecture:** ```python class BuildWorker(QObject): started = pyqtSignal() finished = pyqtSignal(object) # BuildResult error = pyqtSignal(str) def run(self): # Executes in QThread # Calls builder.py functions # Emits signals to MainWindow ``` ### 3. Build System (core/builder.py) **Responsibilities:** - Compile C/C++ source files - Manage incremental builds - Link with appropriate libraries - Auto-detect features (graphics.h, OpenMP) **Key Functions:** ```python build_project(config, toolchains, force_rebuild) -> BuildResult build_single_file(path, toolchains, ...) -> BuildResult check_project(config, toolchains) -> BuildResult # Syntax only check_single_file(path, toolchains, ...) -> BuildResult ``` **BuildResult Structure:** ```python @dataclass class BuildResult: success: bool command: list[str] stdout: str stderr: str exe_path: Optional[Path] elapsed_ms: float skipped: bool ``` ### 4. Toolchain Manager (core/toolchains.py) **Responsibilities:** - Discover MinGW installations - Select appropriate toolchain (32/64-bit) - Provide compiler paths and flags **Toolchain Selection Logic:** ```python if graphics_required: toolchain = mingw32 # 32-bit required for WinBGIm elif openmp_required: toolchain = mingw64 # 64-bit recommended for OpenMP else: toolchain = mingw64 # Default to 64-bit ``` ### 5. Project Configuration (core/project_config.py) **Responsibilities:** - Store project metadata - Serialize/deserialize to JSON - Manage source file lists **Structure:** ```python @dataclass class ProjectConfig: name: str root_path: Path language: str # "c" or "cpp" standard: str # "c17", "c++20", etc. project_type: str # "console" or "graphics" features: dict # {"graphics": bool, "openmp": bool} files: list[str] main_file: str toolchain_preference: str # "auto", "mingw32", "mingw64" ``` ### 6. Custom Widgets #### CodeEditor (widgets/code_editor.py) - Syntax highlighting via QSyntaxHighlighter - Line numbers in margin - Modified state tracking - File path association #### ProjectExplorer (widgets/project_explorer.py) - QTreeView-based file browser - File double-click → open in editor - Context menu (future: add/remove files) #### OutputPanel (widgets/output_panel.py) - Build output display - Auto-scroll to bottom - Monospace font (Consolas) - Clear/append operations ## Data Flow ### Build Flow ``` User Action (Fn+F5 or F5/F7) ↓ MainWindow.build_current() ↓ start_build_task() ↓ Create BuildWorker + QThread ↓ worker.run() [Background Thread] ↓ builder.build_project/build_single_file() ↓ Execute g++/gcc command ↓ BuildResult with elapsed_ms ↓ worker.finished signal ↓ MainWindow.on_build_finished() ↓ Update UI (status bar, output panel) ``` ### Project Load Flow ``` User: File → Open Project ↓ MainWindow.on_open_project() ↓ Load cpplab_project.json ↓ ProjectConfig.load() ↓ Update UI (tree, toolchain combo, standard combo) ↓ Open main file in editor ``` ## Threading Model ### Main Thread (Qt Event Loop) - All UI operations - User input handling - Signal/slot connections - Widget updates ### Background Threads (QThread) - Build operations (BuildWorker) - File operations (future: large file loading) - External process monitoring (future: debugger) ### Thread Safety - **BuildWorker** uses `QObject` + `moveToThread()` pattern (PyQt6 best practice) - No direct UI updates from worker threads - All communication via Qt signals (thread-safe) - Worker auto-deleted after completion (`deleteLater()`) ## State Management ### Application State ```python # Global current_project: Optional[ProjectConfig] open_editors: dict[str, CodeEditor] standalone_files: set[Path] # Build State build_in_progress: bool current_build_thread: Optional[QThread] _pending_run_after_build: bool # Settings settings: AppSettings # Loaded from ~/.cpplab/settings.json ``` ### Project State (Persistent) - Stored in `/cpplab_project.json` - Version controlled with project - Contains all build configuration ### User Settings (Persistent) - Stored in `~/.cpplab/settings.json` - User-specific preferences - Not version controlled ## Design Patterns ### 1. MVC (Model-View-Controller) - **Model**: ProjectConfig, AppSettings - **View**: Qt Widgets (.ui files) - **Controller**: MainWindow (app.py) ### 2. Observer Pattern - Qt Signals/Slots for event handling - BuildWorker emits progress signals - Widgets emit interaction signals ### 3. Factory Pattern - `create_new_project()` creates ProjectConfig - Toolchain selection based on features ### 4. Builder Pattern - `BuildResult` accumulates build information - Command construction in builder.py ### 5. Strategy Pattern - Different build strategies (project vs standalone) - Toolchain selection strategies ## Error Handling ### UI Layer - `QMessageBox` for user-facing errors - Non-blocking error dialogs - Status bar for quick feedback ### Build Layer - Try/catch in BuildWorker.run() - Emit `error` signal on exception - BuildResult captures compiler errors ### File Operations - Path validation before operations - Exception handling with user feedback - Auto-create directories as needed ## Extension Points Future enhancements can be added at these points: 1. [] **New Project Types**: Add to `ProjectConfig.project_type` 2. [] **Additional Toolchains**: Extend `toolchains.py` 3. [x] **Language Support**: Add syntax highlighters 4. [] **Build Profiles**: Add Debug/Release modes 5. [] **Plugin System**: Load external Python modules ## Performance Considerations ### Fast Startup - Lazy widget initialization - [x] Toolchain discovery cached - UI loaded from .ui files (fast) ### Responsive Builds - Asynchronous compilation (no freezing) - Incremental builds (skip unchanged) - Syntax-only checks (fast feedback) ### Memory Efficiency - Single OutputPanel shared - Editors created on-demand - Build threads auto-deleted ### Disk I/O - JSON config files (small, fast) - Minimal file watching (manual reload) - Build artifacts in separate `build/` dir --- **Next**: [Asynchronous Build System](Asynchronous-Build-System.md)