Atari Logo
Programmieren

Hauptseite -
Welches System? -
Hardware -
Software -
Textverarbeitung -
Internet
MausNet
Programmieren
Verweise
Über

TOS - Algorithmen - Beispiele - weitere Informationen


Beispiel: Automaten

Die folgenden Beispiele zeigen das Prinzip eines Automaten anhand eines imaginären und sehr rudimentären Malprogramms.

Sprache C Pascal Modula
Beispiel automat.c automat.pas automat.mod

automat.c

typedef enum {SelectState,RectState,FreehandState} PaintState;

PaintState HandleToolBox(int MausX,int MausY,PaintState DefaultValue)
{
   if (MausX>0 && MausX<20)
      return(SelectState);
   else if (MausX>20 && MausX<40)
      return(RectState);
   else if (MausX>40 && MausX<60)
      return(FreehandState);
   else
      return(DefaultValue);
}

PaintState HandleSelectState(int Event,int MausX,int MausY,int MausButton,int Taste,int SonderTaste)
{  PaintState NewState;

   switch (Event)
   {
      case MU_KEYBD:
         if (MausY < 20)
            NewState = HandleToolBox(MausX, MausY, SelectState);
         else
         {
            /* mache etwas sinnvolles mit der Mausklick */
            NewState = SelectState;
         }
         break;
      case MU_BUTTON:
         /* mache etwas sinnvolles mit der Taste */
         NewState = SelectState;
         break;
   }
   return(NewState);
}

PaintState HandleRectState(int Event,int MausX,int MausY,int MausButton,int Taste,int SonderTaste)
{  PaintState NewState;

   switch (Event)
   {
      case MU_KEYBD:
         if (MausY < 20)
            NewState = HandleToolBox(MausX, MausY, RectState);
         else
         {
            /* mache etwas sinnvolles mit der Mausklick */
            NewState = RectState;
         }
         break;
      case MU_BUTTON:
         /* mache etwas sinnvolles mit der Taste */
         NewState = RectState;
         break;
   }
   return(NewState);
}

PaintState HandleFreehandState(int Event,int MausX,int MausY,int MausButton,int Taste,int SonderTaste)
{  PaintState NewState;

   switch (Event)
   {
      case MU_KEYBD:
         if (MausY < 20)
            NewState = HandleToolBox(MausX, MausY, FreehandState);
         else
         {
            /* mache etwas sinnvolles mit der Mausklick */
            NewState = FreehandState;
         }
         break;
      case MU_BUTTON:
         /* mache etwas sinnvolles mit der Taste */
         NewState = FreehandState;
         break;
   }
   return(NewState);
}

void Automat(int Event,int MausX,int MausY,int MausButton,int Taste,int SonderTaste)
{  static PaintState State;

   switch (State)
   {
      case SelectState:
         State = HandleSelectState(Event, MausX, MausY, MausButton, Taste, SonderTaste);
         break;
      case RectState:
         State = HandleRectState(Event, MausX, MausY, MausButton, Taste, SonderTaste);
         break;
      case FreehandState:
         State = HandleFreehandState(Event, MausX, MausY, MausButton, Taste, SonderTaste);
         break;
   }
}

void main(void)
{  int MausX,MausY,MausButton,SonderTaste,Taste,MausKlicks
       Event,MsgBuff[8];

   ...
   Event=evnt_multi(MU_KEYBD|MU_BUTTON|MU_M1|MU_M2|MU_MESAG|MU_TIMER,
                    1,0x01,0x01, 0,0,0,0,0, 0,0,0,0,0,
                    MsgBuff, 0,0,
                    &MausX,&MausY,&MausButton,
                    &SonderTaste,&Taste,&MausKlicks);
   if (Event&MU_KEYBD) /* gedrueckte Taste */
      Automat(MU_KEYBD, 0, 0, 0, Taste, 0);
   if (Event&MU_BUTTON)
      Automat(MU_BUTTON, MausX, MausY, MausButton, 0, SonderTaste);
   ...
}

automat.pas

{$i gem.pas}

type
   PaintState = (SelectState,RectState,FreehandState);
var
   State : PaintState;

