2
0

TerminalScheduler.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #nullable enable
  2. using System.Reactive.Concurrency;
  3. using System.Reactive.Disposables;
  4. using Terminal.Gui.App;
  5. namespace ReactiveExample;
  6. public class TerminalScheduler : LocalScheduler
  7. {
  8. public TerminalScheduler (IApplication? application) { _application = application; }
  9. private readonly IApplication? _application = null;
  10. public override IDisposable Schedule<TState> (
  11. TState state,
  12. TimeSpan dueTime,
  13. Func<IScheduler, TState, IDisposable> action
  14. )
  15. {
  16. IDisposable PostOnMainLoop ()
  17. {
  18. var composite = new CompositeDisposable (2);
  19. var cancellation = new CancellationDisposable ();
  20. _application?.Invoke (
  21. (_) =>
  22. {
  23. if (!cancellation.Token.IsCancellationRequested)
  24. {
  25. composite.Add (action (this, state));
  26. }
  27. }
  28. );
  29. composite.Add (cancellation);
  30. return composite;
  31. }
  32. IDisposable PostOnMainLoopAsTimeout ()
  33. {
  34. var composite = new CompositeDisposable (2);
  35. object? timeout = _application?.AddTimeout (
  36. dueTime,
  37. () =>
  38. {
  39. composite.Add (action (this, state));
  40. return false;
  41. }
  42. );
  43. composite.Add (Disposable.Create (() =>
  44. {
  45. if (timeout is { })
  46. {
  47. _application?.RemoveTimeout (timeout);
  48. }
  49. }));
  50. return composite;
  51. }
  52. return dueTime == TimeSpan.Zero
  53. ? PostOnMainLoop ()
  54. : PostOnMainLoopAsTimeout ();
  55. }
  56. }