deargui-vpl/docs-classes.md

355 lines
19 KiB
Markdown

# Class Diagram Overview
Compact class diagram showing key classes and their relationships.
```
┌─────────────────────────────────────┐
│ Application │
│ (Base application lifecycle) │
├─────────────────────────────────────┤
│ +OnStart() │
│ +OnStop() │
│ +OnFrame(deltaTime) │
│ +TakeScreenshot() │
└──────────────┬──────────────────────┘
│ extends
┌─────────────────────────────────────┐
│ App │
│ (Main application class) │
├─────────────────────────────────────┤
│ -m_Nodes: vector<Node> │
│ -m_Links: vector<Link> │
│ -m_RootContainers: vector<...> │
│ -m_ActiveRootContainer: RootContainer│
│ +GetNextId(): int │
│ +FindNode(id): Node* │
│ +FindLink(id): Link* │
│ +FindPin(id): Pin* │
│ +SpawnBlockNode(type): Node* │
│ +SpawnParameterNode(type): Node* │
│ +SaveGraph() │
│ +LoadGraph() │
│ +ExecuteRuntimeStep() │
│ +RenderNodes() │
│ +RenderLinks() │
└─┬────────────┬───────────────┬──────┘
│ │ │
│ manages │ owns │ uses
│ │ │
▼ ▼ ▼
┌──────────────────────┐ ┌─────────┐ ┌──────────────┐
│ RootContainer │ │ Node │ │ BlockRegistry│
│ (File-based graph) │ │ │ │ (Factory) │
├──────────────────────┤ └────┬────┘ ├──────────────┤
│ -m_Filename: string │ │ │ +CreateBlock()│
│ -m_IsDirty: bool │ │ has │ +Register() │
│ +GetFilename() │ ▼ └──────────────┘
│ +SetDirty() │ ┌─────────┐
└──────────┬───────────┘ │ Block │◄───┐
│ extends │ │ │
▼ ├─────────┤ │
┌──────────────────────┐ │ +Build() │ │ extends
│ Container │ │ +Render()│ │
│ (Hierarchical group) │ │ +Run() │ │
├──────────────────────┤ │ +Activate│ │
│ -m_NodeIds: vector │ │ Output()│ │
│ -m_LinkIds: vector │ │ +Activate│ │
│ -m_Children: vector │ │ Input() │ │
│ +GetNextId(): int │ └────┬────┘ │
│ +AddNode() │ │ │
│ +RemoveNode() │ │ │
│ +GetNodes(): vector │ │ │
│ +GetLinks(): vector │ │ │
│ +Run() │ │ │
│ +Render() │ │ │
└──────────────────────┘ │ │
│ │
│ │
┌────────────┴──┐ │
│ │ │
▼ ▼ │
┌──────────────────┐ ┌──────────────────┐
│ ParameterizedBlock│ │ ParameterNode │
│ (Block + params) │ │ (Value nodes) │
├──────────────────┤ ├──────────────────┤
│ -m_InputParams │ │ -m_ID: int │
│ -m_OutputParams │ │ -m_Name: string │
│ -m_Inputs │ │ -m_Type: PinType │
│ -m_Outputs │ │ -m_BoolValue │
│ +AddInputParam() │ │ -m_IntValue │
│ +AddOutputParam() │ │ -m_FloatValue │
│ +AddInput() │ │ +GetBool() │
│ +AddOutput() │ │ +SetBool() │
└──────────────────┘ │ +Run() │
│ +Render() │
│ +Build() │
└──────────────────┘
│ creates
┌──────────────────┐
│ParameterRegistry │
│ (Factory) │
├──────────────────┤
│ +CreateParameter()│
└──────────────────┘
┌──────────────────────────────────────┐
│ EditorContext │
│ (Core editor & rendering) │
├──────────────────────────────────────┤
│ -m_Links: vector<Link*> │
│ -m_Nodes: vector<Node*> │
│ -m_GuidedLinks: map<LinkId, ...> │
│ +CreateLink(id): Link* │
│ +DrawNodes() │
│ +DrawLinks() │
│ +HandleControlPointDragging() │
│ +HandleGuidedLinkInteractions() │
│ +ExecuteRuntime() │
└───────┬────────────┬──────────────────┘
│ manages │ manages
│ │
▼ ▼
┌─────────┐ ┌──────────────────┐
│ Link │ │ GuidedLink │
│ │ │ (Waypoint routing)│
└─────────┘ ├──────────────────┤
│ +ID: LinkId │
│ +Mode: LinkMode │
│ +ControlPoints │
│ +AddControlPoint() │
│ +RemoveControlP()│
│ +GetCurveSegm() │
└────┬─────────────┘
│ contains
┌──────────────────┐
│ ControlPoint │
│ (Waypoint) │
├──────────────────┤
│ +Position: ImVec2│
│ +IsManual: bool │
└──────────────────┘
│ persists
┌──────────────────┐
│ LinkSettings │
│ (Persistence) │
├──────────────────┤
│ +m_ID: LinkId │
│ +m_Mode: LinkMode│
│ +m_ControlPoints │
│ +Serialize(): json│
└──────────────────┘
Relationship Legend:
───► = manages/owns (composition)
──..► = uses/creates (dependency)
──┬── = extends (inheritance)
──o── = has (aggregation)
```
## Key Components
### Application Layer
- **[App](examples/blueprints-example/app.h)**: Main application class managing nodes, links, containers, and runtime execution
- Extends **[Application](examples/application/include/application.h)** base class for windowing and rendering
### Block System
- **[Block](examples/blueprints-example/blocks/block.h)**: Abstract base class for executable nodes
- **[ParameterizedBlock](examples/blueprints-example/blocks/block.h)**: Block with input/output parameters and flow control
- **[BlockRegistry](examples/blueprints-example/blocks/block.h)**: Factory pattern for creating block instances
### Parameter System
- **[ParameterNode](examples/blueprints-example/blocks/parameter_node.h)**: Standalone value nodes (Bool/Int/Float/String)
- **[ParameterRegistry](examples/blueprints-example/blocks/parameter_node.h)**: Factory for creating parameter nodes
### Container System
- **[Container](examples/blueprints-example/containers/container.h)**: Hierarchical node/link grouping with ID management
- **[RootContainer](examples/blueprints-example/containers/root_container.h)**: Top-level container tied to a graph file
### Editor System
- **[EditorContext](imgui_node_editor_internal.h)**: Core editor managing rendering and interactions
- **[GuidedLink](links-guided.h)**: User-controllable waypoints for link routing
- **[ControlPoint](links-guided.h)**: Individual waypoint on a guided link
- **[LinkSettings](links-guided.h)**: Persistence for guided link configuration
## Source Files Reference
| Class | Description | Header File | Implementation Files |
|-------|-------------|-------------|---------------------|
| [Application](examples/application/include/application.h) | Base application class for windowing, rendering, and lifecycle management | `examples/application/include/application.h` | - |
| [App](examples/blueprints-example/app.h) | Main application class managing nodes, links, containers, graph persistence, and runtime execution | `examples/blueprints-example/app.h` | `app-logic.cpp`, `app-render.cpp`, `app-runtime.cpp` |
| [Block](examples/blueprints-example/blocks/block.h) | Abstract base class for executable nodes with Build/Render/Run interface and activation API | `examples/blueprints-example/blocks/block.h` | `blocks/*.cpp` |
| [ParameterizedBlock](examples/blueprints-example/blocks/block.h) | Block with input/output parameters and flow control pins | `examples/blueprints-example/blocks/block.h` | `blocks/*.cpp` |
| [BlockRegistry](examples/blueprints-example/blocks/block.h) | Factory pattern registry for creating block instances by type name | `examples/blueprints-example/blocks/block.h` | - |
| [ParameterNode](examples/blueprints-example/blocks/parameter_node.h) | Standalone value nodes (Bool/Int/Float/String) with editable display modes | `examples/blueprints-example/blocks/parameter_node.h` | `blocks/parameter_node.cpp` |
| [ParameterRegistry](examples/blueprints-example/blocks/parameter_node.h) | Factory for creating parameter nodes by type | `examples/blueprints-example/blocks/parameter_node.h` | - |
| [Container](examples/blueprints-example/containers/container.h) | Hierarchical container for grouping nodes/links with ID management and safe pointer resolution | `examples/blueprints-example/containers/container.h` | `containers/container.cpp` |
| [RootContainer](examples/blueprints-example/containers/root_container.h) | Top-level container tied to a graph file, manages root-level nodes and links | `examples/blueprints-example/containers/root_container.h` | `containers/root_container.cpp` |
| [EditorContext](imgui_node_editor_internal.h) | Core editor managing rendering, interactions, link management, and guided link editing | `imgui_node_editor_internal.h` | `imgui_node_editor_render.cpp`, `imgui_node_editor_links.cpp` |
| [GuidedLink](links-guided.h) | User-controllable waypoints for custom link routing with control point management | `links-guided.h` | `imgui_node_editor_links.cpp` |
| [ControlPoint](links-guided.h) | Individual waypoint on a guided link with manual/auto placement flags | `links-guided.h` | - |
| [LinkSettings](links-guided.h) | Persistence structure for guided link configuration (mode, control points, snap settings) | `links-guided.h` | - |
## Key Methods
### App Core Operations
- `SaveGraph()` / `LoadGraph()`: Graph persistence
- `ExecuteRuntimeStep()`: Process activated blocks
- `RenderNodes()` / `RenderLinks()`: Visual rendering
- `FindNode()` / `FindLink()` / `FindPin()`: ID-based lookups
### Block Execution
- `Block::Run()`: Execute block logic
- `Block::ActivateOutput()` / `ActivateInput()`: Flow control
- `Block::Build()`: Create node structure with pins
- `Block::Render()`: Custom rendering per block
### Container Management
- `Container::GetNodes()` / `GetLinks()`: Safe ID-to-pointer resolution
- `Container::GetNextId()`: Unique ID generation
- `Container::Run()`: Execute container contents
### Editor Rendering
- `EditorContext::DrawNodes()` / `DrawLinks()`: Core rendering
- `EditorContext::HandleGuidedLinkInteractions()`: Waypoint editing
- `EditorContext::ExecuteRuntime()`: Runtime integration point
## Simplification Suggestions
### Core API Requirements
The `imgui_node_editor.h` API only requires:
- **NodeId, LinkId, PinId**: Type-safe IDs (already used correctly)
- **BeginNode()/EndNode()**: Node creation blocks
- **BeginPin()/EndPin()**: Pin creation blocks
- **Link()**: Create link between two PinIds
- **QueryNewLink/QueryNewNode**: Creation callbacks
- **QueryDeletedNode/QueryDeletedLink**: Deletion callbacks
- **GetNodePosition/SetNodePosition**: Position management
The editor **does NOT require**:
- ❌ Container/grouping hierarchy
- ❌ Complex inheritance chains
- ❌ Registry/factory patterns
- ❌ Duplicate storage systems
### 🗑️ Candidates for Removal/Simplification
#### 1. **Container System Redundancy** ⚠️ HIGH IMPACT
**Problem**: `App` stores nodes/links in both `m_Nodes`/`m_Links` AND `RootContainer::m_NodeIds`/`m_LinkIds`
- Core API works with IDs directly - doesn't need containers
- Double storage = sync complexity + pointer invalidation risks
- `GetNodes()/GetLinks()` converts IDs→pointers unnecessarily
**Suggestion**:
- **Remove `Container`/`RootContainer` entirely** OR
- **Make Container just a grouping/visual feature** (nodes still in App's flat list)
- Use `std::map<NodeId, Node*>` for O(1) lookups instead of ID vectors
**Files affected**: `containers/container.h`, `containers/root_container.h`, `app-logic.cpp` (GetNodes/GetLinks calls)
---
#### 2. **Registry Pattern Overhead** ⚠️ MEDIUM IMPACT
**Problem**: `BlockRegistry` and `ParameterRegistry` are singleton factories that just map strings to constructors
- Adds indirection for simple "create by type name" operations
- Could be simple function tables or even switch statements
**Suggestion**:
- Replace with `std::function<Block*(int)>` map directly in `App`
- OR use simple `switch(typeName)` if block types are finite
- Keep factories only if you need dynamic plugin loading
**Files affected**: `blocks/block.h` (registry), `app-logic.cpp` (CreateBlock calls)
---
#### 3. **Block vs ParameterizedBlock Inheritance** ⚠️ MEDIUM IMPACT
**Problem**: Two-level inheritance when most/all blocks need parameters anyway
- Base `Block` is abstract but has minimal functionality
- `ParameterizedBlock` adds params, but could just be the base class
**Suggestion**:
- Merge `Block` and `ParameterizedBlock` into single `Block` class
- OR make `ParameterizedBlock` the base, drop abstract `Block` if unused
- Check if any blocks actually use base `Block` without parameters
**Files affected**: `blocks/block.h`, all block implementations
---
#### 4. **LinkSettings vs GuidedLink Duplication** ⚠️ LOW IMPACT
**Problem**: `LinkSettings` (for persistence) and `GuidedLink` (for runtime) store same data
- Two structures for same concept = sync complexity
**Suggestion**:
- Merge into single structure with `Serialize()` method
- OR make `GuidedLink` contain `LinkSettings` directly
- Eliminates conversion between formats
**Files affected**: `links-guided.h`, save/load code
---
#### 5. **Node Instance Union Pattern** ⚠️ LOW IMPACT
**Problem**: `Node` stores either `BlockInstance*` OR `ParameterInstance*` (mutually exclusive)
- Requires runtime type checking (`IsBlockBased()`, `GetBlockInstance()`, etc.)
- Could use `std::variant<Block*, ParameterNode*>` or simpler approach
**Suggestion**:
- Use `std::variant` for type safety OR
- Separate `BlockNode` and `ParameterNode` completely (no shared base)
- Current pattern works but adds complexity
**Files affected**: `types.h` (Node struct), rendering/runtime code
---
#### 6. **GetNodes()/GetLinks() ID→Pointer Conversion** ⚠️ MEDIUM IMPACT
**Problem**: Container stores IDs in vectors, then converts to pointers via `App::FindNode()`
- Adds indirection layer, performance overhead (though minimal)
- Pointer invalidation risks when vectors resize
**Suggestion**:
- Store pointers directly if Container system is kept
- OR use `std::unordered_map<NodeId, Node*>` for O(1) lookup
- Current ID-based storage is safer but adds complexity
**Files affected**: `containers/container.cpp` (GetNodes/GetLinks implementations)
---
### ✅ What to Keep
- **Block abstraction**: Good separation of concerns (Build/Render/Run)
- **Activation API**: Useful for flow control in runtime
- **Guided Links**: Core feature, keep but simplify persistence
- **ID-based lookups**: Type safety is valuable, but consider maps vs vectors
### 📊 Impact Summary
| Simplification | Impact | Effort | Priority |
|---------------|--------|--------|----------|
| Remove Container system | HIGH | HIGH | ⭐⭐⭐ |
| Simplify Registry | MEDIUM | LOW | ⭐⭐ |
| Merge Block inheritance | MEDIUM | MEDIUM | ⭐⭐ |
| Merge LinkSettings | LOW | LOW | ⭐ |
| Simplify Node instances | LOW | MEDIUM | ⭐ |
### 🔍 Recommended Investigation
Before removing anything, verify:
1. Are containers used for anything beyond tracking node/link ownership? (groups? nesting?)
2. Do any blocks actually inherit from `Block` directly without parameters?
3. Can we prove Container system adds value beyond App's flat storage?
4. What percentage of code deals with Container vs direct Node/Link access?
**Core Insight**: The editor API works with IDs. Your abstractions should minimize conversion between IDs ↔ pointers ↔ containers.