• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DemoBytom / DemoEngine / 23720751690

29 Mar 2026 10:33PM UTC coverage: 30.541% (-0.8%) from 31.336%
23720751690

push

coveralls.net

DemoBytom
WIP fixes

1276 of 4178 relevant lines covered (30.54%)

0.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.51
/src/Demo.Engine.Core/Services/MainLoopService.cs
1
// Copyright © Michał Dembski and contributors.
2
// Distributed under MIT license. See LICENSE file in the root for more information.
3

4
using System.Diagnostics;
5
using Demo.Engine.Core.Features.StaThread;
6
using Demo.Engine.Core.Interfaces;
7
using Demo.Engine.Core.Interfaces.Rendering;
8
using Demo.Engine.Core.Requests.Keyboard;
9
using Demo.Engine.Core.ValueObjects;
10
using Mediator;
11
using Microsoft.Extensions.Logging;
12

13
namespace Demo.Engine.Core.Services;
14

15
internal sealed class MainLoopService
16
    : IMainLoopService,
17
      IAsyncDisposable
18
{
19
    private readonly ILogger<MainLoopService> _logger;
20
    private readonly IStaThreadWriter _staThreadWriter;
21
    private readonly IMediator _mediator;
22
    private readonly IFpsTimer _fpsTimer;
23
    private readonly IMainLoopLifetime _mainLoopLifetime;
24
    private readonly ILoopJob _loopJob;
25
    private bool _disposedValue;
26

27
    public Task ExecutingTask { get; }
28

29
    public MainLoopService(
1✔
30
        ILogger<MainLoopService> logger,
1✔
31
        IStaThreadWriter staThreadWriter,
1✔
32
        IMediator mediator,
1✔
33
        IFpsTimer fpsTimer,
1✔
34
        IRenderingEngine renderingEngine,
1✔
35
        IMainLoopLifetime mainLoopLifetime,
1✔
36
        ILoopJob loopJob)
1✔
37
    {
38
        _logger = logger;
1✔
39
        _staThreadWriter = staThreadWriter;
1✔
40
        _mediator = mediator;
1✔
41
        _fpsTimer = fpsTimer;
1✔
42
        _mainLoopLifetime = mainLoopLifetime;
1✔
43
        _loopJob = loopJob;
1✔
44
        ExecutingTask = Task.Run(async () =>
1✔
45
        {
1✔
46
            try
1✔
47
            {
1✔
48
                await DoAsync(renderingEngine);
1✔
49
            }
1✔
50
            catch (TaskCanceledException)
×
51
            {
1✔
52
                _mainLoopLifetime.Cancel();
×
53
            }
×
54
            catch (Exception ex)
×
55
            {
1✔
56
                _logger.LogMainLoopFailedWithError(ex);
×
57
                _mainLoopLifetime.Cancel();
×
58
                //throw;
1✔
59
            }
×
60
        });
1✔
61
    }
1✔
62

63
    private async Task DoAsync(
64
        IRenderingEngine renderingEngine)
65
    {
66
        var keyboardHandle = await _mediator.Send(new KeyboardHandleRequest(), CancellationToken.None);
1✔
67
        var keyboardCharCache = await _mediator.Send(new KeyboardCharCacheRequest(), CancellationToken.None);
1✔
68

69
        var surfaces = new RenderingSurfaceId[]
1✔
70
        {
1✔
71
            await _staThreadWriter.CreateSurface(
1✔
72
                _mainLoopLifetime.Token),
1✔
73
            //await _channelWriter.CreateSurface(
1✔
74
            //    _mainLoopLifetime.Token),
1✔
75
        };
1✔
76

77
        var previous = Stopwatch.GetTimestamp();
1✔
78
        var lag = TimeSpan.Zero;
1✔
79

80
        var msPerUpdate = TimeSpan.FromSeconds(1) / 60;
1✔
81

82
        var doEventsOk = true;
1✔
83

84
        while (
1✔
85
            doEventsOk
1✔
86
            //&& IsRunning
1✔
87
            && !_disposedValue
1✔
88
            && !_mainLoopLifetime.Token.IsCancellationRequested)
1✔
89
        {
90
            var current = Stopwatch.GetTimestamp();
1✔
91
            var elapsed = Stopwatch.GetElapsedTime(previous, current);
1✔
92
            previous = current;
1✔
93
            lag += elapsed;
1✔
94

95
            //process input
96
            // TODO!
97

98
            while (lag >= msPerUpdate)
1✔
99
            {
100
                //Update
101
                // TODO - fix the UPS timer.. somehow :D
102
                _fpsTimer.StopUpdateTimer();
1✔
103
                foreach (var renderingSurfaceId in surfaces)
1✔
104
                {
105
                    if (!renderingEngine.TryGetRenderingSurface(
106
                        renderingSurfaceId,
1✔
107
                        out var renderingSurface))
1✔
108
                    {
109
                        _logger.LogRenderingSurfaceNotFound(
×
110
                            renderingSurfaceId);
×
111
                        break;
×
112
                    }
113

114
                    await _loopJob.Update(
1✔
115
                          renderingSurface,
1✔
116
                          keyboardHandle,
1✔
117
                          keyboardCharCache);
1✔
118
                }
119
                lag -= msPerUpdate;
1✔
120
                _fpsTimer.StartUpdateTimer();
1✔
121
            }
122

123
            //Render
124
            foreach (var renderingSurfaceId in surfaces)
1✔
125
            {
126
                doEventsOk &= await _staThreadWriter.DoEventsOk(
1✔
127
                    renderingSurfaceId,
1✔
128
                    _mainLoopLifetime.Token);
1✔
129

130
                using var scope = _fpsTimer.StartRenderingTimerScope(
1✔
131
                    renderingSurfaceId);
1✔
132

133
                _loopJob.Render(
1✔
134
                    renderingEngine,
1✔
135
                    renderingSurfaceId);
1✔
136
            }
137
        }
138
        _mainLoopLifetime.Cancel();
1✔
139
    }
1✔
140

141
    private async ValueTask Dispose(bool disposing)
142
    {
143
        if (!_disposedValue)
1✔
144
        {
145
            if (disposing)
1✔
146
            {
147
            }
148

149
            _disposedValue = true;
1✔
150
            //Make sure the loop finishes
151
            await ExecutingTask;
1✔
152
        }
153
    }
1✔
154

155
    public async ValueTask DisposeAsync()
156
    {
157
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
158
        await Dispose(disposing: true);
1✔
159
        GC.SuppressFinalize(this);
1✔
160
    }
1✔
161
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc