unit Threads;
interface uses System.Classes, System.SyncObjs;
type
/// <summary>
/// Abstrakte Oberklasse für Threads die Daten
/// bereitstellen und mit <c>OnNewData</c> signalisieren
/// dass neue Daten bereitliegen
/// </summary>
TDataThread =
class(TThread)
protected var
mutex: TSynchroObject;
protected
procedure triggerNewDataEvent();
public var
/// <remarks>
/// Wird immer <b>im Hauptthread</b> ausgeführt
/// </remarks>
OnNewData: TNotifyEvent;
public
constructor Create(
const CreateSuspended: Boolean);
destructor Destroy();
override;
end;
TTemperatureThread =
class(TDataThread)
protected const
noTemperature = -273.15;
protected var
FTemperature: Single;
protected
function retrieveTemperature(): Single;
procedure Execute();
override;
public
constructor Create(
const CreateSuspended: Boolean);
/// <returns>
/// Temperatur in °C
/// </returns>
/// <remarks>
/// Wenn noch keine Temperatur aufgezeichnet wurde wird
/// <c>-273.15</c> zurückgegeben
/// </remarks>
function getTemperature(): Single;
end;
TPressureThread =
class(TDataThread)
protected procedure Execute();
override;
/// <returns>
/// Druck in Pa
/// </returns>
public function getAirPressure(): Single;
end;
implementation
{ TDataThread }
constructor TDataThread.Create(
const CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
mutex := TCriticalSection.Create();
end;
destructor TDataThread.Destroy();
begin
mutex.Free();
inherited;
end;
procedure TDataThread.triggerNewDataEvent();
begin
if not Assigned(OnNewData)
then Exit;
TThread.Queue(
nil,
procedure()
begin
OnNewData(self);
end
);
end;
{ TTemperatureThread }
constructor TTemperatureThread.Create(
const CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FTemperature := noTemperature;
end;
procedure TTemperatureThread.Execute();
var
currentTemperature: Single;
begin
while (
not Terminated)
do begin
currentTemperature := retrieveTemperature();
if (currentTemperature = noTemperature)
then Continue;
mutex.Acquire();
try
FTemperature := currentTemperature;
finally
mutex.Release();
end;
triggerNewDataEvent();
end;
end;
function TTemperatureThread.getTemperature(): Single;
begin
mutex.Acquire();
try
Result := FTemperature;
finally
mutex.Release();
end;
end;
function TTemperatureThread.retrieveTemperature(): Single;
begin
Sleep( 1000 + Random(1000) );
Result := 42.0 + Random() * 10.0;
end;
{ TPressureThread }
procedure TPressureThread.Execute();
begin
while (
not Terminated)
do begin
// Platzhalter
end;
end;
function TPressureThread.getAirPressure(): Single;
begin
// Platzhalter
end;
end.