Der Fehler in der Umsetzung ist der, dass bei der Anweisung "Schließe die Tür" der komplette Vorgang abgearbeitet wird.
In der Praxis wäre es so, dass beim Drücken des Schließen-Knopfes alle Knöpfe ihre Funktion verlieren (blockiert sind), bis die Tür geschlossen ist.
Im Anhang habe ich mal ein kleines Projekt für eine Fahrstuhltür, die man auch im laufenden Betrieb wieder öffnen kann.
Basisklasse
Delphi-Quellcode:
EElevator =
class(
Exception );
TElevatorDoorState = ( edsClosed, edsClosing, edsOpening, edsOpen );
TElevatorDoor =
class( TProgressEntity )
protected
function GetPosition : Integer;
virtual;
abstract;
function GetState : TElevatorDoorState;
virtual;
abstract;
public
// Nur zur Visualisierung (0-100)
property Position : Integer
read GetPosition;
// Status
property State : TElevatorDoorState
read GetState;
// Befehle
procedure Open;
virtual;
abstract;
procedure Close;
virtual;
abstract;
end;
und konkret
Delphi-Quellcode:
TDumbElevatorDoor = class( TElevatorDoor )
private
// Öffnen-/Schließ-Geschwindigkeit in m/s
FDirection : Extended;
// Position der Tür in m (0m - 1m)
FPosition : Extended;
protected
function GetState : TElevatorDoorState; override;
function GetPosition : Integer; override;
procedure Progress( const IntervalMS : Cardinal ); override;
public
procedure Open; override;
procedure Close; override;
end;
implementation
uses
System.Math;
const
cEpsilon = 0.001;
{ TDumbElevatorDoor }
procedure TDumbElevatorDoor.Close;
begin
FDirection := - 0.3; // 0.3m/s Schließgeschwindigkeit
end;
function TDumbElevatorDoor.GetPosition : Integer;
begin
Result := 100 - Round( FPosition * 100 );
end;
function TDumbElevatorDoor.GetState : TElevatorDoorState;
begin
if FDirection > 0
then
Result := edsOpening
else if FDirection < 0
then
Result := edsClosing
else if SameValue( FPosition, 0, cEpsilon )
then
Result := edsClosed
else if SameValue( FPosition, 1, cEpsilon )
then
Result := edsOpen
else
raise EElevator.Create( 'Fahrstuhltür defekt' );
end;
procedure TDumbElevatorDoor.Open;
begin
FDirection := 0.5; // 0.5m/s Öffnen-Geschwindigkeit
end;
procedure TDumbElevatorDoor.Progress( const IntervalMS : Cardinal );
var
LNewPosition : Extended;
begin
LNewPosition := FPosition + FDirection / 1000 * IntervalMS;
if LNewPosition >= 1
then
begin
FPosition := 1;
FDirection := 0;
end
else if LNewPosition <= 0
then
begin
FPosition := 0;
FDirection := 0;
end
else
FPosition := LNewPosition;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ea 0a 4c 14 0d b6 3a a4 c1 c5 b9
dc 90 9d f0 e9 de 13 da 60)