Skip to content

Commit

Permalink
Warnings and nrt
Browse files Browse the repository at this point in the history
  • Loading branch information
tznind committed Dec 29, 2024
1 parent d9a05c7 commit 263e66c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 26 deletions.
5 changes: 2 additions & 3 deletions Terminal.Gui/ConsoleDrivers/V2/ConsoleInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ public abstract class ConsoleInput<T> : IConsoleInput<T>
/// </summary>
public Func<DateTime> Now { get; set; } = () => DateTime.Now;

private readonly Histogram<int> drainInputStream = Logging.Meter.CreateHistogram<int> ("Drain Input (ms)");


/// <inheritdoc/>
public virtual void Dispose () { }

Expand Down Expand Up @@ -51,7 +50,7 @@ public void Run (CancellationToken token)
TimeSpan took = Now () - dt;
TimeSpan sleepFor = TimeSpan.FromMilliseconds (20) - took;

drainInputStream.Record (took.Milliseconds);
Logging.DrainInputStream.Record (took.Milliseconds);

if (sleepFor.Milliseconds > 0)
{
Expand Down
26 changes: 16 additions & 10 deletions Terminal.Gui/ConsoleDrivers/V2/IMainLoop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,40 @@
namespace Terminal.Gui;

/// <summary>
/// Interface for main loop that runs the core Terminal.Gui UI loop.
/// Interface for main loop that runs the core Terminal.Gui UI loop.
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IMainLoop<T> : IDisposable
{
/// <summary>
/// Gets the class responsible for servicing user timeouts and idles
/// Gets the class responsible for servicing user timeouts and idles
/// </summary>
public ITimedEvents TimedEvents { get; }

/// <summary>
/// Gets the class responsible for writing final rendered output to the console
/// Gets the class responsible for writing final rendered output to the console
/// </summary>
public IOutputBuffer OutputBuffer { get; }

/// <summary>
/// Gets the class responsible for processing buffered console input and translating
/// it into events on the UI thread.
/// Class for writing output to the console.
/// </summary>
public IConsoleOutput Out { get; }

/// <summary>
/// Gets the class responsible for processing buffered console input and translating
/// it into events on the UI thread.
/// </summary>
public IInputProcessor InputProcessor { get; }

/// <summary>
/// Gets the class responsible for sending ANSI escape requests which expect a response
/// from the remote terminal e.g. Device Attribute Request
/// Gets the class responsible for sending ANSI escape requests which expect a response
/// from the remote terminal e.g. Device Attribute Request
/// </summary>
public AnsiRequestScheduler AnsiRequestScheduler { get; }

/// <summary>
/// Gets the class responsible for determining the current console size
/// Gets the class responsible for determining the current console size
/// </summary>
public IWindowSizeMonitor WindowSizeMonitor { get; }

Expand All @@ -46,7 +51,8 @@ public interface IMainLoop<T> : IDisposable
void Initialize (ITimedEvents timedEvents, ConcurrentQueue<T> inputBuffer, IInputProcessor inputProcessor, IConsoleOutput consoleOutput);

/// <summary>
/// Perform a single iteration of the main loop without blocking/sleeping anywhere.
/// Perform a single iteration of the main loop then blocks for a fixed length
/// of time, this method is designed to be run in a loop.
/// </summary>
public void Iteration ();
}
}
17 changes: 17 additions & 0 deletions Terminal.Gui/ConsoleDrivers/V2/Logging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,21 @@ public static class Logging
/// create your own static instrument e.g. CreateCounter, CreateHistogram etc
/// </summary>
internal static readonly Meter Meter = new ("Terminal.Gui");

/// <summary>
/// Metric for how long it takes each full iteration of the main loop to occur
/// </summary>
public static readonly Histogram<int> TotalIterationMetric = Logging.Meter.CreateHistogram<int> ("Iteration (ms)");

/// <summary>
/// Metric for how long it took to do the 'timeouts and invokes' section of main loop.
/// </summary>
public static readonly Histogram<int> IterationInvokesAndTimeouts = Logging.Meter.CreateHistogram<int> ("Invokes & Timers (ms)");

