Wobec tego bardziej szczegółowo:
Program jest grą tekstową.
Obiekt:
Czynności przygotowawcze:
- wyświetlenie ekranu powitalnego
- pobranie parametrów wejściowych (nowa gra, ładuj grę...)
- (jeśli jest żądana przez użytkownika) kompilacja plików źródłowych kodu świata gry
- ładowanie świata gry z plików i (jesli jest żądane) ładowanie zapisanego stanu gry
Działanie :
Utwórz dwa wątki:
- jeden z wątków w pętli pobiera kolejne rozkazy z klawiatury i wrzuca je do kolejki (pętla komend)
- drugi z wątków kolejno: obsługuje rozkaz i utrzymuje świat (pozwala światowi "wykonać" czynności związane z upływem czasu) (pętla świata)
Z tego, co pamiętam, pół roku temu myślałem nad utrzymaniem tego w ramach funkcji main(), ale pierwotnie sam obiekt miał być bardziej rozbudowany, później dopiero został okrojony do, w zasadzie, "utrzymywacza wątków". Jakoś zostałem tak nauczony, że w ramach funkcji main() powinno być tak mało kodu, jak to jest możliwe, reszta powinna siedzieć w obiektach.
Do tego metoda wątku "pętli świata" musi posiadać w sobie obiekty mapy świata i mapy bohaterów (tworzone podczas ładowania), przekazuję je (trochę kombinując) przekazując do metody statycznej wątku wskaźnik do mojego obiektu silnika; w przypadku uzycia funkcji main musiałbym zrobić zmienne globalne dla tych map, albo jakiś sztuczny obiekt, który będzie w sobie "transportował" wskaźniki.
[edit]
Zauważyłem, że podobną sytuację wyrzeźbiłem w obiekcie, który również jest singletonem; w tym wypadku jest to mocno uzasadnione: jest to obiekt zawierający słownik na potrzeby gry (odmiana polskich wyrazów). Również tu w ramach konstruktora pobieram z plików i ładuję dane. Dla mnie rozwiązanie w konstruktorze jest eleganckie, konstruktor wygląda tak:
LangUtil::LangUtil() {
log.info("Budowanie slownikow.");
wypelnijRzeczowniki();
wypelnijLiczebniki();
wypelnijPrzymiotniki();
wypelnijPrzyslowki();
}
Również tworzenie obiektu w grze wygląda spokojnie, bo:
//Piszę tak:
LangUtil lang;
//Zamiast, na przykład.
LangUtil lang;
lang.inicjalizuj();