Skocz do zawartości
Viral

YSI - Biblioteka y_timers

Rekomendowane odpowiedzi

y_timers

 

Przedstawienie

  y_timers jest jedną z bibliotek wchodzących w skład zbioru YSI, którego autorem jest y_less. Czy marzyłeś kiedyś o tym aby bez zbędnych ceregieli szybko tworzyć i wykonywać timery? - ta biblioteka jest dla Ciebie!

  y_timers umożliwiwa szybkie tworzenie tasków oraz timerów, a dodatkowo poprawia błąd przez który nie można przekazywać tablic w SetTimerEx!

 

Podstawowe użycie

   Dzięki tej bibliotece nasz dawny kod:

forward RepeatTimer();
public RepeatTimer()
{
    printf("Powtarzajacy sie timer co 1 sekunde.");
}

forward DelayTimer(playerid);
public DelayTimer(playerid)
{
    SendClientMessage(playerid, -1, "Wiadomosc wyslana po 1s.");
}

public OnGameModeInit()
{
    SetTimer("RepeatTimer", 1000, true);
    return 1;
}

public OnPlayerConnect(playerid)
{
    SetTimerEx("DelayTimer", 1000, false, "d", playerid);
    return 1;
}

   ...możemy zastąpić:

task RepeatTimer[1000]()
{
    print("Timer wykonuje sie co 1s.");
}

timer DelayTimer[1000](playerid)
{
    SendClientMessage(playerid, -1, "Wiadomosc wyslana po 1s.");
}

public OnPlayerConnect(playerid)
{
    defer DelayTimer(playerid);
    return 1;
}

Download

 

 

Taski

   y_timers dodaje możliwość tworzenia tasków, które są automatycznie uruchamiane OnGameModeInit lub OnFilterScriptInit. Istnieją ich dwa typy:

  • zwykły task - zwykły timer, który wykonuje się ciągle co jakiś konkretny okres czasu:
task RepeatTimer[5000]()
{
    print("Timer wykonuje sie co 5s.");
}
  • player task(ptask) - podobny do zwykłego task'a z tą różnicą, że automatycznie wykonywany jest dla każdego podłączonego gracza:
ptask PlayerRepeatTimer[2000](playerid)
{
    SendClientMessage(playerid, -1, "Wiadomosc co 2s dla kazdego gracza.");
}

   Ważne! Taski nie mogą przyjmować żadnych parametrów(z wyjątkiem ptask'a, który ma parametr "playerid"), ani nie mogę być używane razem z defer(nie mogą być wykonywane jak timer'y).

   Dodatkowo każdy task możesz również użyć jako zwykłą funkcję co nie przerwie jej ciągłego wykonywania:

task RepeatTimer[5000]()
{
    print("Timer wykonuje sie co 5s.");
}

public OnPlayerConnect(playerid)
{
    RepeatTimer(); // Funkcja będąca taskiem wykona się "asynchronicznie"
    return 1;
}

Timery

   Timery w tym przypadku są bardziej dynamiczne niż zwykłe SetTimer czy SetTimerEx, ponieważ możesz swobodnie zmieniać opóźnienie po jakim zostanie wywołana funkcja:

timer DelayTimer[500](playerid)
{
    printf("Timer wykonywany co 1s.");
}

public OnPlayerConnect(playerid)
{
    defer DelayTimer(playerid); // Timer wykona się po 500ms, tak jak zdefiniowany został czas domyślny
    defer DelayTimer[2000](playerid); // Timer wykona się po 2000ms
    return 1;
}

    Czas opóźnienia przy użyciu defer, może być zmienną lub wyrażeniem, które w wyniku daje liczbę:

timer DelayTimer[500](playerid)
{
    print("Timer wykonywany co jakiś tam czas.");
}

public OnPlayerConnect(playerid)
{
    new
        zmienna = 5000;
    defer DelayTimer[10*100](playerid); // 1000 ms => 1s
    defer DelayTimer[zmienna](playerid); // zmienna => 5000ms => 1s
    return 1;
}

