From f3c5c64390b83b2259084752a305a90304443813 Mon Sep 17 00:00:00 2001 From: jokoho48 Date: Tue, 17 Nov 2015 04:31:17 +0100 Subject: [PATCH 1/4] fix Issue with forEach Loops and deleteAt Index --- .../functions/fnc_handleFirePFH.sqf | 20 +++++++++---------- addons/common/XEH_postInit.sqf | 11 +++++----- .../functions/fnc_setVariablePublic.sqf | 11 ++++------ .../functions/fnc_updateTrajectoryPFH.sqf | 7 +++---- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index 7a432831ad0..5874de96c48 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -26,19 +26,19 @@ _aceTimeSecond = floor ACE_time; _bulletSpeed = vectorMagnitude _bulletVelocity; - if (!alive _bullet || _bulletSpeed < 100) exitWith { - GVAR(allBullets) deleteAt (_forEachIndex - _deleted); - _deleted = _deleted + 1; - }; + if (!alive _bullet || _bulletSpeed < 100) then { + GVAR(allBullets) deleteAt (GVAR(allBullets) find _x); + } else { + _bulletPosition = getPosASL _bullet; - _bulletPosition = getPosASL _bullet; + if (_bulletTraceVisible && _bulletSpeed > 500) then { + drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""]; + }; - if (_bulletTraceVisible && _bulletSpeed > 500) then { - drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""]; + call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, ACE_time - _aceTimeSecond]); }; - - call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, ACE_time - _aceTimeSecond]); -} forEach GVAR(allBullets); + nil +} count +GVAR(allBullets); if (GVAR(allBullets) isEqualTo []) then { [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 032b6148bee..be975e93784 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -8,7 +8,7 @@ ////////////////////////////////////////////////// //Singe PFEH to handle execNextFrame, waitAndExec and waitUntilAndExec: -[{ +{ BEGIN_COUNTER(waitAndExec); //Handle the waitAndExec array: @@ -29,17 +29,16 @@ GVAR(nextFrameNo) = diag_frameno + 1; //Handle the waitUntilAndExec array: - local _deleted = 0; { // if condition is satisifed call statement if ((_x select 2) call (_x select 0)) then { // make sure to delete the correct handle when multiple conditions are met in one frame - GVAR(waitUntilAndExecArray) deleteAt (_forEachIndex - _deleted); - _deleted = _deleted + 1; + GVAR(waitUntilAndExecArray) deleteAt (GVAR(waitUntilAndExecArray) find _x); (_x select 2) call (_x select 1); }; - } forEach GVAR(waitUntilAndExecArray); - + nil + } count +GVAR(waitUntilAndExecArray); + END_COUNTER(waitAndExec); }, 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/common/functions/fnc_setVariablePublic.sqf b/addons/common/functions/fnc_setVariablePublic.sqf index 67dbd5fd2f8..8dbaeffbd60 100644 --- a/addons/common/functions/fnc_setVariablePublic.sqf +++ b/addons/common/functions/fnc_setVariablePublic.sqf @@ -38,19 +38,16 @@ GVAR(setVariablePublicArray) pushBack [_object, _varName, _syncTime, _idName]; if (isNil QGVAR(setVariablePublicPFH)) exitWith {}; GVAR(setVariablePublicPFH) = [{ - private "_delete"; - _delete = 0; - { _x params ["_object", "_varName", "_syncTime", "_idName"]; if (ACE_diagTime > _syncTime) then { // set value public _object setVariable [_varName, _object getVariable _varName, true]; - GVAR(setVariablePublicArray) deleteAt _forEachIndex - _delete; - GVAR(setVariableNames) deleteAt _forEachIndex - _delete; - _delete = _delete + 1; + GVAR(setVariablePublicArray) deleteAt (GVAR(setVariablePublicArray) find _x); + GVAR(setVariableNames) deleteAt (GVAR(setVariableNames) find _x); }; - } forEach GVAR(setVariablePublicArray); + nil + } count +GVAR(setVariablePublicArray); if (GVAR(setVariablePublicArray) isEqualTo []) then { [GVAR(setVariablePublicPFH)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf index baff39516d5..393a5cd7579 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -34,8 +34,7 @@ _bulletSpeed = vectorMagnitude _bulletVelocity; if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeed < 100}}) then { - GVAR(trackedBullets) deleteAt (_forEachIndex - _deleted); - _deleted = _deleted + 1; + GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); } else { if (_isWind) then { _trueVelocity = _bulletVelocity vectorDiff ACE_wind; @@ -51,7 +50,7 @@ }; _bullet setVelocity _bulletVelocity; }; - - } forEach GVAR(trackedBullets); + nil + } count +GVAR(trackedBullets); // END_COUNTER(pfeh); }, GVAR(simulationInterval), [ACE_time]] call CBA_fnc_addPerFrameHandler; From 561f6126dcf4318afc7d4804163c0c1f899131c5 Mon Sep 17 00:00:00 2001 From: jokoho48 Date: Tue, 17 Nov 2015 13:34:34 +0100 Subject: [PATCH 2/4] fix missing bracket --- addons/common/XEH_postInit.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index be975e93784..069105418ce 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -8,7 +8,7 @@ ////////////////////////////////////////////////// //Singe PFEH to handle execNextFrame, waitAndExec and waitUntilAndExec: -{ +[{ BEGIN_COUNTER(waitAndExec); //Handle the waitAndExec array: From a718c827807f470f4fe840fd609a5e516bd1f302 Mon Sep 17 00:00:00 2001 From: SilentSpike Date: Tue, 17 Nov 2015 16:02:52 +0000 Subject: [PATCH 3/4] Implement nice index deletion iteration solution Previously when iterating over an array and modifying the same array via deletion of the current index, incorrect means was used to account for the change in index resulting in any further deletions being applied to the wrong elements. This solution does not require duplication of the array or the use of external variables to track the number of deleted elements. We simply lower the `_forEachIndex` by 1 whenever an element is removed. --- .../functions/fnc_handleFirePFH.sqf | 8 +++++--- addons/common/XEH_postInit.sqf | 9 +++++---- addons/common/functions/fnc_setVariablePublic.sqf | 10 ++++++---- .../functions/fnc_updateTrajectoryPFH.sqf | 8 +++++--- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index 5874de96c48..63d5cc106f3 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -27,7 +27,10 @@ _aceTimeSecond = floor ACE_time; _bulletSpeed = vectorMagnitude _bulletVelocity; if (!alive _bullet || _bulletSpeed < 100) then { - GVAR(allBullets) deleteAt (GVAR(allBullets) find _x); + GVAR(allBullets) deleteAt _forEachIndex; + + // An index was removed, remember to account for it + _forEachIndex = _forEachIndex - 1; } else { _bulletPosition = getPosASL _bullet; @@ -37,8 +40,7 @@ _aceTimeSecond = floor ACE_time; call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, ACE_time - _aceTimeSecond]); }; - nil -} count +GVAR(allBullets); +} forEach GVAR(allBullets); if (GVAR(allBullets) isEqualTo []) then { [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 069105418ce..e17e04f40b3 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -32,12 +32,13 @@ { // if condition is satisifed call statement if ((_x select 2) call (_x select 0)) then { - // make sure to delete the correct handle when multiple conditions are met in one frame - GVAR(waitUntilAndExecArray) deleteAt (GVAR(waitUntilAndExecArray) find _x); + GVAR(waitUntilAndExecArray) deleteAt _forEachIndex; (_x select 2) call (_x select 1); + + // An index was removed, remember to account for it + _forEachIndex = _forEachIndex - 1; }; - nil - } count +GVAR(waitUntilAndExecArray); + } forEach GVAR(waitUntilAndExecArray); END_COUNTER(waitAndExec); }, 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/common/functions/fnc_setVariablePublic.sqf b/addons/common/functions/fnc_setVariablePublic.sqf index 8dbaeffbd60..e74bf6d3139 100644 --- a/addons/common/functions/fnc_setVariablePublic.sqf +++ b/addons/common/functions/fnc_setVariablePublic.sqf @@ -43,11 +43,13 @@ GVAR(setVariablePublicPFH) = [{ if (ACE_diagTime > _syncTime) then { // set value public _object setVariable [_varName, _object getVariable _varName, true]; - GVAR(setVariablePublicArray) deleteAt (GVAR(setVariablePublicArray) find _x); - GVAR(setVariableNames) deleteAt (GVAR(setVariableNames) find _x); + GVAR(setVariablePublicArray) deleteAt _forEachIndex; + GVAR(setVariableNames) deleteAt _forEachIndex; + + // An index was removed, remember to account for it + _forEachIndex = _forEachIndex - 1; }; - nil - } count +GVAR(setVariablePublicArray); + } forEach GVAR(setVariablePublicArray); if (GVAR(setVariablePublicArray) isEqualTo []) then { [GVAR(setVariablePublicPFH)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf index 393a5cd7579..d032ce5bca5 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -34,7 +34,10 @@ _bulletSpeed = vectorMagnitude _bulletVelocity; if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeed < 100}}) then { - GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); + GVAR(trackedBullets) deleteAt _forEachIndex; + + // An index was removed, remember to account for it + _forEachIndex = _forEachIndex - 1; } else { if (_isWind) then { _trueVelocity = _bulletVelocity vectorDiff ACE_wind; @@ -50,7 +53,6 @@ }; _bullet setVelocity _bulletVelocity; }; - nil - } count +GVAR(trackedBullets); + } forEach GVAR(trackedBullets); // END_COUNTER(pfeh); }, GVAR(simulationInterval), [ACE_time]] call CBA_fnc_addPerFrameHandler; From 49d4f233d974fd5cc394415b18878ae50963fc98 Mon Sep 17 00:00:00 2001 From: SilentSpike Date: Wed, 18 Nov 2015 13:10:01 +0000 Subject: [PATCH 4/4] Revert commit a718c827807f470f4fe840fd609a5e516bd1f302 --- .../functions/fnc_handleFirePFH.sqf | 8 +++----- addons/common/XEH_postInit.sqf | 9 ++++----- addons/common/functions/fnc_setVariablePublic.sqf | 10 ++++------ .../functions/fnc_updateTrajectoryPFH.sqf | 8 +++----- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index 63d5cc106f3..5874de96c48 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -27,10 +27,7 @@ _aceTimeSecond = floor ACE_time; _bulletSpeed = vectorMagnitude _bulletVelocity; if (!alive _bullet || _bulletSpeed < 100) then { - GVAR(allBullets) deleteAt _forEachIndex; - - // An index was removed, remember to account for it - _forEachIndex = _forEachIndex - 1; + GVAR(allBullets) deleteAt (GVAR(allBullets) find _x); } else { _bulletPosition = getPosASL _bullet; @@ -40,7 +37,8 @@ _aceTimeSecond = floor ACE_time; call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, ACE_time - _aceTimeSecond]); }; -} forEach GVAR(allBullets); + nil +} count +GVAR(allBullets); if (GVAR(allBullets) isEqualTo []) then { [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index e17e04f40b3..069105418ce 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -32,13 +32,12 @@ { // if condition is satisifed call statement if ((_x select 2) call (_x select 0)) then { - GVAR(waitUntilAndExecArray) deleteAt _forEachIndex; + // make sure to delete the correct handle when multiple conditions are met in one frame + GVAR(waitUntilAndExecArray) deleteAt (GVAR(waitUntilAndExecArray) find _x); (_x select 2) call (_x select 1); - - // An index was removed, remember to account for it - _forEachIndex = _forEachIndex - 1; }; - } forEach GVAR(waitUntilAndExecArray); + nil + } count +GVAR(waitUntilAndExecArray); END_COUNTER(waitAndExec); }, 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/common/functions/fnc_setVariablePublic.sqf b/addons/common/functions/fnc_setVariablePublic.sqf index e74bf6d3139..8dbaeffbd60 100644 --- a/addons/common/functions/fnc_setVariablePublic.sqf +++ b/addons/common/functions/fnc_setVariablePublic.sqf @@ -43,13 +43,11 @@ GVAR(setVariablePublicPFH) = [{ if (ACE_diagTime > _syncTime) then { // set value public _object setVariable [_varName, _object getVariable _varName, true]; - GVAR(setVariablePublicArray) deleteAt _forEachIndex; - GVAR(setVariableNames) deleteAt _forEachIndex; - - // An index was removed, remember to account for it - _forEachIndex = _forEachIndex - 1; + GVAR(setVariablePublicArray) deleteAt (GVAR(setVariablePublicArray) find _x); + GVAR(setVariableNames) deleteAt (GVAR(setVariableNames) find _x); }; - } forEach GVAR(setVariablePublicArray); + nil + } count +GVAR(setVariablePublicArray); if (GVAR(setVariablePublicArray) isEqualTo []) then { [GVAR(setVariablePublicPFH)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf index d032ce5bca5..393a5cd7579 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -34,10 +34,7 @@ _bulletSpeed = vectorMagnitude _bulletVelocity; if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeed < 100}}) then { - GVAR(trackedBullets) deleteAt _forEachIndex; - - // An index was removed, remember to account for it - _forEachIndex = _forEachIndex - 1; + GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); } else { if (_isWind) then { _trueVelocity = _bulletVelocity vectorDiff ACE_wind; @@ -53,6 +50,7 @@ }; _bullet setVelocity _bulletVelocity; }; - } forEach GVAR(trackedBullets); + nil + } count +GVAR(trackedBullets); // END_COUNTER(pfeh); }, GVAR(simulationInterval), [ACE_time]] call CBA_fnc_addPerFrameHandler;