Działają odwrotnie do natywów. Funkcja natywna jest udostępniana innym pluginom. Forwardy to abstrakcyjne funkcje, które biblioteka próbuje wywołać. Wykonując forward dajemy sygnał, że nastąpiło jakieś zdarzenie i plugin może na nie zareagować. Można to lepiej zrozumieć biorąc pod uwagę forwardy samego AMXX, takie jak:
forward plugin_init(); forward client_putinserver(id);stąd powinieneś się domyślić je rozpowszechniać.
W pliku .inc podajemy nagłówek
forward nazwa(Float:para, met, ry[]);a w pliku .sma
public nazwa(Float:para, met, ry[]){ //nasz kod }Dalej tę funkcji publiczną nazywam 'funkcją oczekującą'.
O tym jak zaprojektować czytaj dalej ->
2. Tworzenie ↵
Po pierwsze musimy zarejestrować forward.
MultiForward ↵
Gdy użyjemy poniższej, oczekująca funkcja będzie wywoływana w każdym pluginie, który z niej korzysta.
/**
* Rejestruje forward dostępny dla wszystkich pluginów
*
* @param name[] Nazwa publicznej funkcji
* @param stop_type Typ zatrzymania
* @param ... Parametry
* @return Uchwyt (liczba całkowita)
*/
CreateMultiForward ( const name[], stop_type, ... )
Jako name[] podajemy nazwę, Typ zatrzymania określa sposób realizacji:
#define ET_IGNORE 0 //ignoruj zwracaną wartość #define ET_STOP 1 //zatrzymuje przy PLUGIN_HANDLED #define ET_STOP2 2 //to samo,tylko nie zwraca największej wartości #define ET_CONTINUE 3 //bez stopu, zwraca największą wartośćforward z typem ingore i continue będzie wywołany zawsze we wszystkich pluginach
opcje stopu (STOP i STOP2) zatrzymują rozsyłanie forwardu po otrzymaniu PLUGIN_HANDLED
Jeśli na tym skończymy to powstaje forward bez parametrów, jak:
//sma biblioteki
CreateMultiForward ( "nic_sie_nie_stalo", ET_IGNORE);
//w pliku .inc
forward nic_sie_nie_stalo();
Aby dodać jakieś argumenty trzeba rozwinąć rejestrowanie o dodatkowe wartości. Do określenia typu parametru służą stałe (nazwy są sugestywne)
#define FP_CELL 0 #define FP_FLOAT 1 #define FP_STRING 2 #define FP_ARRAY 4Dodanie argumentu forwardu polega na dopisniu jego typu po przecinku
//sma biblioteki
CreateMultiForward ( "nic_sie_nie_stalo", ET_IGNORE, FP_CELL, FP_FLOAT);
//w pliku .inc
forward nic_sie_nie_stalo(id, Float:fTime);
MultiForwardEx ↵
Jest to wersja kompatybilna z pluginami AMX. Nie będę się tym zajmował, szczegóły w pliku amxmodx.inc.
OneForward ↵
Druga możliwość to forward przeznaczony wyłącznie dla jednego pluginu.
/**
* Rejestruje forward dostępny dla pojedynczego pluginu
*
* @param plugin_id Id pluginu
* @param name[] Nazwa publicznej funkcji
* @param ... Parametry
* @return uchwyt (liczba całkowita)
*/
CreateOneForward ( plugin_id, const name[], ... )
Nie ma tu opcji stopu, bo tylko jeden, konkretny plugin może wykonać forward i zwróci on równie konkretną wartość.
plugin_id to id zwrócone przez funkcję
find_plugin_byfile(const pname[]);albo....
Ciekawym rozwiązaniem jest połączenie funkcji natywnej z forwardem w ten sposób. Wyobraźmy sobie rdzeń modu, który pozwala dodawać itemy w osobnych pluginach. Rdzeń ten udostępnia natywną funkcję
register_item( /*parametry*/), która zapisuje informacje i tworzy właśnie pojedynczy forward powiedzmy:
forward get_item(id)ten osobny plugin będzie czekał na sygnał, gdy gracz zdobędzie ten przedmiot. Wygodne prawda? Zwłaszcza, że id pluginu to jeden z parametrów funkcji obsługującej natyw.
Parametry jak przy MultiForward↵
3. Wywołanie ↵
Pora wysłać sygnał wywołania forwardu.
/**
* Wywołuje wskazany forward
*
* @param forward_handle Wartość zwrócona przez Create(One|Multi)Forward
* @param &ret Wartość zwrócona przez wywołane forwardy przekazana przez referencję
* @param ... Dokładnie tyle parametrów i takich typów jak podaliśmy przy tworzeniu
* Dane zostaną przekazane do funkcji oczekujących na forward
* @return 1 jeśli wywołano jakąś funkcję oczekującą, 0 jeśli nie
*/
ExecuteForward ( forward_handle, &ret, ... )
Przykład:
new gFW; public plugin_init(){ gFW = CreateMultiForward("jakies_zdarzenie", ET_CONTINUE, FP_FLOAT, FP_CELL, FP_STRING); } public plugin_cfg(){ new iRet; ExecuteForward(gFW, iRet, 3.14, -5, "Pi"); }Tak podane parametry są jak najbardziej w porządku. Inaczej ma się sprawa z type FP_ARRAY. Nie podajemy bezpośrednio tablicy, ale rezultat funkcji
/**
* Przygotowuje tablicę do przekazania do forwardu
*
* @param array[] Tablica wejściowa
* @param size Ilość komórek
* @param copyback Czy tablica zmieniona przez funkcje oczekującą ma wrócić
*/
PrepareArray(array[], size, copyback=0 )
Ostatni parametr jest dosyć ciekawy. Wynika z niego, że oprócz podania danych do forwardu możemy także z niego uzyskać. Ustawiając 0 mamy normalne przekazanie, podając 1 funkcje oczekujące będą pracować niejako na tej tablicy.
new gFW; public plugin_init(){ gFW = CreateMultiForward("jakies_zdarzenie", ET_CONTINUE, FP_CELL, FP_ARRAY); } public plugin_cfg(){ new data[2]; data[0] = 0; data[1] = 1; new iRet; ExecuteForward(gFW, iRet, 0, PrepareArray(data, 2, 1)); //data[0] == 0? możliwe, że już nie! }4. Przykłady ↵
w załączniku

plik udostępniający i korzystający z forwardu w jednym pliku odzielone kreskami
ex1 - tylko wywołanie
ex2 - z analizą z wyniku (istotne co funkcje oczekujące zwracają)
ex3 - przekazywanie tablicy
ex4 - przekazywanie tablicy i powrót wyniku
Załączone pliki
Użytkownik glut edytował ten post 25.02.2014 21:56
Mutli na Multi