Odczytanie zmiennej i wyniku funkcji

Żółwie w POOL są aktywnymi obiektami posiadającymi składowe zmienne, właściwości i funkcje. Każdy żółw-obiekt posiada własną kolejkę zadań (wątek). Jeśli funkcja składowa jednego żółwia jest wywołana przez innego żółwia, wykonywanie funkcji jest równolegle z kodem wywołującym. Tak wywołane funkcje są traktowane jako osobne zadania i są ustawiane w kolejce w kolejności, w jakiej wystąpiły wywołania. W ten sam sposób traktowane są także wywołania instrukcji, które zmieniają stan żółwia, np.: forward, setpencolor.
Wykonanie programu zostanie wstrzymane przy pierwszej próbie użycia wyniku zadania innego żółwia, jeśli wynik ten nie jest jeszcze gotowy (przykłady 1 i 2).

W ordóżnieniu od wywołań funkcji, odczytanie zmiennych i właściwości żółwia odbywa się w ramach zadania żółwia wykonującego operację odczytu. Nie jest tworzone równoległe zadanie, a wynik jest dostępny natychmiast. W ten sposób możliwe jest monitorowanie na bieżąco wartości zmiennych i właściwości (np.: pos, pencolor), nawet jeśli monitorowany żółw wykonuje długotrwałe zadanie (przykład 3).
Aby odczytywać zmienne i właściwości w sposób zsynchronizowany z zadaniami żółwia, należy zdefiniować funkcje dostępu, np.:

to model
  "x := 5
  to getx op :x end
  to getpos op pos end
end

Przykład 1:
Program zapisuje wynik funkcji silnia w tablicy :y. Ponieważ elementy tablicy są używane dopiero w poleceniu print :y, możliwe jest wykonanie całej pętli for i uruchomienie równoległych obliczeń funkcji.

to silnia :x
  (print who :x)
  if :x > 1 [op :x * silnia :x - 1]
  op 1
end

"n := 3
"y := newarray :n
"t := (anewturtles :n)
for [i 1 :n] [:y,:i := (silnia :i+2) @ :t,:i]
print :y

Rezultat wykonania:
Kolejność pojawienia się napisów może być różna dla każdego uruchomienia, poza wynikiem "{6 24 120}", który zawsze wypisywany jest jako ostatni.

t1 3
t2 4
t3 5
t1 2
t2 3
t3 4
t1 1
t2 2
t3 3
t2 1
t3 2
t3 1
{6 24 120}

Przykład 2:
Program zapisuje wynik funkcji fn w zmiennej :p. Ponieważ wynik funkcji jest używany przez program dopiero w ostatnim poleceniu, możliwe jest wykonanie wcześniejszych poleceń w trakcie długotrwałego wykonania funkcji.

to model :param
  to fn :x
    (print "start "fn :x)
    wait 2000 ;opóźnienie (lub czasochłonne operacje)
    let "wynik :x * :param
    (print "wynik "gotowy)
    op :wynik
  end
end

"t := (newt $model 2)

(print "wywołaj "funkcję)
"p := (fn 5) @ :t

repeat 3 [wait 200 (print "równoległy "kod repcount)]

print "czekaj...
(print "użyj :p)

Rezultat wykonania:

wywołaj funkcję
start fn 5
równoległy kod 1
równoległy kod 2
równoległy kod 3
czekaj...
wynik gotowy
użyj 10

Przykład 3:
Funkcja zmieniaj_q jest czasochłonna, w trakcie jej wykonania zmienia się wartość zmiennej :q. Program wywołuje funkcję i następnie monitoruje zmiany wartości :q, równolegle z wykonaniem funkcji.

to model :param
  to zmieniaj_q
    repeat 3 [
      wait 200
      "q += 1
      wait 200
    ]
    "koniec := true
  end

  ;zmienne globalne (dostępne publicznie):
  "koniec := false
  "q := :param
end

"t := (newt $model 0)
"test := :q @ :t
zmieniaj_q @ :t

while not :koniec @ :t [
  "n := :q @ :t
  if :test <> :n ["test := :n (print "zmiana :n repcount)]
  wait 10
]
print "stop

Rezultat wykonania:

zmiana 1 22
zmiana 2 61
zmiana 3 101
stop

Zobacz także:

Zmienne lokalne, globalne, współdzielone
Klasy i dziedziczenie
@ (dostęp do składowych)

Spis treści