diff --git a/TERMINOLOGY_README.md b/TERMINOLOGY_README.md new file mode 100644 index 000000000..af0b151d7 --- /dev/null +++ b/TERMINOLOGY_README.md @@ -0,0 +1,254 @@ +# 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 new file mode 100644 index 000000000..af8644f38 --- /dev/null +++ b/TERMINOLOGY_VISUAL_GUIDE.md @@ -0,0 +1,438 @@ +# Application.Run Terminology - Visual Guide + +This document provides visual representations of the Application execution lifecycle to clarify the terminology. + +## Current Terminology (Confusing) + +### The Problem: "Run" Everywhere + +``` +┌─────────────────────────────────────────────────────────┐ +│ Application.Run() │ ← High-level API +│ │ +│ "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) +│ │ +│ 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 + └─────────────────────────────────────┘ + +Benefits: +✅ "Session" clearly indicates bounded execution +✅ "ProcessEvents" describes the action +✅ BeginSession/EndSession are unambiguous +✅ Terminology is consistent and clear +``` + +## Lifecycle Comparison + +### Application Lifecycle (Init/Shutdown) vs Session Lifecycle (Begin/ProcessEvents/End) + +``` +┌────────────────────────── 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) +``` + +## Manual Control Pattern + +When you need fine-grained control over the event loop: + +### Current (Confusing) + +``` +RunState rs = Begin(toplevel); ← Begin what? +EndAfterFirstIteration = true; ← End what? + +while (!done) +{ + RunIteration(ref rs, first); ← Run what? How does this relate to RunLoop? + first = false; + + // Custom processing + DoMyCustomStuff(); +} + +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 +``` + +## 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 +``` + +### Proposed (Same flow, clearer names) + +``` +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 +``` + +## Nested Sessions (Modal Dialogs) + +``` +┌────────────── 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) +``` + +## Complete Example Flow + +### Simple Application + +``` +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 +``` + +### 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 +``` + +## 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?" + + ┌─────────────┐ + │ 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: Clarity + +``` +User understands: +"Run() does the complete lifecycle" +"BeginSession/EndSession manage a session" +"ProcessEvents processes events until stopped" +"ToplevelSession is a token for the session" + + ┌─────────────────┐ + │ Run() │ ✅ Complete lifecycle + └─────────────────┘ + │ + ┌─────────────────┐ + │ BeginSession() │ ✅ Start a session + └─────────────────┘ + │ + ┌─────────────────┐ + │ ProcessEvents() │ ✅ Process events + └─────────────────┘ + │ + ┌─────────────────┐ + │ EndSession() │ ✅ End the session + └─────────────────┘ + +Result: Clear understanding, faster learning curve +``` + +## 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