PROGRAM ServerSim2; USES cs65; TYPE AniBar = OBJECT yLow, yHigh, xHigh, CurrX : INTEGER; DrawColor, EraseColor : INTEGER; PROCEDURE Initialize(X, Y, Height, DColor, EColor : INTEGER); PROCEDURE Update(Size : INTEGER); END; PROCEDURE AniBar.Initialize(AnchorX, AnchorY, Height, DColor, EColor : INTEGER); BEGIN yLow := AnchorY; yHigh := AnchorY + Height; xHigh := AnchorX; DrawColor := DColor; EraseColor := EColor; CurrX := AnchorX; END; PROCEDURE AniBar.Update(Size : INTEGER); VAR X : INTEGER; BEGIN X := XHigh + Size; IF X < CurrX THEN {Bar must contract to left} BEGIN SetColor(EraseColor); Bar(X, yLow, CurrX, yHigh); END ELSE BEGIN {Bar must expand to right} SetColor(DrawColor); Bar(CurrX, yLow, X, yHigh); END; CurrX := X; END; FUNCTION Message : LONGINT; VAR Event : REAL; BEGIN Message := 0; Event := Random; IF Event < 0.05 THEN Message := 50 * (RandomInt(39) + 1); END; PROCEDURE Server(VAR PSize, MSize : LONGINT); BEGIN IF PSize = 1000 THEN PSize := 0; PSize := PSize + 50; MSize := MSize - 50; END; FUNCTION DigitToChar(D : INTEGER) : Char; {Converts a digit to a character (e.g. 3 becomes '3'). Numbers other than a single digit become an 'X' } BEGIN IF (D > 9) OR (D < 0) THEN DigitToChar := 'X' ELSE DigitToChar := CHR(D+48); END; PROCEDURE IntToStr( X, Width:INTEGER; VAR Result:STRING); {Converts an Integer into a String suitable for outTextXY. If X has fewer than Width digits, it is padded on the left with blanks. If X has more than Width digits, Result will be whatever length is required to store the digits} VAR Length,Digit, i, Index : INTEGER; tempStr : STRING; BEGIN {IntToStr} {First decode digits into tempStr} Length := 0; IF X = 0 THEN BEGIN Length := 1; tempStr := "0"; END ELSE WHILE X > 0 DO BEGIN Length := Length + 1; Digit := X MOD 10; TempStr[Length] := DigitToChar(Digit); X := X DIV 10; END; {Pad to appropriate width} WHILE Length < Width DO BEGIN Length := Length + 1; TempStr[Length] := ' '; END; {Copy into Reslt in reverse order} Index := 1; FOR i := Length DOWNTO 1 DO BEGIN Result[Index] := tempStr[i]; Index := Index + 1; END; {Set length of Result} Result[0] := CHR(Length); END; {IntToStr} CONST Inc = 2.5; Scale = 10; MaxTicks = 1000; VAR MessFile, MessMax, LastMess, Tick, Packet : LONGINT; VAR MessBar, MessFileBar, PacketBar, TickBar : AniBar; VAR TickDisplay : INTEGER; VAR Num : STRING; BEGIN {main program} SetGraph; ClrScr; {Screen title and key display module} OUTTEXTXY(220, 40, 'Internet Server Simulation'); OUTTEXTXY(465, 65, 'Display Color Key'); Line(420, 70, 626, 70); Line(626, 70, 626, 148); Line(626, 148, 420, 148); Line(420, 148, 420, 70); SetColor(4); Bar(430, 80, 454, 104); SetColor(0); OUTTEXTXY(464, 96, 'Current Size'); Bar(430, 114, 454, 138); OUTTEXTXY(464, 130, 'Maximum Size Attained'); {Incoming message display module} New(MessBar); MessBar.Initialize(10, 70, 50, 4, 0); OUTTEXTXY(10, 65, 'Incoming Messages (in hundreds of characters)'); FOR TickDisplay := 0 TO 10 DO BEGIN IntToStr(TickDisplay*2, 2, Num); OUTTEXTXY((TRUNC(TickDisplay*200/Scale))+2, 143, Num); OUTTEXTXY((TRUNC(TickDisplay*200/Scale))+9, 130, '|'); END; {Message queue display module} New(MessFileBar); MessFileBar.Initialize(10, 310, 50, 4, 0); OUTTEXTXY(10, 305, 'Message Queue (in thousands of characters)'); FOR TickDisplay := 0 TO 15 DO BEGIN IntToStr(TickDisplay, 2, Num); OUTTEXTXY((TRUNC(TickDisplay*1000/(Scale*Inc)))+2, 383, Num); OUTTEXTXY((TRUNC(TickDisplay*1000/(Scale*Inc)))+9, 370, '|'); END; {Packet processing display module} New(PacketBar); PacketBar.Initialize(10, 190, 50, 4, 15); OUTTEXTXY(10, 185, 'Current Packet (in hundreds of characters)'); FOR TickDisplay := 0 TO 5 DO BEGIN IntToStr(TickDisplay*2, 2, Num); OUTTEXTXY((TRUNC(TickDisplay*200/Scale))+2, 263, Num); OUTTEXTXY((TRUNC(TickDisplay*200/Scale))+9, 250, '|'); END; {Run time tickbar display module} New(TickBar); TickBar.Initialize(0, 425, 25, 2, 1); OUTTEXTXY(10, 420, 'Simulation Run Time'); OUTTEXTXY(1, 465, 'Start'); OUTTEXTXY(600, 465, 'Finish'); RANDOMIZE; Packet := 0; MessFile := 0; MessMax := 0; FOR Tick := 1 TO MaxTicks DO BEGIN IF ButtonPressed THEN HALT; {Abort Button} LastMess := Message; MessFile := MessFile + LastMess; IF MessFile > 0 THEN Server(Packet, MessFile); TickBar.Update(TRUNC(Tick*640/MaxTicks)); MessFileBar.Update(TRUNC(MessFile/(Scale*Inc))); PacketBar.Update(TRUNC(Packet/Scale)); MessBar.Update(TRUNC(LastMess/Scale)); Delay(500); END; Pause; END.