Revise terminology proposal based on maintainer feedback

Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-10-25 22:04:11 +00:00
parent 76a5401414
commit 3f5fea0cd0
6 changed files with 740 additions and 1476 deletions

View File

@@ -1,159 +1,114 @@
# Application.Run Terminology Proposal - Executive Summary
# Application.Run Terminology - Executive Summary
## 🎯 Purpose
## The Ask
Propose clearer, more intuitive terminology for the `Application.Run` lifecycle APIs in Terminal.Gui.
Propose improved terminology for `Application.Run` lifecycle APIs to reduce confusion.
## 📊 The Problem in 30 Seconds
## Maintainer Feedback
Based on @tig's review:
- ✅ Keep deep analysis and diagrams
- ✅ Keep `Begin` and `End` (not wordy like BeginSession/EndSession)
- ✅ Keep `RequestStop` (non-blocking nature is clear)
- ✅ Preserve distinction between `RunLoop` (starts driver's mainloop) and `RunIteration` (one iteration)
## The Real Problems (Only 2)
### 1. `RunState` Sounds Like State Data
```csharp
// Current: "Run" means too many things
Application.Run(window); // ← Complete lifecycle
Application.RunLoop(runState); // ← Event loop?
Application.RunIteration(); // ← One iteration?
RunState runState = Application.Begin(window); // ← Begin what? What's RunState?
Application.End(runState); // ← End what?
RunState rs = Application.Begin(window); // ❌ What state does it hold?
```
**Result:** Confused users, unclear docs, steep learning curve.
**Reality:** It's a token/handle for Begin/End pairing, not state data.
## ✅ The Solution in 30 Seconds
**Solution:** Rename to `RunToken` (clear it's a token, concise).
### 2. `EndAfterFirstIteration` Confuses End() Method with Loop Control
```csharp
// Proposed: Clear, self-documenting names
Application.Run(window); // ← Unchanged (high-level)
ToplevelSession session = Application.BeginSession(window); // ✅ Clear
Application.ProcessEvents(session); // ✅ Clear
Application.EndSession(session); // ✅ Clear
Application.EndAfterFirstIteration = true; // ❌ Does this call End()?
```
**Result:** Self-documenting APIs, faster learning, industry alignment.
**Reality:** It controls `RunLoop()` behavior, not lifecycle cleanup.
## 📈 Impact
**Solution:** Rename to `StopAfterFirstIteration` (aligns with `RequestStop`, clearly about loop control).
### Who This Affects
-**New users:** Easier to understand and learn
-**Existing users:** Optional upgrade via [Obsolete] warnings
-**Documentation:** Clearer explanations possible
-**Maintainers:** Fewer confused user questions
## Proposed Changes (Minimal - 2 Names Only)
### Breaking Changes
-**NONE** - All existing APIs continue to work
- ✅ Old APIs marked `[Obsolete]` with helpful migration messages
- ✅ Gradual migration at each user's own pace
| Current | Proposed | Why |
|---------|----------|-----|
| `RunState` | `RunToken` | Clear it's a token, not state |
| `EndAfterFirstIteration` | `StopAfterFirstIteration` | Clear it controls loop, aligns with RequestStop |
## 🔄 Complete Mapping
## Keep Unchanged
| Current API | Proposed API | Benefit |
|-------------|--------------|---------|
| `RunState` | `ToplevelSession` | Clear it's a session token |
| `Begin()` | `BeginSession()` | Unambiguous what's beginning |
| `RunLoop()` | `ProcessEvents()` | Describes the action |
| `RunIteration()` | `ProcessEventsIteration()` | Consistent naming |
| `End()` | `EndSession()` | Unambiguous what's ending |
| `RequestStop()` | `StopProcessingEvents()` | Explicit about what stops |
| API | Why It Works |
|-----|--------------|
| `Begin` / `End` | Clear, concise - not wordy |
| `RequestStop` | "Request" appropriately conveys non-blocking |
| `RunLoop` / `RunIteration` | Distinction is important: RunLoop starts mainloop, RunIteration processes one iteration |
## 💡 Why "Session"?
## Usage Comparison
1. **Industry Standard**
- `HttpContext` - one HTTP request session
- `DbContext` - one database session
- `CancellationToken` - one cancellation scope
2. **Accurate**
- A Toplevel execution IS a bounded session
- Multiple sessions can exist (nested modals)
- Sessions have clear begin/end lifecycle
3. **Clear**
- "Session" implies temporary, bounded execution
- "BeginSession/EndSession" are unambiguous pairs
- "ToplevelSession" clearly indicates purpose
## 📚 Documentation Structure
```
TERMINOLOGY_README.md (Start Here)
├─ Overview and navigation
├─ Problem statement
└─ Links to all documents
TERMINOLOGY_PROPOSAL.md
├─ Complete analysis
├─ 3 options with rationale
├─ Migration strategy
└─ FAQ
TERMINOLOGY_QUICK_REFERENCE.md
├─ Side-by-side comparisons
├─ Usage examples
└─ Quick lookup tables
TERMINOLOGY_INDUSTRY_COMPARISON.md
├─ Framework comparisons
├─ Industry patterns
└─ Why this solution
TERMINOLOGY_VISUAL_GUIDE.md
├─ ASCII diagrams
├─ Flow charts
└─ Visual comparisons
### Before (Confusing)
```csharp
RunState rs = Application.Begin(window);
Application.EndAfterFirstIteration = true;
Application.RunLoop(rs);
Application.End(rs);
```
## 🚀 Next Steps
### After (Clear)
```csharp
RunToken token = Application.Begin(window);
Application.StopAfterFirstIteration = true;
Application.RunLoop(token);
Application.End(token);
```
1. **Review** - Community reviews this proposal
2. **Feedback** - Gather comments and suggestions
3. **Refine** - Adjust based on feedback
4. **Approve** - Get maintainer approval
5. **Implement** - Add new APIs with [Obsolete] on old ones
6. **Document** - Update all documentation
7. **Migrate** - Examples and guides use new terminology
## Benefits
## ⏱️ Timeline (Proposed)
- ✅ Addresses the 2 primary sources of confusion
- ✅ Minimal disruption (only 2 names)
- ✅ Backward compatible (obsolete attributes on old names)
- ✅ Respects maintainer feedback
- ✅ Preserves what works well
- **Phase 1 (Release N):** Add new APIs, mark old ones obsolete
- **Phase 2 (Release N+1):** Update all documentation
- **Phase 3 (Release N+2):** Update all examples
- **Phase 4 (Release N+3+):** Consider removing obsolete APIs (or keep forever)
## Documents
## 🗳️ Alternative Options
- **TERMINOLOGY_PROPOSAL.md** - Complete analysis with rationale
- **TERMINOLOGY_QUICK_REFERENCE.md** - Quick comparison and examples
- **TERMINOLOGY_VISUAL_GUIDE.md** - Visual diagrams showing the issues
This proposal includes 3 options:
## Alternative Options
1. **Session-Based** ⭐ (Recommended)
- BeginSession/ProcessEvents/EndSession
- Most accurate and industry-aligned
### For RunState
- **RunToken** ⭐ (Recommended) - Clear, concise
- ExecutionContext - Industry standard but longer
- Keep as-is - Not recommended (remains misleading)
2. **Modal/Show**
- Activate/EventLoop/Deactivate
- Aligns with WPF patterns
### For EndAfterFirstIteration
- **StopAfterFirstIteration** ⭐ (Recommended) - Aligns with RequestStop
- SingleIteration - Shorter but less obvious
- Keep as-is - Not recommended (continues confusion)
3. **Lifecycle**
- Start/Execute/Stop
- Simple verbs
## Migration Path
See [TERMINOLOGY_PROPOSAL.md](TERMINOLOGY_PROPOSAL.md) for detailed comparison.
Backward compatible via obsolete attributes:
## 💬 Feedback Welcome
```csharp
[Obsolete("Use RunToken instead")]
public class RunState { ... }
- What do you think of the proposed names?
- Do you prefer a different option?
- Any concerns about migration?
- Timeline reasonable for your projects?
[Obsolete("Use StopAfterFirstIteration instead")]
public static bool EndAfterFirstIteration { get; set; }
```
## 📖 Full Documentation
Read the complete proposal: [TERMINOLOGY_README.md](TERMINOLOGY_README.md)
Users can migrate gradually with simple find/replace.
---
**Status:** 📝 Awaiting Community Feedback
**Issue:** #4329
**Created:** 2025-10-25
**Author:** GitHub Copilot
**Status:** Revised based on maintainer feedback
**Focus:** Minimal, targeted changes addressing real confusion
**Impact:** Low (2 names), High clarity gain

View File

@@ -1,291 +0,0 @@
# Application.Run Terminology - Industry Comparison
This document compares Terminal.Gui's terminology with other popular UI frameworks to provide context for the proposed changes.
## Framework Comparison Matrix
### Complete Lifecycle (Show/Run a Window)
| Framework | API | Notes |
|-----------|-----|-------|
| **Terminal.Gui (current)** | `Application.Run(toplevel)` | Modal execution |
| **Terminal.Gui (proposed)** | `Application.Run(toplevel)` | Keep same (high-level API) |
| **WPF** | `window.ShowDialog()` | Modal, returns DialogResult |
| **WPF** | `window.Show()` | Non-modal |
| **WinForms** | `form.ShowDialog()` | Modal |
| **WinForms** | `Application.Run(form)` | Main message loop |
| **Avalonia** | `window.ShowDialog()` | Modal, async |
| **GTK#** | `window.ShowAll()` + `Gtk.Application.Run()` | Combined |
| **Qt** | `QApplication::exec()` | Main event loop |
| **Electron** | `mainWindow.show()` | Non-modal |
### Session/Context Token
| Framework | Concept | Type | Purpose |
|-----------|---------|------|---------|
| **Terminal.Gui (current)** | `RunState` | Class | Token for Begin/End pairing |
| **Terminal.Gui (proposed)** | `ToplevelSession` | Class | Session token (clearer name) |
| **WPF** | N/A | - | Hidden by framework |
| **WinForms** | `ApplicationContext` | Class | Message loop context |
| **Avalonia** | N/A | - | Hidden by framework |
| **ASP.NET** | `HttpContext` | Class | Request context (analogous) |
| **Entity Framework** | `DbContext` | Class | Session context (analogous) |
**Analysis:** "Session" or "Context" are industry standards for bounded execution periods. "State" is misleading.
### Initialize/Start
| Framework | API | Purpose |
|-----------|-----|---------|
| **Terminal.Gui (current)** | `Application.Begin(toplevel)` | Prepare toplevel for execution |
| **Terminal.Gui (proposed)** | `Application.BeginSession(toplevel)` | Start an execution session |
| **WPF** | `window.Show()` / `window.ShowDialog()` | Combined with event loop |
| **WinForms** | `Application.Run(form)` | Combined initialization |
| **Node.js HTTP** | `server.listen()` | Start accepting requests |
| **ASP.NET** | `app.Run()` | Start web server |
| **Qt** | `widget->show()` | Show widget |
**Analysis:** Most frameworks combine initialization with execution. Terminal.Gui's separation is powerful for advanced scenarios.
### Event Loop Processing
| Framework | API | Purpose | Notes |
|-----------|-----|---------|-------|
| **Terminal.Gui (current)** | `Application.RunLoop(runState)` | Process events until stopped | Confusing "Run" + "Loop" |
| **Terminal.Gui (proposed)** | `Application.ProcessEvents(session)` | Process events until stopped | Clear action verb |
| **WPF** | `Dispatcher.Run()` | Run dispatcher loop | Hidden in most apps |
| **WinForms** | `Application.Run()` | Process message loop | Auto-started |
| **Node.js** | `eventLoop.run()` | Run event loop | Internal |
| **Qt** | `QApplication::exec()` | Execute event loop | "exec" = execute |
| **GTK** | `Gtk.Application.Run()` | Main loop | Standard GTK term |
| **Win32** | `GetMessage()` / `DispatchMessage()` | Message pump | Manual control |
| **X11** | `XNextEvent()` | Process events | Manual control |
**Analysis:** "ProcessEvents" or "EventLoop" are clearer than "RunLoop". The term "pump" is Windows-specific.
### Single Iteration
| Framework | API | Purpose |
|-----------|-----|---------|
| **Terminal.Gui (current)** | `Application.RunIteration()` | Process one event cycle |
| **Terminal.Gui (proposed)** | `Application.ProcessEventsIteration()` | Process one event cycle |
| **Game Engines (Unity)** | `Update()` / `Tick()` | One frame/tick |
| **Game Engines (Unreal)** | `Tick(DeltaTime)` | One frame |
| **WPF** | `Dispatcher.ProcessEvents()` | Process pending events |
| **WinForms** | `Application.DoEvents()` | Process pending events |
| **Node.js** | `setImmediate()` / `process.nextTick()` | Next event loop iteration |
**Analysis:** "Iteration", "Tick", or "DoEvents" are all clear. "ProcessEvents" aligns with WPF.
### Cleanup/End
| Framework | API | Purpose |
|-----------|-----|---------|
| **Terminal.Gui (current)** | `Application.End(runState)` | Clean up after execution |
| **Terminal.Gui (proposed)** | `Application.EndSession(session)` | End the execution session |
| **WPF** | `window.Close()` | Close window |
| **WinForms** | `form.Close()` | Close form |
| **ASP.NET** | Request ends automatically | Dispose context |
| **Entity Framework** | `context.Dispose()` | Dispose context |
**Analysis:** "EndSession" pairs clearly with "BeginSession". "Close" works for windows but not for execution context.
### Stop/Request Stop
| Framework | API | Purpose |
|-----------|-----|---------|
| **Terminal.Gui (current)** | `Application.RequestStop()` | Signal loop to stop |
| **Terminal.Gui (proposed)** | `Application.StopProcessingEvents()` | Stop event processing |
| **WPF** | `window.Close()` | Close window, stops its loop |
| **WinForms** | `Application.Exit()` | Exit application |
| **Node.js** | `server.close()` | Stop accepting connections |
| **CancellationToken** | `cancellationToken.Cancel()` | Request cancellation |
**Analysis:** "RequestStop" is already clear. "StopProcessingEvents" is more explicit about what stops.
## Terminology Patterns Across Industries
### Game Development
Game engines use clear, explicit terminology:
```csharp
// Unity pattern
void Start() { } // Initialize
void Update() { } // Per-frame update (tick)
void OnDestroy() { } // Cleanup
// Typical game loop
while (running)
{
ProcessInput();
UpdateGameState();
Render();
}
```
**Lesson:** Use explicit verbs that describe what happens each phase.
### Web Development
Web frameworks use session/context patterns:
```csharp
// ASP.NET Core
public void Configure(IApplicationBuilder app)
{
app.Run(async context => // HttpContext = request session
{
await context.Response.WriteAsync("Hello");
});
}
// Entity Framework
using (var context = new DbContext()) // Session
{
// Work with data
}
```
**Lesson:** "Context" or "Session" for bounded execution periods is industry standard.
### GUI Frameworks
Desktop GUI frameworks separate showing from modal execution:
```csharp
// WPF pattern
window.Show(); // Non-modal
var result = window.ShowDialog(); // Modal (blocks)
// Terminal.Gui (current - confusing)
Application.Run(toplevel); // Modal? Non-modal? Unclear
// Terminal.Gui (proposed - clearer)
Application.Run(toplevel); // High-level: modal execution
// OR low-level:
var session = Application.BeginSession(toplevel);
Application.ProcessEvents(session);
Application.EndSession(session);
```
**Lesson:** Separate high-level convenience from low-level control.
## Key Insights
### 1. "Run" is Overloaded Everywhere
Many frameworks have "Run" methods, but they mean different things:
- **WPF**: `Application.Run()` - "run the entire application"
- **WinForms**: `Application.Run(form)` - "run with this form as main"
- **ASP.NET**: `app.Run()` - "start the web server"
- **Terminal.Gui**: `Application.Run(toplevel)` - "run this toplevel modally"
**Solution:** Keep high-level `Run()` for simplicity, but clarify low-level APIs.
### 2. Session/Context Pattern is Standard
The pattern of a token representing a bounded execution period is common:
- `HttpContext` - one HTTP request
- `DbContext` - one database session
- `ExecutionContext` - one execution scope
- `CancellationToken` - one cancellation scope
**Terminal.Gui's `RunState` fits this pattern** - it should be named accordingly.
### 3. Begin/End vs Start/Stop vs Open/Close
Different frameworks use different pairs:
- **Begin/End** - .NET (BeginInvoke/EndInvoke, BeginInit/EndInit)
- **Start/Stop** - Common (StartService/StopService)
- **Open/Close** - Resources (OpenFile/CloseFile, OpenConnection/CloseConnection)
Terminal.Gui currently uses **Begin/End**, which is fine, but it needs a noun:
-`BeginSession/EndSession` - Clear
-`Begin/End` - Begin what?
### 4. Event Processing Terminology
Most frameworks use one of:
- **ProcessEvents** - Explicit action (WPF, WinForms)
- **EventLoop** - Noun describing the construct
- **Pump/PumpMessages** - Windows-specific
- **Dispatch** - Action of dispatching events
**Terminal.Gui's "RunLoop"** is ambiguous - it could be a verb (run the loop) or a noun (the RunLoop object).
## Recommendations Based on Industry Analysis
### Primary Recommendation: Session-Based (Option 1)
```
Application.Run(toplevel) // Keep - familiar, simple
├─ Application.BeginSession(toplevel) → ToplevelSession
├─ Application.ProcessEvents(session)
└─ Application.EndSession(session)
```
**Aligns with:**
- .NET patterns (BeginInvoke/EndInvoke, HttpContext sessions)
- Industry standard "session" terminology
- Explicit "ProcessEvents" from WPF/WinForms
**Why it wins:**
1. "Session" is universally understood as bounded execution
2. "ProcessEvents" is explicit about what happens
3. Begin/End is already .NET standard
4. Minimal disruption to existing mental model
### Alternative: Lifecycle-Based (Option 3)
```
Application.Run(toplevel)
├─ Application.Start(toplevel) → ExecutionContext
├─ Application.Execute(context)
└─ Application.Stop(context)
```
**Aligns with:**
- Service patterns (StartService/StopService)
- Game patterns (Start/Update/Stop)
- Simpler verbs
**Trade-offs:**
- ⚠️ "Start/Stop" breaks existing Begin/End pattern
- ✅ More intuitive for newcomers
- ⚠️ "Execute" is less explicit than "ProcessEvents"
### Why Not Modal/Show (Option 2)
```
Application.ShowModal(toplevel)
├─ Application.Activate(toplevel)
└─ Application.Deactivate(toplevel)
```
**Issues:**
- Terminal.Gui doesn't distinguish modal/non-modal the way WPF does
- "Activate/Deactivate" implies window state, not execution
- Bigger departure from current API
## Conclusion
**Industry analysis supports Option 1 (Session-Based):**
1. ✅ "Session" is industry standard for bounded execution
2. ✅ "ProcessEvents" is clear and matches WPF/WinForms
3. ✅ Begin/End is established .NET pattern
4. ✅ Minimal disruption to existing API
5. ✅ Clear improvement over current "Run*" terminology
The proposed terminology brings Terminal.Gui in line with industry patterns while respecting its unique architecture that exposes low-level event loop control.
## References
- [WPF Application Model](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/app-development/application-management-overview)
- [WinForms Application Class](https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.application)
- [Avalonia Application Lifetime](https://docs.avaloniaui.net/docs/concepts/application-lifetimes)
- [GTK Application](https://docs.gtk.org/gtk4/class.Application.html)
- [Qt Application](https://doc.qt.io/qt-6/qapplication.html)
- [.NET HttpContext](https://docs.microsoft.com/en-us/dotnet/api/system.web.httpcontext)
- [Entity Framework DbContext](https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/)

View File

@@ -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 APIs and Their Actual Purposes
| 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 |
### Current Flow
```
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
```
## Proposed Terminology
### Option 1: Session-Based Terminology (Recommended)
This option emphasizes that running a Toplevel is a "session" with clear lifecycle management.
| 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 |
**Usage Example:**
**Current:**
```csharp
// High-level (unchanged)
Application.Run(myWindow);
// Low-level (new names)
ToplevelSession session = Application.BeginSession(myWindow);
Application.ProcessEvents(session);
Application.EndSession(session);
RunState runState = Application.Begin(toplevel);
Application.RunLoop(runState);
Application.End(runState);
```
### Option 2: Modal/Show Terminology
**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
This option aligns with WPF/WinForms patterns, emphasizing the modal/non-modal nature.
**Proposed Options:**
| 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 |
**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.)
**Usage Example:**
**Option B: `ExecutionContext`**
```csharp
ExecutionContext context = Application.Begin(toplevel);
Application.RunLoop(context);
Application.End(context);
```
- ✅ 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"
```
**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
**Proposed Options:**
**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
**Option B: `SingleIteration`**
```csharp
Application.SingleIteration = true;
```
- ✅ Shorter, positive framing
- ✅ Describes the mode, not the action
- ⚠️ Less obvious it's about stopping
**Option C: `RunLoopOnce`**
```csharp
Application.RunLoopOnce = true;
```
- ✅ Very explicit about what happens
- ⚠️ Slightly awkward phrasing
### 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
```
**Issue:** Three different APIs with "Run" in the name doing different things at different levels.
**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.
**Possible future consideration (not recommended now):**
- Document the distinction more clearly
- Keep names as-is since they work with understanding
## Recommended Changes
### 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
2. **`EndAfterFirstIteration``StopAfterFirstIteration`**
- Aligns with `RequestStop` terminology
- Clearly about loop control
- Minimal change
3. **Keep everything else:**
- `Begin` / `End` - Perfect as-is
- `RequestStop` - Clear non-blocking signal
- `RunLoop` / `RunIteration` - Distinction is valuable
- `Run()` - Familiar high-level API
### Usage Comparison
**Current (Confusing):**
```csharp
// High-level
Application.ShowModal(myWindow);
Application.Run(window);
// Low-level
ToplevelHandle handle = Application.Activate(myWindow);
while (!stopped)
Application.ProcessEvents(handle);
Application.Deactivate(handle);
Application.EndAfterFirstIteration = true;
RunState rs = Application.Begin(window);
Application.RunLoop(rs);
Application.End(rs);
```
### Option 3: Lifecycle Terminology
This option uses explicit lifecycle phases.
| 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 Example:**
**Proposed (Clearer):**
```csharp
// High-level (unchanged)
Application.Run(myWindow);
Application.Run(window);
// Low-level
ExecutionContext context = Application.Start(myWindow);
Application.Execute(context);
Application.Stop(context);
// Low-level (clearer)
Application.StopAfterFirstIteration = true;
RunToken token = Application.Begin(window);
Application.RunLoop(token);
Application.End(token);
```
## Recommendation: Option 1 (Session-Based)
## Understanding RunLoop vs RunIteration
**Recommended choice:** Option 1 - Session-Based Terminology
It's important to preserve the distinction:
**Reasons:**
- **`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
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
- **`RunIteration(ref token)`** - Processes ONE iteration
- Processes pending driver events
- Does layout if needed
- Draws if needed
- Returns immediately
**Migration Strategy:**
**Visual:**
```
RunLoop(token):
┌─────────────────────┐
│ while (Running) │
│ RunIteration() │ ← One call
│ RunIteration() │ ← Another call
│ RunIteration() │ ← Another call
└─────────────────────┘
```
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)
```
This distinction is valuable and should be preserved.
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**
## Migration Strategy
## Alternative Names Considered
### Phase 1: Add New Names with Obsolete Attributes
### 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
```csharp
// Add new type
public class RunToken { ... }
### 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
// Add conversion from old to new
public static implicit operator RunToken(RunState state) => new RunToken(state.Toplevel);
### 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
// Mark old type obsolete
[Obsolete("Use RunToken instead. RunState will be removed in a future version.")]
public class RunState { ... }
### For End/EndSession
- `CloseSession` - Could work with OpenSession
- `FinishSession` - Less common
- `TerminateSession` - Too harsh/formal
// Add new property
public static bool StopAfterFirstIteration { get; set; }
## Documentation Changes Required
// Mark old property obsolete
[Obsolete("Use StopAfterFirstIteration instead.")]
public static bool EndAfterFirstIteration
{
get => StopAfterFirstIteration;
set => StopAfterFirstIteration = value;
}
```
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
### Phase 2: Update Documentation
2. **Conceptual Documentation**
- Create "Application Lifecycle" documentation page
- Add diagrams showing the flow
- Explain when to use `Run()` vs. low-level APIs
- Update all docs to use new terminology
- Add migration guide
- Explain the distinction between RunLoop and RunIteration
3. **Migration Guide**
- Create mapping table (old → new)
- Provide before/after code examples
- Explain the rationale for changes
### Phase 3: Update Examples
## Implementation Notes
- Examples use new APIs
- Keep old examples in "legacy" section temporarily
### Backward Compatibility
### Phase 4: Future Removal (Multiple Releases Later)
- 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
- After sufficient adoption period, consider removing obsolete APIs
- Or keep them indefinitely with internal delegation
### Internal Implementation
## Alternative Naming Options
- New APIs can delegate to existing implementation
- Gradually refactor internals to use new terminology
- Update variable names and comments to use new terms
### For RunState/RunToken
### Testing
| 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 |
- Keep all existing tests working
- Add new tests using new terminology
- Test obsolete warnings work correctly
### For EndAfterFirstIteration
| 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`?**
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 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?**
A: No. Clear terminology is essential for framework usability. The current confusion around "Run" causes real problems for users learning the framework.
**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.
A: No. These specific names (`RunState`, `EndAfterFirstIteration`) cause real confusion. The changes are minimal, focused, and address documented pain points while preserving what works.
## Conclusion
## Summary
The proposed Session-Based terminology clarifies the Application execution lifecycle while maintaining backward compatibility. The new names are:
**Recommended Changes (Minimal Impact):**
- **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
1. `RunState``RunToken`
2. `EndAfterFirstIteration``StopAfterFirstIteration`
The migration path is straightforward, with minimal disruption to existing users.
**Keep Unchanged:**
- `Begin` / `End` - Clear and concise
- `RequestStop` - Appropriately conveys non-blocking
- `RunLoop` / `RunIteration` - Distinction is valuable
- `Run()` - Familiar high-level API
---
**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
## Next Steps
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.

View File

@@ -1,258 +1,202 @@
# Application Run Terminology - Quick Reference
# Application.Run Terminology - Quick Reference
## Current State (Confusing)
## The Problem
```
Application.Run(toplevel)
├─ Application.Begin(toplevel) → RunState
├─ Application.RunLoop(RunState)
│ └─ Application.RunIteration()
└─ Application.End(RunState)
```
Current terminology has two specific issues:
**Problems:**
- "Run" means too many things (lifecycle, loop, method names)
- "RunState" sounds like state data, but it's a token
- "Begin/End" - begin/end what?
- "RunLoop" vs "RunIteration" - relationship unclear
1. **`RunState`** sounds like state data, but it's actually a token/handle
2. **`EndAfterFirstIteration`** uses "End" but controls loop behavior, not lifecycle
## Proposed (Clear) - Option 1: Session-Based ⭐
## Recommended Solution
```
Application.Run(toplevel) // High-level API (unchanged)
├─ Application.BeginSession(toplevel) → ToplevelSession
├─ Application.ProcessEvents(ToplevelSession)
│ └─ Application.ProcessEventsIteration()
└─ Application.EndSession(ToplevelSession)
```
### Minimal Changes
**Benefits:**
- "Session" clearly indicates bounded execution period
- "ProcessEvents" describes what the loop does
- "BeginSession/EndSession" are unambiguous pairs
- "ToplevelSession" clearly indicates a session token
| Current | Proposed | Why |
|---------|----------|-----|
| `RunState` | `RunToken` | Clear it's a token, not state data |
| `EndAfterFirstIteration` | `StopAfterFirstIteration` | "Stop" aligns with `RequestStop`, clearly about loop control |
## Proposed (Clear) - Option 2: Modal/Show
### Keep Unchanged
```
Application.ShowModal(toplevel) // or keep Run()
├─ Application.Activate(toplevel) → ToplevelHandle
├─ Application.EventLoop(ToplevelHandle)
│ └─ Application.ProcessEvents()
└─ Application.Deactivate(ToplevelHandle)
```
| API | Why It Works |
|-----|--------------|
| `Begin` / `End` | Clear, concise lifecycle pairing |
| `RequestStop` | "Request" appropriately conveys non-blocking |
| `RunLoop` / `RunIteration` | Distinction is important: RunLoop starts the driver's mainloop, RunIteration processes one iteration |
**Benefits:**
- Aligns with WPF/WinForms patterns
- "Activate/Deactivate" are familiar GUI concepts
- "EventLoop" is industry standard terminology
## Proposed (Clear) - Option 3: Lifecycle
```
Application.Run(toplevel)
├─ Application.Start(toplevel) → ExecutionContext
├─ Application.Execute(ExecutionContext)
│ └─ Application.Tick()
└─ Application.Stop(ExecutionContext)
```
**Benefits:**
- Explicit lifecycle phases (Start → Execute → Stop)
- "Tick" is familiar from game development
- Simple, clear verbs
## Side-by-Side Comparison
| Concept | Current | Option 1 (Session) ⭐ | Option 2 (Modal) | Option 3 (Lifecycle) |
|---------|---------|---------------------|------------------|---------------------|
| Complete lifecycle | `Run()` | `Run()` | `ShowModal()` or `Run()` | `Run()` |
| Session token | `RunState` | `ToplevelSession` | `ToplevelHandle` | `ExecutionContext` |
| Initialize | `Begin()` | `BeginSession()` | `Activate()` | `Start()` |
| Event loop | `RunLoop()` | `ProcessEvents()` | `EventLoop()` | `Execute()` |
| One iteration | `RunIteration()` | `ProcessEventsIteration()` | `ProcessEvents()` | `Tick()` |
| Cleanup | `End()` | `EndSession()` | `Deactivate()` | `Stop()` |
| Stop loop | `RequestStop()` | `StopProcessingEvents()` | `Close()` or `RequestStop()` | `RequestStop()` |
| Stop mode flag | `EndAfterFirstIteration` | `StopAfterFirstIteration` | `SingleIteration` | `StopAfterFirstTick` |
## Usage Examples
### High-Level (All Options - Unchanged)
```csharp
// Simple case - most users use this
Application.Init();
Application.Run(myWindow);
Application.Shutdown();
```
### Low-Level - Current (Confusing)
```csharp
Application.Init();
RunState runState = Application.Begin(myWindow); // Begin what?
Application.RunLoop(runState); // Run vs RunLoop?
Application.End(runState); // End what?
Application.Shutdown();
```
### Low-Level - Option 1: Session-Based ⭐
```csharp
Application.Init();
ToplevelSession session = Application.BeginSession(myWindow); // Clear: starting a session
Application.ProcessEvents(session); // Clear: processing events
Application.EndSession(session); // Clear: ending the session
Application.Shutdown();
```
### Low-Level - Option 2: Modal/Show
```csharp
Application.Init();
ToplevelHandle handle = Application.Activate(myWindow); // Clear: activating for display
Application.EventLoop(handle); // Clear: running event loop
Application.Deactivate(handle); // Clear: deactivating
Application.Shutdown();
```
### Low-Level - Option 3: Lifecycle
```csharp
Application.Init();
ExecutionContext context = Application.Start(myWindow); // Clear: starting execution
Application.Execute(context); // Clear: executing
Application.Stop(context); // Clear: stopping
Application.Shutdown();
```
## Manual Event Loop Control
## Usage Comparison
### Current (Confusing)
```csharp
RunState rs = Application.Begin(myWindow);
Application.EndAfterFirstIteration = true;
while (!done)
{
Application.RunIteration(ref rs, firstIteration); // What's RunIteration vs RunLoop?
firstIteration = false;
// Do custom processing...
}
// What is RunState? State data or a handle?
RunState rs = Application.Begin(window);
Application.RunLoop(rs);
Application.End(rs);
// Does this call End()? No, it controls RunLoop()
Application.EndAfterFirstIteration = true;
```
### Option 1: Session-Based (Clear)
### Proposed (Clear)
```csharp
ToplevelSession session = Application.BeginSession(myWindow);
// Clearly a token, not state data
RunToken token = Application.Begin(window);
Application.RunLoop(token);
Application.End(token);
// Clearly controls loop stopping, aligns with RequestStop
Application.StopAfterFirstIteration = true;
while (!done)
{
Application.ProcessEventsIteration(ref session, firstIteration); // Clear: process one iteration
firstIteration = false;
// Do custom processing...
}
Application.EndSession(session);
```
### Option 2: Modal/Show (Clear)
## Understanding RunLoop vs RunIteration
**Important distinction to preserve:**
```
RunLoop(token): RunIteration(token):
┌──────────────────┐ ┌──────────────────┐
│ Starts driver's │ │ Processes ONE │
│ MainLoop │ │ iteration: │
│ │ │ - Events │
│ Loops calling: │ │ - Layout │
│ RunIteration() │ │ - Draw │
│ RunIteration() │ │ │
│ ... │ │ Returns │
│ │ │ immediately │
│ Until stopped │ │ │
└──────────────────┘ └──────────────────┘
```
This distinction is valuable and should be kept.
## Complete API Overview
```
Application.Run(window) ← High-level: complete lifecycle
├─ Application.Begin(window) → RunToken
│ └─ Initialize, layout, draw
├─ Application.RunLoop(token)
│ └─ Loop: while(running) { RunIteration() }
└─ Application.End(token)
└─ Cleanup
Application.RunIteration(ref token) ← Low-level: one iteration
Application.RequestStop() ← Signal loop to stop
Application.StopAfterFirstIteration ← Mode: stop after 1 iteration
```
## Alternative Options Considered
### For RunState
| Option | Pros | Cons |
|--------|------|------|
| **RunToken** ⭐ | Clear, concise | New term |
| ExecutionContext | Industry standard | Longer |
| RunHandle | Clear | Win32-ish |
### For EndAfterFirstIteration
| Option | Pros | Cons |
|--------|------|------|
| **StopAfterFirstIteration** ⭐ | Aligns with RequestStop | Slightly longer |
| SingleIteration | Shorter | Less obvious |
| RunLoopOnce | Explicit | Awkward |
## Migration Example
### Backward Compatible Migration
```csharp
ToplevelHandle handle = Application.Activate(myWindow);
Application.SingleIteration = true;
// Old code continues to work with obsolete warnings
[Obsolete("Use RunToken instead")]
public class RunState { ... }
while (!done)
{
Application.ProcessEvents(ref handle, firstIteration); // Clear: process events
firstIteration = false;
// Do custom processing...
[Obsolete("Use StopAfterFirstIteration instead")]
public static bool EndAfterFirstIteration
{
get => StopAfterFirstIteration;
set => StopAfterFirstIteration = value;
}
Application.Deactivate(handle);
// New code uses clearer names
public class RunToken { ... }
public static bool StopAfterFirstIteration { get; set; }
```
### Option 3: Lifecycle (Clear)
### User Migration
```csharp
ExecutionContext context = Application.Start(myWindow);
Application.StopAfterFirstTick = true;
// Before
RunState rs = Application.Begin(window);
Application.EndAfterFirstIteration = true;
Application.RunLoop(rs);
Application.End(rs);
while (!done)
{
Application.Tick(ref context, firstIteration); // Clear: one tick
firstIteration = false;
// Do custom processing...
}
Application.Stop(context);
// After (simple find/replace)
RunToken token = Application.Begin(window);
Application.StopAfterFirstIteration = true;
Application.RunLoop(token);
Application.End(token);
```
## Recommendation: Option 1 (Session-Based)
## Why These Changes?
**Why Session-Based wins:**
1. ✅ Most accurate - "session" perfectly describes bounded execution
2. ✅ Least disruptive - keeps Begin/End pattern, just clarifies it
3. ✅ Most descriptive - "ProcessEvents" is clearer than "RunLoop"
4. ✅ Industry standard - "session" is widely understood in software
5. ✅ Extensible - easy to add session-related features later
### RunState → RunToken
**Implementation:**
- Add new APIs alongside existing ones
- Mark old APIs `[Obsolete]` with helpful messages
- Update docs to use new terminology
- Maintain backward compatibility indefinitely
**Problem:** Users see "State" and think it holds state data. They ask:
- "What state does it hold?"
- "Can I query the state?"
- "Is it like a state machine?"
## Related Concepts
**Solution:** "Token" clearly indicates it's an identity/handle for Begin/End pairing, like `CancellationToken`.
### Application Lifecycle
### EndAfterFirstIteration → StopAfterFirstIteration
```
Application.Init() // Initialize the application
├─ Create driver
├─ Setup screen
└─ Initialize subsystems
**Problem:** Users see "End" and think of `End()` method. They ask:
- "Does this call `End()`?"
- "Why is it called 'End' when it controls the loop?"
Application.Run(toplevel) // Run a toplevel (modal)
├─ BeginSession
├─ ProcessEvents
└─ EndSession
**Solution:** "Stop" aligns with `RequestStop` and clearly indicates loop control, not lifecycle cleanup.
Application.Shutdown() // Shutdown the application
├─ Cleanup resources
└─ Restore terminal
```
## What We're NOT Changing
### Session vs Application Lifecycle
### Begin / End
| Application Lifecycle | Session Lifecycle |
|----------------------|-------------------|
| `Init()` - Once per app | `BeginSession()` - Per toplevel |
| `Run()` - Can have multiple | `ProcessEvents()` - Within one session |
| `Shutdown()` - Once per app | `EndSession()` - Per toplevel |
**Keep as-is** - Clear, concise lifecycle pairing
- Not wordy
- Industry standard pattern (BeginInvoke/EndInvoke, etc.)
- Works well
## Events and Notifications
### RequestStop
| Current | Proposed (Option 1) |
|---------|---------------------|
| `NotifyNewRunState` | `NotifyNewSession` |
| `NotifyStopRunState` | `NotifyStopSession` |
| `RunStateEventArgs` | `ToplevelSessionEventArgs` |
**Keep as-is** - Appropriately conveys non-blocking nature
- "Request" indicates it doesn't block
- Clear about what it does
- Works well
## See Also
### RunLoop / RunIteration
- [Full Proposal Document](TERMINOLOGY_PROPOSAL.md) - Detailed rationale and analysis
- [Migration Guide](docs/migration-guide.md) - How to update your code (TODO)
- [API Reference](docfx/api/Terminal.Gui.App.Application.yml) - API documentation
**Keep as-is** - Distinction is important and understood
- RunLoop = starts the driver's mainloop (blocking)
- RunIteration = processes one iteration (immediate)
- The distinction is valuable
- "Run" prefix is OK when the difference is clear
## Summary
**Changes (2 names only):**
- `RunState``RunToken`
- `EndAfterFirstIteration``StopAfterFirstIteration`
**Benefits:**
- ✅ Addresses the two primary sources of confusion
- ✅ Minimal disruption
- ✅ Backward compatible
- ✅ Respects maintainer feedback
- ✅ Preserves what works well
See [TERMINOLOGY_PROPOSAL.md](TERMINOLOGY_PROPOSAL.md) for detailed analysis.

View File

@@ -1,254 +0,0 @@
# Application.Run Terminology Proposal - README
This directory contains a comprehensive proposal for improving the terminology around `Application.Run` and related APIs in Terminal.Gui.
## 📋 Documents
### 1. [TERMINOLOGY_PROPOSAL.md](TERMINOLOGY_PROPOSAL.md)
**Complete proposal with detailed analysis**
Contents:
- Executive Summary
- Problem Statement (why current terminology is confusing)
- Current Terminology Analysis
- Three proposed options with pros/cons
- Recommendation: Option 1 (Session-Based)
- Migration strategy
- Documentation changes required
- FAQ
**Start here** for the full context and rationale.
### 2. [TERMINOLOGY_QUICK_REFERENCE.md](TERMINOLOGY_QUICK_REFERENCE.md)
**Quick comparison tables and code examples**
Contents:
- Current vs Proposed (all 3 options)
- Side-by-side comparison table
- Usage examples for each option
- Manual event loop control examples
- High-level vs low-level API comparison
**Use this** for quick lookup and comparison.
### 3. [TERMINOLOGY_INDUSTRY_COMPARISON.md](TERMINOLOGY_INDUSTRY_COMPARISON.md)
**How Terminal.Gui compares to other frameworks**
Contents:
- Comparison with WPF, WinForms, Avalonia, GTK, Qt
- Web framework patterns (ASP.NET, Entity Framework)
- Game engine patterns (Unity, Unreal)
- Industry standard terminology analysis
- Why "Session" is the right choice
**Read this** to understand industry context.
### 4. [TERMINOLOGY_VISUAL_GUIDE.md](TERMINOLOGY_VISUAL_GUIDE.md)
**Visual diagrams and flowcharts**
Contents:
- Visual comparison of current vs proposed
- Lifecycle diagrams
- Event flow diagrams
- Nested sessions (modal dialogs)
- Complete example flows
- Benefits visualization
**Use this** for visual learners and presentations.
## 🎯 The Problem
The current `Application.Run` terminology is confusing:
```csharp
// What's the difference between these "Run" methods?
Application.Run(window); // Complete lifecycle
Application.RunLoop(runState); // Event loop
Application.RunIteration(); // One iteration
// What is RunState? State or a handle?
RunState runState = Application.Begin(window); // Begin what?
// What's ending?
Application.End(runState); // End what?
```
**Result:** Confused users, steeper learning curve, unclear documentation.
## ✅ The Solution
### Option 1: Session-Based Terminology (Recommended)
```csharp
// High-level API (unchanged)
Application.Run(window); // Simple and familiar
// Low-level API (clearer names)
ToplevelSession session = Application.BeginSession(window); // ✅ Clear
Application.ProcessEvents(session); // ✅ Clear
Application.EndSession(session); // ✅ Clear
```
**Why this wins:**
- ✅ "Session" accurately describes bounded execution
- ✅ "ProcessEvents" is explicit about what happens
- ✅ "BeginSession/EndSession" are unambiguous
- ✅ Aligns with industry patterns (HttpContext, DbContext)
- ✅ Minimal disruption to existing API
### Complete Mapping
| Current | Proposed | Why |
|---------|----------|-----|
| `Run()` | `Run()` | Keep - familiar |
| `RunState` | `ToplevelSession` | Clear it's a session token |
| `Begin()` | `BeginSession()` | Clear what's beginning |
| `RunLoop()` | `ProcessEvents()` | Describes the action |
| `RunIteration()` | `ProcessEventsIteration()` | Consistent |
| `End()` | `EndSession()` | Clear what's ending |
| `RequestStop()` | `StopProcessingEvents()` | Explicit |
## 📊 Comparison Matrix
| Criterion | Current | Proposed (Option 1) |
|-----------|---------|---------------------|
| **Clarity** | ⚠️ "Run" overloaded | ✅ Each term is distinct |
| **Accuracy** | ⚠️ "State" is misleading | ✅ "Session" is accurate |
| **Learnability** | ⚠️ Steep curve | ✅ Self-documenting |
| **Industry Alignment** | ⚠️ Unique terminology | ✅ Standard patterns |
| **Breaking Changes** | N/A | ✅ None (old APIs kept) |
## 🚀 Migration Path
### Phase 1: Add New APIs (Release 1)
```csharp
// Add new APIs
public static ToplevelSession BeginSession(Toplevel toplevel) { ... }
// Mark old APIs obsolete
[Obsolete("Use BeginSession instead. See TERMINOLOGY_PROPOSAL.md")]
public static RunState Begin(Toplevel toplevel) { ... }
```
### Phase 2: Update Documentation (Release 1-2)
- Update all docs to use new terminology
- Add migration guide
- Update examples
### Phase 3: Community Adoption (Release 2-4)
- Examples use new APIs
- Community feedback period
- Adjust based on feedback
### Phase 4: Consider Removal (Release 5+)
- After 2-3 releases, consider removing `[Obsolete]` APIs
- Or keep them indefinitely with internal delegation
## 💡 Key Insights
### 1. High-Level API Unchanged
Most users won't be affected:
```csharp
Application.Init();
Application.Run(window); // Still works exactly the same
Application.Shutdown();
```
### 2. Low-Level API Clarified
Advanced users get clearer APIs:
```csharp
// Before (confusing)
var rs = Application.Begin(window);
Application.RunLoop(rs);
Application.End(rs);
// After (clear)
var session = Application.BeginSession(window);
Application.ProcessEvents(session);
Application.EndSession(session);
```
### 3. Complete Backward Compatibility
```csharp
// Old code continues to work
RunState rs = Application.Begin(window); // Works, but obsolete warning
Application.RunLoop(rs); // Works, but obsolete warning
Application.End(rs); // Works, but obsolete warning
```
## 📈 Benefits
### For Users
-**Faster learning** - Self-documenting APIs
-**Less confusion** - Clear, distinct names
-**Better understanding** - Matches mental model
### For Maintainers
-**Easier to explain** - Clear terminology in docs
-**Fewer questions** - Users understand the pattern
-**Better code** - Internal code can use clearer names
### For the Project
-**Professional** - Aligns with industry standards
-**Accessible** - Lower barrier to entry
-**Maintainable** - Clearer code is easier to maintain
## 🤔 Alternatives Considered
### Option 2: Modal/Show Terminology
```csharp
Application.ShowModal(window);
var handle = Application.Activate(window);
Application.EventLoop(handle);
Application.Deactivate(handle);
```
**Rejected:** Doesn't fit Terminal.Gui's model well.
### Option 3: Lifecycle Terminology
```csharp
var context = Application.Start(window);
Application.Execute(context);
Application.Stop(context);
```
**Rejected:** Breaks Begin/End pattern, "Execute" less explicit.
See [TERMINOLOGY_PROPOSAL.md](TERMINOLOGY_PROPOSAL.md) for full analysis.
## 📚 Additional Resources
### Terminal.Gui Documentation
- [Application Class](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.App.Application.html)
- [Multitasking Guide](docfx/docs/multitasking.md)
### Related Issues
- Issue #4329 - Original discussion about Run terminology
## 🗳️ Community Feedback
We welcome feedback on this proposal:
1. **Preferred option?** Session-Based, Modal/Show, or Lifecycle?
2. **Better names?** Suggest alternatives
3. **Migration concerns?** Share your use cases
4. **Timeline?** How long do you need to migrate?
## 📞 Contact
For questions or feedback:
- Open an issue in the Terminal.Gui repository
- Comment on the PR associated with this proposal
- Join the discussion in the community forums
## 📄 License
This proposal is part of the Terminal.Gui project and follows the same license (MIT).
---
**Status:** 📝 Proposal (awaiting community feedback)
**Author:** GitHub Copilot (generated based on issue #4329)
**Date:** 2025-10-25
**Version:** 1.0

View File

@@ -1,438 +1,319 @@
# Application.Run Terminology - Visual Guide
This document provides visual representations of the Application execution lifecycle to clarify the terminology.
## The Two Problems
## Current Terminology (Confusing)
### Problem 1: RunState Sounds Like State Data
### The Problem: "Run" Everywhere
```
Current (Confusing):
┌─────────────────────────────────────┐
│ RunState rs = Begin(window); │ ← "State"? What state does it hold?
│ │
│ Application.RunLoop(rs); │
│ │
│ Application.End(rs); │
└─────────────────────────────────────┘
Users think: "What state information does RunState contain?"
Reality: It's a token/handle for the Begin/End pairing
Proposed (Clear):
┌─────────────────────────────────────┐
│ RunToken token = Begin(window); │ ✅ Clear: it's a token, not state
│ │
│ Application.RunLoop(token); │
│ │
│ Application.End(token); │
└─────────────────────────────────────┘
Users understand: "It's a token for the Begin/End pairing"
```
### Problem 2: EndAfterFirstIteration Confuses End() with Loop Control
```
Current (Confusing):
┌──────────────────────────────────────────┐
│ EndAfterFirstIteration = true; │ ← "End"? Like End() method?
│ │
│ RunState rs = Begin(window); │
│ │
│ RunLoop(rs); // Stops after 1 iteration│
│ │
│ End(rs); // This is "End" │
└──────────────────────────────────────────┘
Users think: "Does EndAfterFirstIteration call End()?"
Reality: It controls RunLoop() behavior, not End()
Proposed (Clear):
┌──────────────────────────────────────────┐
│ StopAfterFirstIteration = true; │ ✅ Clear: controls loop stopping
│ │
│ RunToken token = Begin(window); │
│ │
│ RunLoop(token); // Stops after 1 iter │
│ │
│ End(token); // Cleanup │
└──────────────────────────────────────────┘
Users understand: "Stop controls the loop, End cleans up"
```
## Understanding RunLoop vs RunIteration
**This distinction is valuable and should be preserved:**
```
┌─────────────────────────────────────────────────────────┐
Application.Run() ← High-level API
RunLoop(token)
│ │
"Run" means the complete lifecycle
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────┐
│ Application.Begin(toplevel) │ ← "Begin" what?
│ Returns: RunState │ ← Sounds like state data
└─────────────────────────────────┘
─────────────────────────────────
│ Application.RunLoop(runState) │ ← "Run" again? Run vs RunLoop?
│ │
│ ┌───────────────────────────┐ │
│ │ while (running) │ │
│ │ RunIteration() │ │ ← "Run" again? What's the difference?
│ │ ProcessInput() │ │
│ │ Layout/Draw() │ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ Application.End(runState) │ ← "End" what?
└─────────────────────────────────┘
Issues:
❌ "Run" appears 4 times meaning different things
❌ RunState sounds like state, but it's a token
❌ Begin/End don't clarify what's beginning/ending
❌ RunLoop vs RunIteration relationship unclear
```
## Proposed Terminology - Option 1: Session-Based ⭐
### The Solution: Clear, Explicit Names
```
┌─────────────────────────────────────────────────────────┐
│ Application.Run() │ ← High-level (unchanged)
Starts the driver's MainLoop
│ Loops until stopped: │
┌────────────────────────────────────────────────┐
│ │ while (toplevel.Running) │ │
│ │ { │ │
RunIteration(ref token); ←──────────┐ │
RunIteration(ref token); ←──────────┤ │ │
│ │ RunIteration(ref token); ←──────────┤ │ │
│ │ ... │ │
│ │ } │ │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Complete lifecycle: Begin + ProcessEvents + End │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Application.BeginSession(toplevel) ✅ Clear: starting a session
│ Returns: ToplevelSession ✅ Clear: it's a session token
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Application.ProcessEvents(session) ✅ Clear: processing events
│ ┌──────────────────────────────┐ │
│ │ while (running) │ │
│ │ ProcessEventsIteration() │ │ ✅ Clear: one iteration of processing
│ │ ProcessInput() │ │
│ │ Layout/Draw() │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Application.EndSession(session) │ ✅ Clear: ending the session
└─────────────────────────────────────┘
┌────────────────────────────┐
│ RunIteration(ref token)
│ Processes ONE iteration: │
│ 1. Process driver events │
│ 2. Layout (if needed)
│ 3. Draw (if needed) │
│ │
│ Returns immediately
└─────────────────────────────┘
Benefits:
✅ "Session" clearly indicates bounded execution
✅ "ProcessEvents" describes the action
✅ BeginSession/EndSession are unambiguous
✅ Terminology is consistent and clear
Key Insight:
- RunLoop = The LOOP itself (blocking, manages iterations)
- RunIteration = ONE iteration (immediate, processes events)
```
## Lifecycle Comparison
### Application Lifecycle (Init/Shutdown) vs Session Lifecycle (Begin/ProcessEvents/End)
## Complete Lifecycle Visualization
```
┌────────────────────────── Application Lifetime ──────────────────────────┐
│ │
Application.Init() ← Initialize once per application
├─ Create driver
├─ Initialize screen
└─ Setup subsystems
┌──────────────────────── Session 1 ────────────────────────┐
Application.BeginSession(window1) → session1
│ ├─ Initialize window1
│ ├─ Layout window1
└─ Draw window1 │
│ │
│ Application.ProcessEvents(session1) │ │
└─ Event loop until RequestStop() │ │
│ │
Application.EndSession(session1) │ │
│ │ └─ Cleanup window1 │
└────────────────────────────────────────────────────────────┘
┌──────────────────────── Session 2 ────────────────────────┐
Application.BeginSession(dialog) → session2 │ │
│ Application.ProcessEvents(session2) │ │
│ Application.EndSession(session2) │
│ └────────────────────────────────────────────────────────────┘ │
Application.Shutdown() ← Cleanup once per application
├─ Dispose driver
└─ Restore terminal
└───────────────────────────────────────────────────────────────────────────┘
Key Insight: Multiple sessions within one application lifetime
```
## Event Flow During ProcessEvents
### Current (Confusing)
```
RunLoop(runState)
└─> while (toplevel.Running)
├─> RunIteration(runState) ← What's the difference?
│ │
│ ├─> MainLoop.RunIteration()
│ │ └─> Process driver events
│ │
│ ├─> Layout (if needed)
│ └─> Draw (if needed)
└─> (repeat)
```
### Proposed (Clear)
```
ProcessEvents(session)
└─> while (toplevel.Running)
├─> ProcessEventsIteration(session) ✅ Clear: one iteration of event processing
│ │
│ ├─> MainLoop.RunIteration()
│ │ └─> Process driver events
│ │
│ ├─> Layout (if needed)
│ └─> Draw (if needed)
└─> (repeat)
Application.Run(window)
┌───────────────────────────────────────────────────────┐
1. Begin(window) → RunToken
┌─────────────────────────────────┐
│ • Initialize window │
│ • Layout views
│ • Draw to screen │
└─────────────────────────────────┘
2. RunLoop(token)
┌─────────────────────────────────┐
│ Start driver's MainLoop
│ while (Running) {
RunIteration(ref token)
│ ├─ Process events
├─ Layout (if needed) │
│ └─ Draw (if needed) │
│ }
│ │
│ Exits when:
│ - RequestStop() called
│ - StopAfterFirstIteration=true │
└─────────────────────────────────┘
│ │
3. End(token)
┌─────────────────────────────────┐
│ • Cleanup window
│ • Dispose token │
│ └─────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────┘
```
## Manual Control Pattern
When you need fine-grained control over the event loop:
### Current (Confusing)
When you need fine-grained control:
```
RunState rs = Begin(toplevel); ← Begin what?
EndAfterFirstIteration = true; ← End what?
┌────────────────────────────────────────────┐
│ RunToken token = Begin(window); │
│ StopAfterFirstIteration = true; │ ✅ Clear: stop after one iter
│ │
│ while (!myCondition) │
│ { │
│ // Process one iteration │
│ RunIteration(ref token, first); │
│ first = false; │
│ │
│ // Your custom logic here │
│ DoCustomProcessing(); │
│ } │
│ │
│ End(token); │
└────────────────────────────────────────────┘
while (!done)
{
RunIteration(ref rs, first); ← Run what? How does this relate to RunLoop?
first = false;
// Custom processing
DoMyCustomStuff();
}
vs Old (Confusing):
End(rs); ← End what?
```
### Proposed (Clear)
```
ToplevelSession session = BeginSession(toplevel); ✅ Clear: starting a session
StopAfterFirstIteration = true; ✅ Clear: stop after one iteration
while (!done)
{
ProcessEventsIteration(ref session, first); ✅ Clear: process one iteration
first = false;
// Custom processing
DoMyCustomStuff();
}
EndSession(session); ✅ Clear: ending the session
┌────────────────────────────────────────────┐
│ RunState rs = Begin(window); │
│ EndAfterFirstIteration = true; │ ❌ Confusing: sounds like End()
│ │
│ while (!myCondition) │
│ { │
│ RunIteration(ref rs, first); │
│ first = false; │
│ DoCustomProcessing(); │
│ } │
│ │
│ End(rs); │
└────────────────────────────────────────────┘
```
## RequestStop Flow
### Current
```
User Action (e.g., Quit Key)
Application.RequestStop(toplevel)
Sets toplevel.Running = false
RunLoop detects !Running
RunLoop exits
Application.End() cleans up
┌────────────────────────┐
RequestStop(window) │ ✅ Keep: "Request" is clear
└────────────────────────┘
┌────────────────────────┐
│ window.Running=false │
└────────────────────────┘
┌────────────────────────┐
│ RunLoop exits │
└────────────────────────┘
┌────────────────────────┐
│ End() cleans up │
└────────────────────────┘
```
### Proposed (Same flow, clearer names)
## What We're Keeping
```
User Action (e.g., Quit Key)
Application.StopProcessingEvents(toplevel) ✅ Clear: stops event processing
Sets toplevel.Running = false
ProcessEvents detects !Running
ProcessEvents exits
Application.EndSession() cleans up
✅ KEEP AS-IS:
Begin/End
┌──────────────────┐ ┌──────────────────┐
│ Begin(window) │ ... │ End(token)
└──────────────────┘ └──────────────────┘
↑ ↑
Clear, concise Clear, concise
Not wordy Not wordy
RequestStop
┌─────────────────────┐
RequestStop() │
└─────────────────────┘
"Request" appropriately
conveys non-blocking
RunLoop / RunIteration
┌─────────────────┐ ┌──────────────────┐
│ RunLoop() │ │ RunIteration() │
│ (the loop) │ │ (one iteration) │
└─────────────────┘ └──────────────────┘
↑ ↑
│ │
Distinction is important and valuable
```
## Nested Sessions (Modal Dialogs)
## Side-by-Side Summary
```
┌────────────── Main Window Session ──────────────┐
│ session1 = BeginSession(mainWindow) │
ProcessEvents(session1) starts...
User clicks "Open Dialog" button │
│ ├─> ┌──────── Dialog Session ──────┐
│ │ │
│ │ │ session2 = BeginSession(dialog) │
│ │ │ │ │
│ │ │ ProcessEvents(session2) │ │
│ │ │ (blocks until dialog closes) │ │
│ │ │ │ │
│ │ │ EndSession(session2) │ │
│ │ │ │ │
│ │ └───────────────────────────────┘ │
│ │ │
│ │ (returns to main window) │
│ │ │
│ ...ProcessEvents continues │
│ │
│ EndSession(session1) │
│ │
└──────────────────────────────────────────────────┘
Key Insight: Sessions can be nested (modal dialogs)
╔═══════════════════════════════════╦═══════════════════════════════════╗
CURRENT PROPOSED
╠═══════════════════════════════════╬═══════════════════════════════════╣
RunState rs = Begin(window); RunToken token = Begin(window); ║
EndAfterFirstIteration = true; StopAfterFirstIteration = true;
RunLoop(rs); ║ RunLoop(token);
End(rs); ║ End(token); ║
║ ❌ "State" misleading ║ ✅ "Token" clear
║ ❌ "End" confuses with End() ✅ "Stop" aligns with RequestStop║
╚═══════════════════════════════════╩═══════════════════════════════════╝
```
## Complete Example Flow
### Simple Application
## Terminology Mapping
```
START
├─> Application.Init() [Application Lifecycle]
│ └─> Initialize driver, screen
├─> window = new Window()
├─> Application.Run(window) [High-level API]
│ │
│ ├─> BeginSession(window) [Session begins]
│ │ └─> Initialize, layout, draw
│ │
│ ├─> ProcessEvents(session) [Event processing]
│ │ └─> Loop until stopped
│ │
│ └─> EndSession(session) [Session ends]
│ └─> Cleanup
├─> window.Dispose()
└─> Application.Shutdown() [Application Lifecycle]
└─> Restore terminal
END
```
CHANGE (2 names):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
RunState → RunToken
EndAfterFirstIteration → StopAfterFirstIteration
### Application with Manual Control
```
START
├─> Application.Init()
├─> window = new Window()
├─> session = Application.BeginSession(window) [Manual Session Control]
│ └─> Initialize, layout, draw
├─> Application.StopAfterFirstIteration = true
├─> while (!done) [Custom Event Loop]
│ │
│ ├─> Application.ProcessEventsIteration(ref session, first)
│ │ └─> Process one iteration
│ │
│ ├─> DoCustomProcessing()
│ │
│ └─> first = false
├─> Application.EndSession(session) [Manual Session Control]
│ └─> Cleanup
├─> window.Dispose()
└─> Application.Shutdown()
END
```
## Terminology Mapping Summary
### API Name Changes
```
CURRENT PROPOSED
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Application.Run() → Application.Run() (unchanged)
RunState → ToplevelSession ✅ Clear: session token
Application.Begin() → Application.BeginSession() ✅ Clear: begin a session
Application.RunLoop() → Application.ProcessEvents() ✅ Clear: processes events
Application.RunIteration() → Application.ProcessEventsIteration() ✅ Clear: one iteration
Application.End() → Application.EndSession() ✅ Clear: end the session
Application.RequestStop() → Application.StopProcessingEvents() ✅ Clear: stops processing
EndAfterFirstIteration → StopAfterFirstIteration ✅ Consistent naming
NotifyNewRunState → NotifyNewSession ✅ Consistent naming
NotifyStopRunState → NotifyStopSession ✅ Consistent naming
RunStateEventArgs → ToplevelSessionEventArgs ✅ Consistent naming
KEEP UNCHANGED:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Begin → Begin ✅
End → End ✅
RequestStop → RequestStop ✅
RunLoop → RunLoop ✅
RunIteration → RunIteration ✅
Run → Run ✅
```
## Benefits Visualized
### Before: Confusion
```
User thinks:
"What's the difference between Run, RunLoop, and RunIteration?"
"Is RunState storing state or just a handle?"
"What am I Beginning and Ending?"
Before:
┌─────────────────────────────────────────┐
│ Users think: │
│ • "What state does RunState hold?" │
│ • "Does EndAfterFirstIteration call │
│ End()?" │
│ │
│ Result: Confusion, questions │
└─────────────────────────────────────────┘
┌─────────────┐
│ Run() │ ← What does "Run" mean exactly?
└─────────────┘
┌─────────────┐
Begin() ← Begin what?
└─────────────┘
─────────────
│ RunLoop() │ ← Is this the same as Run?
└─────────────┘
┌─────────────┐
│ End() │ ← End what?
└─────────────┘
Result: User confusion, slower learning curve
After:
┌─────────────────────────────────────────┐
│ Users understand: │
│ • "RunToken is a token"
• "StopAfterFirstIteration controls │
the loop"
│ │
Result: Clear, self-documenting
└─────────────────────────────────────────┘
```
### After: Clarity
## Summary
```
User understands:
"Run() does the complete lifecycle"
"BeginSession/EndSession manage a session"
"ProcessEvents processes events until stopped"
"ToplevelSession is a token for the session"
**2 Changes Only:**
- `RunState``RunToken` (clear it's a token)
- `EndAfterFirstIteration``StopAfterFirstIteration` (clear it controls loop)
┌─────────────────┐
│ Run() │ ✅ Complete lifecycle
└─────────────────┘
┌─────────────────┐
│ BeginSession() │ ✅ Start a session
└─────────────────┘
┌─────────────────┐
│ ProcessEvents() │ ✅ Process events
└─────────────────┘
┌─────────────────┐
│ EndSession() │ ✅ End the session
└─────────────────┘
**Everything Else Stays:**
- `Begin` / `End` - Clear and concise
- `RequestStop` - Appropriately non-blocking
- `RunLoop` / `RunIteration` - Valuable distinction
Result: Clear understanding, faster learning curve
```
**Result:**
- ✅ Addresses confusion at the source
- ✅ Minimal disruption (2 names)
- ✅ Preserves what works well
- ✅ Respects maintainer feedback
## See Also
- [TERMINOLOGY_PROPOSAL.md](TERMINOLOGY_PROPOSAL.md) - Full proposal with rationale
- [TERMINOLOGY_QUICK_REFERENCE.md](TERMINOLOGY_QUICK_REFERENCE.md) - Quick comparison tables
- [TERMINOLOGY_INDUSTRY_COMPARISON.md](TERMINOLOGY_INDUSTRY_COMPARISON.md) - Industry patterns
See [TERMINOLOGY_PROPOSAL.md](TERMINOLOGY_PROPOSAL.md) for complete analysis.