Skocz do zawartości
  • Chmurka
  • Boróweczka
  • Jabłuszko
  • Limonka
  • Czekoladka
  • Węgielek

Polecane posty

DataPacki

Przeważnie podczas tworzenia funkcji definiujemy pożądaną liczbę parametrów, którą chcemy użyć. Przykład:

int Mnozenie(int a, int b) {
  return a * b;
}

///////////////

void JakasFunkcja() {
  PrintToChatAll("5x6 = %d", Mnozenie(5,6));
}

Aby zrobić tutaj użytek z funkcji Mnozenie() konieczne było przekazanie dwóch argumentów.

 

Niestety, w niektórych sytuacjach nie mamy komfortu przekazywania dowolnej ilości argumentów - jesteśmy ograniczeni tylko do...jednego!

Dotyczy to chociażby asynchronicznych zapytać SQL lub timerów. Przykład:

void JakasFunkcja(int client) {
  int a = 5;
  int b = 6;
  CreateTimer(10.0, PomnozCosPozniej, /*TUTAJ TYLKO JEDEN ARGUMENT!*/);
}

public Action PomnozCosPozniej(Handle timer, any data) {
  /// co tu zrobic ?! 
}

Gdybyśmy chcieli wykonać operację mnożenia w tym przypadku, niezbędne jest przekazanie dwóch zmiennych. Co robić w takiej sytuacji?

Z pomocą przychodzą nam DataPacki!
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!

Umożliwiają nam one "upakowanie" dowolnej liczby zmiennych o dowolnym typie do jednego ciągu danych. Cały proces zaczyna się od stworzenia uchwytu do DataPacka:

DataPack data = new DataPack();

jesteśmy gotowi do załadowania go danymi. Do tego celu wykorzystuje się kolejno WriteCell
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!, WriteFloat
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!, WriteFunction
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!, WriteString
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!

W naszym przykładzie poza dwiema zmiennymi przekażemy dodatkowo komunikat do wyświetlenia, aby pokazać jak posługiwać się ciągami znaków. Nasza funkcja będzie teraz wyglądać tak:

void JakasFunkcja(int client) {
  char helloString[128];
  Format(helloString, sizeof(helloString), "Siemanko %N!", client);
  DataPack data = new DataPack();
  data.WriteCell(5);
  data.WriteString(helloString);
  data.WriteCell(6);
  CreateTimer(10.0, PomnozCosPozniej, data);
}

Celowo umieściłem stringa pomiędzy dwiema liczbami, aby pokazać, że odczyt jest odrobinę bardziej skomplikowany niż zapis.

Po pierwsze, każdy DataPack posiada swój specjalny wskaźnik, który pokazuje w którym miejscu ma być przeprowadzany odczyt/zapis. Przeanalizujmy proces zapisu informacji w naszej funkcji JakasFunkcja(int client). Po stworzeniu DataPacka mamy pustą strukturę i wskaźnik znajdujący się na początku:

[|]
Znak '|' to właśnie nasz wskaźnik

Po wywołaniu żądania umieszczenia piątki, proces zaczął się w miejscu gdzie stał nasz wskaźnik - czyli na samym początku:

[5|]
Po dodaniu inta, wskaźnik przesunął się (troche jak wskaźnik podczas pisania na klawiaturze)

Kolejny w kolejce jest string:

[5string|]

I ostatnia już wartość - 6:

[5string6|]

W tym miejscu mamy już przygotowanego do wysyłki DataPacka. Zauważmy jednak, że nasz wskaźnik nie zmienił swojej pozycji - jest cały czas ustawiony na końcu struktury. Czy domyślacie się, jak wyglądałby odczyt tych danych? Bez przesunięcia wskaźnika na początek pliku ten proces jest niemożliwy...

Na szczęście, istnieje operacja, która może tego dokonać. Nazywa się ona Reset
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!:

// zauważmy, że drugi argument funkcji zmienił się na nasz DataPack :)
public Action PomnozCosPozniej(Handle timer, DataPack data) {
  data.Reset();
}

Od tego momentu struktura DataPacka wygląda tak:

[|5string6]

Oznacza to, że jesteśmy gotowi do odczytu 🙂

 

Istnieje jednak jeszcze jeden haczyk. Wspomniałem wcześniej, że dane w DataPacku przyjmują forme ciągu danych. Oznacza to, że SourceMod widzi je jako swoisty strumień. Właśnie do nas należy zadanie zapanowania nad tym haosem.

 

Do odczytywania danych stosujemy kolejno ReadCell
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!, ReadFloat
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!, ReadFunction
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami! i ReadString
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!.

 

W naszym DataPacku nie możemy zacząć wyciągania od np. stringa - wszystko musimy wykonywać w takiej samej kolejności, w jakiej wkładaliśmy dane! Na pierwszy ogień pójdzie więc 5, następnie komunikat, a na samym końcu - 6.

 

A więc pierwszą wartością jest int. Korzystamy z ReadCell
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami!:

// zauważmy, że drugi argument funkcji zmienił się na nasz DataPack :)
public Action PomnozCosPozniej(Handle timer, DataPack data) {
  data.Reset();
  int a = data.ReadCell();
}
// Aktualny stan DataPacka: [5|string6]

Przyszła pora na stringa. W naszym przypadku nasz łańcuch składa się z 128 znaków i dokładnie tyle zapisaliśmy w DataPacku! Pamiętajmy więc o przygotowaniu odpowiednio dużej tablicy:

char helloString[256]; // wielkość tablicy do której zapisujemy może się różnić - ważne, abyśmy pamiętali ile znaków zapisaliśmy WCZEŚNIEJ!
data.ReadString(helloString, sizeof(helloString));

 I na sam koniec ostatnia liczba:

int b = data.ReadCell();

 

Gotowe! Wszystkie dane zostały pobrane prawidłowo. Nasz efekt końcowy:

void JakasFunkcja(int client) {
  char helloString[128];
  Format(helloString, sizeof(helloString), "Siemanko %N!", client);
  DataPack data = new DataPack();
  data.WriteCell(5);
  data.WriteString(helloString);
  data.WriteCell(6);
  CreateTimer(10.0, PomnozCosPozniej, data);
}

public Action PomnozCosPozniej(Handle timer, DataPack data) {
  char helloString[256];
  data.Reset();
  int a = data.ReadCell();
  data.ReadString(helloString, sizeof(helloString));
  int b = data.ReadCell();
  PrintToChatAll("Komunikat: %s", helloString);
  PrintToChatAll("%d x %d = %d", a, b, a*b);
}
// stan DataPacka: [5string6|]

 

Oczywiście w razie pojawienia się pytań bądź wątpliwości zapraszam do dyskusji pod spodem 🙂

 

PS: suplementem do tego materiału jest napisany przez @Vasto_Lorde poradnik o timerach: 

 

  • Lubię to! 5
  • Dobry pomysł! 1
  • Kocham to! 2

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Bądź aktywny! Zaloguj się lub utwórz konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się

  • Kto przegląda   0 użytkowników

    Brak zalogowanych użytkowników przeglądających tę stronę.

×