-
Notifications
You must be signed in to change notification settings - Fork 740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add localUnits array and use that inside medical statemachines #4836
Conversation
I think this is a good idea, will really shine with high unit counts. Need to use retro init - Need to handle deleted units, |
A quick workaround against CBATeam/CBA_A3#567 would probably just be using pushBackUnique |
Adding at preInit or just using the config should work fine. |
@PabstMirror: deleted units should become objectNull, right? The state machine skips null elements. |
Think of something like ALIVE that does unit caching |
Then we should rather wait till 1.68 with this.
I do favor the preInit one if thats reliable enough. What do you think? |
Solution for deleted units is using the "deleted" event handler (requires 1.68) I think these two should cover these potential problems. |
Retro init is not needed if the "init" event handler is installed in preInit. (Which should be the way to go anyways). |
Since the state machine is filtering null objects anyway, I think we can just add the "deleted" event handler and play the waiting game with the Arma update. CBA will update soon, hopefully. |
It's failing when deleting via zeus
So it takes 2+ frames for it to actually be deleted? |
🤕 I hate Arma. I guess easiest solution might just be having a PFH in Draw3D that does |
In the end.. Can't we just make a getLocalUnits function. Then we should also remove the deleted EH as it only creates problems. Btw I figured out why Zeus deletion takes 2 frames. deleting a vehicle schedules it's deletion. And it get's really deleted in next simulation. so call deleteVehicle from scheduled or PFH. After that simulation runs and deletes vehicle. Next frame in PFH we check if it was deleted and it was. Zeus seems to schedule deletion in simulation or UI cycle. Normal deleteVehicle looks like |
params ["_unit"]; | ||
TRACE_3("unit deleted nextFrame",_unit,local _unit,isNull _unit); | ||
if (isNull _unit) then { //If it is not null then the deleted EH was Fake. | ||
GVAR(localUnits) = GVAR(localUnits) - [objNull]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I delete all objNull here as using find
to find a null object will find the first null object and not the one the deleted EH belongs to anyway.
I would prefer to just call FUNC(getLocalUnits)
here in case we add a check to getLocalUnits so it only removes null objects once per frame.
But it would hurt readability.
*/ | ||
|
||
//Remove null objects | ||
GVAR(localUnits) = GVAR(localUnits) - [objNull]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can check diag_frameNo against a global variable so we only remove null objects once a frame to get us a little more perf.
But I'm not sure if GVAR(localUnits) = GVAR(localUnits) - [objNull];
is really that expensive that it's worth it. Needs profiling with atleast a hundred local units.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually we only need to run this if there was a deletedEH in the last 2-3 frames. But I don't think it hurts.
Considering this will already be about a 100x improvement vs iterating through allUnits everytime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also to checking diag_frameNo
objects are deleted in simulation cycle. Draw3D runs after that in the same frame. So that could cause Draw3D to still get null objects.
}; | ||
}] call CBA_fnc_addClassEventHandler; | ||
|
||
["CAManBase", "respawn", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't "init" also fire for respawning units?
But I guess they might be !alive at init?
Respawning in MP should be tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Init does not fire for respawned objects.
What's currently the problem? Besides merge conflict. As vehicles are deleted in SIM cycle this means after using Draw3D it's "impossible" to get null objects into the localUnits array. Because we clean up right after they get deleted. |
What about the issues we talked about? |
I tested on a dedicated server and it and The addition of |
this should also work |
* Added localUnits EH Code by @commy2 * Init localUnits Variable * use localUnits for medical_blood statemachine * use localUnits for medical_ai statemachine * Remove bracket hell * Add Deleted EH * Run at preInit, move to seperate file * Handle Respawns, Filter Dead * Add detection for Fake deleted EH * Use a getter function * delete all objNull at deletedEH * Cleanup header/comments * Move isBleeding check to inside statemachine * opps * debug off
This will add an array of localUnits which is kept up-to-date by Eventhandlers and remove the need to dynamically create that list every few frames inside the medical state machines.
The EH has about a performance penalty of 0.015ms per spawned unit.
Currently the Statemachines inside medical_ai and medical_blood create this array of local Units dynamically each time they refresh their list (https://github.com/CBATeam/CBA_A3/blob/master/addons/statemachine/fnc_clockwork.sqf#L37)
by using
allUnits select {local _x}
which has about a 0.24ms impact.This is basically moving the performance impact from a PFH thats executed every few frames to an Eventhandler and also reducing the performance cost in the meantime.
I didn't test this yet but i don't know what could go wrong. Besides the "local" EH misbehaving.
Currently the Statemachine clockwork for the 2 medical Statemachines is with 1.2ms the longest executing PFH when on a server with exactly 100 non-local AI's.
diag_captureFrame:
And because 0 of these AI's are local and the Statemachine will recreate the unit list when it iterated through it fully. It will recreate it every frame.
For both Statemachines thats about 0.48ms per frame just for recreating that list over and over again.
This PR should cut down on the bulk of that.
This would essentially be replaced by BI adding a localUnits script function. Which i would hope they would do but.. They probably won't.