Tablica symboli parsera, dynamiczne rzutowanie typów 9080 27

O temacie

Autor Demonical Monk

Zaczęty 29.12.2011 roku

Wyświetleń 9080

Odpowiedzi 27

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator
Aaa, rozumiałem że chodzi ci o dwa niezależne skrypty npc o tym samym instance :D
Kiedy npc'a nie ma przywołanego, jest traktowany jako martwy. Kiedy go przywołałem, jest traktowany jako żywy. Kiedy przywołałem drugie wystąpienie, nadal jest traktowany jako żywy. Kiedy jednego zabiłem, jest traktowany jako martwy. Kiedy w trakcie gdy jest martwy, przywołuję żywego, staje się traktowany jako żywy. To po prostu się nadpisuje, działa identycznie jak w przypadku podawania jako argumentu c_npc. To kombinowanie z indeksami symboli nie dotyczy tylko funkcji npc_isdead, podałem ją tylko jako przykład. Powinno dotyczyć każdej. Swoją drogą jestem ciekaw czy działa w drugą stronę, tzn co się stanie jeśli funkcji która wymaga podania indeksu (np hlp_getnpc) podać obiekt.

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator
Heh, w drugą stronę też działa :D
testowyenpec2 = hlp_getnpc(testowyenpec);
testowyenpec2 = hlp_getnpc(testowyenpec2);
print(testowyenpec2.name);
Nie wywala błędu, ładnie wyświetla prawidłowy wynik, mimo że tu jest sytuacja odwrotna niż w npc_isdead - prawidłowym argumentem jest int (indeks symbolu), a ja podaję odniesienie do obiektu (c_npc). Co ciekawe działa dopiero kiedy npc zostaje przyzwany do świata.

Zysk

Zysk

Użytkownicy
posty606
Propsy451
  • Użytkownicy
czyli pewnie jest tak, że nazwa instancji może być podana tylko jako:
1. argument funkcji ; jest wtedy interpretowana jako odpowiedni typ.
2. lewa strona wyrażenia instancja.pole ; ale to widziałem tylko dla c_info i nie wiem dokładnie jak to działa
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Nie wiem, o czym dyskutujecie :D  Czy instancja dowolnego NPC (np. NONE_100_Xardas) nie jest typu C_NPC?
Sprawdziłem i wychodzi na to że jest to po prostu "inteligentne" (cudzysłów celowy, na gg Monk już mnie poprawił że "dynamicznie rzutuje typy"). Działa zarówno:
if (Npc_IsDead(NONE_100_Xardas))(mimo że argumentem jest c_npc a nie int)
jak i prawidłowe:
var c_npc xardasek; xardasek = Hlp_GetNpc(NONE_100_Xardas);
if (Npc_IsDead(xardasek))
Jak dla mnie oba są prawidłowe. NONE_100_Xardas jest typu c_npc.

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator
Cały ten temat jest o tym, że identyfikatory są zawsze typu int (są indeksami tablicy symboli parsera), ale w pewnych warunkach (całkiem często) są automatycznie zamieniane na odniesienia do obiektów (Monk nazywa to dynamicznym rzutowaniem typów). Jak przed chwilą sprawdziłem, działa to także w drugą stronę.
Aby w skryptach otrzymać to samemu, trzeba użyć funkcji analogicznej do hlp_getnpc, która pobiera jako argument indeks symbolu, a zwraca odniesienie do obiektu.

Mżna to sprawdzić wykonując prościutki eksperyment, przez który przypadkiem kiedyś ten mechanizm zauważyłem:
print(IntToString(pc_hero));Wpisując tam dowolną instancję, za każdym razem zwróci liczbę, która mówi o tym jako który z kolei dany identyfikator został przeczytany przez parser (dotyczy nie tylko instancji, ale i zmiennych, stałych, tablic, klas, prototypów, funkcji i argumentów funkcji).



Cytuj
instancja dowolnego NPC (np. NONE_100_Xardas) nie jest typu C_NPC?
Najprościej udowodnić że tak nie jest, próbując przypisać ją do zmiennej o zadeklarowanym takim typie:
var c_npc enpec; enpec = NONE_100_Xardas;Wywali błąd. Za to:
var int indeks_symbolu; indeks_symbolu = NONE_100_Xardas;Już jak najbardziej zadziała, i jak przed chwilą napisałem, można nawet takie liczby spokojnie wyświetlać. A później możesz zrobić
var c_npc enpec; enpec = Hlp_GetNpc(indeks_symbolu);Co zwróci ci już odniesienie do obiektu c_npc.

Zysk

Zysk

Użytkownicy
posty606
Propsy451
  • Użytkownicy
Cały ten temat jest o tym, że identyfikatory są zawsze typu int (są indeksami tablicy symboli parsera), ale w pewnych warunkach (całkiem często) są automatycznie zamieniane na odniesienia do obiektów (Monk nazywa to dynamicznym rzutowaniem typów).
Nie dokładnie. Raczej identyfikatory są wewnętrznego typu instance, który się rzutuje na #msg1015359int#msg1015359 i jeśli jest przekazany do funkcji, jako argument typu c_npc, to jest rzutowany przez funkcję hlp_getnpc. Być może to działa też dla innych klas w jakiś niezupełnie jasny sposób.
 


Demonical Monk

Demonical Monk

Użytkownicy
posty145
Propsy152
  • Użytkownicy
Cały ten temat jest o tym, że identyfikatory są zawsze typu int (są indeksami tablicy symboli parsera), ale w pewnych warunkach (całkiem często) są automatycznie zamieniane na odniesienia do obiektów (Monk nazywa to dynamicznym rzutowaniem typów).
Nie dokładnie. Raczej identyfikatory są wewnętrznego typu instance, który się rzutuje na #msg1015378int#msg1015378 i jeśli jest przekazany do funkcji, jako argument typu c_npc, to jest rzutowany przez funkcję hlp_getnpc. Być może to działa też dla innych klas w jakiś niezupełnie jasny sposób.

Identyfikatory typu instance i pochodnych to tak naprawdę wskaźniki opakowane w symbol parsera. Przy wywołaniu funkcji te symbole lecą na stos, w trakcie zdejmowania można je po cichu zrzutować. Silnik udostępnia sporo przeładowanych wersji:
void GetParameter(int&) // jeśli symbol wskazuje na instancję to w praktyce zwróci ID tego symbolu
void GetParameter(float&)
void GetParameter(ZString&) // ficzer do łatwiejszej pracy na stringach
void* GetInstance() // wyciągamy obiekt wprost
Gdzie `void*` oznacza wskaźnik na dowolny typ. Od piszącego natywną funkcję zależy jak sobie obiekt wyciągnie. Dodatkowo, jeśli w DefineExternal zarejestruje jakiś argument funkcji jako przyjmujący ZEN_INSTANCE to ta funkcja w argumencie na etapie kompilacji łyknie wszystko. Wszelkie ewentualne rzutowania dokonują się gdy natywna część funkcji precyzuje w jaki sposób chce uzyskać dane.
 


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry