diff --git a/TERMINOLOGY_EXECUTIVE_SUMMARY.md b/TERMINOLOGY_EXECUTIVE_SUMMARY.md index 390ca8808..ba735794e 100644 --- a/TERMINOLOGY_EXECUTIVE_SUMMARY.md +++ b/TERMINOLOGY_EXECUTIVE_SUMMARY.md @@ -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 diff --git a/TERMINOLOGY_INDUSTRY_COMPARISON.md b/TERMINOLOGY_INDUSTRY_COMPARISON.md deleted file mode 100644 index 263d00eb9..000000000 --- a/TERMINOLOGY_INDUSTRY_COMPARISON.md +++ /dev/null @@ -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/) diff --git a/TERMINOLOGY_PROPOSAL.md b/TERMINOLOGY_PROPOSAL.md index 3fadee13d..c1ad9fbd3 100644 --- a/TERMINOLOGY_PROPOSAL.md +++ b/TERMINOLOGY_PROPOSAL.md @@ -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. diff --git a/TERMINOLOGY_QUICK_REFERENCE.md b/TERMINOLOGY_QUICK_REFERENCE.md index 56cee877c..c3193b220 100644 --- a/TERMINOLOGY_QUICK_REFERENCE.md +++ b/TERMINOLOGY_QUICK_REFERENCE.md @@ -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. diff --git a/TERMINOLOGY_README.md b/TERMINOLOGY_README.md deleted file mode 100644 index af0b151d7..000000000 --- a/TERMINOLOGY_README.md +++ /dev/null @@ -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 diff --git a/TERMINOLOGY_VISUAL_GUIDE.md b/TERMINOLOGY_VISUAL_GUIDE.md index af8644f38..277ad5377 100644 --- a/TERMINOLOGY_VISUAL_GUIDE.md +++ b/TERMINOLOGY_VISUAL_GUIDE.md @@ -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.