Wywoływanie timerów

  • defer - wykonanie funkcji raz po określonym opóźnieniu:
defer DelayTimer(playerid);
  • repeat - powtarzanie wykonywania funkcji po określonym opóźnieniu(wykonywana jest co czas opóźnienia):
new
    Timer:a = repeat DelayTimer[1000](playerid); // DelayTimer wykona się po sekundzie i będzie powtarzać co 1s

stop a; // Aby zatrzymać timer
  • zwykłe - natychmiastowo wykonuje funkcje:
DelayTimer(playerid);

Przekazywanie tablicy jako parametru

   Jak wspomniałem na początku, y_timers naprawia błąd występujący w SetTimerEx, a przez który nie można przekazywać tablic i stringów.

   Aby przekazać tablice do timer'a, musimy:

timer ArrayTimer[500](arr[], len)
{
    printf("Array (%d): %d, %d, ...", len, arr[0], arr[1]);
}

   Gdzie pierwszym parametrem jest sama tablica, a drugi jest jej wielkość(sizeof).

   Natomiast jeśli chcemy przekazać string:

timer StringTimer[500](string:str[])
{
    printf("String: %s", str);
}

    Uwaga! Powyższy kod może powodować tag-mismatch, ale nie macie się nim co przejmować.

 

    Przykład użycia dwóch powyższych timerów:

public OnGameModeInit()
{
    new
        array[3] = {42, 43, 44};
    defer ArrayTimer(array, sizeof(array));
    defer StringTimer("Hi there");

    return 1;
}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

y_timers umożliwiwa szybkie tworzenie tasków oraz timerów, a dodatkowo poprawia błąd przez który nie można przekazywać tablic w SetTimerEx!

 

Y_Timers, naprawia bug w samp'ie, bo kiedy wpiszemy 1000 ms w zwykły timer, to czas różni się.

Korzystanie z tego wcale nie jest szybsze.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

@up jest wydajniejsze jeśli chodzi o taski. A to co napisałeś to nie bug, tylko po prostu problem z kolejkowaniem, który jako tako został rozwiązany w y_timers.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

e men bo nie czaje ok ?

 

 
if(Iter_Count(pWG) == MIN_PLAYERS_WG && !gTemp[WGStartuje])
{
   defer StartWG[20000]();
   
   return 1;
}
 
return 1;
}
 
defer StartWG[20000]()
{
 
return 1;
}

 

Chcę żeby wykonało mi to po 20 sek, a wyskakuja jakies errory z kosmosu xd

 

 

 
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(70) : error 017: undefined symbol "defer"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(70) : error 028: invalid subscript (not an array or too many subscripts): "StartWG"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(70) : warning 215: expression has no effect
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(70) : error 001: expected token: ";", but found "]"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(70) : fatal error 107: too many error messages on one line
 
Compilation aborted.Pawn compiler 3.2.3664     Copyright (c) 1997-2006, ITB CompuPhase
 
 
4 Errors.
 

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dałem tak i lipa, wszędzie errory.

 

 
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(79) : error 017: undefined symbol "defer"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(79) : error 017: undefined symbol "StartWG"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(88) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(91) : error 021: symbol already defined: "format"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(95) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(98) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(101) : error 021: symbol already defined: "mysql_fetch_row_format"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(103) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(110) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(113) : error 021: symbol already defined: "mysql_free_result"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(115) : error 021: symbol already defined: "format"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(119) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(127) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(133) : error 021: symbol already defined: "SetPlayerSkin"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(138) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(140) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(146) : error 021: symbol already defined: "SetPlayerSkin"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(151) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(155) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(157) : error 010: invalid function or declaration
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(367) : warning 203: symbol is never used: "TimerWG"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(367) : warning 203: symbol is never used: "pName"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(367) : warning 203: symbol is never used: "query"
C:\Documents and Settings\Lagowy\Pulpit\nowamapa_ext\mapa.pwn(367) : warning 203: symbol is never used: "wg_team"
Pawn compiler 3.2.3664     Copyright (c) 1997-2006, ITB CompuPhase
 
 
20 Errors.
 

 

 
#include <a_samp>
#include <zcmd>
#include <sscanf2>
#include <streamer>
#include <mysql>
#include <gvar>
#include <whirlpool>
#include <YSI/y_timers>
#include <YSI/y_iterate>
 

 

