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.