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.
This commit is contained in:
SilentSpike 2015-11-17 16:02:52 +00:00
parent 561f6126dc
commit a718c82780
4 changed files with 21 additions and 14 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;