function HandleToolBox(MausX,MausY:integer;DefaultValue:PaintState):PaintState;
begin
   if (MausX>0) and (MausX<20) then
      HandleToolBox := SelectState
   else if (MausX>20) and (MausX<40) then
      HandleToolBox := RectState
   else if (MausX>40) and (MausX<60) then
      HandleToolBox := FreehandState
   else
      HandleToolBox := DefaultValue;
end;

function HandleSelectState(Event,MausX,MausY,MausButton,Taste,SonderTaste:integer):PaintState;
var
   NewState:PaintState;
begin
   case Event of
      E_Keyboard:
      begin
         if (MausY < 20) then
            NewState := HandleToolBox(MausX, MausY, SelectState)
         else
         begin
            (* mache etwas sinnvolles mit der Mausklick *)
            NewState := SelectState;
         end;
      end;
      E_Button:
         (* mache etwas sinnvolles mit der Taste *)
         NewState := SelectState;
   end;
   HandleSelectstate := NewState;
end;

function HandleRectState(Event,MausX,MausY,MausButton,Taste,SonderTaste:integer):PaintState;
var
   NewState:PaintState;
begin
   case Event of
      E_Keyboard:
      begin
         if (MausY < 20) then
            NewState := HandleToolBox(MausX, MausY, SelectState)
         else
         begin
            (* mache etwas sinnvolles mit der Mausklick *)
            NewState := SelectState;
         end;
      end;
      E_Button:
         (* mache etwas sinnvolles mit der Taste *)
         NewState := SelectState;
   end;
   HandleRectState := NewState;
end;

function HandleFreehandState(Event,MausX,MausY,MausButton,Taste,SonderTaste:integer):PaintState;
var
   NewState:PaintState;
begin
   case Event of
      E_Keyboard:
      begin
         if (MausY < 20) then
            NewState := HandleToolBox(MausX, MausY, SelectState)
         else
         begin
            (* mache etwas sinnvolles mit der Mausklick *)
            NewState := SelectState;
         end;
      end;
      E_Button:
         (* mache etwas sinnvolles mit der Taste *)
         NewState := SelectState;
   end;
   HandleFreehandState := NewState;
end;

procedure Automat(Event,MausX,MausY,MausButton,Taste,SonderTaste:integer);
begin
   case State of
      SelectState:
         State := HandleSelectState(Event, MausX, MausY, MausButton, Taste, SonderTaste);
      RectState:
         State := HandleRectState(Event, MausX, MausY, MausButton, Taste, SonderTaste);
      FreehandState:
         State := HandleFreehandState(Event, MausX, MausY, MausButton, Taste, SonderTaste);
   end;
end;

var
   MausX,MausY,MausButton,SonderTaste,Taste,MausKlicks,Event : integer;
   MsgBuff : Message_Buffer;
begin
   ...
   Event:=Get_Event(E_Keyboard|E_Button|E_Mouse1|E_Mouse2|E_Message|E_Timer,
                    1,1,1,1, false,0,0,0,0, false,0,0,0,0, MsgBuff,
                    Taste,MausButton,MausKlicks,MausX,MausY,SonderTaste);
   if (Event & E_Keyboard <> 0) then (* gedrueckte Taste *)
      Automat(E_Keyboard, 0, 0, 0, Taste, 0);
   if (Event & E_Button <> 0) then
      Automat(E_Button, MausX, MausY, MausButton, 0, SonderTaste);
   ...
end.

automat.mod

FROM SYSTEM IMPORT SETREG,INLINE,LONG,ADR;
FROM GEMAESbase IMPORT KeyboardEvent, ButtonEvent, Mouse1Event,
                       Mouse2Event, MesageEvent, TimerEvent;
FROM AES IMPORT EventMultiple;

TYPE
   PaintState = (SelectState,RectState,FreehandState);
VAR
   State : PaintState;

PROCEDURE HandleToolBox(MausX,MausY:INTEGER;DefaultValue:PaintState):PaintState;
BEGIN
   IF (MausX>0) AND(MausX<20) THEN
      RETURN SelectState;
   ELSIF (MausX>20) AND (MausX<40) THEN
      RETURN RectState;
   ELSIF (MausX>40) AND (MausX<60) THEN
      RETURN FreehandState;
   ELSE
      RETURN DefaultValue;
   END;
