Snake Opublikowano 31 Lipca 2008 Udostępnij Opublikowano 31 Lipca 2008 Last update: 29.12.2009:Features: - Wsparcie dla GM8 - Dodano funkcję thread_wait, służącą do oczekiwania na zakończenie wątku - Dodano możliwość sprawdzenia błędu danego wątku - DLL został napisany od nowa w MASMie - Wydano kod źródłowy (na LGPL) Compatibility issues: - Zmiany w nazwach funkcji (thread_priority, thread_affinity_mask, thread_ideal_processor, thread_num_of_processors) - Usunięto funkcje thread_last_error i thread_is_suspended - Teraz po utworzeniu wątku trzeba zamykać jego uchwyt (za pomocą thread_close). Dzięki temu można przechwycić kod błędu wątków (thread_get_error). FAQ styleCo to jest ?GMThreads to biblioteka DLL dzięki której można wykonywać podany kod GML w... wątkach ;D Właściwie, to to jest eksperyment i trzeba to przetestować. Co to są "wątki" ? ;o Hmm... nie chce mi się tego opisywać więc zacytuje: Wątek (ang. thread) - to jednostka wykonawcza w obrębie jednego procesu, będąca kolejnym ciągiem instrukcji wykonywanym w obrębie tych samych danych (w tej samej przestrzeni adresowej). Czytaj dalej... Zdaje sobie z tego sprawę że większość użytkowników Game Makera nie wie o co biega więc łopatologicznie: Wątek to taki "proces" który działa w tle aplikacji i wykonuje kod niezależnie od tego, co się z nią dzieje. Do czego te wątki mogą mi się przydać ? Cóż, kod wykonywany w wątkach jest cały czas tzn. nawet gdy okno gry jest zminimalizowane, przemieszczane, wyświetla wiadomość [show_message] itd. Poza tym, dzięki nim można ładować zasoby, wykonywać obliczenia i tak dalej w tle, przez co główne okno się nie "zawiesi" w czasie ładowania (FPS-y mogą spaść, chociaż to też zależy od priorytetu wątku). Hmm... więc jak tego używać ? Może najpierw wymienię funkcje:thread_init( NazwaPliku ) - Inicjuje GMThreads. Można podać inną ścieżkę do pliku (domyślnie: GMThreads.dll). Ta funkcja musi być wykonana żeby korzystać z dll-a.thread_create( SkryptGML, Wstrzymany? ) - Tworzy nowy wątek, w którym będzie wykonywany podany kod GML. Wątek można stworzyć wstrzymany. Zwraca uchwyt wątku, dzięki któremu można nim zarządzać za pomocą poniższych funkcji (jeśli wystąpił błąd w utworzeniu wątku - zwraca 0). Uchwyt powinien zostać zamknięty za pomocą funkcji thread_close.thread_close( UchwytWątku ) - Zamyka uchwyt podanego wątku. Uwaga: Wątek nie jest zakańczany po wywołaniu tej funkcji.thread_wait( UchwytWątku, Czas ) - Wstrzymuje wątek, który wywołuje tą funkcję do czasu aż podany wątek nie zakończy pracy lub dopóki nie upłynie podana ilość czasu. Czas podajemy w milisekundach, podając -1 funkcja wróci jedynie, gdy podany wątek zakończy pracę. Zwraca -1 jeśli wystąpił błąd (np. podano nieprawidłowy uchwyt), 0 gdy upłynęła podana ilość czasu a wątek nadal nie zakończył pracy i 1 gdy wątek zakończył pracę.thread_suspend( UchwytWątku ) - Wstrzymuje podany wątek. Zwraca 1 jeśli nie wystąpił żaden błąd.thread_resume( UchwytWątku ) - Wznawia podany wątek. Zwraca 1 jeśli nie wystąpił żaden błąd.thread_set_priority( UchwytWątku, Priorytet ) - Ustawia priorytet podanego wątku. Zwraca 1 jeśli nie wystąpił żaden błąd. Argument "Priorytet" można ustawić na: 0 = Bezczynny (Idle) - wątek będzie wykonywany gdy inne aplikacje nie będą używały procesora. 1 = Niski (Lowest) 2 = Poniżej normalnego (Low) 3 = Normalny (Normal) - Domyślny priorytet każdego wątku 4 = Powyżej normalnego (Higher) 5 = Wysoki (High) 6 = Czasu rzeczywistego (Time critical / Realtime) - Najwyższy priorytet, jako że wątek będzie korzystał z całej mocy procesora - wszystko w koło się zawiesi (system, myszka itd.), ale wątek będzie wykonywany. thread_get_priority( UchwytWątku ) - sprawdza jaki priorytet ma podany wątek, gdy wystąpi błąd przy sprawdzaniu zwraca -1.thread_get_error( UchwytWątku ) - zwraca kod błędu, który wystąpił w danym wątku. ( -1 - zły uchwyt, 0 - brak błędu, 1 - błąd GML ).thread_terminate( UchwytWątku ) - Wymusza zamknięcie wątku. Zwraca 1 jeśli wątek został zamknięty. Ostrzeżenie: używać tylko w ostateczności - zamknięty wątek nie będzie mógł zwolnić użytych zasobów, doprowadzając do wycieków pamięci.thread_is_running( UchwytWątku ) - Sprawdza czy podany wątek jest uruchomiony / czy istnieje. Jeśli tak - zwraca 1 (true).thread_set_affinity( UchwytWatku, Maska ) - ustawia maskę affinity (typ wektora bitowego) podanego wątku. Jak to działa ? Każdy bit podanej wartości (maski) reprezentuje procesor (rdzeń) czyli np. 3 w postaci binarnej to 0000 0011, więc wątek z taką maską będzie korzystał z pierwszego i drugiego rdzenia 10 w postaci binarnej to 0000 1010, więc wątek będzie korzystał z 2 i 4 rdzenia. Żeby sobie dopasować taką wartość możecie użyć kalkulatora windowsowego w trybie naukowym. Jeśli funkcja zawiedzie - zwraca 0, w innym wypadku zwraca poprzednia maskę. more info: http://msdn.microsoft.com/en-us/library/ms686247(VS.85).aspxthread_set_processor( UchwytWatku, NumerProcesora ) - ustawia preferowany procesor (rdzeń) dla wątku. Numer procesora ustawiany jest od 0, czyli 0 = pierwszy rdzeń, 1 = drugi itd. Zwraca -1 gdy wystąpi błąd, inaczej zwróci poprzedni ustawiony numer procesora. more info: http://msdn.microsoft.com/en-us/library/ms686253(VS.85).aspxthread_get_cpucount() - Zwraca ilość rdzeni/procesorów.Tworzenie wątku: Wątek tworzy się za pomocą funkcji thread_create, której zwróconą wartość należałoby zapisać w zmiennej, żeby móc go później kontrolować np.GML moj_watek = thread_create( "repeat (1000) global.zmienna += 1;", 1 ); // stworz watek (wstrzymany) if ( moj_watek ) { thread_set_priority( moj_watek, 2 ); // ustaw priorytet na "ponizej normalnego" thread_resume( moj_watek ); // wznow watek } elseshow_message( "Nie można utworzyć wątku." ); Powyższy kod uruchomi wątek z niższym priorytetem, a jeśli nie uda się go stworzyć zostanie wyświetlona wiadomość z błędem. ;p Proste, nie ? Z takim kodem GML na pewno ;d W podanym skrypcie GML można definiować zmienne ( zmienna = 0... ), ale nie będą one dostępne z żadnego obiektu ( nawet z tego w którym wątek został utworzony ), nie licząc zmiennych globalnych. Po wykonaniu kodu wątek zostaje zakończony. "Nieskończone" wykonywanie kodu w wątkach Też proste i chyba oczywiste. ;D Do tego można użyć pętli while. np. GML moj_watek = thread_create( " while ( true ) { if ( costam ) { zrob_cos(); } zmienna += 0.1; } ", 0 ); Jednak trzeba pamiętać, że kod w pętlach jest wykonywany niezależnie od prędkości pokoju (room_speed) i dlatego taki kod spowoduje większe użycie procesora. Tak, więc nieraz trzeba użyć sleep(), żeby opóźnić wykonywanie pętli np. GML moj_watek = thread_create( " while (1) { if ( costam ) { zrob_cos(); } zmienna += 0.1; sleep( 1000 ); // poczekaj sekunde } ", 0 ); Zakończenie wątku Zakończyć wątek można za pomocą funkcji thread_terminate, ale używać jej należy tylko w ostateczności, gdyż wymuszenie zamknięcia wątku uniemożliwi mu zwolnienia zasobów z pamięci powodując tzw. memory leak. Żeby bezpiecznie zakończyć wątek trzeba skorzystać z warunków ;d przykładowy kod: GML moj_watek = thread_create( " while (!global.zakonczony) { // wykonuj dopoki watek nie zostal zakonczony usun_cos(); zrob_cos(); zrob_cos(); if ( global.zakonczony ) exit; // przerwij w tym miejscu jesli zostal zakonczony dodaj_cos(); zrob_cos(); } ", 0 ); i po prostu ustawiasz zmienną global.zakonczony na true ;o Dodatkowe informacje: Wątek jest wykonywany nawet podczas i po zmianie pokoju, dlatego trzeba sprawdzać czy dany obiekt czy zmienna istnieje. Gdy wystąpi błąd w GML (syntax error, nieznana zmienna czy obiekt itd.) wtedy wątek zostaje zakończony, bez wyświetlenia komunikatu błędu. No i można używać komentarzy ;D Znane bugi: - W wątkach GM-owych okienek wiadomości (show_message*) nie można zamknąć. - W wątkach wszystkie otwierane okna nie blokują głównego okna gry.Download (V2.0): http://www.gmclan.org/up541_4_GMThreads2.html (~9KB) W archiwum jest prosty przykład, DLL i kod źródłowy. Jeśli chcesz używać tej biblioteki - umieść mnie w credits ;D Podziękowania dla Maxpayna, za testowanie nowej wersji na swoim procku (Quad) :D Jeśli masz konto na GMC, możesz napisać w tym temacie swoją ocenę: ;Dhttp://gmc.yoyogames.com/index.php?showtopic=390517 Testujcie i zgłaszajcie bugi ;dDLL działa tylko z GM6.1, GM7.0 i GM8.0 Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Marek.S Opublikowano 31 Lipca 2008 Udostępnij Opublikowano 31 Lipca 2008 Zapowiada się zaje.iście! :D już się biorę za testowanie "DLL działa tylko w wersją 7.0 Game Makera" - ;/ nie możan by tak pod 6.1?? ;( Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 31 Lipca 2008 Autor Udostępnij Opublikowano 31 Lipca 2008 Później się zajmę wersją 6.1 ;p Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Marek.S Opublikowano 31 Lipca 2008 Udostępnij Opublikowano 31 Lipca 2008 Nasz Snejkuś znów nam usprawnia gm'a :* rozumiem, że taki wątek wykonuje sprawniej(szybciej) kod niż gm =P btw co to ma być. 2 min, 213 sek ? :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 31 Lipca 2008 Autor Udostępnij Opublikowano 31 Lipca 2008 btw co to ma być. 2 min, 213 sek ? lul xd zapomniałem modulo pewnie ;D rozumiem, że taki wątek wykonuje sprawniej(szybciej) kod niż gm =P Nie szybciej tylko asynchronicznie z grą ;p nie może być szybciej bo okno GM-a rysuje obraz w trakcie wykonywania kodu w wątkach ;p No chyba że ustawisz priorytet na time critical ;D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 1 Sierpnia 2008 Autor Udostępnij Opublikowano 1 Sierpnia 2008 K, nowa wersja: - Teraz GMThreads będzie działał na GM6.1 ;p http://www.gmclan.org/up541_4_GMThreads11.html Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Marek.S Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 super! czyli teoretycznie jak np. zmrożę grę i dodam wątek w którym zapiszę sprita do pliku bmp(ręcznie) to rezultat z takiego wątku będzie taki sam jak by to robił gm?? :( Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 1 Sierpnia 2008 Autor Udostępnij Opublikowano 1 Sierpnia 2008 Jak zamrozisz/wyłączysz rysowanie obrazu w GM to tak. Ale chodzi tu o to hmm... np. używasz supersound.dll (taki DLL dla GM który odtwarza dźwięk) i chcesz załadować jakiś plik z muzyką, to okno gry się zamrozi dopóki muzyka się nie załaduje. A jeśli załadujesz muzykę przez wątek to zamrozi się tylko wątek dopóki się nie załaduje, a gra będzie normalnie chodzić ;p Szybciej niż normalnie w GM może działać jak zmienisz priorytet wątku na "Czasu rzeczywistego", bo użyje wtedy całego procesora. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TeeGee Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 Wow! Jeśli to faktycznie będzie działać bez problemu, to niemal na pewno zastosuje Twój .dll w ArcMagi :D. Właśnie tego mi w GM brakowało - możliwości ładowania zasobów w odzielnym wątku (lub przynajmniej streamowania muzyki). Mógłbym zaoszczędzić sporo pamięci wgrywając zasoby tylko kiedy są faktycznie potrzebne, jednocześnie nie powodując drobnych "przeskoków" w czasie gry. Świetna robota, Snake! Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 1 Sierpnia 2008 Autor Udostępnij Opublikowano 1 Sierpnia 2008 Trzeba sprawdzić dokładniej z tym ładowaniem, bo np. jak użyłem sprite_add() z zaznaczoną opcją "Preload", to samo załadowanie do pamięci pliku nie zawiesiło gry, ale ten "preload" jest wykonywany poza wątkami i dlatego przetwarzanie załadowanego sprite'a już przywiesiło ;[ (a samo ładowanie w sprite_add bez opcji preload nie zawiesza okna) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TeeGee Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 Auć :(. Szkoda, miałem nadzieję, że ładowanie do pamięci graficznej z preloada też poleci od razu w dodatkowym wątku. Bez tego faktycznie będzie ścinać niemal tak samo jak bez zabawy w multithreading. Przynajmniej muzykę będę mógł ładować poza grą, to już zawsze coś. Ech... nie ma lekko. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Dawidds Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 Ale wypas :P Jak nie będzie będów no to... :D Snake, powinieneś pracować w YYG ;) Dobra, idę testować =D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 1 Sierpnia 2008 Autor Udostępnij Opublikowano 1 Sierpnia 2008 Może spróbuję zrobić hacka z tym ładowaniem sprite'ów/backgroundów, dodałbym oddzielną funkcję która tworzyłaby wątek i w nim ładowałaby obrazy razem z preload. ;p Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Dawidds Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 Snake ty serio pomyśl o pracy w YYG :P Mam wrażenie, że jakby nad GM'em pracowali jego użytkownicy to byłby lepszy niż jak YYG nad nim pracuje.... Teraz tylko czekać, aż Snake naprawi ten preload =D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 1 Sierpnia 2008 Autor Udostępnij Opublikowano 1 Sierpnia 2008 Tia, mogli by mnie pozwać za praktykowanie reverse engineeringu na ich aplikacjach ;D Tworząc Game Protectora, Instant Player Offline i GMThreads złamałem ich "End User License Agreement" ;p Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 A co robić, gdy ich zabezpieczenie jest nieudolne? :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 1 Sierpnia 2008 Autor Udostępnij Opublikowano 1 Sierpnia 2008 To nie uprawnia mnie do łamania umowy licencyjnej ;p Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Marek.S Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 Snake zrób proszę to ładowanie spritów zanim Cię zamknął :P Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
TeeGee Opublikowano 1 Sierpnia 2008 Udostępnij Opublikowano 1 Sierpnia 2008 Snake, jakbyś zrobił odzielną funkcję, która by ładowała sprite do zasobów i od razu do pamięci graficznej, to to by było cholernie dobre. Kurde, nowa jakość resource managmentu w GM :). Moim zdaniem, jeśli masz czas i ochotę, to naprawdę warto. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 2 Sierpnia 2008 Autor Udostępnij Opublikowano 2 Sierpnia 2008 Haha, mam dobrą wiadomość :D Nie wiem czemu mi wcześniej zamrażało okno, ale... właśnie chciałem spróbować zrobić tego hacka na grafikę, dla testu dopisałem sprite/background add/replace w wątku i... załadowało się bez żadnej przycinki xD Ale przetestujcie ten przykład (gm6 i gmk) dla pewności: http://www.gmclan.org/up541_4_ThreadLoadTest.html (ładuje 2MB plik JPG w wątku) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Pieter Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 jak dla mnie? działa perfect ;) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 u mnie przycina, gdzies na 0.5 sekundy, dziwne o.o Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Pieter Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 normalne, że jak się sprite zmieni na tak duży to spadnie o 1 fps. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 2 Sierpnia 2008 Autor Udostępnij Opublikowano 2 Sierpnia 2008 PsichiX, a spróbuj się przyjrzeć, czy nie rysuje przez to pół sekundy obrazu, czy może blokuje całego GM-a (kod gml też się nie wykonuje) Kurde, u mnie i u Pietera działa ;/ Aha, i jak możesz to porównaj ładowanie bez wątku tego pliku z ładowaniem w wątku ;p Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Maximal Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 Snake, kocham Cię. Oczyma wyobraźni widzę już grono zastosowań dla systemu wątków. Cholera, przecież to szalenie usprawni pracę GMa. :) Szkoda tylko, że ni możesz tego pokazać na YoYo... Edit: Przykład sprawdzałem, ładuje się bez zająknięcia. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 w sumie to chyba tylko wina rysowania, no ale fpsy ciagle na maxa po zmianie mialem. mnie to tylko interesuje czy Ty ten kod gmla assemblerem wstrzykujesz do watku czy jak, bo nie moge zrozumiec jakim cudem to dziala - sam sie swojego czasu z tym bawilem. PS. fakt, do YYG nie startuj bo pociagna Cie po sadach - idioci zamiast doceniac wklad innych i pomoc w ulepszanie oraz poszerzanie mozliwosci gma, sami sobie utrudniaja zycie - chociaz w koncu kto by chcial by ingerowano w ich dzielo. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Kofel Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 PsihiX, to nie jest jedyny przypadek gdy firma ciągla ludzi po sądach za to że usprawniają prace ich dzieła, np. był przypadek z Creative jak ktoś napisał sterownik, to na oficjalnym forum odrazu usuneli temat, a autor miał problemy z prawem. Szara rzeczywistość. Co do pomysłu, ######ście ogólnie, nigdy nie wiedziałem o co chodzi tak dokładnie w wątkach, ale już kapuje. ;p BTW Snake wejdź na gadu? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Snake Opublikowano 2 Sierpnia 2008 Autor Udostępnij Opublikowano 2 Sierpnia 2008 mnie to tylko interesuje czy Ty ten kod gmla assemblerem wstrzykujesz do watku czy jak, bo nie moge zrozumiec jakim cudem to dziala Nieważne jak to zrobiłem - ważne że działa ;D Edit: Przykład sprawdzałem, ładuje się bez zająknięcia. w sumie to chyba tylko wina rysowania, no ale fpsy ciagle na maxa po zmianie mialem. To świetnie B) więc dzięki mojej bibliotece można znacznie lepiej zarządzać zasobami i nie tylko, w GM :) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Marek.S Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 fajniście to wyszło :D ni drgnięcia przy przeładowaniu Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Dawidds Opublikowano 2 Sierpnia 2008 Udostępnij Opublikowano 2 Sierpnia 2008 Nie no pięknie :D Ty.... zapomniałem dać 5 gwiazdek :P Wszyscy zapomnieli :P Edit: To można wykorzystać nie tylko do zasobów =D Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się