Aplikacja JavaScript jest podzielona na warstwę logiki i prezentacji. Funkcja warstwy logiki analizuje instrukcje wczytane z pliku. W pewnym momencie jest przejście do warstwy prezentacji, gdzie trzeba coś wyświetlić na ekranie lub oczekiwać na ruch użytkownika (np. kliknięcie obiektu, naciśnięcie klawisza, wybrać akcję). W przeciwieństwie do aplikacji konsolowych GUI (np. dokument HTML) działa cały czas i nie zatrzymuje programu, oczekując na dane wejściowe. Jak zaprojektować komunikację między tymi 2 warstwami, aby uniknąć błędów i zapewnić najlepszą wydajność? Aplikacja działa tak:

function analizuj_kod()
{
   switch(instrukcja)
   {
      case 'prezentacja': funkcja_prezentacji(akcja); break;
      //poza tym dużo innych operacji
   }
}

function funkcja_prezentacji(akcja)
{
   switch(akcja)
   {
      case 'pokaz_tekst': wypisz(tekst); opoznienie(500); break;
      case 'wybierz_obiekt': /* użytkownik ma coś kliknąć lub nacisnąć klawisz */ break;
      case 'pobierz_wybor': analizer.id_obiektu = id_obiektu; break; //przekazujemy ID obiektu do logiki
      case 'odwtorz_dzwiek': /* odtwarza dzwiek */ break;
      //poza tym dużo innych akcji
      //nigdzie nie ma return, zawsze przekazujemy dane do analizatora kodu
      //ostatecznie można wprowadzić return
   }
}

Mam kilka pomysłów:

A. Wątki - Web Workers:

Działają tylko w nowych wersjach przeglądarek. Przykładowy przepływ:

  1. Tworzymy wątek, w którym będą analizowane instrukcje
  2. Warstwa logiki wysyła wiadomość do warstwy prezentacji i czeka na odpowiedź
  3. Warstwa prezentacji wysyła komunikat do warstwy logiki np. po wyborze obiektu

Wątki w JS prawdopodobnie nie obsługują oczekiwania na odpowiedź (nie ma odpowiednika WaitForSingleObject z WinAPI ani Receive z QNX), więc nie przerwiemy wykonywania kodu w danym miejscu. Trzeba to obejść.

B. Wznawianie wykonywania kodu.

  1. Po wywołaniu funkcji warstwy prezentacji zatrzymujemy analizę kodu.
  2. Warstwa prezentacji znów uruchamia interpreter: analizer.start() np. po wyborze obiektu.
  3. Jeśli wywołamy analizer.start() w nieodpowiednim miejscu i czasie, wszystko się posypie.
  4. Jeśli gdzieś ma być opóźnienie: zatrzymujemy analizę, setTimeout, wznawiamy analizę.

C. Inne pomysły?
Jakie macie pomysły na poprawny i optymalny przepływ sterowania? Co trzeba wiedzieć:

  1. Interpreter kodu decyduje o przeniesieniu sterowania do prezentacji.
  2. On także decyduje, czy coś wyświetlić, czy oczekujemy na wejście...
  3. W aplikacji konsolowej scanf() zatrzymuje przepływ kodu, a tutaj mamy cały czas GUI
  4. Potrzebny dostęp do stosu interpretera w warstwie prezentacji.
  5. Obiekty mogą być cały czas widoczne, ale wybór przesyłamy tylko wtedy, gdy warstwa logiki tego chce.