Teraz jest Cz 28 mar, 2024 15:49


[rozwiązane] lokalność zmiennych w skrypcie

Archiwum działów sekcji Armed Assault
  • Autor
  • Wiadomość
Offline
Avatar użytkownika

kondor

Major

Major

  • Posty: 880
  • Dołączył(a): Pt 11 lut, 2005 04:00
  • Lokalizacja: Berlin (wschodni)

[rozwiązane] lokalność zmiennych w skrypcie

PostSo 07 lut, 2009 20:57

Witam,
w pewnej misji w różnych skryptach często używam m.in. zmiennej lokalnej _side, która w różnych skryptach (wykonywanych niekiedy równolegle) ma różne zastosowanie.
Kod: Zaznacz cały
...
_side = _this select 1;
...
if( _side != (_this select 1) )then
{
  hint "uuuuu! zmienna _side zmienila swoja wartosc!";
};

Po testach okazało się, że _side zmienia swoją wartość gdzieś na zewnątrz i psuje mi powyższy skrypt
Do tej pory wydawało mi się, że zmienne z prefiksem "_" są lokalne tylko w skrypcie i nie są dzielone między różne skrypty.
Próbowałem "sprywatyzować" zmienną:
Kod: Zaznacz cały
private "_side";

przed jej pierwszym wywołaniem, lecz nic to nie zmieniło.
Pomogła dopiero zmiana nazwy na unikalną. Jednak jest to rozwiązanie conajmniej brzydkie (i wymaga sprawdzania czy takiej zmiennej już nie było).
1. Czy ktoś zna sposób jak zapobiec współdzieleniu takiej zmiennej?
2. Czy nie temu właśnie służy komenda "private"?

z góry dzięki za odpowiedź
Ostatnio edytowano Pn 09 lut, 2009 10:48 przez kondor, łącznie edytowano 1 raz
Offline
Avatar użytkownika

Kadryl

Major

Major

  • Posty: 883
  • Dołączył(a): Cz 14 wrz, 2006 14:04
  • Lokalizacja: Wa-wa

PostSo 07 lut, 2009 21:51

Mialem podobny problem, w skrypcie wywołanie funkcji zmienilo mi wartośc lokalną chociaż w żaden sposób nie były ze soba powiązane (nawet wykonana funkcja nie bazowała na podobnej nazwie). Niestety nie widze realnego sposobu zaradzenia temu - komenda "private" służy do definowania zmiennych lokalnych w plikach sqf. - sądze, że trzeba zachować czujność. Problem - procedurę zmieniającą wartosć lokalną - można wyłapać stosując przed :
Kod: Zaznacz cały
player globalchat format ["%1", _zmienna]
i za
Kod: Zaznacz cały
player sidechat format ["%1", _zmienna]
oraz dalej zastosować patent ponownego przypisania wartości zmiennej np.
Kod: Zaznacz cały
_fix = _zmienna
problem
_zmienna = _fix


Co do źródła błędu znalazłem że wymiana informacji w programie zależna jest od "szerokości przekazywanego kodu" przykładowo chcemy przekazać liczbę o wartości 2^0+2^1+2^2 ....2^n, z powodu ograniczenia pamięci wielkość pasma nie będzie większa niż 2^(n-1). tak więc liczba przesłana będzie zmniejszona o pierwsza pozycję czyli bez 2^0. Przy małych wartościach są to wartości dziesiętne, pomijalne. Przy dużych (ponad milion) może wartość róznić się znacznie - liczbą calkowitą.

P.s. lepiej stonić od nazywania zmiennej lokalnej podobnie jak nazwy stałe, przypisanym działaniem jak np. "side"
Offline
Avatar użytkownika

kondor

Major

Major

  • Posty: 880
  • Dołączył(a): Pt 11 lut, 2005 04:00
  • Lokalizacja: Berlin (wschodni)

PostPn 09 lut, 2009 10:47

mój skrypt dokładniej wyglądał tak:
Kod: Zaznacz cały
...
_side = _this select 1;
...
_prevSide = call compile preprocess "get_flag_side.sqf";
...
if( _side != (_this select 1) )then
{
  hint "uuuuu! zmienna _side zmienila swoja wartosc!";
};

