Skocz do zawartości

[KOSZ] [PAWN] Forwardy


Rekomendowane odpowiedzi

  • Właściciel
Opublikowano

Forwardy

1. Opis

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.

MutliForward

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        4

Dodanie 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 = CreateMutliForward("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 = CreateMutliForward("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

Autor: R3X | amxx.pl

  • 4 lata później...
  • Właściciel
Opublikowano

Wiadomość została wygenerowana automatycznie.

 

Ten temat został oznaczony przez Moderatora jako spam i wyrzucony do -> archiwum.

Jeśli się z tym nie zgadzasz, raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.

Gość
Ten temat został zamknięty. Brak możliwości dodania odpowiedzi.
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Polityka prywatności