No przecież wszystko dobrze robię więc nie wiem o co cmon. 

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Tak też próbowałem, aż tak głupi nie jestem, ale dalej są te same errory.

Może ten Y_Timers ma błąd? Dałby ktoś mi link do zaktualizowanej paczki Y_Less'a ? No  i ten, gdybyś mógł usuń ten kod który dałem :P

 

// Poradziłem se. 

Edytowane przez Mlody954

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeszcze do niedawna korzystałem z timerów od y_ini + foreach wewnątrz takiego timera. Teraz postanowiłem wykorzystać funkcje y_timerów, która powoduje, że timer wykonuje się dla każdego gracza.

Przedtem:

timer CheckAfterTen[900000]()
{
    foreach(Player,i)
    {
    blablabla funkcje itp
    }
}

Natomiast teraz mam:

timer CheckAfterTen[900000](playerid)
{
   blablabla funkcje itp
}

Moje błache pytanko: czy muszę w tym drugim wypadku sprawdzać czy gracz jest podłączony do serwera czy same y_timery mają w sobie zawarte to działanie?

Edytowane przez TerminatorPL7

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Moje błache pytanko: czy muszę w tym drugim wypadku sprawdzać czy gracz jest podłączony do serwera czy same y_timery mają w sobie zawarte to działanie?

Powiem tak, patrząc po kodzie y_timers - nie ma tam zadnej funkcji sprawdzajacej czy gracz jest podlaczony, aczkolwiek osobiscie uzywam tej biblioteki od kilku miesiecy i jeszcze ani razu nie zastosowalem w niej funkcji sprawdzajacej czy gracz jest na serwerze (toteż podlaczony). Edytowane przez FJT

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Powiem tak, patrząc po kodzie y_timers - nie ma tam zadnej funkcji sprawdzajacej czy gracz jest podlaczony, aczkolwiek osobiscie uzywam tej biblioteki od kilku miesiecy i jeszcze ani razu nie zastosowalem w niej funkcji sprawdzajacej czy gracz jest na serwerze (toteż podlaczony).

Nie zaglądałem w kod, ale można się domyślać, że Y_Less użył tam foreach :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witam wszystkich, mam pytanie.

CMD:test1(playerid, params[])
{
timer(playerid);
return 1;
}

CMD:test2(playerid, params[])
{
SetTimerEx("timer",5000, 0, "d", playerid);
return 1;
}

forward timer(playerid);
public timer(playerid)
{
SendClientMessage(playerid, -1, "Wykonano.");
return 1;
}

W pierwszej komendzie wykonuję public od razu, a w drugiej po 5 sekundach, jak to przełożyć na bibliotekę y_timers?

Edytowane przez FoLeY-X

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witam wszystkich, mam pytanie.

CMD:test1(playerid, params[])
{
timer(playerid);
return 1;
}

CMD:test2(playerid, params[])
{
SetTimerEx("timer",5000, 0, "d", playerid);
return 1;
}

forward timer(playerid);
public timer(playerid)
{
SendClientMessage(playerid, -1, "Wykonano.");
return 1;
}

W pierwszej komendzie wykonuję public od razu, a w drugiej po 5 sekundach, jak to przełożyć na bibliotekę y_timers?

CMD:timet1(p,c[]) {
   defer timer_func(p, 1);
   return 1;
}

CMD:timer2(p,c[]) {
   defer timer_func(p, 5000);
   return 1;
}

timer timer_func[time](playerid, time) {
   #pragma unused time
   SendClientMessage(playerid, -1, "wykonano");
   return 1;
}

Nie zaglądałem w kod, ale można się domyślać, że Y_Less użył tam foreach :)

Ta, ale nigdze go nie uzywa. ;-) Edytowane przez FJT

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Przeglądający   0 użytkowników

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

×