|
|
@@ -1,277 +1,306 @@
|
|
|
-# Application.Run Terminology Proposal
|
|
|
+# Application.Run Terminology Proposal (Revised)
|
|
|
|
|
|
## Executive Summary
|
|
|
|
|
|
-This document proposes improved terminology for the Terminal.Gui application execution lifecycle. The current `Run` terminology is overloaded and confusing, encompassing multiple distinct concepts. This proposal introduces clearer, more precise naming that better communicates the purpose and relationships of each API.
|
|
|
+This proposal addresses specific terminology issues in the Terminal.Gui Application.Run lifecycle while preserving what works well. Based on maintainer feedback, we keep `Begin`, `End`, and `RequestStop` unchanged, and focus on the real sources of confusion.
|
|
|
|
|
|
-## Problem Statement
|
|
|
+## What Works Well (Keep Unchanged)
|
|
|
|
|
|
-The current terminology around `Application.Run` is confusing because:
|
|
|
+- ✅ **`Begin` and `End`** - Clear, concise lifecycle pairing without being wordy
|
|
|
+- ✅ **`RequestStop`** - Non-blocking nature is appropriately conveyed by "Request"
|
|
|
+- ✅ **Distinction between `RunLoop` and `RunIteration`** - `RunLoop` starts the driver's mainloop, `RunIteration` processes one iteration
|
|
|
|
|
|
-1. **"Run" is overloaded** - It refers to both:
|
|
|
- - The complete lifecycle (Begin → RunLoop → End → Stop)
|
|
|
- - The event loop itself (RunLoop)
|
|
|
- - Multiple API methods (Run, RunLoop, RunIteration)
|
|
|
+## The Real Problems
|
|
|
|
|
|
-2. **Relationships are unclear** - Users don't understand that:
|
|
|
- - `Run()` is a convenience method = `Begin()` + `RunLoop()` + `End()`
|
|
|
- - `RunState` is a session token, not a state object
|
|
|
- - `RequestStop()` affects `RunLoop()` which triggers `End()`
|
|
|
+### Problem 1: `RunState` Sounds Like State Data
|
|
|
|
|
|
-3. **Inconsistent with industry patterns** - Other frameworks use clearer terms:
|
|
|
- - WPF: `Show()`, `ShowDialog()`, `Close()`
|
|
|
- - WinForms: `Show()`, `ShowDialog()`, `Application.Run()`
|
|
|
- - Avalonia: `Show()`, `ShowDialog()`, `StartWithClassicDesktopLifetime()`
|
|
|
-
|
|
|
-## Current Terminology Analysis
|
|
|
+**Current:**
|
|
|
+```csharp
|
|
|
+RunState runState = Application.Begin(toplevel);
|
|
|
+Application.RunLoop(runState);
|
|
|
+Application.End(runState);
|
|
|
+```
|
|
|
|
|
|
-### Current APIs and Their Actual Purposes
|
|
|
+**Issue:** The name `RunState` suggests it holds state/data about the run, but it's actually:
|
|
|
+- A token/handle returned by `Begin()` to pair with `End()`
|
|
|
+- An execution context for the Toplevel
|
|
|
+- Not primarily about "state" - it's about identity/scoping
|
|
|
|
|
|
-| Current Name | Actual Purpose | Confusion Point |
|
|
|
-|-------------|----------------|-----------------|
|
|
|
-| `Run()` | Complete lifecycle: Begin + Loop + End | Overloaded - means too many things |
|
|
|
-| `RunState` | Session token/handle for a Toplevel execution | Sounds like state data, not a handle |
|
|
|
-| `Begin()` | Initialize and prepare a Toplevel for execution | "Begin" what? Begin running? |
|
|
|
-| `RunLoop()` | Execute the event loop until stopped | Clear, but tied to "Run" |
|
|
|
-| `RunIteration()` | Execute one iteration of the event loop | Clear |
|
|
|
-| `End()` | Clean up after a Toplevel execution session | "End" what? End running? |
|
|
|
-| `RequestStop()` | Signal the event loop to stop | What does it stop? |
|
|
|
-| `EndAfterFirstIteration` | Exit after one loop iteration | Tied to "End" but affects loop |
|
|
|
+**Proposed Options:**
|
|
|
|
|
|
-### Current Flow
|
|
|
+**Option A: `RunToken`**
|
|
|
+```csharp
|
|
|
+RunToken token = Application.Begin(toplevel);
|
|
|
+Application.RunLoop(token);
|
|
|
+Application.End(token);
|
|
|
+```
|
|
|
+- ✅ Clear it's a token, not state data
|
|
|
+- ✅ Concise (not wordy)
|
|
|
+- ✅ Industry standard pattern (CancellationToken, etc.)
|
|
|
|
|
|
+**Option B: `ExecutionContext`**
|
|
|
+```csharp
|
|
|
+ExecutionContext context = Application.Begin(toplevel);
|
|
|
+Application.RunLoop(context);
|
|
|
+Application.End(context);
|
|
|
```
|
|
|
-Application.Run(toplevel)
|
|
|
- └─> Application.Begin(toplevel) → returns RunState
|
|
|
- └─> Initialize
|
|
|
- └─> Layout
|
|
|
- └─> Draw
|
|
|
- └─> Application.RunLoop(runState)
|
|
|
- └─> while (Running)
|
|
|
- └─> Application.RunIteration()
|
|
|
- └─> Process events
|
|
|
- └─> Layout (if needed)
|
|
|
- └─> Draw (if needed)
|
|
|
- └─> Application.End(runState)
|
|
|
- └─> Clean up
|
|
|
- └─> Dispose RunState
|
|
|
+- ✅ Accurately describes bounded execution scope
|
|
|
+- ✅ Familiar from .NET (HttpContext, DbContext)
|
|
|
+- ⚠️ Slightly longer
|
|
|
+
|
|
|
+**Option C: Keep `RunState` but clarify in docs**
|
|
|
+- ⚠️ Name remains misleading even with good documentation
|
|
|
+
|
|
|
+### Problem 2: `EndAfterFirstIteration` Confuses "End" with Loop Control
|
|
|
+
|
|
|
+**Current:**
|
|
|
+```csharp
|
|
|
+Application.EndAfterFirstIteration = true; // Controls RunLoop, not End()
|
|
|
+RunState rs = Application.Begin(window);
|
|
|
+Application.RunLoop(rs); // Stops after 1 iteration due to flag
|
|
|
+Application.End(rs); // This is actual "End"
|
|
|
```
|
|
|
|
|
|
-## Proposed Terminology
|
|
|
+**Issue:**
|
|
|
+- "End" in the flag name suggests the `End()` method, but it actually controls `RunLoop()`
|
|
|
+- The flag stops the loop, not the lifecycle
|
|
|
+- Creates confusion about when `End()` gets called
|
|
|
|
|
|
-### Option 1: Session-Based Terminology (Recommended)
|
|
|
+**Proposed Options:**
|
|
|
|
|
|
-This option emphasizes that running a Toplevel is a "session" with clear lifecycle management.
|
|
|
+**Option A: `StopAfterFirstIteration`**
|
|
|
+```csharp
|
|
|
+Application.StopAfterFirstIteration = true;
|
|
|
+```
|
|
|
+- ✅ "Stop" aligns with `RequestStop` which also affects the loop
|
|
|
+- ✅ Clearly about loop control, not lifecycle end
|
|
|
+- ✅ Minimal change
|
|
|
|
|
|
-| Current | Proposed | Rationale |
|
|
|
-|---------|----------|-----------|
|
|
|
-| `Run()` | `Run()` | Keep for backward compatibility and familiarity |
|
|
|
-| `RunState` | `ToplevelSession` | Clear that it's a session token, not state |
|
|
|
-| `Begin()` | `BeginSession()` | Clear what is beginning |
|
|
|
-| `RunLoop()` | `ProcessEvents()` | Describes what it does, not abstract "run" |
|
|
|
-| `RunIteration()` | `ProcessEventsIteration()` | Consistent with ProcessEvents |
|
|
|
-| `End()` | `EndSession()` | Clear what is ending |
|
|
|
-| `RequestStop()` | `StopProcessingEvents()` | Clear what stops |
|
|
|
-| `EndAfterFirstIteration` | `StopAfterFirstIteration` | Consistent with Stop terminology |
|
|
|
+**Option B: `SingleIteration`**
|
|
|
+```csharp
|
|
|
+Application.SingleIteration = true;
|
|
|
+```
|
|
|
+- ✅ Shorter, positive framing
|
|
|
+- ✅ Describes the mode, not the action
|
|
|
+- ⚠️ Less obvious it's about stopping
|
|
|
|
|
|
-**Usage Example:**
|
|
|
+**Option C: `RunLoopOnce`**
|
|
|
```csharp
|
|
|
-// High-level (unchanged)
|
|
|
-Application.Run(myWindow);
|
|
|
+Application.RunLoopOnce = true;
|
|
|
+```
|
|
|
+- ✅ Very explicit about what happens
|
|
|
+- ⚠️ Slightly awkward phrasing
|
|
|
|
|
|
-// Low-level (new names)
|
|
|
-ToplevelSession session = Application.BeginSession(myWindow);
|
|
|
-Application.ProcessEvents(session);
|
|
|
-Application.EndSession(session);
|
|
|
+### Problem 3: "Run" Overload (Lower Priority)
|
|
|
+
|
|
|
+**Current:**
|
|
|
+```csharp
|
|
|
+Application.Run(window); // Complete lifecycle
|
|
|
+Application.RunLoop(state); // Starts the driver's mainloop
|
|
|
+Application.RunIteration(state); // One iteration
|
|
|
```
|
|
|
|
|
|
-### Option 2: Modal/Show Terminology
|
|
|
+**Issue:** Three different APIs with "Run" in the name doing different things at different levels.
|
|
|
|
|
|
-This option aligns with WPF/WinForms patterns, emphasizing the modal/non-modal nature.
|
|
|
+**Note:** @tig's feedback indicates the distinction between `RunLoop` and `RunIteration` is important and understood. The "Run" prefix may not be a critical issue if the distinction is clear.
|
|
|
|
|
|
-| Current | Proposed | Rationale |
|
|
|
-|---------|----------|-----------|
|
|
|
-| `Run()` | `ShowModal()` or `Run()` | Emphasizes modal nature, or keep Run |
|
|
|
-| `RunState` | `ToplevelHandle` | It's a handle/token for the execution |
|
|
|
-| `Begin()` | `Activate()` | Activates the Toplevel for display |
|
|
|
-| `RunLoop()` | `EventLoop()` | Standard terminology |
|
|
|
-| `RunIteration()` | `ProcessEvents()` | Processes one iteration of events |
|
|
|
-| `End()` | `Deactivate()` | Deactivates the Toplevel |
|
|
|
-| `RequestStop()` | `Close()` or `RequestStop()` | Familiar to GUI developers |
|
|
|
-| `EndAfterFirstIteration` | `SingleIteration` | Mode rather than action |
|
|
|
+**Possible future consideration (not recommended now):**
|
|
|
+- Document the distinction more clearly
|
|
|
+- Keep names as-is since they work with understanding
|
|
|
|
|
|
-**Usage Example:**
|
|
|
-```csharp
|
|
|
-// High-level
|
|
|
-Application.ShowModal(myWindow);
|
|
|
+## Recommended Changes
|
|
|
|
|
|
-// Low-level
|
|
|
-ToplevelHandle handle = Application.Activate(myWindow);
|
|
|
-while (!stopped)
|
|
|
- Application.ProcessEvents(handle);
|
|
|
-Application.Deactivate(handle);
|
|
|
-```
|
|
|
+### Minimal Impact Recommendation
|
|
|
+
|
|
|
+Change only what's most confusing:
|
|
|
+
|
|
|
+1. **`RunState` → `RunToken`** (or `ExecutionContext`)
|
|
|
+ - Clear it's a token/handle
|
|
|
+ - Less ambiguous than "state"
|
|
|
+ - Concise
|
|
|
|
|
|
-### Option 3: Lifecycle Terminology
|
|
|
+2. **`EndAfterFirstIteration` → `StopAfterFirstIteration`**
|
|
|
+ - Aligns with `RequestStop` terminology
|
|
|
+ - Clearly about loop control
|
|
|
+ - Minimal change
|
|
|
|
|
|
-This option uses explicit lifecycle phases.
|
|
|
+3. **Keep everything else:**
|
|
|
+ - `Begin` / `End` - Perfect as-is
|
|
|
+ - `RequestStop` - Clear non-blocking signal
|
|
|
+ - `RunLoop` / `RunIteration` - Distinction is valuable
|
|
|
+ - `Run()` - Familiar high-level API
|
|
|
|
|
|
-| Current | Proposed | Rationale |
|
|
|
-|---------|----------|-----------|
|
|
|
-| `Run()` | `Run()` | Keep for compatibility |
|
|
|
-| `RunState` | `ExecutionContext` | It's a context for execution |
|
|
|
-| `Begin()` | `Start()` | Lifecycle: Start → Execute → Stop |
|
|
|
-| `RunLoop()` | `Execute()` | The execution phase |
|
|
|
-| `RunIteration()` | `Tick()` | Common game/event loop term |
|
|
|
-| `End()` | `Stop()` | Lifecycle: Start → Execute → Stop |
|
|
|
-| `RequestStop()` | `RequestStop()` | Keep, it's clear |
|
|
|
-| `EndAfterFirstIteration` | `StopAfterFirstTick` | Consistent with Tick |
|
|
|
+### Usage Comparison
|
|
|
|
|
|
-**Usage Example:**
|
|
|
+**Current (Confusing):**
|
|
|
```csharp
|
|
|
-// High-level (unchanged)
|
|
|
-Application.Run(myWindow);
|
|
|
+// High-level
|
|
|
+Application.Run(window);
|
|
|
|
|
|
// Low-level
|
|
|
-ExecutionContext context = Application.Start(myWindow);
|
|
|
-Application.Execute(context);
|
|
|
-Application.Stop(context);
|
|
|
+Application.EndAfterFirstIteration = true;
|
|
|
+RunState rs = Application.Begin(window);
|
|
|
+Application.RunLoop(rs);
|
|
|
+Application.End(rs);
|
|
|
```
|
|
|
|
|
|
-## Recommendation: Option 1 (Session-Based)
|
|
|
-
|
|
|
-**Recommended choice:** Option 1 - Session-Based Terminology
|
|
|
+**Proposed (Clearer):**
|
|
|
+```csharp
|
|
|
+// High-level (unchanged)
|
|
|
+Application.Run(window);
|
|
|
|
|
|
-**Reasons:**
|
|
|
+// Low-level (clearer)
|
|
|
+Application.StopAfterFirstIteration = true;
|
|
|
+RunToken token = Application.Begin(window);
|
|
|
+Application.RunLoop(token);
|
|
|
+Application.End(token);
|
|
|
+```
|
|
|
|
|
|
-1. **Accuracy** - "Session" accurately describes what's happening: a bounded period of execution for a Toplevel
|
|
|
-2. **Clarity** - "BeginSession/EndSession" are unambiguous pairs
|
|
|
-3. **ProcessEvents** - Clearly communicates what the loop does
|
|
|
-4. **Minimal conceptual shift** - The pattern is still Begin/Loop/End, just clearer
|
|
|
-5. **Extensibility** - "Session" can encompass future session-related features
|
|
|
+## Understanding RunLoop vs RunIteration
|
|
|
|
|
|
-**Migration Strategy:**
|
|
|
+It's important to preserve the distinction:
|
|
|
|
|
|
-1. **Phase 1: Add new APIs with Obsolete attributes on old ones**
|
|
|
- ```csharp
|
|
|
- [Obsolete("Use BeginSession instead")]
|
|
|
- public static RunState Begin(Toplevel toplevel)
|
|
|
-
|
|
|
- public static ToplevelSession BeginSession(Toplevel toplevel)
|
|
|
- ```
|
|
|
+- **`RunLoop(token)`** - Starts the driver's MainLoop and runs until stopped
|
|
|
+ - This is a blocking call that manages the loop
|
|
|
+ - Calls `RunIteration` repeatedly
|
|
|
+ - Returns when `RequestStop()` is called or `StopAfterFirstIteration` is true
|
|
|
|
|
|
-2. **Phase 2: Update documentation to use new terminology**
|
|
|
-3. **Phase 3: Update examples to use new APIs**
|
|
|
-4. **Phase 4: After 2-3 releases, consider removing obsolete APIs**
|
|
|
+- **`RunIteration(ref token)`** - Processes ONE iteration
|
|
|
+ - Processes pending driver events
|
|
|
+ - Does layout if needed
|
|
|
+ - Draws if needed
|
|
|
+ - Returns immediately
|
|
|
|
|
|
-## Alternative Names Considered
|
|
|
+**Visual:**
|
|
|
+```
|
|
|
+RunLoop(token):
|
|
|
+ ┌─────────────────────┐
|
|
|
+ │ while (Running) │
|
|
|
+ │ RunIteration() │ ← One call
|
|
|
+ │ RunIteration() │ ← Another call
|
|
|
+ │ RunIteration() │ ← Another call
|
|
|
+ └─────────────────────┘
|
|
|
+```
|
|
|
|
|
|
-### For RunState/ToplevelSession
|
|
|
-- `ToplevelToken` - Too focused on the token aspect
|
|
|
-- `ToplevelHandle` - C/Win32 feel, less modern
|
|
|
-- `ExecutionSession` - Too generic
|
|
|
-- `ToplevelContext` - Could work, but "context" is overloaded in .NET
|
|
|
-- `ToplevelExecution` - Sounds like a verb, not a noun
|
|
|
+This distinction is valuable and should be preserved.
|
|
|
|
|
|
-### For Begin/BeginSession
|
|
|
-- `StartSession` - Could work, but Begin/End is a common .NET pattern
|
|
|
-- `OpenSession` - Open/Close works but less common for this use
|
|
|
-- `InitializeSession` - Too long
|
|
|
+## Migration Strategy
|
|
|
|
|
|
-### For RunLoop/ProcessEvents
|
|
|
-- `EventLoop` - Good, but sounds like a noun not a verb
|
|
|
-- `PumpEvents` - Win32 terminology, might work
|
|
|
-- `HandleEvents` - Similar to ProcessEvents
|
|
|
-- `MainLoop` - Confusing with MainLoop class
|
|
|
+### Phase 1: Add New Names with Obsolete Attributes
|
|
|
|
|
|
-### For End/EndSession
|
|
|
-- `CloseSession` - Could work with OpenSession
|
|
|
-- `FinishSession` - Less common
|
|
|
-- `TerminateSession` - Too harsh/formal
|
|
|
+```csharp
|
|
|
+// Add new type
|
|
|
+public class RunToken { ... }
|
|
|
+
|
|
|
+// Add conversion from old to new
|
|
|
+public static implicit operator RunToken(RunState state) => new RunToken(state.Toplevel);
|
|
|
+
|
|
|
+// Mark old type obsolete
|
|
|
+[Obsolete("Use RunToken instead. RunState will be removed in a future version.")]
|
|
|
+public class RunState { ... }
|
|
|
+
|
|
|
+// Add new property
|
|
|
+public static bool StopAfterFirstIteration { get; set; }
|
|
|
+
|
|
|
+// Mark old property obsolete
|
|
|
+[Obsolete("Use StopAfterFirstIteration instead.")]
|
|
|
+public static bool EndAfterFirstIteration
|
|
|
+{
|
|
|
+ get => StopAfterFirstIteration;
|
|
|
+ set => StopAfterFirstIteration = value;
|
|
|
+}
|
|
|
+```
|
|
|
|
|
|
-## Documentation Changes Required
|
|
|
+### Phase 2: Update Documentation
|
|
|
|
|
|
-1. **API Documentation**
|
|
|
- - Update XML docs for all affected methods
|
|
|
- - Add clear examples showing lifecycle
|
|
|
- - Document the relationship between high-level `Run()` and low-level session APIs
|
|
|
+- Update all docs to use new terminology
|
|
|
+- Add migration guide
|
|
|
+- Explain the distinction between RunLoop and RunIteration
|
|
|
|
|
|
-2. **Conceptual Documentation**
|
|
|
- - Create "Application Lifecycle" documentation page
|
|
|
- - Add diagrams showing the flow
|
|
|
- - Explain when to use `Run()` vs. low-level APIs
|
|
|
+### Phase 3: Update Examples
|
|
|
|
|
|
-3. **Migration Guide**
|
|
|
- - Create mapping table (old → new)
|
|
|
- - Provide before/after code examples
|
|
|
- - Explain the rationale for changes
|
|
|
+- Examples use new APIs
|
|
|
+- Keep old examples in "legacy" section temporarily
|
|
|
|
|
|
-## Implementation Notes
|
|
|
+### Phase 4: Future Removal (Multiple Releases Later)
|
|
|
|
|
|
-### Backward Compatibility
|
|
|
+- After sufficient adoption period, consider removing obsolete APIs
|
|
|
+- Or keep them indefinitely with internal delegation
|
|
|
|
|
|
-- All existing APIs remain functional
|
|
|
-- Mark old APIs with `[Obsolete]` attributes
|
|
|
-- Provide clear upgrade path in obsolete messages
|
|
|
-- Consider keeping old APIs indefinitely with internal delegation to new ones
|
|
|
+## Alternative Naming Options
|
|
|
|
|
|
-### Internal Implementation
|
|
|
+### For RunState/RunToken
|
|
|
|
|
|
-- New APIs can delegate to existing implementation
|
|
|
-- Gradually refactor internals to use new terminology
|
|
|
-- Update variable names and comments to use new terms
|
|
|
+| Option | Pros | Cons | Recommendation |
|
|
|
+|--------|------|------|----------------|
|
|
|
+| `RunToken` | Clear it's a token, concise | New terminology | ⭐ Best |
|
|
|
+| `ExecutionContext` | Industry standard | Slightly longer | Good alternative |
|
|
|
+| `RunHandle` | Clear it's a handle | "Handle" sounds Win32-ish | Acceptable |
|
|
|
+| `RunContext` | Familiar pattern | "Context" overloaded in .NET | OK |
|
|
|
+| Keep `RunState` | No change needed | Remains misleading | Not recommended |
|
|
|
|
|
|
-### Testing
|
|
|
+### For EndAfterFirstIteration
|
|
|
|
|
|
-- Keep all existing tests working
|
|
|
-- Add new tests using new terminology
|
|
|
-- Test obsolete warnings work correctly
|
|
|
+| Option | Pros | Cons | Recommendation |
|
|
|
+|--------|------|------|----------------|
|
|
|
+| `StopAfterFirstIteration` | Aligns with RequestStop | Slightly longer | ⭐ Best |
|
|
|
+| `SingleIteration` | Shorter | Less obvious meaning | Good alternative |
|
|
|
+| `RunLoopOnce` | Very explicit | Awkward phrasing | OK |
|
|
|
+| Keep `EndAfterFirstIteration` | No change | Continues confusion | Not recommended |
|
|
|
|
|
|
## Comparison with Other Frameworks
|
|
|
|
|
|
-| Framework | Show View | Modal | Event Loop | Close |
|
|
|
-|-----------|-----------|-------|------------|-------|
|
|
|
-| **WPF** | `Show()` | `ShowDialog()` | `Dispatcher.Run()` | `Close()` |
|
|
|
-| **WinForms** | `Show()` | `ShowDialog()` | `Application.Run()` | `Close()` |
|
|
|
-| **Avalonia** | `Show()` | `ShowDialog()` | `Start()` | `Close()` |
|
|
|
-| **GTK** | `show()` | `run()` | `main()` | `close()` |
|
|
|
-| **Terminal.Gui v2 (current)** | `Run()` | `Run()` | `RunLoop()` | `RequestStop()` |
|
|
|
-| **Terminal.Gui v2 (proposed)** | `Run()` | `Run()` | `ProcessEvents()` | `StopProcessingEvents()` |
|
|
|
+**Token/Context Pattern:**
|
|
|
+- .NET: `CancellationToken` - token for cancellation scope
|
|
|
+- ASP.NET: `HttpContext` - context for HTTP request
|
|
|
+- Entity Framework: `DbContext` - context for database session
|
|
|
+- **Terminal.Gui:** `RunToken` (proposed) - token for execution scope
|
|
|
+
|
|
|
+**Loop Control Flags:**
|
|
|
+- WinForms: `Application.Exit()` - stops message loop
|
|
|
+- WPF: `Dispatcher.InvokeShutdown()` - stops dispatcher
|
|
|
+- **Terminal.Gui:** `RequestStop()` (keep), `StopAfterFirstIteration` (proposed)
|
|
|
|
|
|
## FAQ
|
|
|
|
|
|
-**Q: Why not just keep "Run"?**
|
|
|
-A: "Run" is too overloaded. It doesn't distinguish between the complete lifecycle and the event loop, leading to confusion about what `RunLoop`, `RunState`, and `RunIteration` mean.
|
|
|
+**Q: Why not change `Begin` and `End` to `BeginSession` and `EndSession`?**
|
|
|
|
|
|
-**Q: Why "Session" instead of "Context" or "Handle"?**
|
|
|
-A: "Session" best captures the bounded execution period. "Context" is overloaded in .NET (DbContext, HttpContext, etc.). "Handle" is too low-level and platform-specific.
|
|
|
+A: Per maintainer feedback, "Session" makes the names wordy without adding clarity. `Begin` and `End` are clear, concise, and work well as a lifecycle pair.
|
|
|
|
|
|
-**Q: What about breaking existing code?**
|
|
|
-A: We maintain complete backward compatibility by keeping old APIs and using `[Obsolete]` attributes. Users can migrate at their own pace.
|
|
|
+**Q: Why keep `RunLoop`?**
|
|
|
|
|
|
-**Q: Is this bikeshedding?**
|
|
|
-A: No. Clear terminology is essential for framework usability. The current confusion around "Run" causes real problems for users learning the framework.
|
|
|
+A: The distinction between `RunLoop` (starts the driver's mainloop) and `RunIteration` (one iteration) is important and well-understood. The "Run" prefix is not the primary source of confusion.
|
|
|
|
|
|
-**Q: Why not align exactly with WPF/WinForms?**
|
|
|
-A: Terminal.Gui has a different model - it exposes the event loop explicitly, which WPF/WinForms don't. We need terminology that fits our model while learning from established patterns.
|
|
|
+**Q: Why change `RunState`?**
|
|
|
+
|
|
|
+A: "State" implies the object holds state/data about the run. In reality, it's a token/handle for the Begin/End pairing. Calling it a "Token" or "Context" is more accurate.
|
|
|
+
|
|
|
+**Q: Why change `EndAfterFirstIteration`?**
|
|
|
+
|
|
|
+A: "End" in the flag name creates confusion with the `End()` method. The flag controls loop behavior, not lifecycle cleanup. "Stop" aligns better with `RequestStop` which also affects the loop.
|
|
|
+
|
|
|
+**Q: Is this bikeshedding?**
|
|
|
|
|
|
-## Conclusion
|
|
|
+A: No. These specific names (`RunState`, `EndAfterFirstIteration`) cause real confusion. The changes are minimal, focused, and address documented pain points while preserving what works.
|
|
|
|
|
|
-The proposed Session-Based terminology clarifies the Application execution lifecycle while maintaining backward compatibility. The new names are:
|
|
|
+## Summary
|
|
|
|
|
|
-- **More descriptive** - `ToplevelSession` vs `RunState`, `ProcessEvents` vs `RunLoop`
|
|
|
-- **More consistent** - `BeginSession`/`EndSession` pair, `ProcessEvents`/`StopProcessingEvents` pair
|
|
|
-- **More familiar** - Aligns with common patterns while respecting Terminal.Gui's unique architecture
|
|
|
-- **More maintainable** - Clear naming reduces cognitive load for contributors
|
|
|
+**Recommended Changes (Minimal Impact):**
|
|
|
|
|
|
-The migration path is straightforward, with minimal disruption to existing users.
|
|
|
+1. `RunState` → `RunToken`
|
|
|
+2. `EndAfterFirstIteration` → `StopAfterFirstIteration`
|
|
|
|
|
|
----
|
|
|
+**Keep Unchanged:**
|
|
|
+- `Begin` / `End` - Clear and concise
|
|
|
+- `RequestStop` - Appropriately conveys non-blocking
|
|
|
+- `RunLoop` / `RunIteration` - Distinction is valuable
|
|
|
+- `Run()` - Familiar high-level API
|
|
|
|
|
|
-## Next Steps
|
|
|
+**Benefits:**
|
|
|
+- ✅ Eliminates the two primary sources of confusion
|
|
|
+- ✅ Maintains clarity of successful patterns
|
|
|
+- ✅ Minimal disruption (2 names only)
|
|
|
+- ✅ Complete backward compatibility via obsolete attributes
|
|
|
+- ✅ Respects maintainer feedback
|
|
|
|
|
|
-1. **Community Feedback** - Gather feedback on this proposal from maintainers and community
|
|
|
-2. **Refinement** - Adjust terminology based on feedback
|
|
|
-3. **Implementation Plan** - Create detailed implementation plan with milestones
|
|
|
-4. **Documentation** - Prepare comprehensive documentation updates
|
|
|
-5. **Migration** - Implement changes with proper obsolete warnings and guidance
|
|
|
+This focused approach addresses real problems without over-engineering the solution.
|