/// <summary>
/// Metric for how long it takes to read all available input from the input stream - at which
/// point input loop will sleep.
/// </summary>
public static readonly Histogram<int> DrainInputStream = Logging.Meter.CreateHistogram<int> ("Drain Input (ms)");

}
52 changes: 39 additions & 13 deletions Terminal.Gui/ConsoleDrivers/V2/MainLoop.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#nullable enable
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Diagnostics.Metrics;

namespace Terminal.Gui;

/// <inheritdoc/>
public class MainLoop<T> : IMainLoop<T>
{
private ITimedEvents? _timedEvents;
private ConcurrentQueue<T>? _inputBuffer;
private IInputProcessor? _inputProcessor;
private IConsoleOutput? _out;
private AnsiRequestScheduler? _ansiRequestScheduler;
private IWindowSizeMonitor? _windowSizeMonitor;

/// <inheritdoc/>
public ITimedEvents TimedEvents
Expand All @@ -24,27 +28,49 @@ public ITimedEvents TimedEvents
/// thread by a <see cref="IConsoleInput{T}"/>. Is drained as part of each
/// <see cref="Iteration"/>
/// </summary>
public ConcurrentQueue<T> InputBuffer { get; private set; }
public ConcurrentQueue<T> InputBuffer
{
get => _inputBuffer ?? throw new NotInitializedException (nameof (InputBuffer));
private set => _inputBuffer = value;
}

public IInputProcessor InputProcessor { get; private set; }
/// <inheritdoc/>
public IInputProcessor InputProcessor
{
get => _inputProcessor ?? throw new NotInitializedException (nameof (InputProcessor));
private set => _inputProcessor = value;
}

/// <inheritdoc/>
public IOutputBuffer OutputBuffer { get; } = new OutputBuffer ();

public IConsoleOutput Out { get; private set; }
public AnsiRequestScheduler AnsiRequestScheduler { get; private set; }
/// <inheritdoc/>
public IConsoleOutput Out
{
get => _out ?? throw new NotInitializedException (nameof (Out));
private set => _out = value;
}

/// <inheritdoc/>
public AnsiRequestScheduler AnsiRequestScheduler
{
get => _ansiRequestScheduler ?? throw new NotInitializedException (nameof (AnsiRequestScheduler));
private set => _ansiRequestScheduler = value;
}

public IWindowSizeMonitor WindowSizeMonitor { get; private set; }
/// <inheritdoc/>
public IWindowSizeMonitor WindowSizeMonitor
{
get => _windowSizeMonitor ?? throw new NotInitializedException (nameof (WindowSizeMonitor));
private set => _windowSizeMonitor = value;
}

/// <summary>
/// Determines how to get the current system type, adjust
/// in unit tests to simulate specific timings.
/// </summary>
public Func<DateTime> Now { get; set; } = () => DateTime.Now;

private static readonly Histogram<int> totalIterationMetric = Logging.Meter.CreateHistogram<int> ("Iteration (ms)");

private static readonly Histogram<int> iterationInvokesAndTimeouts = Logging.Meter.CreateHistogram<int> ("Invokes & Timers (ms)");

public void Initialize (ITimedEvents timedEvents, ConcurrentQueue<T> inputBuffer, IInputProcessor inputProcessor, IConsoleOutput consoleOutput)
{
InputBuffer = inputBuffer;
Expand All @@ -67,15 +93,15 @@ public void Iteration ()
TimeSpan took = Now () - dt;
TimeSpan sleepFor = TimeSpan.FromMilliseconds (50) - took;

totalIterationMetric.Record (took.Milliseconds);
Logging.TotalIterationMetric.Record (took.Milliseconds);

if (sleepFor.Milliseconds > 0)
{
Task.Delay (sleepFor).Wait ();
}
}

public void IterationImpl ()
internal void IterationImpl ()
{
InputProcessor.ProcessQueue ();

Expand All @@ -100,7 +126,7 @@ public void IterationImpl ()

TimedEvents.LockAndRunIdles ();

iterationInvokesAndTimeouts.Record (swCallbacks.Elapsed.Milliseconds);
Logging.IterationInvokesAndTimeouts.Record (swCallbacks.Elapsed.Milliseconds);
}

private bool AnySubviewsNeedDrawn (View v)
Expand Down

0 comments on commit 263e66c

Please sign in to comment.