SA-MP Forums Archive
Рекурсия в коде - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: Non-English (https://sampforum.blast.hk/forumdisplay.php?fid=9)
+--- Forum: Languages (https://sampforum.blast.hk/forumdisplay.php?fid=33)
+---- Forum: Русский/Russian (https://sampforum.blast.hk/forumdisplay.php?fid=32)
+---- Thread: Рекурсия в коде (/showthread.php?tid=579390)



Рекурсия в коде - Parlianment - 26.06.2015

Всех приветствую. Компилятор обнаружил рекурсию в коде, нужна помощь в исправлении.

PHP код:
    foreach(new xPlayer)
    {
        if(!
IsPlayerConnected(x)) continue;
        if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] == playerid)
        {
            
AdvanceSpectate(x);
        }
    } 


Полный код

PHP код:
stock StartSpectate(playeridspecid)
{
    
SetPVarInt(playerid,"PlayerSpec",1);
    if(
GetPlayerState(playerid) != PLAYER_STATE_SPECTATING)
    {
        
ShowMenuForPlayer(OdminMeny,playerid);
        
GetPlayerPos(playeridTeleportDest[playerid][0],TeleportDest[playerid][1],TeleportDest[playerid][2]);
        
TeleportDestNoFloat[playerid][0] = GetPlayerInterior(playerid);
        
TeleportDestNoFloat[playerid][1] = GetPlayerVirtualWorld(playerid);
    }
    foreach(new 
xPlayer)
    {
        if(!
IsPlayerConnected(x)) continue;
        if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] == playerid)
        {
            
AdvanceSpectate(x);
        }
    }
    if(
IsPlayerInAnyVehicle(specid))
    {
        
SetPlayerInterior(playerid,GetPlayerInterior(specid));
        
SetPlayerVirtualWorld(playeridGetPlayerVirtualWorld(specid));
        
TogglePlayerSpectating(playerid1);
        
PlayerSpectateVehicle(playeridGetPlayerVehicleID(specid));
        
gSpectateID[playerid] = specid;
        
gSpectateType[playerid] = ADMIN_SPEC_TYPE_VEHICLE;
    }
    else
    {
        
SetPlayerInterior(playerid,GetPlayerInterior(specid));
        
SetPlayerVirtualWorld(playeridGetPlayerVirtualWorld(specid));
        
TogglePlayerSpectating(playerid1);
        
PlayerSpectatePlayer(playeridspecid);
        
gSpectateID[playerid] = specid;
        
gSpectateType[playerid] = ADMIN_SPEC_TYPE_PLAYER;
    }
    
SpecAd[playerid] = specid;
    
SpecID[specid] = playerid;
    
PlayerTextDrawShow(playeridFULLRECON[playerid]);
    return 
true;




Re: Рекурсия в коде - James_Braga - 26.06.2015

playerid != x не?


Re: Рекурсия в коде - Parlianment - 26.06.2015

Quote:
Originally Posted by James_Braga
Посмотреть сообщение
playerid != x не?
Не, где-то тут, если закрыть в StartSpectate "AdvanceSpectate" - рекурсии нет так как Advance не вызывается.
А если раскоментировать Advance то рекурсия появится
PHP код:
stock AdvanceSpectate(playerid

    if(
ConnectedPlayers() == 2
    { 
        
StopSpectate(playerid); 
        return 
true
    } 
    if(
GetPlayerState(playerid) == PLAYER_STATE_SPECTATING && gSpectateID[playerid] != INVALID_PLAYER_ID
    { 
        for(new 
gSpectateID[playerid]+1<= MAX_PLAYERSx++) 
        { 
            if(
== MAX_PLAYERS
            { 
                
0
            } 
            if(
IsPlayerConnected(x) && != playerid
            { 
                if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] != INVALID_PLAYER_ID || 
                        (
GetPlayerState(x) != && GetPlayerState(x) != && GetPlayerState(x) != 3)) 
                { 
                    continue; 
                } 
                else 
                { 
                    
StartSpectate(playeridx); 
                    break; 
                } 
            } 
        } 
    } 
    return 
true




Re: Рекурсия в коде - po61 - 27.06.2015

Quote:
Originally Posted by Parlianment
Посмотреть сообщение
Не, где-то тут, если закрыть в StartSpectate "AdvanceSpectate" - рекурсии нет так как Advance не вызывается.
А если раскоментировать Advance то рекурсия появится
PHP код:
stock AdvanceSpectate(playerid

    if(
ConnectedPlayers() == 2
    { 
        
StopSpectate(playerid); 
        return 
true
    } 
    if(
GetPlayerState(playerid) == PLAYER_STATE_SPECTATING && gSpectateID[playerid] != INVALID_PLAYER_ID
    { 
        for(new 
gSpectateID[playerid]+1<= MAX_PLAYERSx++) 
        { 
            if(
== MAX_PLAYERS
            { 
                
0
            } 
            if(
IsPlayerConnected(x) && != playerid
            { 
                if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] != INVALID_PLAYER_ID || 
                        (
GetPlayerState(x) != && GetPlayerState(x) != && GetPlayerState(x) != 3)) 
                { 
                    continue; 
                } 
                else 
                { 
                    
StartSpectate(playeridx); 
                    break; 
                } 
            } 
        } 
    } 
    return 
true

естественно находит, внутри StartSpectate вызывается AdvanceSpectate. А в AdvanceSpectate при некоторых событиях вызывается StartSpectate. В итоге компилятор видит очевидную рекурсию. Рекомендации: переписать систему слежения за игроками или же забить (Я за первый вариант)