Private
Public Access
Docs: Complete detailed SSDL guide via cluster append
This adds SSDL Cluster 2 (Branch Defusing Mechanics) and Cluster 3 (Python-to-SSDL Mapping Rules) to the docs and combines them into guide_ssdl.md.
This commit is contained in:
+180
-10
@@ -7,7 +7,7 @@ This document provides a comprehensive technical guide and reference specificati
|
||||
## 1. Context & Architectural Rationale
|
||||
|
||||
SSDL is heavily inspired by modern data-oriented design paradigms:
|
||||
1. ** Taxonomy of Computation Shapes** (Ryan Fleury, 2023) — mapping logic structures to visual topologies.
|
||||
1. **Taxonomy of Computation Shapes** (Ryan Fleury, 2023) — mapping logic structures to visual topologies.
|
||||
2. **The Big OOPs: A 35-Year Mistake** (Casey Muratori, 2025) — prioritizing system data transformations over compile-time entity hierarchies.
|
||||
3. **Assuming as Much as Possible** (Andrew Reece, 2025) — reducing abstraction layers by exploiting specific access patterns.
|
||||
|
||||
@@ -48,11 +48,47 @@ Modifiers are applied to instructions to indicate state operations, termination
|
||||
|
||||
---
|
||||
|
||||
## 3. Architectural Defusing Techniques in SSDL
|
||||
## 3. Visual Topology Diagrams
|
||||
|
||||
SSDL diagrams trace control and data progression through functions.
|
||||
|
||||
### 3.1 Sequential Execution Path
|
||||
A linear sequence containing queries and instructions, terminating cleanly:
|
||||
```
|
||||
[Q:active_window] -> [I:SetupWindowFlags] -> [I:BeginRender] -> [T]
|
||||
```
|
||||
|
||||
### 3.2 Branching and Reconvergence
|
||||
Models a conditional fork and subsequent merge back into the main flow:
|
||||
```
|
||||
[Q:show_preview]
|
||||
│
|
||||
▼
|
||||
[B:is_enabled?]
|
||||
╱ ╲
|
||||
yes no
|
||||
╱ ╲
|
||||
▼ ▼
|
||||
[I:RenderMD] [I:RenderText]
|
||||
│ │
|
||||
▼ ▼
|
||||
└──────► [M] ◄──────┘
|
||||
│
|
||||
▼
|
||||
[I:RenderFooter]
|
||||
│
|
||||
▼
|
||||
[T]
|
||||
```
|
||||
This diagram maps a 2-way conditional execution path, returning to a single straight-line path after the merge.
|
||||
|
||||
---
|
||||
|
||||
## 4. Architectural Defusing Techniques in SSDL
|
||||
|
||||
The primary goal of SSDL during spec design is to **defuse branches**, collapsing N effective codepaths into 1.
|
||||
|
||||
### 3.1 Technique 1: The Nil Sentinel (Branch Elimination)
|
||||
### 4.1 Technique 1: The Nil Sentinel (Branch Elimination)
|
||||
|
||||
Null pointer checks (`if node is None:`) are a major source of branch multiplication. By introducing a self-referential nil sentinel node, we can eliminate null checks entirely.
|
||||
|
||||
@@ -92,9 +128,17 @@ nil_node: [N] = { &nil_node, &nil_node, 0 }
|
||||
[T:return n3] (if not found, returns nil_node; caller safely queries it without checking)
|
||||
```
|
||||
|
||||
#### Sentinel Memory Layout (Linear Defused):
|
||||
```
|
||||
Node A (0x1000) ────► Node B (0x2000) ────► Sentinel Node (0x8000)
|
||||
│ ▲
|
||||
└──────────┘ (Self-Loop)
|
||||
```
|
||||
In the sentinel topology, the child/next pointers of the sentinel node point back to `0x8000` (itself). Any query, no matter how deep, resolves safely to the sentinel itself without checking for null.
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Technique 2: Generational Handles (Lifetime Defusing)
|
||||
### 4.2 Technique 2: Generational Handles (Lifetime Defusing)
|
||||
|
||||
Checking if an allocated object has been freed or replaced typically introduces branch complexity. Generational handles defuse this by resolving queries through a validation check that returns a nil sentinel on mismatch.
|
||||
|
||||
@@ -114,9 +158,40 @@ Main Path:
|
||||
```
|
||||
The caller's rendering code remains a single straight-line path (`[I:DrawAtPosition]`), having outsourced the lifetime checks to the validation layer.
|
||||
|
||||
#### Handle Anatomy
|
||||
A handle is a lightweight, 64-bit value split into two fields:
|
||||
* **Index (32-bit):** The offset in the flat allocation array.
|
||||
* **Generation (32-bit):** A monotonically increasing counter incremented every time the slot at `index` is reused.
|
||||
|
||||
```
|
||||
+───────────────────────────────┬───────────────────────────────+
|
||||
| Index (32-bit) | Generation (32-bit) |
|
||||
+───────────────────────────────┴───────────────────────────────+
|
||||
```
|
||||
|
||||
#### SSDL Resolution Flow
|
||||
When resolving a handle to a concrete object, the validation check is encapsulated within the registry, returning the Nil Sentinel on failure:
|
||||
|
||||
```
|
||||
[Q:handle]
|
||||
│
|
||||
▼
|
||||
[I:LookupRegistry(handle.index)]
|
||||
│
|
||||
▼
|
||||
[B:Slot.Generation == handle.generation?]
|
||||
├── No ──► [I:Return Nil Sentinel] ──┐
|
||||
└── Yes ──► [I:Return Real Object] │
|
||||
▼
|
||||
[M:Safe Node]
|
||||
│
|
||||
▼
|
||||
[I:ExecuteAction]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Technique 3: Immediate-Mode Cache Allocation
|
||||
### 4.3 Technique 3: Immediate-Mode Cache Allocation
|
||||
|
||||
Retained-mode API resource management requires tracking allocation, deletion, and reload states (e.g. `is_loading`, `reloading_failed`). Immediate-mode caching defuses this by making resource fetching a synchronous key query that handles lazy loading in the background.
|
||||
|
||||
@@ -135,13 +210,34 @@ IMMEDIATE MODE (Defused Caching):
|
||||
(cache loads in background if missing)
|
||||
```
|
||||
|
||||
#### Synchronous Key Querying
|
||||
The caller requests the resource synchronously every frame using a key:
|
||||
```
|
||||
Caller Path:
|
||||
[Q:ResourceKey] -> [I:GetCachedResource(Key)] -> [I:DrawResource] -> [T]
|
||||
```
|
||||
|
||||
#### Behind the Scenes: Parallel Worker Topology
|
||||
If the resource is not in memory, the cache returns a placeholder (nil sentinel representation of the resource) and issues an asynchronous load request to a background thread pool.
|
||||
|
||||
```
|
||||
Foreground (Render Thread):
|
||||
[I:GetCachedResource] -> [B:In Cache?]
|
||||
├── Yes ──► [I:Return Resource]
|
||||
└── No ──► [I:Enqueue Load Task] ──► [I:Return Placeholder]
|
||||
|
||||
Background (Worker Thread):
|
||||
o=> [I:Dequeue Load Task] -> [I:Load Asset] -> [S:Write to Cache] -> [T:Worker Idle]
|
||||
```
|
||||
Once the background worker writes the loaded asset into the cache, the next frame's synchronous call `GetCachedResource(Key)` naturally hits the cache and returns the fully loaded asset. The control flow in the main rendering loop remains completely linear.
|
||||
|
||||
---
|
||||
|
||||
## 4. Mapping SSDL to Python 3.11 ImGui
|
||||
## 5. Mapping SSDL to Python 3.11 ImGui
|
||||
|
||||
To enforce SSDL as a strict design contract, SSDL symbols correspond to specific Python code constructs in `src/gui_2.py`.
|
||||
|
||||
### 4.1 Basic SSDL-to-Code Transformations
|
||||
### 5.1 Basic SSDL-to-Code Transformations
|
||||
|
||||
| SSDL Code Pattern | Python Implementation |
|
||||
|---|---|
|
||||
@@ -153,11 +249,85 @@ To enforce SSDL as a strict design contract, SSDL symbols correspond to specific
|
||||
| `=>` | `imgui.table_next_column()` or `imgui.same_line()` |
|
||||
| `[B:popup] => [B:choices]` | `if imgui.begin_popup_modal(...)[0]:` |
|
||||
|
||||
### 4.2 Comprehensive Code Mapping Example
|
||||
### 5.2 Python-to-SSDL Mapping Rules & Concrete Examples
|
||||
|
||||
All Python code snippets adhere to the manual-slop project's **1-space indentation rule**.
|
||||
|
||||
#### Basic Linear Panel
|
||||
A sequential panel containing labels, inputs, and a button.
|
||||
|
||||
```python
|
||||
def render_simple_panel(app: App) -> None:
|
||||
"""Renders a basic configuration sidebar panel.
|
||||
|
||||
SSDL: [Q:app.config] -> [I:Header] -> [I:TextInput] -> [I:Checkbox] -> [B:SaveButton] -> [S:app.config]
|
||||
"""
|
||||
imgui.text("Configuration Settings")
|
||||
changed, app.temp_username = imgui.input_text("Username", app.temp_username)
|
||||
if imgui.checkbox("Enable Notifications", app.notifications_enabled)[0]:
|
||||
app.notifications_enabled = not app.notifications_enabled
|
||||
if imgui.button("Save Changes"):
|
||||
app.save_configuration()
|
||||
```
|
||||
|
||||
#### Tabbed / Columnar Layouts (Wide Codepath `=>`)
|
||||
When layouts expand horizontally (via columns, tables, or tab bars), control flow diverges into concurrent visual segments. SSDL represents this using the `=>` separator.
|
||||
|
||||
```python
|
||||
def render_workspace_tabs(app: App) -> None:
|
||||
"""Renders workspace tabs.
|
||||
|
||||
SSDL: [I:BeginTabBar] -> [B:Tab1] => [B:Tab2] -> [I:EndTabBar]
|
||||
"""
|
||||
if imgui.begin_tab_bar("WorkspaceTabs"):
|
||||
if imgui.begin_tab_item("Agent View")[0]:
|
||||
imgui.text("Agent Panel Content")
|
||||
imgui.end_tab_item()
|
||||
if imgui.begin_tab_item("File Editor")[0]:
|
||||
imgui.text("File Editor Content")
|
||||
imgui.end_tab_item()
|
||||
imgui.end_tab_bar()
|
||||
```
|
||||
|
||||
#### Loops & Lists (Codecycle `o->`)
|
||||
Rendering lists of data requires looping. SSDL represents this using the Codecycle marker `o->`.
|
||||
|
||||
```python
|
||||
def render_active_agents(app: App) -> None:
|
||||
"""Renders a list of running agent worker tasks.
|
||||
|
||||
SSDL: [Q:app.active_workers] -> o-> [I:WorkerRow] -> [B:KillButton] -> [S:app.active_workers]
|
||||
"""
|
||||
for worker in app.active_workers:
|
||||
imgui.text(f"ID: {worker.id} | Status: {worker.status}")
|
||||
imgui.same_line()
|
||||
if imgui.button(f"Terminate##{worker.id}"):
|
||||
app.controller.kill_worker(worker.id)
|
||||
```
|
||||
|
||||
#### Popups & Modal Windows
|
||||
Modals interrupt the parent window flow and create temporary sub-graphs.
|
||||
|
||||
```python
|
||||
def render_error_modal(app: App) -> None:
|
||||
"""Renders a modal popup dialog when an error occurs.
|
||||
|
||||
SSDL: [Q:app.error_msg] -> [B:open_trigger] -> [I:draw_modal] -> [B:close_btn] -> [S:app.error_msg]
|
||||
"""
|
||||
if app.pending_error:
|
||||
imgui.open_popup("Error Alert")
|
||||
app.pending_error = False
|
||||
if imgui.begin_popup_modal("Error Alert", True, imgui.WindowFlags_.always_auto_resize)[0]:
|
||||
imgui.text(f"Operation Failed: {app.error_message}")
|
||||
if imgui.button("Acknowledge"):
|
||||
app.error_message = ""
|
||||
imgui.close_current_popup()
|
||||
imgui.end_popup()
|
||||
```
|
||||
|
||||
#### Comprehensive Code Mapping Example
|
||||
This example demonstrates a complete ImGui popup modal implementation and its corresponding SSDL annotation.
|
||||
|
||||
#### Python Code
|
||||
```python
|
||||
def render_confirm_action_modal(app: App) -> None:
|
||||
"""Renders the confirm action popup modal.
|
||||
@@ -182,7 +352,7 @@ def render_confirm_action_modal(app: App) -> None:
|
||||
imgui.end_popup()
|
||||
```
|
||||
|
||||
#### SSDL Trace Breakdown
|
||||
##### SSDL Trace Breakdown:
|
||||
1. `[Q:show_confirm]`: The function checks `app.show_confirm_modal` state.
|
||||
2. `-> [B:open_popup]`: If true, it opens the modal dialog.
|
||||
3. `-> [I:message]`: Draws the warning text `"Are you sure you want to proceed?"`.
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# SSDL Cluster 1: Core Primitives & Visual Typologies
|
||||
|
||||
This document establishes the formal specifications, structural grammar, and visual topologies of the **Spec/Sketch Description Language (SSDL)**. SSDL is a domain-specific modeling language designed to represent computational shapes and control-flow topologies within immediate-mode graphical interfaces.
|
||||
|
||||
---
|
||||
|
||||
## 1. The Theory of Computational Shapes
|
||||
|
||||
SSDL is built upon data-oriented design (DOD) principles. In modern object-oriented programming (OOP), compile-time entity hierarchies often obscure the runtime behavior of data. SSDL shifts the focus back to **computational shapes**—the visual paths that data and control follow through a program.
|
||||
|
||||
By defining a set of visual primitives, SSDL allows developers to:
|
||||
1. Map execution paths before writing code.
|
||||
2. Expose branching complexity and identify branch multiplication.
|
||||
3. Design interfaces that favor linear data transformations over complex conditional logic.
|
||||
|
||||
---
|
||||
|
||||
## 2. SSDL Primitive Grammar Specification
|
||||
|
||||
SSDL represents control flow, concurrency, repetition, and data dependencies using a standardized ASCII symbol set.
|
||||
|
||||
### 2.1 The 6 Primitives of Computation
|
||||
|
||||
```
|
||||
+-------------------------------------------------------------+
|
||||
| Primitive Shape | SSDL Symbol | Topology |
|
||||
+--------------------------+-------------+--------------------+
|
||||
| 1. Instruction | [I:name] | Bounded Node |
|
||||
| 2. Codepath | -> | Linear Arrow |
|
||||
| 3. Wide Codepath | => | Forked Arrow |
|
||||
| 4. Codecycle | o-> | Looping Indicator |
|
||||
| 5. Wide Codecycle | o=> | Parallel Loops |
|
||||
| 6. Codecycle Graph | Boxes/Lines | Visual Network |
|
||||
+-------------------------------------------------------------+
|
||||
```
|
||||
|
||||
1. **Instruction (`[I:name]`)**: A discrete, non-branching block of execution. It represents a single visual widget rendering (e.g., `imgui.text`) or a simple state query.
|
||||
2. **Codepath (`->`)**: Traces sequential, vertical, or horizontal control flow. A codepath has a single entry, progresses linearly, and must terminate at a terminator `[T]`.
|
||||
3. **Wide Codepath (`=>`)**: Represents a split or concurrent path of execution. In immediate-mode rendering, it maps to tab groups, collapsible sections, or columns.
|
||||
4. **Codecycle (`o->`)**: Represents loop iterations. It indicates that control cycles back to the first instruction of the sequence after the last instruction completes (e.g., scanning list items).
|
||||
5. **Wide Codecycle (`o=>`)**: Represents concurrent looping structures (e.g., parallel sub-agent workers rendering streams simultaneously).
|
||||
6. **Codecycle Graph**: A visual map composed of instructions, paths, and cycles, representing the system-level topology of data flow and control.
|
||||
|
||||
---
|
||||
|
||||
## 3. SSDL Modifiers and Annotations
|
||||
|
||||
Annotations are attached to instructions to specify their functional role:
|
||||
|
||||
* **`[T]` (Terminator)**: The final exit node of a codepath (e.g., `return` statement or window closing).
|
||||
* **`[B:condition]` (Branch)**: A fork in control flow based on a conditional statement.
|
||||
* **`[M]` (Merge)**: The point where previously split control-flow branches reconverge.
|
||||
* **`[S:state]` (Stateful Mutation)**: Marks an instruction that writes to mutable, persistent memory (e.g. updating configuration).
|
||||
* **`[Q:state]` (State Query)**: Marks an instruction that reads from mutable, persistent memory.
|
||||
* **`[N:sentinel]` (Nil Sentinel)**: A guaranteed-safe default node that satisfies pointer checks.
|
||||
* **`───` (Data Flow)**: A line tracking the propagation of data values, distinct from control-flow paths.
|
||||
* **`[•]` (Defused Branch)**: An instruction where a conditional branch has been refactored into a straight-line sequence.
|
||||
|
||||
---
|
||||
|
||||
## 4. Visual Topology Diagrams
|
||||
|
||||
SSDL diagrams trace control and data progression through functions.
|
||||
|
||||
### 4.1 Sequential Execution Path
|
||||
A linear sequence containing queries and instructions, terminating cleanly:
|
||||
```
|
||||
[Q:active_window] -> [I:SetupWindowFlags] -> [I:BeginRender] -> [T]
|
||||
```
|
||||
|
||||
### 4.2 Branching and Reconvergence
|
||||
Models a conditional fork and subsequent merge back into the main flow:
|
||||
```
|
||||
[Q:show_preview]
|
||||
│
|
||||
▼
|
||||
[B:is_enabled?]
|
||||
╱ ╲
|
||||
yes no
|
||||
╱ ╲
|
||||
▼ ▼
|
||||
[I:RenderMD] [I:RenderText]
|
||||
│ │
|
||||
▼ ▼
|
||||
└──────► [M] ◄──────┘
|
||||
│
|
||||
▼
|
||||
[I:RenderFooter]
|
||||
│
|
||||
▼
|
||||
[T]
|
||||
```
|
||||
This diagram maps a 2-way conditional execution path, returning to a single straight-line path after the merge.
|
||||
@@ -0,0 +1,138 @@
|
||||
# SSDL Cluster 2: Branch Defusing Mechanics & Memory Topologies
|
||||
|
||||
This document details the architectural, memory-level, and execution-flow mechanics of **Branch Defusing** within the Spec/Sketch Description Language (SSDL) framework. Defusing is the practice of converting conditional, branch-heavy control topologies into straight-line, cache-friendly data flows.
|
||||
|
||||
---
|
||||
|
||||
## 1. Branch Multiplication and Entropy
|
||||
|
||||
In immediate-mode interfaces (such as ImGui), the UI is rebuilt from scratch every frame. When business logic, resource management, and state queries are coupled with rendering, the execution graph splits into a combinatoric web of branches.
|
||||
|
||||
A branch in SSDL is defined as any point where a control path splits based on state:
|
||||
$$P_{effective} = \prod_{i=1}^{n} B_i$$
|
||||
Where $B_i$ is the number of branch outcomes at condition $i$. In a typical interface with 10 conditional panels or dynamic checks, the execution space reaches $2^{10} = 1024$ distinct codepaths. This introduces branch misprediction overhead, CPU pipeline stalls, and testing instability.
|
||||
|
||||
SSDL maps and guides the process of **defusing** these branches by introducing structural invariants.
|
||||
|
||||
---
|
||||
|
||||
## 2. Memory Topology of Nil Sentinels (`[N]`)
|
||||
|
||||
The most common branch in Python application code is the null validation check:
|
||||
```python
|
||||
if node is not None:
|
||||
# do work
|
||||
```
|
||||
In SSDL, a null check is a conditional fork: `[Q:node] -> [B:is_null?]`.
|
||||
By substituting a static, self-referential **Nil Sentinel** (`[N]`), we defuse the branch.
|
||||
|
||||
### 2.1 The Pointer Loop Topology
|
||||
|
||||
Instead of pointing to a memory location `0x0` (which triggers a hardware page fault or Python `AttributeError` upon dereference), unallocated or empty elements point to a dedicated static structure: the `nil_sentinel`.
|
||||
|
||||
#### Normal Memory Layout (Branchy Null-Checks):
|
||||
```
|
||||
Node A (0x1000) ────► Node B (0x2000) ────► NULL (0x0)
|
||||
│
|
||||
▼
|
||||
[AttributeError / Crash]
|
||||
```
|
||||
|
||||
#### Sentinel Memory Layout (Linear Defused):
|
||||
```
|
||||
Node A (0x1000) ────► Node B (0x2000) ────► Sentinel Node (0x8000)
|
||||
│ ▲
|
||||
└──────────┘ (Self-Loop)
|
||||
```
|
||||
|
||||
In the sentinel topology, the child/next pointers of the sentinel node point back to `0x8000` (itself). Any query, no matter how deep, resolves safely to the sentinel itself without checking for null.
|
||||
|
||||
### 2.2 SSDL Representation of Nil Sentinel Traversal
|
||||
|
||||
A multi-level lookup that is normally represented as a nested tree of decisions:
|
||||
```
|
||||
[Q:root] -> [B:root?] => [Q:child] -> [B:child?] => [Q:leaf] -> [B:leaf?]
|
||||
```
|
||||
Is defused into a single linear sequence:
|
||||
```
|
||||
[Q:root] -> [I:child] -> [I:leaf] -> [Q:value] -> [T]
|
||||
```
|
||||
If `child` or `leaf` is empty, it returns the `nil_sentinel`. The final query `[Q:value]` reads the default value stored in the sentinel (e.g., `0`, `""`, or a blank text buffer) instead of throwing an error or requiring a branch.
|
||||
|
||||
---
|
||||
|
||||
## 3. Generational Registry Tables
|
||||
|
||||
When resources (such as agents, files, or background tasks) are dynamically allocated and destroyed, tracking their lifespans introduces branch checking. SSDL models the resolution of dynamic lifespans via **Generational Handles**.
|
||||
|
||||
### 3.1 Handle Anatomy
|
||||
|
||||
A handle is a lightweight, 64-bit value split into two fields:
|
||||
* **Index (32-bit):** The offset in the flat allocation array.
|
||||
* **Generation (32-bit):** A monotonically increasing counter incremented every time the slot at `index` is reused.
|
||||
|
||||
```
|
||||
+───────────────────────────────┬───────────────────────────────+
|
||||
| Index (32-bit) | Generation (32-bit) |
|
||||
+───────────────────────────────┴───────────────────────────────+
|
||||
```
|
||||
|
||||
### 3.2 SSDL Resolution Flow
|
||||
|
||||
When resolving a handle to a concrete object, the validation check is encapsulated within the registry, returning the Nil Sentinel on failure:
|
||||
|
||||
```
|
||||
[Q:handle]
|
||||
│
|
||||
▼
|
||||
[I:LookupRegistry(handle.index)]
|
||||
│
|
||||
▼
|
||||
[B:Slot.Generation == handle.generation?]
|
||||
├── No ──► [I:Return Nil Sentinel] ──┐
|
||||
└── Yes ──► [I:Return Real Object] │
|
||||
▼
|
||||
[M:Safe Node]
|
||||
│
|
||||
▼
|
||||
[I:ExecuteAction]
|
||||
```
|
||||
|
||||
By guaranteeing that the registry always returns a valid, callable object (either the real object or the non-op nil sentinel), the caller does not need to check `is_valid` or wrap their execution in conditional branches.
|
||||
|
||||
---
|
||||
|
||||
## 4. Cache Worker Topologies (Immediate-Mode Loading)
|
||||
|
||||
To render remote or file-system-bound assets (like icons, file listings, or LLM response history) without blocking the frame rate, retained-mode systems rely on complex state machines:
|
||||
```
|
||||
State: [Unloaded] ──► [Loading] ──► [Ready]
|
||||
│
|
||||
└──► [Failed]
|
||||
```
|
||||
This introduces branches at every render call to check the loading state. SSDL models an **Immediate-Mode Cache Allocation** topology that hides this complexity.
|
||||
|
||||
### 4.1 Synchronous Key Querying
|
||||
|
||||
The caller requests the resource synchronously every frame using a key:
|
||||
|
||||
```
|
||||
Caller Path:
|
||||
[Q:ResourceKey] -> [I:GetCachedResource(Key)] -> [I:DrawResource] -> [T]
|
||||
```
|
||||
|
||||
### 4.2 Behind the Scenes: Parallel Worker Topology
|
||||
|
||||
If the resource is not in memory, the cache returns a placeholder (nil sentinel representation of the resource) and issues an asynchronous load request to a background thread pool.
|
||||
|
||||
```
|
||||
Foreground (Render Thread):
|
||||
[I:GetCachedResource] -> [B:In Cache?]
|
||||
├── Yes ──► [I:Return Resource]
|
||||
└── No ──► [I:Enqueue Load Task] ──► [I:Return Placeholder]
|
||||
|
||||
Background (Worker Thread):
|
||||
o=> [I:Dequeue Load Task] -> [I:Load Asset] -> [S:Write to Cache] -> [T:Worker Idle]
|
||||
```
|
||||
|
||||
Once the background worker writes the loaded asset into the cache, the next frame's synchronous call `GetCachedResource(Key)` naturally hits the cache and returns the fully loaded asset. The control flow in the main rendering loop remains completely linear.
|
||||
@@ -0,0 +1,143 @@
|
||||
# SSDL Cluster 3: Python-to-SSDL Mapping Rules & Concrete Examples
|
||||
|
||||
This document establishes the precise mapping guidelines between Python 3.11 ImGui code constructs and SSDL (Spec/Sketch Description Language) notation. It serves as a syntax validation manual for documenting the `gui_2.py` codebase.
|
||||
|
||||
---
|
||||
|
||||
## 1. Indentation & Structural Mapping Invariant
|
||||
|
||||
All Python code snippets within this specification adhere to the manual-slop project's **1-space indentation rule**.
|
||||
|
||||
### 1.1 SSDL Trace Header Convention
|
||||
|
||||
Every major render routine, popup modal, or loop structure in the codebase should document its computational shape in its docstring using a dedicated `SSDL:` header.
|
||||
|
||||
Format:
|
||||
```python
|
||||
def render_example() -> None:
|
||||
"""Short description.
|
||||
|
||||
SSDL: [Trace String]
|
||||
"""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Standard Widget & Pattern Mappings
|
||||
|
||||
This section defines the mapping rules for core user interface structures.
|
||||
|
||||
### 2.1 The Basic Linear Panel
|
||||
|
||||
A sequential panel containing labels, inputs, and a button.
|
||||
|
||||
#### Python Code:
|
||||
```python
|
||||
def render_simple_panel(app: App) -> None:
|
||||
"""Renders a basic configuration sidebar panel.
|
||||
|
||||
SSDL: [Q:app.config] -> [I:Header] -> [I:TextInput] -> [I:Checkbox] -> [B:SaveButton] -> [S:app.config]
|
||||
"""
|
||||
imgui.text("Configuration Settings")
|
||||
changed, app.temp_username = imgui.input_text("Username", app.temp_username)
|
||||
if imgui.checkbox("Enable Notifications", app.notifications_enabled)[0]:
|
||||
app.notifications_enabled = not app.notifications_enabled
|
||||
if imgui.button("Save Changes"):
|
||||
app.save_configuration()
|
||||
```
|
||||
|
||||
#### SSDL Trace Breakdown:
|
||||
1. `[Q:app.config]`: Queries the active configurations.
|
||||
2. `-> [I:Header]`: Renders text header.
|
||||
3. `-> [I:TextInput]`: Renders text input widget.
|
||||
4. `-> [I:Checkbox]`: Renders and evaluates the checkbox state.
|
||||
5. `-> [B:SaveButton]`: Evaluates button click.
|
||||
6. `-> [S:app.config]`: Save routine writes to persistent state file.
|
||||
|
||||
---
|
||||
|
||||
### 2.2 Tabbed / Columnar Layouts (Wide Codepath `=>`)
|
||||
|
||||
When layouts expand horizontally (via columns, tables, or tab bars), control flow diverges into concurrent visual segments. SSDL represents this using the `=>` separator.
|
||||
|
||||
#### Python Code:
|
||||
```python
|
||||
def render_workspace_tabs(app: App) -> None:
|
||||
"""Renders workspace tabs.
|
||||
|
||||
SSDL: [I:BeginTabBar] -> [B:Tab1] => [B:Tab2] -> [I:EndTabBar]
|
||||
"""
|
||||
if imgui.begin_tab_bar("WorkspaceTabs"):
|
||||
if imgui.begin_tab_item("Agent View")[0]:
|
||||
imgui.text("Agent Panel Content")
|
||||
imgui.end_tab_item()
|
||||
if imgui.begin_tab_item("File Editor")[0]:
|
||||
imgui.text("File Editor Content")
|
||||
imgui.end_tab_item()
|
||||
imgui.end_tab_bar()
|
||||
```
|
||||
|
||||
#### SSDL Trace Breakdown:
|
||||
1. `[I:BeginTabBar]`: Starts the tab group.
|
||||
2. `-> [B:Tab1]`: Check tab selection branch for "Agent View".
|
||||
3. `=>`: Denotes horizontal/parallel option branch.
|
||||
4. `[B:Tab2]`: Check tab selection branch for "File Editor".
|
||||
5. `-> [I:EndTabBar]`: Reconverges back to single control path.
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Loops & Lists (Codecycle `o->`)
|
||||
|
||||
Rendering lists of data requires looping. SSDL represents this using the Codecycle marker `o->`.
|
||||
|
||||
#### Python Code:
|
||||
```python
|
||||
def render_active_agents(app: App) -> None:
|
||||
"""Renders a list of running agent worker tasks.
|
||||
|
||||
SSDL: [Q:app.active_workers] -> o-> [I:WorkerRow] -> [B:KillButton] -> [S:app.active_workers]
|
||||
"""
|
||||
for worker in app.active_workers:
|
||||
imgui.text(f"ID: {worker.id} | Status: {worker.status}")
|
||||
imgui.same_line()
|
||||
if imgui.button(f"Terminate##{worker.id}"):
|
||||
app.controller.kill_worker(worker.id)
|
||||
```
|
||||
|
||||
#### SSDL Trace Breakdown:
|
||||
1. `[Q:app.active_workers]`: Read dynamic list of workers.
|
||||
2. `-> o->`: Enter loop sequence.
|
||||
3. `[I:WorkerRow]`: Render text label for each active worker.
|
||||
4. `-> [B:KillButton]`: Check if button was clicked.
|
||||
5. `-> [S:app.active_workers]`: Action modifies the worker list.
|
||||
|
||||
---
|
||||
|
||||
### 2.4 Popups & Modal Windows
|
||||
|
||||
Modals interrupt the parent window flow and create temporary sub-graphs.
|
||||
|
||||
#### Python Code:
|
||||
```python
|
||||
def render_error_modal(app: App) -> None:
|
||||
"""Renders a modal popup dialog when an error occurs.
|
||||
|
||||
SSDL: [Q:app.error_msg] -> [B:open_trigger] -> [I:draw_modal] -> [B:close_btn] -> [S:app.error_msg]
|
||||
"""
|
||||
if app.pending_error:
|
||||
imgui.open_popup("Error Alert")
|
||||
app.pending_error = False
|
||||
if imgui.begin_popup_modal("Error Alert", True, imgui.WindowFlags_.always_auto_resize)[0]:
|
||||
imgui.text(f"Operation Failed: {app.error_message}")
|
||||
if imgui.button("Acknowledge"):
|
||||
app.error_message = ""
|
||||
imgui.close_current_popup()
|
||||
imgui.end_popup()
|
||||
```
|
||||
|
||||
#### SSDL Trace Breakdown:
|
||||
1. `[Q:app.error_msg]`: Checks if error state is set.
|
||||
2. `-> [B:open_trigger]`: Evaluates flag to open the modal.
|
||||
3. `-> [I:draw_modal]`: Renders title, window frame, and warning text.
|
||||
4. `-> [B:close_btn]`: Evaluates clicking the acknowledge button.
|
||||
5. `-> [S:app.error_msg]`: Writes state change resetting error message.
|
||||
Reference in New Issue
Block a user