Instytut Systemów Informatycznych
Symulacja
z
MODSIM II
Materiały szkoleniowe cz. II
Cechy obiektowe języka MODSIM II
Definicja i własności obiektu
• Obiekt w języku MODSIM jest dynamicznie powoływaną i
usuwaną strukturą danych ściśle powiązaną z pewnymi
procedurami, zwanymi tu metodami.
• Własności:
– hermetyzacja (ang. encapsulation)
– dziedziczenie
– przesyłanie komunikatów
– polimorfizm
– hierarchizacja typów
• Składnia deklaracji
typu obiektowego
(zapowiedź pól
i metod)
Definicja i własności obiektu
• Składnia definicji typu obiektowego (implementacja metod
obiektu)
Definicja i własności obiektu
Podstawowe rodzaje metod
• ASK - działanie natychmiastowe, podobne do działania
procedury lub funkcji- nie wytraca czasu symulacji;
• TELL - związana jest z upływem czasu symulacji;
Przykład deklaracji typu
TYPE
complexNbrObj = OBJECT
realPart
: REAL;
imaginaryPart : REAL;
ASK METHOD setValue(IN r, i : REAL);
ASK METHOD addComplex(IN a, b : complexNbrObj);
END OBJECT;
VAR
x, y, z : complexNbrObj;
Przykład bloku definicji obiektu
OBJECT complexNbrObj;
ASK METHOD setValue(IN r, i : REAL);
BEGIN
realPart := r;
imaginaryPart := i;
END METHOD;
ASK METHOD addComplex(IN a, b : complexNbrObj);
BEGIN
{kod dodawania}
END METHOD;
END OBJECT;
Powoływanie instancji obiektu: ObjInit
Niektóre typy obiektów wymagają inicjalizacji, np.
TYPE
movingObj = OBJECT
x, y
: REAL;
ASK METHOD ObjInit;
ASK METHOD Stop;
END OBJECT;
Jeśli obiekt posiada zdefiniowaną metodę ObjInit, wtedy jest ona
automatycznie wywoływana przez procedurę NEW.
ObjInit Method
OBJECT movingObj;
ASK METHOD ObjInit;
BEGIN
… Kod źródłowy inicjalizujący obiekt
END METHOD {ObjInit};
ASK METHOD stop;
BEGIN
… Kod źródłowy inny
END METHOD {stop};
END OBJECT {movingObj};
Usuwanie instancji obiektu: ObjTerminate
ObjTerminate jest wykorzystywana do wykonania czynności przed
usunięciem samego obiektu.
TYPE
movingObj = OBJECT
x, y : REAL;
ASK METHOD ObjInit;
ASK METHOD ObjTerminate
;
ASK METHOD Stop;
END OBJECT;
Metoda jest wywoływana automatycznie przez procedurę
DISPOSE, zanim obiekt zostanie usunięty.
ObjTerminate Method
OBJECT movingObj;
ASK METHOD ObjTerminate;
BEGIN
… Kod źródłowy realizujący ostatnie operacje obiektu
END METHOD {ObjTerminate};
…
END OBJECT {movingObj};
Klonowanie obiektów: ObjClone
Do tworzenia kopii instancji obiektu służy funkcja
CLONE
.
W wyniku jej wywołania następuje:
– Alokacja pamięci dla nowej instancji obiektu
– Przepisanie wartości pól obiektu klonowanego do nowego
obiektu
– Wywołanie metody ObjInit dla nowej instancji
– Wywołanie metody ObjClone dla nowej instancji
ObjClone – deklaracja i definicja
TYPE
movingObj = OBJECT
x, y : REAL;
ASK METHOD ObjInit;
ASK METHOD ObjTerminate;
ASK METHOD ObjClone;
ASK METHOD stop;
END OBJECT {movingObj};
OBJECT movingObj;
ASK METHOD ObjClone
;
BEGIN
… Kod do realizacji po
klonowaniu.
END METHOD {ObjClone};
…
END OBJECT {movingObj};
Przykład klonowania obiektu
VAR movingObject1, movingObject2 : movingObj;
BEGIN
NEW(movingObject1);
...
movingObject2:=CLONE(movingObject1);
END MODULE;
Kiedy zachowana jest zgodność typów obiektów?
• Typ1 i Typ2 są tym samym typem obiektowym;
• Typy są zdefiniowane w sekcji:
• TYPE type1 = type2;
• Typ pochodny w hierarchii dziedziczenia jest zgodny dla typów
będących jego przodkami;
• Typ ANYOBJ jest typem zgodnym ze wszystkimi typami
obiektowymi i na odwrót;
Typ obiektowy: ANYOBJ
PROCEDURE switchObjects( INOUT firstObj
: ANYOBJ;
INOUT secondObj
: ANYOBJ);
VAR temp : ANYOBJ;
BEGIN
temp := firstObj;
firstObj := secondObj;
secondObj := temp;
END PROCEDURE;
Typ obiektowy: ANYOBJ
TYPE
linkedListObj = OBJECT
first, last : ANYOBJ;
numberIn : INTEGER;
ASK METHOD addObject (IN newObject : ANYOBJ);
END OBJECT;
VAR
linkedList : linkedListObj;
yourObject : userDefinedObj;
BEGIN
NEW (linkedList);
NEW (yourObject);
ASK linkedList TO addObject (yourObject);
Stała referencyjna: SELF
Jest ona wykorzystywana:
• przy odwoływaniu się obiektu do własnych pól i metod
ASK SELF TO Move(IN x : REAL;IN y : REAL);
• przy identyfikacji obiektu przez inny obiekt:
ASK METHOD airTrafficController;
BEGIN
distance := ASK movingObject TO reportDistance(SELF);
END METHOD;
Stała referencyjna: SELF
• przy odwoływaniu się obiektu do własnych pól i metod
dopuszczalne są następujące wywołania:
ASK SELF TO requestTakeoff (plane);
lub
requestTakeoff (plane);
location := ASK SELF position ();
lub
location := position ();
Dziedziczenie
poweredObj
vehicleObj
shipObj
aircraftObj
helicopterObj
Proste obiekty
Obiekty złożone
TYPE
aircraftObj = OBJECT (vehicleObj)
altitude : INTEGER;
ASK METHOD refuel;
END OBJECT;
Dziedziczenie
TYPE
missileObj = OBJECT (aircraftObj,
weaponObj)
… definicja pól i metod
END OBJECT {missileObj};
poweredObj
vehicleObj
helicopterObj
missileObj
weaponObj
aircraftObj
shipObj
Dziedziczenie
• aircraftObj dziedziczy wszystkie pola i metody obiekltu vehicleObj;
• aircraftObj może definiować własne pola i metody;
• aircraftObj może przykrywać metody, zmieniając ich funkcjonalność – Uwaga na
ObjInit (ObjTermionate, ObjClone);
• Przykład
aircraftObj = OBJECT (vehicleObj)
altitude : INTEGER;
OVERRIDE
ASK METHOD stop;
END OBJECT;
ASK METHOD stop;
BEGIN
… dodatkowa funkcjonalność
INHERITED stop;
… jeszcze inna funkcjonalność
END METHOD;
Dziedziczenie -
PRIVATE
• Jeżeli wystąpi sekcja PRIVATE, musi poprzedzać sekcję
OVERRIDE;
• Pola i metody tej sekcji są dostępne tylko dla definiowanego
obiektu;
TYPE
aircraftObj = OBJECT (vehicleObj)
altitude : INTEGER;
ASK METHOD climbTo (IN height : REAL);
ASK METHOD findTarget (IN enemy : vehicleObj);
PRIVATE
liftCoefficient : REAL;
ASK METHOD calcLiftCoeff;
OVERRIDE
ASK METHOD stop;
END OBJECT;
Prototypowanie obiektów
Przykład:
AObj =
PROTO
field :
#BObj
;
ASK METHOD doSomething(IN a :
#BObj
) :
#BObj
;
END PROTO;
CObj = OBJECT(Aobj
[Bobj : DObj])
END OBJECT;
Uwaga:
DObj musi być typem pochodnym od Bobj.
Obiekty grupowe
• Wielokrotnie pojawia się konieczność grupowania obiektów-
często zgodnie z ustalonym porządkiem, np.
– obiekt - „klient”
– uporządkowana grupa obiektów - „kolejka klientów do kasy”
• MODSIM udostępnia dedykowane w tym celu klasy obiektów,
będące dynamicznymi listami obiektów:
– QueueObj
: porządek first-in-first-out
– StackObj
: porządek last-in-first-out
– RankedObj
: porządkowana przez metodę Rank
– BTreeObj
: porządek Key-Determined-In-First-Out
• Obiekty grupowe zdefiniowane są jako PROTO dla elementów
ANYOBJ- mogą być modyfikowane dla jednego typu
obiektowego
Metody obiektów grupowych
• Wszystkie grupy mają metody realizujące:
– Includes(IN candidate: ANYOBJ) : BOOLEAN;
– Add(IN NewMember : ANYOBJ);
– Remove() : ANYOBJ;
– First() : ANYOBJ; oraz Last() : ANYOBJ;
– Next(IN candidate: ANYOBJ) : ANYOBJ;
– Prev(IN candidate: ANYOBJ) : ANYOBJ;
– RemoveThis(IN member: ANYOBJ);
– AddBefore(IN ExistingMember, NewMember: ANYOBJ);
– AddAfter(IN ExistingMember, NewMember: ANYOBJ);
– Rank (IN a, b : ANYOBJ) : INTEGER; - w RankedObj
– Key(IN object : ANYOBJ) : STRING; - w BTreeObj
– Find(IN key : STRING) : ANYOBJ; - w BTreeObj
Dodawanie obiektów do grup
FROM GrpMod IMPORT QueueObj;
VAR
boxA, boxB, boxC : cargoObj;
loadingDock : QueueObj;
BEGIN
NEW (loadingDock);
NEW (boxA); NEW (boxB); NEW (boxC);
ASK loadingDock TO Add (boxB);
ASK loadingDock TO AddBefore (boxB, boxA);
ASK loadingDock TO AddAfter (boxB, boxC);
END MODULE.
Zawartość grup
BEGIN
IF loadingDock.numberIn > 0
boxA := ASK loadingDock First();
boxC := ASK loadingDock Last();
IF (ASK loadingDock Includes (boxB))
boxA := ASK loadingDock Prev (boxB);
boxC := ASK loadingDock Next (boxB);
END IF;
END IF;
END MODULE.
Przeszukiwanie grup
BEGIN
FOREACH box IN loadingDock;
END FOREACH {box in loadingDock};
END MODULE.
Usuwanie obiektów z grup
BEGIN
WHILE loadingDock.numberIn > 0;
box := ASK loadingDock TO
Remove
();
DISPOSE (box);
END WHILE;
END MODULE.
lub usuwanie konkretnego obiektu:
FOREACH box IN loadingDock;
IF box.weight < 10.0
ASK loadingDock TO
RemoveThis
(box);
DISPOSE (box);
EXIT;
END IF;
END FOREACH {box in loadingDock};
RankedObj
• Metoda Rank musi być przykryta i uzupełniona, wartość
parametru zwracanego powinna oznaczać:
– ’-1’ - element 1-szy ’gorszy’ od 2-ego
– ’ 0’ - elementy jednakowe
– ’ 1’ - element 1-szy ’leszy’ od 2-ego
• Przykład
PojazdObj = OBJECT
predkosc : INTEGER;
waga : wType;
ASK METHOD UstawPredkosc(IN NowaPredkosc :
INTEGER);
END OBJECT;
QueueObj
StackObj
RankedObj
RankedObj
ASK METHOD Rank( IN a, b: PojazdObj ) : INTEGER;
VAR PojA, PojB: PojazdObj;
BEGIN
PojA := a; PojB := b;
IF ASK PojA predkosc < ASK PojB predkosc
RETURN -1;
END IF;
IF ASK PojA predkosc > ASK PojB predkosc
RETURN 1;
END IF;
RETURN 0;
{porządkuje rosnąco na podstawie pola „ predkosc”}
END METHOD;
Grupowe obiekty dla rekordów
• Analogiczne grupowe klasy obiektów dla rekordów:
QueueList
: porządek first-in-first-out
StackList
: porządek last-in-first-out
RankedList : porządkowana przez metodę Rank
BTreeList
: porządek Key-Determined-In-First-Out
• Przykład:
ArmamentTypeRec = RECORD;
Type : WeaponType;
RealState : REAL;
END RECORD;
ArmamentTypeListObj = PROTO(QueueList
[ANYREC :
ArmamentTypeRec]);
ASK METHOD GetRec(IN typ : WeaponType) : ArmamentTypeRec;
. . .
END PROTO;
Klasa Resource
• Wiele rozwiązywanych problemów dotyczy pozyskiwania
współdzielonych zasobów , np.
– zasób - „komputer”
– grupa zasobów (zgodny typ) - „komputery w laboratorium”
– pozyskuj¹cy zasób - „student”
• MODSIM udostępnia w tym celu klasę ResourceObj, która:
– zadeklarowana jest jako PROTO
– umożliwia pozyskanie/zwrot zadeklarowanej liczby zasobów
– opóźnia przydział w przypadku braku zasobów
– automatycznie gromadzi wybrane dane statystyczne
– udostępnia szereg informacji o stanie zasobów, ich
posiadaczach oraz oczekujących na przydział
Klasa Resource
ResourceObj = PROTO
{Pola}
AllocationList : AllocQueueObj;
PendingList : PriorityList;
MaxResources : INTEGER;
Resources : INTEGER;
PendingResources : INTEGER;
{Metody ASK}
Create(IN number : INTEGER);
IncrementResourcesBy(IN incBy : INTEGER);
ReportAvailability() : INTEGER;
ReportNumberPending() : INTEGER;
NumberAllocatedTo(IN Object : #ANYOBJ) : INTEGER;
TakeBack(IN FromMe : #ANYOBJ; IN numberReturned :
INTEGER);
Klasa Resource
Transfer(IN From, To : #ANYOBJ; IN numberTrans : INTEGER);
Cancel(IN Object : #ANYOBJ; IN numberToCancel :
INTEGER);
AllocMaximum() : INTEGER; PendingMaximum() : INTEGER;
AllocMinimum() : INTEGER; PendingMinimum() : INTEGER;
AllocCount() : INTEGER; PendingCount() : INTEGER;
{Metody związane ze statystykami i danymi statystycznymi...}
{Metody WAITFOR}
DecrementResourcesBy(IN incBy : INTEGER);
{Metody TELL}
Give(IN Me : #ANYOBJ; IN numberDesired : INTEGER);
TimedGive(IN Me : #ANYOBJ; IN numberDesired :
INTEGER;
IN timePeriod : REAL);
PriorityGive(IN Me : #ANYOBJ; IN numberDesired :
INTEGER;
IN priority : REAL);
GetResource(IN Me : #ANYOBJ; IN numberDesired :
INTEGER; IN timePeriod : REAL; IN priority : REAL)
Klasa Resource
Sterowanie zasobami – przykład
:
• Powołanie grupy zasobów
New( LabKom );
• Ustalenie max liczby zasobów
ASK LabKom TO Create(30);
• Alokacja , wykorzystanie i zwrot zasobów przez obiekt „Student”
WAIT FOR LabKom TO TimeGive(Student, 1, 15);
WAIT DURATION 90;
ASK LabKom TO TakeBack (Student, 1);
ASK Student TO GoHome(TRUE);
END WAIT;
ON INTERRUPT
ASK Student TO GoHome(FALSE);
END WAIT;
żądanie przydziału
użytkowanie zasobu
Student 1
Student 2
czas symulacyjny
żądanie przydziału
oczekiwanie
na zasób
rezygnacja
zwrot
zasobu
żądanie przydziału
użytkowanie
zasobu
żądanie przydziału
oczekiwanie na zasób
zwrot zasobu
pozyskanie zasobu
użytkowanie
zasobu
zwrot zasobu
itd..
Klasa Resource - Konflikt w przydziale zasobów
Klasa Resource
Sterowanie zasobami c.d.
• Zmiana liczności zasobów
IF bWypozyczonyKomputer
TELL LabKom TO DecrementResourcesBy(1) [IN czas];
END IF;
• Usunięcie grupy zasobów
IF (ASK LabKom AllocCount = 0) AND (ASK LabKom PendingCount
= 0)
DISPOSE(LabKom);
ELSE
lDostepnych:=ASK LabKom TO ReportAvailability();
lPotrzebnych:=ASK LabKom TO ReportNumberPending()
END IF;
Metody obiektów
TELL
WAITFOR
Różnice między metodami a procedurami
• Metoda jest przywiązana do obiektu i może być wywołana
jedynie poprzez wysłanie komunikatu do tego obiektu z
żądaniem wykonania określonej metody.
• W przeciwieństwie do procedur, może istnieć wiele metod o tej
samej nazwie, przy czym każda z nich może mieć różny kod
(działanie).
• Niektóre metody mogą wytracać czas symulacyjny (TELL i
WAITFOR).
Rodzaje metod
• Metody typu ASK
• Metody typu TELL
• Metody typu WAITFOR
• W jakim celu w MODSIM wyróżnia się różne metody?
Przykład
• Załóżmy, że mamy system telefonii, składający się z dwu linii
wejściowych.
• Co pewien czas pojawiają się rozmowy na liniach, o ile są one
wolne.
• Jeżeli linia jest wolna, następuje rozmowa trwająca określony
czas. Następnie linia jest zwalniana.
• Jeżeli obie linie są zajęte, dzwoniący odłącza się i połączenie
jest tracone.
• Naszym zadaniem jest symulacyjne oszacowanie liczby
utraconych połączeń.
• Pytania:
–
Jaki model zaproponować?
–
Jak zapisać w MODSIM program symulacyjny?
–
Jakie cechy MODSIM’a będą nam pomocne?
Przykład – upływ czasu
Line 1
Line 2
Start
Call
End
Call
Start
Call
End
Call
End
Call
Zdarzeni
e
Proces
Aktywnoś
ć
Start
Call
Another
Call
Cechy symulacji dyskretno-zdarzeniowej
• Zdarzenie może wywołać:
– zmianę wartości elementu stanu
– utworzenie lub usunięcie struktury dynamicznej
– dodanie lub usunięcie obiektu z grupy
– inne zdarzenie
• Czas płynie od zdarzenia do zdarzenia
• Nie dozwolone jest opuszczanie zdarzeń
• Nie dozwolone jest generowanie zdarzeń z czasem „przeszłym”
Cechy symulacji obiektowej zorientowanej na
procesy
• Procesy opisują pojedyncze aktywności obiektów
reprezentujących elementy rzeczywiste
• Kompletne zachowanie odwzorowane jest przez zbiór procesów
• Upływ czasu realizowany może być w wielu miejscach procesów
• Każdy obiekt mieć wiele aktywności
• Każda aktywność pochodzi od metody TELL (lub WAITFOR)
• Aktywności kończą się zgodnie z założeniami lub mogą zostać
przerwane
Cechy symulacji obiektowej zorientowanej na
procesy
• System zbudowany jest z obiektów wymieniających interakcje
• Każdy obiekt, to stan i metody
• Cztery kluczowe elementy:
Pending List
Procedury upływu czasu
Simulation Time
TELL Method
Asynchroniczne wywołania metody TELL
Wywołanie metody TELL:
TELL object [TO] method [ (arguments) ] [ IN delay ];
1. Referencja na ‘object’ zostaje wstawiona do Pending List.
2. Utworzony zostaje referencja ‘activity record’ do metody TELL
METHOD oraz zapisany zostaje czas.
3. ‘activity record’ zostaje wstawiony do Activity List.
Po wywołaniu metody kolejne instrukcje programu są
wykonywane bez oczekiwania.
Pending List oraz Activity List
• Pending List jest uporządkowaną listą obiektów posiadających
własne uporządkowane listy aktywności
A
c
t
i
v
i
t
y
L
i
s
t
Pending List
Ob. A
Ob. D
Ob. C
Ob. B
Akt. 1 - 5
Akt. 5 - 25
Akt. 3 - 120
Akt. 11 - 15
Akt. 4 - 45
Akt. 22 - 26
Akt. 30 - 35
Akt. 7 - 46
Akt. 40 - 100
Akt. 1 - 5
Aktualny czas symulacji :
5
Pending List oraz Activity List
• Pending List jest uporządkowaną listą obiektów posiadających
własne uporządkowane listy aktywności
A
c
t
i
v
i
t
y
L
i
s
t
Pending List
Ob. D
Ob. A
Ob. C
Ob. B
Akt. 5 - 25
Akt. 3 - 120
Akt. 11 - 15
Akt. 4 - 45
Akt. 22 - 26
Akt. 30 - 35
Akt. 7 - 46
Akt. 40 - 100
Aktualny czas symulacji : 5
Akt. 11 - 15
Aktualny czas symulacji :
15
Procedura upływu czasu
Start symulacji
Wybierz obiekt
z najmniejszym
czasem planowanej
czynności tp
Ustaw ’ts’ na ’tp’
Zidentyfikuj
metodę
dla planowanej
czynności
Usuń czynność
z listy planowanych
aktywności obiektu
Wykonaj metodę
planowanej
czynności
Czy koniec?
NIE
TAK
Cz
y t
s >
tk
?
Cz
y li
sta
zda
rze
ń p
ust
a?
Ko
ni
ec
sy
m
ul
ac
ji
Metoda TELL
• Wywołanie TELL może być wstawione w dowolnej metodzie lub
procedurze;
• Metoda TELL pozwala tylko na parametry wejściowe IN;
• Metoda TELL nie może być funkcyjną ani też nie może mieć
parametrów typu OUT lub INOUT – wynika to z faktu, że
informacje zwrotne nie zostaną wykorzystane w odpowiednim
miejscu i czasie.
MAIN MODULE telephone;
FROM SimMod IMPORT StartSimulation;
BEGIN
TELL generator TO generateCalls;
StartSimulation;
END {MAIN} MODULE.
Metoda TELL
Opis aktywności generatora ...
FROM SimMod IMPORT SimTime;
TELL METHOD generatorCalls;
VAR
call : callObj;
BEGIN
WHILE SimTime < runLength
WAIT DURATION stream1.UniformReal (2.0, 6.0);
NEW (call);
TELL call TO commence;
END WAIT;
END WHILE;
END METHOD;
Metoda TELL
OBJECT callObj;
TELL METHOD commence;
BEGIN
IF numberBusyLines < 2
INC (numberBusyLines);
WAIT DURATION stream2.UniformReal (6.0,
10.0);
DEC (numberBusyLines);
END WAIT;
ELSE
INC (numberLostCalls);
END IF;
DISPOSE (SELF);
END {TELL} METHOD {commence};
END OBJECT {callObj};
Opis aktywności połączenia wejściowego (dzwoniący) ...
Metoda TELL
• Metoda TELL wykorzystuje sekwencję WAIT do określenia
miejsca upływu i wielkości czasu symulacyjnego, który ma
zostać „wytracony”;
• Każde wywołanie WAIT jest zapisane w postaci activity w
obiekcie właścicielu.
• Po napotkaniu sekwencji WAIT metoda TELL wstrzymuje
realizację
przez określony czas symulacyjny.
• Po tym czasie metoda TELL wznawia wykonanie.
WAIT
• Cztery rodzaje WAIT:
WAIT DURATION timeValue
WAIT FOR completion of another METHOD
WAIT FOR synchronizing trigger TO Fire
WAIT FOR resource acquisition
WAIT DURATION
• Sekwencja wytracająca zadany czas symulacyjny:
WAIT DURATION timeValue;
… kod źródłowy dla WAIT DURATION
ON INTERRUPT
... sekwencja po przerwaniu
END WAIT;
• timeValue
określone jest w programie
WAIT FOR
• Do synchronizacji metod wykorzystujemy:
WAIT FOR object [ TO ] method [ (arg) ];
... pozostały kod
END WAIT;
• Obiekt wywołujący oczekuje w metodzie wywołującej na
wykonanie metody w drugim obiekcie;
• Deklaracja:
TYPE
yourObj = OBJECT
TELL METHOD yourTellMethod;
WAITFOR METHOD yourWaitForMethod
;
END OBJECT {yourObj};
Synchroniczny upływ czasu
• Gdy dwie lub więcej czynności obiektu wzajemnie zależą od siebie,
można je synchronizować poprzez sekwencję:
...
TELL obiekt1 TO metoda [lista argumentów typu ’IN’] [IN czas]
...
• a w kodzie źródłowym metody umieszczenie bloku instrukcji:
WAIT FOR obiekt2 TO metoda2 [lista argumentów ’IN’]
...instrukcje do wykonania po przejęciu sterowania
END WAIT;
{ ’obiekt1’ oczekuje na wykonanie przez ’obiekt2’ metody
’metoda2’,
następnie realizuje określone wewnątrz instrukcje }
Synchroniczny upływ czasu
• Analogiczny efekt po wywołaniu metody typu WAITFOR :
...
TELL obiekt TO metoda [lista argumentów ’IN, INOUT’] [IN
czas]
...
• a w kodzie źródłowym metody umieszczenie bloku instrukcji:
WAIT FOR obiekt2 TO metoda2 [lista argumentów]
...instrukcje do wykonania po przejęciu sterowania
END WAIT;
• Różnica w odniesieniu do TELL:
– ’WAITFOR’ można wywoływać tylko w powyższej sekwencji;
– w przeciwieństwie do ’TELL’ dopuszcza parametry IN, INOUT;
Odwołania do metod - ACTID
• Każda wywołana metoda otrzymuje swój niepowtarzalny
identyfikator typu ACTID
VAR
actid : ACTID;
...
BEGIN
actid := TELL obiekt TO Metoda();
...
• Wykorzystanie ACTID w bloku
WAIT FOR actid .... END WAIT;
• Wykorzystanie ACTID w sekwencji INTERRUPT
Przerywanie czynności realizowanych przez
metody
• Przerwanie wszystkich aktywności w obiekcie object:
InterruptAll(IN object : ANYOBJ);
• Przerwanie aktywności ( metody ) o identyfikatorze activity:
InterruptMethod(IN activity : ACTID);
• Przerwanie pierwszej napotkanej w Pending List aktywności
( metody ) o nazwie methName w obiekcie object:
Interrupt(IN object : ANYOBJ; IN methName : STRING);
• Uwaga :
– próba przerwania nieistniejącej czynności nie powoduje błędu
– ’runtime error’ generowany jest przy braku sekwencji ’ON
INTERRUPT’ w przerywanej metodzie
Czas symulacyjny: Simulation Time
• Czas symulacyjny SimTime() jest aktualizowany wewnętrznie.
• Bieżącą wartość można odczytać przez wywołanie funkcji
SimTime().
• W każdej chwili może być aktywne wiele metod.
• Po zrealizowaniu operacji skojarzonych z każdą aktywnością
czas jest aktualizowany na wartość znacznika czasu (time
stamp) kolejnej aktywności.
• SimTime jest „bezjednostkowy”.
SimControlObj
• Możliwość nadzorowania upływu czasu z wykorzystaniem
dedykowanych procedur i typów obiektowych
SimControlObj = OBJECT
ASK METHOD TimeAdvance(IN newTime : REAL) : REAL;
ASK METHOD ChooseNext(IN group : ActivityGroup) :
ACTID;
ASK METHOD SetTieBreaking(IN flag : BOOLEAN);
ASK METHOD SetTimeAdvance(IN flag : BOOLEAN);
....
END OBJECT;
Procedury sterowania symulacją
– Uruchomienie upływu czasu (rozpoczęcie symulacji):
StartSimulation
;
– Zakończenie symulacji:
StopSimulation
;
– Odczytanie aktualnej wartości czasu symulacyjnego:
SimTime ( ) : REAL;
– Ustalenie wartości początkowej czasu:
ResetSimTime ( IN newTime : REAL );
– Odczytanie liczby zaplanowanych czynności:
NumActivities ( IN object : ANYOBJ ) : INTEGER;
Procedury sterowania symulacją
– Odczytanie liczby obiektów w Pending List:
NumObjPending() : INTEGER;
– Odczytanie liczby wszystkich zaplanowanych czynności w
listach aktywności obiektów Pending List:
NumActPending() : INTEGER;
– Odczytanie liczby aktywności związanych z sekwencją WAIT ...
FOR:
NumWAITFOR() : INTEGER;
– Odczytanie zawartości Pending List (opcjonalnie także list
aktywności obiektów):
PendingListDump(IN DoActList: BOOLEAN);
– Zmienna
Timescale : REAL
(dostępna przez import) określająca
liczbę rzeczywistych sekund / jednostkę czasu symulacji
Procedury sterowania symulacją
• Przerwanie czynności (realizowanych przez metody)
realizowane jest przez instrukcję:
Terminate;
• W odróżnieniu od wszystkich ’Interrupt” wywoływana jest
wewnątrz metody w celu zakończenia własnej czynności:
IF SimTime() > czasStop
Terminate;
END
IF;
• Zatrzymanie metody ’M1’ oczekującej w sekwencji WAIT FOR ...
na wykonanie drugiej metody ’M2’ powoduje w pierwszej
kolejności zakończenie metody ’M2’ a następnie ’M1’ (w
przypadku dalszej rekrencji - analogicznie)
Symulacja Telefonii
1
MAIN MODULE telphn3;
2
3
{ Telephone Model3 - CACI Products Company }
4
5
FROM IOMod IMPORT ReadKey;
6
FROM SimMod IMPORT StartSimulation;
7
FROM generatorMod IMPORT generatorObj;
8
FROM callMod IMPORT numberLostCalls, initializeStream2;
9
10
VAR
11
ch : CHAR;
12
timeToQuit : REAL;
13
generator : generatorObj;
14
15
BEGIN
16
17
timeToQuit := 60.0; { minutes }
18
19
initializeStream2;
20
21
NEW (generator);
22
TELL generator TO generateCall (timeToQuit);
23
24
StartSimulation;
25
26
OUTPUT;
27
OUTPUT ("NUMBER OF LOST CALLS = ", numberLostCalls);
28
OUTPUT;
29
OUTPUT ("Press any key to end program.");
30
ch := ReadKey;
31
32
END {MAIN} MODULE {telephone3}.
1
DEFINITION MODULE generatorMod;
2
3
FROM callMod IMPORT callObj;
4
FROM RandMod IMPORT FetchSeed, RandomObj;
5
FROM SimMod IMPORT SimTime;
6
7
TYPE
8
generatorObj = OBJECT
9
10
TELL METHOD generateCall (IN timeToQuit: REAL);
11
12
END OBJECT {generatorObj};
13
14
END {DEFINITION} MODULE {generatorMod}.
1
IMPLEMENTATION MODULE generatorMod;
2
3
OBJECT generatorObj;
4
5
TELL METHOD generateCall (IN timeToQuit: REAL);
6
7
VAR
8
call : callObj;
9
stream1 : RandomObj;
10
11
BEGIN
12
13
NEW (stream1);
14
15
WHILE SimTime <= timeToQuit
16
WAIT DURATION stream1.UniformReal (2.0, 6.0);
17
NEW (call);
18
TELL call TO commence;
19
END WAIT;
20
END WHILE;
21
22
END {TELL} METHOD {generateCall};
23
24
END OBJECT {generatorObj};
25
26
END {IMPLEMENTATION} MODULE {generatorMod}.
1
DEFINITION MODULE callMod;
2
3
FROM RandMod IMPORT FetchSeed, RandomObj;
4
5
TYPE
6
callObj = OBJECT
7
8
TELL METHOD commence;
9
10
END OBJECT {callObj};
11
12
VAR
13
numberLostCalls : INTEGER;
14
15
PROCEDURE initializeStream2;
16
17
END {DEFINITION} MODULE {callMod}.
1
IMPLEMENTATION MODULE callMod;
2
3
VAR
4
numberBusyLines : INTEGER;
5
stream2 : RandomObj;
6
7 PROCEDURE initializeStream2;
8 BEGIN
9
10 NEW (stream2);
11 ASK stream2 TO SetSeed (FetchSeed(2));
12
13 END PROCEDURE {initializeStream2};
14
15
16 OBJECT callObj;
17
18 TELL METHOD commence;
19 BEGIN
20
21 IF numberBusyLines < 2
22 INC (numberBusyLines);
23 WAIT DURATION stream2.UniformReal (6.0, 10.0);
24 DEC (numberBusyLines);
25 END WAIT;
26 ELSE
27 INC (numberLostCalls);
28 END IF;
29
30 DISPOSE (SELF);
31
32 END {TELL} METHOD {commence};
33
34 END OBJECT {callObj};
35
36 END {IMPLEMENTATION} MODULE {callMod}.