Skip to content

Commit 73d3837

Browse files
committed
Moved from threads to tasks
1 parent 8beae48 commit 73d3837

File tree

3 files changed

+57
-38
lines changed

3 files changed

+57
-38
lines changed

DoomFire/DoomFireSim.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.ComponentModel;
4-
using System.Diagnostics;
5-
using System.Drawing;
6-
using System.Drawing.Drawing2D;
7-
using System.Drawing.Imaging;
84
using System.Runtime.CompilerServices;
9-
using System.Runtime.InteropServices;
10-
using System.Security.Cryptography;
11-
using System.Threading.Tasks;
125

136
namespace DoomFire {
147
public class DoomFireSim: INotifyPropertyChanged {
@@ -153,8 +146,10 @@ public void DoFire() {
153146
}
154147

155148
private void SpreadFire(int x, int row, int nextRow) {
149+
var pixels = this.Pixels;
150+
156151
var idx = row + x;
157-
var pixel = this.Pixels[idx];
152+
var pixel = pixels[idx];
158153

159154
var rnd = this.GetRandomFloat();
160155
var randomRemapped = (rnd - 0.5f) * 2; // 0.0 - 1.0 remapped to -1.0 - 1.0
@@ -166,11 +161,13 @@ private void SpreadFire(int x, int row, int nextRow) {
166161
var nextIdx = nextRow + newX;
167162

168163
if (pixel == 0) {
169-
this.Pixels[nextIdx] = 0;
164+
pixels[nextIdx] = 0;
170165
return;
171166
}
172167

173-
this.Pixels[nextIdx] = (byte)Math.Max(0, Math.Round(pixel - rnd * this.FadeSpeedBase));
168+
pixels[nextIdx] = (byte)Math.Max(0, Math.Round(pixel - rnd * this.FadeSpeedBase));
169+
170+
this.Pixels = pixels;
174171
}
175172
}
176173
}

DoomFireGUI/MainWindow.xaml

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,22 @@
103103
</Grid>
104104

105105
<Button Content="Initialize" Padding="10,4" Click="InitButton_OnClick" />
106-
<Grid>
107-
<Grid.ColumnDefinitions>
108-
<ColumnDefinition />
109-
<ColumnDefinition Width="5" />
110-
<ColumnDefinition />
111-
</Grid.ColumnDefinitions>
112-
<Button Content="Start" Padding="10,4" Click="StartButton_OnClick" />
113-
<Button Grid.Column="2" Content="Pause" Padding="10,4" Click="PauseButton_OnClick" />
114-
</Grid>
106+
107+
<Button Padding="10,4" Margin="0,5,0,0"
108+
Click="StartButton_OnClick">
109+
<Button.Style>
110+
<Style TargetType="Button">
111+
<Style.Triggers>
112+
<DataTrigger Binding="{Binding DFIsRunning}" Value="True">
113+
<Setter Property="Content" Value="Stop"/>
114+
</DataTrigger>
115+
<DataTrigger Binding="{Binding DFIsRunning}" Value="False">
116+
<Setter Property="Content" Value="Start"/>
117+
</DataTrigger>
118+
</Style.Triggers>
119+
</Style>
120+
</Button.Style>
121+
</Button>
115122

116123
<CheckBox Content="Use Palette"
117124
IsChecked="{Binding UsePalette}" />
@@ -172,7 +179,7 @@
172179

173180
<StackPanel DataContext="{Binding DF}">
174181
<TextBlock>
175-
<Run>Bits:</Run>
182+
<Run>Randomness Bits:</Run>
176183
<Run Text="{Binding CutoffBits, FallbackValue=N/A}" />
177184
</TextBlock>
178185
<Slider Value="{Binding CutoffBits}"

DoomFireGUI/MainWindow.xaml.cs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
using System.Diagnostics;
55
using System.Runtime.CompilerServices;
66
using System.Threading;
7+
using System.Threading.Tasks;
78
using System.Windows;
89
using System.Windows.Media;
9-
using System.Windows.Media.Animation;
1010
using System.Windows.Media.Imaging;
1111
using DoomFire;
1212
using DColor = System.Drawing.Color;
@@ -32,6 +32,8 @@ private void SetField<T>(ref T field, T value, [CallerMemberName] string propert
3232

3333
#endregion
3434

35+
#region Properties
36+
3537
private DoomFireSim _df;
3638
public DoomFireSim DF {
3739
get => this._df;
@@ -92,9 +94,12 @@ public int ActualFrameRate {
9294
set => this.SetField(ref this._actualFrameRate, value);
9395
}
9496

97+
#endregion
98+
9599
private readonly DColor[] firePalette;
96100

97-
private Thread simThread;
101+
private CancellationTokenSource tokenSource = new CancellationTokenSource();
102+
private Task simulationTask;
98103

99104
public MainWindow() {
100105
this.firePalette = DoomFire.Colors.PopulatePalette(256);
@@ -107,7 +112,7 @@ private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) {
107112
}
108113

109114
private void MainWindow_OnClosing(object sender, CancelEventArgs e) {
110-
this.DFIsRunning = false;
115+
this.tokenSource.Cancel();
111116
}
112117

113118
private void InitButton_OnClick(object sender, RoutedEventArgs e) {
@@ -127,32 +132,42 @@ private void InitButton_OnClick(object sender, RoutedEventArgs e) {
127132
}
128133

129134
private void StartButton_OnClick(object sender, RoutedEventArgs e) {
130-
if (this.DFIsRunning)
131-
return;
135+
if (this.DFIsRunning) {
136+
this.ResizeMode = ResizeMode.CanResizeWithGrip;
132137

133-
this.ResizeMode = ResizeMode.NoResize;
134-
this.DFIsRunning = true;
138+
this.tokenSource.Cancel();
139+
this.DFIsRunning = false;
135140

136-
this.simThread = new Thread(this.ThreadLoop);
137-
this.simThread.Start();
138-
}
141+
} else {
142+
this.ResizeMode = ResizeMode.NoResize;
143+
144+
this.tokenSource = new CancellationTokenSource();
145+
this.simulationTask = Task.Run(() => {
146+
this.ThreadLoop(this.tokenSource.Token);
147+
});
139148

140-
private void PauseButton_OnClick(object sender, RoutedEventArgs e) {
141-
this.DFIsRunning = false;
142-
this.ResizeMode = ResizeMode.CanResizeWithGrip;
149+
this.DFIsRunning = true;
150+
}
143151
}
144152

145-
private void ThreadLoop() {
153+
private void ThreadLoop(CancellationToken token) {
146154
var sw = new Stopwatch();
147155
sw.Start();
148156

149-
while (this.DF != null && this.DFIsRunning) {
157+
while (true) {
158+
if (token.IsCancellationRequested)
159+
break;
160+
150161
var curTime = sw.ElapsedMilliseconds;
162+
151163
this.SimulationStep();
152164
this.UpdateImage();
153165

154-
var targetSleep = 1000 / this._targetFrameRate;
166+
// another check for good measure
167+
if (token.IsCancellationRequested)
168+
break;
155169

170+
var targetSleep = 1000 / this._targetFrameRate;
156171
var frameElapsed = (int)(sw.ElapsedMilliseconds - curTime);
157172
var sleepElapsed = (int)Math.Round(targetSleep - frameElapsed);
158173

@@ -168,12 +183,12 @@ private void ThreadLoop() {
168183
}
169184

170185
sw.Stop();
186+
Debug.WriteLine("Task completed");
171187
}
172188

173189
private void SimulationStep() {
174-
if (this.DFIsProcessing) {
190+
if (this.DFIsProcessing)
175191
return;
176-
}
177192

178193
this.DFIsProcessing = true;
179194

0 commit comments

Comments
 (0)