public async Task Start(CancellationToken cancellationToken) { ConsoleDriver.Init(); _currentConsole = new VirtualConsole(); var hookContext = new HookContext(this); EventHookManager = new EventHookManager(_options.HookTypes ?? Enumerable.Empty <Type>(), _options.AfterUpdates ?? Enumerable.Empty <Action>(), hookContext, ServiceProvider); foreach (var afterCreateTask in _options.AfterCreateInvokers) { afterCreateTask.Invoke(this, ServiceProvider); } if (_options.StartupFunc != null) { await _options.StartupFunc(ServiceProvider, this); } var startup = ServiceProvider.GetService <ITvisionAppStartup>(); if (startup != null) { await startup.Startup(this); } PerformDrawOperations(force: true); while (!cancellationToken.IsCancellationRequested) { _watcher.Start(); var evts = _eventPumper.ReadEvents(); if (evts.HasWindowEvent) { _currentConsole.Resize(evts.WindowEvent.NewRows, evts.WindowEvent.NewColumns); } EventHookManager.ProcessEvents(evts); _ui.Update(evts); PerformDrawOperations(force: false); EventHookManager.ProcessAfterUpdateActions(); // TODO: At this point we still have all events in evts, but: // 1. No clue of which events had been processed (should annotate that) // 2. Don't do anything with remaining events. A list of pluggable "remaining events handler" could be implemented _watcher.Stop(); var ellapsed = (int)_watcher.ElapsedTicks; if (ellapsed < TIME_PER_FRAME) { await Task.Delay(TimeSpan.FromTicks(TIME_PER_FRAME - ellapsed), cancellationToken); } _watcher.Reset(); } }