a w "get_flag_side.sqf" nadpisywałem zmienną lokalną _side (w skrypty potomne dziedziczą zmienne lokalne ojca - co np w języku C/Java nie zachodzi) :
biwiki:Local variables napisał(a):Local variables are only visible in a specific script. The whole code in this script has access to the variable, that includes also functions called within the script.

Imho najlepszym rozwiązaniem jest ograniczenie zasięgu zmiennej lokalnej tylko do bieżącego skryptu poprzez komendę private w skrypcie potomnym
Offline
Avatar użytkownika

Kadryl

Major

Major

  • Posty: 883
  • Dołączył(a): Cz 14 wrz, 2006 14:04
  • Lokalizacja: Wa-wa

PostPn 09 lut, 2009 12:18

A czy komenda "private" dotyczy lokalności zmiennej w ramach danego skryptu czy też lokalności zmiennej w ramach danego komputera ?
Offline
Avatar użytkownika

kondor

Major

Major

  • Posty: 880
  • Dołączył(a): Pt 11 lut, 2005 04:00
  • Lokalizacja: Berlin (wschodni)

PostPn 09 lut, 2009 12:28

Sets a variable to the innermost scope.

W najmniejszym zasięgu w jakim została poddana tej komendzie. Czyli jeśli na początku skryptu to w tym skrypcie, jeśli np w bloku:
Kod: Zaznacz cały
_zmienna = 1;
if( true )then
{
  private "_zmienna";
  _zmienna = 2;
};
hint format["%1", _zmienna];

to uczyni ją lokalną tylko dla tego bloku, a hint wyświetli 1

lokalna zmienna w ramach danego komputera to zmienna globalna
Offline
Avatar użytkownika

Kadryl

Major

Major

  • Posty: 883
  • Dołączył(a): Cz 14 wrz, 2006 14:04
  • Lokalizacja: Wa-wa

PostPn 09 lut, 2009 17:57

Masz rację.
Ale rzecz w tym że polecenie private ["'] można zastosować tylko w plikach rezydujących w pamięci, czyli sqf. Także w tym konkretnym przypadku, kiedy w skrypcie sqs i funkcji sqf użyłes tej samej zmiennej lokalnej rozwiązanie jest prawidłowe.
lokalna zmienna w ramach danego komputera to zmienna globalna
z tym raczej się nie zgodzę wystarczy sprawdzić wywołanie pliku 2.sqs przez inny plik 1.sqs.
1.sqs
Kod: Zaznacz cały
_zmienna = 1
[] exec "2.sqs"
~10
player globalchat format ["%1", _zmienna]
exit

2.sqs
Kod: Zaznacz cały
_zmienna = 2
exit

wynik na ekranie to 1.
ale oczywiście odbiegam od problemu. Jeszcze raz przyznaje racje.
Offline
Avatar użytkownika

kondor

Major

Major

  • Posty: 880
  • Dołączył(a): Pt 11 lut, 2005 04:00
  • Lokalizacja: Berlin (wschodni)

PostPn 09 lut, 2009 18:22

Kadryl napisał(a):Cytat:
lokalna zmienna w ramach danego komputera to zmienna globalna

z tym raczej się nie zgodzę wystarczy sprawdzić wywołanie pliku 2.sqs przez inny plik 1.sqs.


pisząc "lokalna zmienna w ramach danego komputera" miałem na myśli, że jest dostępna w każdym miejscu na komputerze (bo taka jest definicja lokalności - w skrócie - zmienna jest lokalna w danym miejscu jeśli jest dostępna w tym miejscu) i wg tej definicji zmienna globalna jest zmienną lokalną w każdym miejscu na danym komputerze. A nie miałem na myśli zmiennej lokalnej skryptu (_zmienna).
Kontynuując, zmienna globalna (na danym komputerze) jest nielokalna (jest niedostępna) na innych komputerach, bo nie istnieje coś takiego jak zmienna publiczna. Dlatego nie ma sensu robić zmiennej jako prywatnej dla całego komputera.
Mam nadzieję, że jasno to napisałem

Powrót do Armed Assault

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 11 gości

cron