Universität Ulm, Fakultät für Mathematik und Wirtschaftswissenschaften, SAI

SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library

MODULE RemotePGs


(* Edit RemotePGs.rm instead of this file which has been generated
   by genrem.test at Fri Jul 16 18:36:38 MET DST 1999
*)

MODULE RemotePGs;

   IMPORT ChessClocks, ConstStrings, Events, Iterators, Messages, NetIO,
      Objects, PersistentObjects, Puzzle, PuzzleGames, PuzzlePlayers,
      RelatedEvents, RemoteChessClocks, RemoteEvents, RemoteIterators,
      RemoteObjects, RemotePuzzlePlayers, Services, Streams;

   TYPE
      Game = POINTER TO GameRec;
      GameRec = RECORD (PuzzleGames.GameRec) END;

   TYPE
      Message = POINTER TO MessageRec;
      MessageRec = RECORD (Messages.MessageRec) END;

   TYPE
      GetNamesMessage = POINTER TO GetNamesMessageRec;
      GetNamesMessageRec =
         RECORD
            (MessageRec)
            name1: ConstStrings.String; (* OUT via ConstString *)
            name2: ConstStrings.String; (* OUT via ConstString *)
         END;
   VAR
      getNamesMessageType: Services.Type;

   TYPE
      GetCurrentSituationMessage = POINTER TO GetCurrentSituationMessageRec;
      GetCurrentSituationMessageRec =
         RECORD
            (MessageRec)
            situation: Puzzle.Situation; (* OUT via COPY *)
         END;
   VAR
      getCurrentSituationMessageType: Services.Type;

   TYPE
      GetChessClockMessage = POINTER TO GetChessClockMessageRec;
      GetChessClockMessageRec =
         RECORD
            (MessageRec)
            chessclock: ChessClocks.ChessClock; (* OUT via REF *)
         END;
   VAR
      getChessClockMessageType: Services.Type;

   TYPE
      TakeInterestMessage = POINTER TO TakeInterestMessageRec;
      TakeInterestMessageRec =
         RECORD
            (MessageRec)
            eventType: Events.EventType; (* OUT via REF *)
         END;
   VAR
      takeInterestMessageType: Services.Type;

   TYPE
      IterateMovesMessage = POINTER TO IterateMovesMessageRec;
      IterateMovesMessageRec =
         RECORD
            (MessageRec)
            it: Iterators.Iterator; (* OUT via REF *)
         END;
   VAR
      iterateMovesMessageType: Services.Type;

   VAR
      if: PuzzleGames.Interface; (* of PuzzleGames *)
      type: Services.Type; (* of RemotePuzzleGames.Game *)

   PROCEDURE CreateGetNamesMessage(VAR object: PersistentObjects.Object);
      VAR msg: GetNamesMessage;
   BEGIN
      NEW(msg);
      PersistentObjects.Init(msg, getNamesMessageType);
      Messages.Init(msg);
      object := msg;
   END CreateGetNamesMessage;

   PROCEDURE WriteGetNamesMessage(s: Streams.Stream;
                                  msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: GetNamesMessage DO
         IF msg.processed THEN
            RETURN NetIO.WriteConstString(s, msg.name1) &
                   NetIO.WriteConstString(s, msg.name2)
         ELSE
            RETURN TRUE
         END;
      END;
   END WriteGetNamesMessage;

   PROCEDURE ReadGetNamesMessage(s: Streams.Stream;
                                 msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: GetNamesMessage DO
         IF msg.processed THEN
            RETURN NetIO.ReadConstString(s, msg.name1) &
                   NetIO.ReadConstString(s, msg.name2)
         ELSE
            RETURN TRUE
         END;
      END;
   END ReadGetNamesMessage;

   PROCEDURE CreateGetCurrentSituationMessage(VAR object: PersistentObjects.Object);
      VAR msg: GetCurrentSituationMessage;
   BEGIN
      NEW(msg);
      PersistentObjects.Init(msg, getCurrentSituationMessageType);
      Messages.Init(msg);
      object := msg;
   END CreateGetCurrentSituationMessage;

   PROCEDURE WriteGetCurrentSituationMessage(s: Streams.Stream;
                                             msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: GetCurrentSituationMessage DO
         IF msg.processed THEN
            RETURN PersistentObjects.Write(s, msg.situation)
         ELSE
            RETURN TRUE
         END;
      END;
   END WriteGetCurrentSituationMessage;

   PROCEDURE ReadGetCurrentSituationMessage(s: Streams.Stream;
                                            msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: GetCurrentSituationMessage DO
         IF msg.processed THEN
            RETURN PersistentObjects.Read(s, msg.situation)
         ELSE
            RETURN TRUE
         END;
      END;
   END ReadGetCurrentSituationMessage;

   PROCEDURE CreateGetChessClockMessage(VAR object: PersistentObjects.Object);
      VAR msg: GetChessClockMessage;
   BEGIN
      NEW(msg);
      PersistentObjects.Init(msg, getChessClockMessageType);
      Messages.Init(msg);
      object := msg;
   END CreateGetChessClockMessage;

   PROCEDURE WriteGetChessClockMessage(s: Streams.Stream;
                                       msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: GetChessClockMessage DO
         IF msg.processed THEN
            RETURN RemoteObjects.Export(s, msg.chessclock)
         ELSE
            RETURN TRUE
         END;
      END;
   END WriteGetChessClockMessage;

   PROCEDURE ReadGetChessClockMessage(s: Streams.Stream;
                                      msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: GetChessClockMessage DO
         IF msg.processed THEN
            RETURN RemoteObjects.Import(s, msg.chessclock)
         ELSE
            RETURN TRUE
         END;
      END;
   END ReadGetChessClockMessage;

   PROCEDURE CreateTakeInterestMessage(VAR object: PersistentObjects.Object);
      VAR msg: TakeInterestMessage;
   BEGIN
      NEW(msg);
      PersistentObjects.Init(msg, takeInterestMessageType);
      Messages.Init(msg);
      object := msg;
   END CreateTakeInterestMessage;

   PROCEDURE WriteTakeInterestMessage(s: Streams.Stream;
                                      msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: TakeInterestMessage DO
         IF msg.processed THEN
            RETURN RemoteObjects.Export(s, msg.eventType)
         ELSE
            RETURN TRUE
         END;
      END;
   END WriteTakeInterestMessage;

   PROCEDURE ReadTakeInterestMessage(s: Streams.Stream;
                                     msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: TakeInterestMessage DO
         IF msg.processed THEN
            RETURN RemoteObjects.Import(s, msg.eventType)
         ELSE
            RETURN TRUE
         END;
      END;
   END ReadTakeInterestMessage;

   PROCEDURE CreateIterateMovesMessage(VAR object: PersistentObjects.Object);
      VAR msg: IterateMovesMessage;
   BEGIN
      NEW(msg);
      PersistentObjects.Init(msg, iterateMovesMessageType);
      Messages.Init(msg);
      object := msg;
   END CreateIterateMovesMessage;

   PROCEDURE WriteIterateMovesMessage(s: Streams.Stream;
                                      msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: IterateMovesMessage DO
         IF msg.processed THEN
            RETURN RemoteObjects.Export(s, msg.it)
         ELSE
            RETURN TRUE
         END;
      END;
   END WriteIterateMovesMessage;

   PROCEDURE ReadIterateMovesMessage(s: Streams.Stream;
                                     msg: PersistentObjects.Object) : BOOLEAN;
   BEGIN
      WITH msg: IterateMovesMessage DO
         IF msg.processed THEN
            RETURN RemoteObjects.Import(s, msg.it)
         ELSE
            RETURN TRUE
         END;
      END;
   END ReadIterateMovesMessage;

   PROCEDURE Handler(object: Messages.Object; VAR msg: Messages.Message);
      VAR
         oldQueue, newQueue: RelatedEvents.Queue;
         name1Buf: ARRAY 1024 OF CHAR;
         name2Buf: ARRAY 1024 OF CHAR;
   BEGIN
      IF ~(msg IS Message) THEN RETURN END;
      WITH object: PuzzleGames.Game DO
         RelatedEvents.QueueEvents(object);
         RelatedEvents.GetQueue(object, oldQueue);
         msg.processed := TRUE;
         IF msg IS GetNamesMessage THEN
            WITH msg: GetNamesMessage DO
               PuzzleGames.GetNames(object, name1Buf, name2Buf);
               ConstStrings.Create(msg.name1, name1Buf);
               ConstStrings.Create(msg.name2, name2Buf);
               msg.done := TRUE;
            END;
         ELSIF msg IS GetCurrentSituationMessage THEN
            WITH msg: GetCurrentSituationMessage DO
               PuzzleGames.GetCurrentSituation(object, msg.situation);
               msg.done := TRUE;
            END;
         ELSIF msg IS GetChessClockMessage THEN
            WITH msg: GetChessClockMessage DO
               PuzzleGames.GetChessClock(object, msg.chessclock);
               msg.done := TRUE;
            END;
         ELSIF msg IS TakeInterestMessage THEN
            WITH msg: TakeInterestMessage DO
               PuzzleGames.TakeInterest(object, msg.eventType);
               msg.done := TRUE;
            END;
         ELSIF msg IS IterateMovesMessage THEN
            WITH msg: IterateMovesMessage DO
               PuzzleGames.IterateMoves(object, msg.it);
               msg.done := TRUE;
            END;
         END;
         RelatedEvents.GetQueue(object, newQueue);
         RelatedEvents.AppendQueue(msg.errors, newQueue);
         RelatedEvents.AppendQueue(object, oldQueue);
      END;
   END Handler;

   PROCEDURE GetNames(game: PuzzleGames.Game;
                      VAR name1: ARRAY OF CHAR;
                      VAR name2: ARRAY OF CHAR);
      VAR msg: GetNamesMessage; queue: RelatedEvents.Queue;
   BEGIN
      CreateGetNamesMessage(msg);
      Messages.Send(game, msg);
      ConstStrings.Extract(name1, msg.name1);
      ConstStrings.Extract(name2, msg.name2);
      RelatedEvents.GetQueue(msg.errors, queue);
      RelatedEvents.AppendQueue(game, queue);
   END GetNames;

   PROCEDURE GetCurrentSituation(game: PuzzleGames.Game;
                                 VAR situation: Puzzle.Situation);
      VAR msg: GetCurrentSituationMessage; queue: RelatedEvents.Queue;
   BEGIN
      CreateGetCurrentSituationMessage(msg);
      Messages.Send(game, msg);
      situation := msg.situation;
      RelatedEvents.GetQueue(msg.errors, queue);
      RelatedEvents.AppendQueue(game, queue);
   END GetCurrentSituation;

   PROCEDURE GetChessClock(game: PuzzleGames.Game;
                           VAR chessclock: ChessClocks.ChessClock);
      VAR msg: GetChessClockMessage; queue: RelatedEvents.Queue;
   BEGIN
      CreateGetChessClockMessage(msg);
      Messages.Send(game, msg);
      chessclock := msg.chessclock;
      RelatedEvents.GetQueue(msg.errors, queue);
      RelatedEvents.AppendQueue(game, queue);
   END GetChessClock;

   PROCEDURE TakeInterest(game: PuzzleGames.Game;
                          VAR eventType: Events.EventType);
      VAR msg: TakeInterestMessage; queue: RelatedEvents.Queue;
   BEGIN
      CreateTakeInterestMessage(msg);
      Messages.Send(game, msg);
      eventType := msg.eventType;
      RelatedEvents.GetQueue(msg.errors, queue);
      RelatedEvents.AppendQueue(game, queue);
   END TakeInterest;

   PROCEDURE IterateMoves(game: PuzzleGames.Game;
                          VAR it: Iterators.Iterator);
      VAR msg: IterateMovesMessage; queue: RelatedEvents.Queue;
   BEGIN
      CreateIterateMovesMessage(msg);
      Messages.Send(game, msg);
      it := msg.it;
      RelatedEvents.GetQueue(msg.errors, queue);
      RelatedEvents.AppendQueue(game, queue);
   END IterateMoves;

   PROCEDURE InitPO(VAR type: Services.Type;
                    name, baseName: ARRAY OF CHAR;
                    create: PersistentObjects.CreateProc;
                    read: PersistentObjects.ReadProc;
                    write: PersistentObjects.WriteProc);
      VAR if: PersistentObjects.Interface;
   BEGIN
      NEW(if);
      if.create := create; if.read := read; if.write := write;
      if.createAndRead := NIL;
      PersistentObjects.RegisterType(type, name, baseName, if);
   END InitPO;

   PROCEDURE ^ CreateProxy(VAR object: Services.Object;
                           params: PersistentObjects.Object);

   PROCEDURE InitIFs;
      VAR
         msgtype: Services.Type;
         remoteObjIf: RemoteObjects.Interface;
         baseType: Services.Type;
   BEGIN
      NEW(if);
      if.getNames := GetNames;
      if.getCurrentSituation := GetCurrentSituation;
      if.getChessClock := GetChessClock;
      if.takeInterest := TakeInterest;
      if.iterateMoves := IterateMoves;
      PersistentObjects.RegisterType(msgtype,
         "RemotePuzzleGames.Message", "Messages.Message", NIL);
      InitPO(getNamesMessageType, "RemotePuzzleGames.GetNamesMessage", "RemotePuzzleGames.Message",
             CreateGetNamesMessage, ReadGetNamesMessage, WriteGetNamesMessage);
      InitPO(getCurrentSituationMessageType, "RemotePuzzleGames.GetCurrentSituationMessage", "RemotePuzzleGames.Message",
             CreateGetCurrentSituationMessage, ReadGetCurrentSituationMessage, WriteGetCurrentSituationMessage);
      InitPO(getChessClockMessageType, "RemotePuzzleGames.GetChessClockMessage", "RemotePuzzleGames.Message",
             CreateGetChessClockMessage, ReadGetChessClockMessage, WriteGetChessClockMessage);
      InitPO(takeInterestMessageType, "RemotePuzzleGames.TakeInterestMessage", "RemotePuzzleGames.Message",
             CreateTakeInterestMessage, ReadTakeInterestMessage, WriteTakeInterestMessage);
      InitPO(iterateMovesMessageType, "RemotePuzzleGames.IterateMovesMessage", "RemotePuzzleGames.Message",
             CreateIterateMovesMessage, ReadIterateMovesMessage, WriteIterateMovesMessage);
      Services.CreateType(type,
         "RemotePuzzleGames.Game", "PuzzleGames.Game");

      Services.SeekType("PuzzleGames.Game", baseType);
      ASSERT(baseType # NIL);
      NEW(remoteObjIf);
      remoteObjIf.getParams := NIL;
      remoteObjIf.createProxy := CreateProxy;
      remoteObjIf.msgHandler := Handler;
      RemoteObjects.Register(baseType, remoteObjIf, RemoteObjects.parallel);
   END InitIFs;


   PROCEDURE CreateProxy(VAR object: Services.Object;
			 params: PersistentObjects.Object);
      VAR game: Game;
   BEGIN
      NEW(game);
      Services.Init(game, type);
      PuzzleGames.Init(game, if);
      RelatedEvents.QueueEvents(game);
      object := game;
   END CreateProxy;

BEGIN
   InitIFs;
END RemotePGs.

SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library

Andreas Borchert, 26. Juli 1999