Universität Ulm,
Fakultät für Mathematik und Wirtschaftswissenschaften,
SAI
SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library
MODULE RemotePuzzlePlayers
(* Edit RemotePuzzl.rm instead of this file which has been generated
by genrem at Mon Jul 26 15:20:58 MET DST 1999
*)
MODULE RemotePuzzlePlayers;
IMPORT ChessClocks, Messages, Objects, PersistentObjects, Puzzle,
PuzzlePlayers, RelatedEvents, RemoteObjects, Services, Streams;
TYPE
Player = POINTER TO PlayerRec;
PlayerRec = RECORD (PuzzlePlayers.PlayerRec) END;
TYPE
Message = POINTER TO MessageRec;
MessageRec = RECORD (Messages.MessageRec) END;
TYPE
MakeMoveMessage = POINTER TO MakeMoveMessageRec;
MakeMoveMessageRec =
RECORD
(MessageRec)
situation: Puzzle.Situation; (* IN via COPY *)
clock: ChessClocks.ChessClock; (* IN via REF *)
game: Services.Object; (* IN via REF *)
move: Puzzle.Move; (* OUT via COPY *)
END;
VAR
makeMoveMessageType: Services.Type;
TYPE
AcceptMessage = POINTER TO AcceptMessageRec;
AcceptMessageRec =
RECORD
(MessageRec)
game: Services.Object; (* IN via REF *)
END;
VAR
acceptMessageType: Services.Type;
TYPE
GameOverMessage = POINTER TO GameOverMessageRec;
GameOverMessageRec =
RECORD
(MessageRec)
game: Services.Object; (* IN via REF *)
END;
VAR
gameOverMessageType: Services.Type;
VAR
if: PuzzlePlayers.Interface; (* of PuzzlePlayers *)
type: Services.Type; (* of RemotePuzzlePlayers.Player *)
PROCEDURE CreateMakeMoveMessage(VAR object: PersistentObjects.Object);
VAR msg: MakeMoveMessage;
BEGIN
NEW(msg);
PersistentObjects.Init(msg, makeMoveMessageType);
Messages.Init(msg);
object := msg;
END CreateMakeMoveMessage;
PROCEDURE WriteMakeMoveMessage(s: Streams.Stream;
msg: PersistentObjects.Object) : BOOLEAN;
BEGIN
WITH msg: MakeMoveMessage DO
IF msg.processed THEN
RETURN PersistentObjects.Write(s, msg.move)
ELSE
RETURN PersistentObjects.Write(s, msg.situation) &
RemoteObjects.Export(s, msg.clock) &
RemoteObjects.Export(s, msg.game)
END;
END;
END WriteMakeMoveMessage;
PROCEDURE ReadMakeMoveMessage(s: Streams.Stream;
msg: PersistentObjects.Object) : BOOLEAN;
BEGIN
WITH msg: MakeMoveMessage DO
IF msg.processed THEN
RETURN PersistentObjects.Read(s, msg.move)
ELSE
RETURN PersistentObjects.Read(s, msg.situation) &
RemoteObjects.Import(s, msg.clock) &
RemoteObjects.Import(s, msg.game)
END;
END;
END ReadMakeMoveMessage;
PROCEDURE CreateAcceptMessage(VAR object: PersistentObjects.Object);
VAR msg: AcceptMessage;
BEGIN
NEW(msg);
PersistentObjects.Init(msg, acceptMessageType);
Messages.Init(msg);
object := msg;
END CreateAcceptMessage;
PROCEDURE WriteAcceptMessage(s: Streams.Stream;
msg: PersistentObjects.Object) : BOOLEAN;
BEGIN
WITH msg: AcceptMessage DO
IF msg.processed THEN
RETURN TRUE
ELSE
RETURN RemoteObjects.Export(s, msg.game)
END;
END;
END WriteAcceptMessage;
PROCEDURE ReadAcceptMessage(s: Streams.Stream;
msg: PersistentObjects.Object) : BOOLEAN;
BEGIN
WITH msg: AcceptMessage DO
IF msg.processed THEN
RETURN TRUE
ELSE
RETURN RemoteObjects.Import(s, msg.game)
END;
END;
END ReadAcceptMessage;
PROCEDURE CreateGameOverMessage(VAR object: PersistentObjects.Object);
VAR msg: GameOverMessage;
BEGIN
NEW(msg);
PersistentObjects.Init(msg, gameOverMessageType);
Messages.Init(msg);
object := msg;
END CreateGameOverMessage;
PROCEDURE WriteGameOverMessage(s: Streams.Stream;
msg: PersistentObjects.Object) : BOOLEAN;
BEGIN
WITH msg: GameOverMessage DO
IF msg.processed THEN
RETURN TRUE
ELSE
RETURN RemoteObjects.Export(s, msg.game)
END;
END;
END WriteGameOverMessage;
PROCEDURE ReadGameOverMessage(s: Streams.Stream;
msg: PersistentObjects.Object) : BOOLEAN;
BEGIN
WITH msg: GameOverMessage DO
IF msg.processed THEN
RETURN TRUE
ELSE
RETURN RemoteObjects.Import(s, msg.game)
END;
END;
END ReadGameOverMessage;
PROCEDURE Handler(object: Messages.Object; VAR msg: Messages.Message);
VAR
oldQueue, newQueue: RelatedEvents.Queue;
BEGIN
IF ~(msg IS Message) THEN RETURN END;
WITH object: PuzzlePlayers.Player DO
RelatedEvents.QueueEvents(object);
RelatedEvents.GetQueue(object, oldQueue);
msg.processed := TRUE;
IF msg IS MakeMoveMessage THEN
WITH msg: MakeMoveMessage DO
msg.done := PuzzlePlayers.MakeMove(object, msg.situation, msg.clock, msg.game, msg.move);
END;
ELSIF msg IS AcceptMessage THEN
WITH msg: AcceptMessage DO
msg.done := PuzzlePlayers.Accept(object, msg.game);
END;
ELSIF msg IS GameOverMessage THEN
WITH msg: GameOverMessage DO
PuzzlePlayers.GameOver(object, msg.game);
msg.done := TRUE;
END;
END;
RelatedEvents.GetQueue(object, newQueue);
RelatedEvents.AppendQueue(msg.errors, newQueue);
RelatedEvents.AppendQueue(object, oldQueue);
END;
END Handler;
PROCEDURE MakeMove(player: PuzzlePlayers.Player;
situation: Puzzle.Situation;
clock: ChessClocks.ChessClock;
game: Services.Object;
VAR move: Puzzle.Move) : BOOLEAN;
VAR msg: MakeMoveMessage; queue: RelatedEvents.Queue;
BEGIN
CreateMakeMoveMessage(msg);
msg.situation := situation;
msg.clock := clock;
msg.game := game;
Messages.Send(player, msg);
move := msg.move;
RelatedEvents.GetQueue(msg.errors, queue);
RelatedEvents.AppendQueue(player, queue);
RETURN msg.done
END MakeMove;
PROCEDURE Accept(player: PuzzlePlayers.Player;
game: Services.Object) : BOOLEAN;
VAR msg: AcceptMessage; queue: RelatedEvents.Queue;
BEGIN
CreateAcceptMessage(msg);
msg.game := game;
Messages.Send(player, msg);
RelatedEvents.GetQueue(msg.errors, queue);
RelatedEvents.AppendQueue(player, queue);
RETURN msg.done
END Accept;
PROCEDURE GameOver(player: PuzzlePlayers.Player;
game: Services.Object);
VAR msg: GameOverMessage; queue: RelatedEvents.Queue;
BEGIN
CreateGameOverMessage(msg);
msg.game := game;
Messages.Send(player, msg);
RelatedEvents.GetQueue(msg.errors, queue);
RelatedEvents.AppendQueue(player, queue);
END GameOver;
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.makeMove := MakeMove;
if.accept := Accept;
if.gameOver := GameOver;
PersistentObjects.RegisterType(msgtype,
"RemotePuzzlePlayers.Message", "Messages.Message", NIL);
InitPO(makeMoveMessageType, "RemotePuzzlePlayers.MakeMoveMessage", "RemotePuzzlePlayers.Message",
CreateMakeMoveMessage, ReadMakeMoveMessage, WriteMakeMoveMessage);
InitPO(acceptMessageType, "RemotePuzzlePlayers.AcceptMessage", "RemotePuzzlePlayers.Message",
CreateAcceptMessage, ReadAcceptMessage, WriteAcceptMessage);
InitPO(gameOverMessageType, "RemotePuzzlePlayers.GameOverMessage", "RemotePuzzlePlayers.Message",
CreateGameOverMessage, ReadGameOverMessage, WriteGameOverMessage);
Services.CreateType(type,
"RemotePuzzlePlayers.Player", "PuzzlePlayers.Player");
Services.SeekType("PuzzlePlayers.Player", 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 p: Player;
BEGIN
NEW(p);
Services.Init(p, type);
PuzzlePlayers.Init(p, if);
RelatedEvents.QueueEvents(p);
object := p;
END CreateProxy;
BEGIN
InitIFs;
END RemotePuzzlePlayers.
SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library
Andreas Borchert, 26. Juli 1999