END HandleToolBox;

PROCEDURE HandleSelectState(Event,MausX,MausY,MausButton,Taste,SonderTaste:INTEGER):PaintState;
VAR
   NewState:PaintState;
BEGIN
   CASE Event OF
      KeyboardEvent:
         IF (MausY < 20) THEN
            NewState := HandleToolBox(MausX, MausY, SelectState);
         ELSE
            (* mache etwas sinnvolles mit der Mausklick *)
            NewState := SelectState;
         END; |
      ButtonEvent:
         (* mache etwas sinnvolles mit der Taste *)
         NewState := SelectState; |
   END;
   RETURN NewState;
END HandleSelectState;

PROCEDURE HandleRectState(Event,MausX,MausY,MausButton,Taste,SonderTaste:INTEGER):PaintState;
VAR
   NewState:PaintState;
BEGIN
   CASE Event OF
      KeyboardEvent:
         IF (MausY < 20) THEN
            NewState := HandleToolBox(MausX, MausY, SelectState);
         ELSE
            (* mache etwas sinnvolles mit der Mausklick *)
            NewState := SelectState;
         END; |
      ButtonEvent:
         (* mache etwas sinnvolles mit der Taste *)
         NewState := SelectState; |
   END;
   RETURN NewState;
END HandleRectState;

PROCEDURE HandleFreehandState(Event,MausX,MausY,MausButton,Taste,SonderTaste:INTEGER):PaintState;
VAR
   NewState:PaintState;
BEGIN
   CASE Event OF
      KeyboardEvent:
         IF (MausY < 20) THEN
            NewState := HandleToolBox(MausX, MausY, SelectState);
         ELSE
            (* mache etwas sinnvolles mit der Mausklick *)
            NewState := SelectState;
         END; |
      ButtonEvent:
         (* mache etwas sinnvolles mit der Taste *)
         NewState := SelectState; |
   END;
   RETURN NewState;
END HandleFreehandState;

PROCEDURE Automat(Event,MausX,MausY,MausButton,Taste,SonderTaste:INTEGER);
BEGIN
   CASE State OF
      SelectState:
         State := HandleSelectState(Event, MausX, MausY, MausButton, Taste, SonderTaste); |
      RectState:
         State := HandleRectState(Event, MausX, MausY, MausButton, Taste, SonderTaste); |
      FreehandState:
         State := HandleFreehandState(Event, MausX, MausY, MausButton, Taste, SonderTaste); |
   END;
END Automat;

CONST
   AndLD0A0=0C190H; (* and.l D0,(A0) *)
   RegD0=0; (* Wert fuer SETREG *)
   RegA0=8; (* Wert fuer SETREG *)
VAR
   MausX,MausY,MausButton,SonderTaste,Taste,MausKlicks,Event : INTEGER;
   MsgBuff : ARRAY[1..8] OF INTEGER;
PROCEDURE And(x,y:LONGINT):LONGINT;
   BEGIN
      SETREG(RegD0,x);      (* x nach D0      *)
      SETREG(RegA0,ADR(y)); (* ADR(y) nach A0 *)
      INLINE(AndLD0A0);     (* and.l D0,(A0)  *)
      RETURN y;
   END And;
BEGIN
   ...
   Event:=EventMultiple(KeyboardEvent + ButtonEvent + Mouse1Event +
                        Mouse2Event + MesageEvent + TimerEvent,
                        1,1,1, 0,0,0,0,0, 0,0,0,0,0, ADR(MsgBuff),0,0,
                        MausX,MausY,MausButton,MausKlicks,Taste,SonderTaste);
   IF (And(LONG(Event), LONG(KeyboardEvent)) # 0D) THEN
      Automat(KeyboardEvent, 0, 0, 0, Taste, 0);
   END;
   IF (And(LONG(Event), LONG(ButtonEvent)) # 0D) THEN
      Automat(ButtonEvent, MausX, MausY, MausButton, 0, SonderTaste);
   END;
   ...
END automat.

Best viewed with any browser English version not yet available.

Änderungen und Irrtümer vorbehalten. Letzte Änderung:
22 Februar 2002.
Home - Mail an den Webmaster - Impressum