2010-06-19 19 views
7

SDL na OS X używa preprocesorów do przeciążania main() z własnym punktem wejścia, napisanym w Objective C, który wywołuje główną stronę użytkownika.Haskell SDL na OS X

Te sztuczki sprawiają, że życie użytkowników innych niż SDL (np. Powiązania Haskella) jest bardzo trudne.

Czy istnieje ku temu dobry powód?

Dlaczego SDL nie może wykonać inicjalizacji kakao celu C w SDL_init?

Odpowiedz

5

Podejście do systemu Mac OS X nie różni się zbytnio od podejścia dla innych platform innych niż Linux (Windows, stary Mac, BeOS). Można zapytać SDL deweloperom się dlaczego zrobili to w ten sposób, ale widzę kilka powodów mogą one zdecydowały się to zrobić:

  • To utrzymuje zależności kodu SDL, która koncentruje się na inicjalizacji SDL-specyficzny podsystemy (wideo, audio, synchronizacja itd.) ograniczone do konkretnych podsystemów, z którymi SDL został specjalnie zaprojektowany do pracy. To znaczy. w ten sposób SDL pozostaje szczupła i podła.
  • Pozwala to uniknąć konieczności wprowadzania nowego podsystemu specyficznego dla platformy do inicjowania aplikacji. Nie wszyscy będą chcieli uzyskać obiekt aplikacji i menu, który SDL skonfiguruje dla aplikacji na Maca, a nie przez długie ujęcie - więc jeśli zamierzasz umieścić go w SDL_init, musisz ustawić go jako opcjonalny podsystem, tak aby nie przeszkadza to programistom, którzy tego nie potrzebują.
  • Obsługuje inwersję kontroli poprawnie, tak właśnie zwykle działa Mac OS X i inne struktury aplikacji, przy zachowaniu operacyjnej semantyki procedur SDL. SDL_init zakłada, że ​​powróci do wywołującego po zakończeniu inicjalizacji, ale jeśli próbowałeś naiwnie utworzyć obiekt aplikacji w SDL_init i wywołałeś na nim [app run], aby zakończyć inicjowanie aplikacji i jej uruchomienie, nigdy nie wróciłeś. Jeśli nie zadzwoniłeś pod numer run, musisz utworzyć osobną funkcję SDL, aby skonfigurować pętlę uruchamiania aplikacji. To może dość skomplikować bibliotekę SDL. Wybrane podejście pozwala uniknąć tego wszystkiego, pozwalając ramom zadbać o całą skonfigurowaną aplikację jako pierwszą i wywołać procedurę SDL_main() od applicationDidFinishLaunching.
  • Ułatwia konwersję wersji demonstracyjnych SDL zakodowanych w systemie Linux na Mac OS X. Nie trzeba nawet zmieniać nazwy głównej - zmiana nazwy preprocesora na main() na SDL_main() dba o to!

Zgaduję, ostatni z tych powodów jest głównym motorem redefinicji Głównym w SDL_main.h, który Zgadzam jest brzydki Hack.

Jeśli jesteś gotów zrezygnować z tego poziomu przenośności między platformami do biblioteki i aplikacje, sugeruję po prostu modyfikując SDL_main.h usunąć następujący wiersz:

#define main SDL_main 

i usuwanie następujących z SDLMain.m w projekcie:

#ifdef main 
# undef main 
#endif 

nie należy nawet trzeba skompilować SDL jeśli to zrobisz. Zauważ, że SDLMain.m jest już skonfigurowany do wywoływania SDL_main() bez hakowania preprocesora, i nic więcej w SDL tego nie zrobi, więc w ten sposób możesz po prostu podać SDL_main() jako punkt wejścia swojej gry.

Jeśli chcesz iść w drugą stronę, przejmując main() się, że nadal chcesz pozbyć się #define main SDL_main siekać w SDL_main.h, ale poza tym, nie jesteś zobowiązany do main() że SDL przewiduje ty. Po pierwsze, należy pamiętać, że SDLMain.{h,m} nie są częścią biblioteki właściwej; musisz uwzględnić je osobno w swoim projekcie. Po drugie, należy zwrócić uwagę na następujące uwagi w SDLMain.h:

/* SDLMain.m - main entry point for our Cocoa-ized SDL app 
     Initial Version: Darrell Walisser <[email protected]> 
     Non-NIB-Code & other changes: Max Horn <[email protected]> 

    Feel free to customize this file to suit your needs 
*/ 

To brzmi dla mnie jak zaproszenie, aby przejść toczyć własną rękę, jeśli te nie pracują dla Ciebie, począwszy SDLMain.{h,m} jako model. A jeśli toczycie się samodzielnie, możecie robić, co chcecie! W tym przypadku możesz napisać odpowiednik SDLMain.m w Haskell, używając HOC, jeśli tego chcesz. Jednak jeśli nie jesteś świetnym graczem z HOC, utrzymam to w prostocie.