Skip to content
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

don't skip next PFH if current one is removed while iterating through #950

Merged
merged 3 commits into from Jul 23, 2018

Conversation

commy2
Copy link
Contributor

@commy2 commy2 commented Jul 3, 2018

When merged this pull request will:

Needs testing, I won't have access to Arma this and the next week.

@commy2 commy2 added the Bug Fix label Jul 3, 2018
@commy2 commy2 added this to the 3.8 milestone Jul 3, 2018
@commy2
Copy link
Contributor Author

commy2 commented Jul 3, 2018

Q: What happens if the removePFH function is called twice with the same handle in the same frame (deleting already removed PFH waiting to be cleaned up NextFrame)?

Copy link
Contributor

@dedmen dedmen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code wise looks good. Didn't test tho ._.

@@ -29,13 +29,19 @@ if (_handle < 0 || {_handle >= count GVAR(PFHhandles)}) exitWith {};
[{
params ["_handle"];

GVAR(perFrameHandlerArray) deleteAt (GVAR(PFHhandles) select _handle);
GVAR(PFHhandles) set [_handle, nil];
GVAR(perFrameHandlerArray) set [GVAR(PFHhandles) select _handle select 0, {}];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fun fact. call doesn't exit early if it has no code. It will actually really build a callstack and everything required. And then execute the empty code and exit right after.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't have implemented it any other way tbh. For simplicity.

GVAR(PFHhandles) set [_handle, nil];

{
_x params ["", "", "", "", "", "_handle"];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reusing _handle here looks confusing to some people. But these people don't look at CBA code anyway.

(I pressed send review and wanted to submit the comment after that.. But who could've guessed that the comment is discarded when you submit the review.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just indented the previous code. The function is simple enough I'd say.

@kymckay
Copy link
Contributor

kymckay commented Jul 3, 2018

I like the elegance, though running through it in my head I'm also not sure this isn't still broken as per commy's comment above.

The way it is currently, I believe that if the function is called n times in the same frame for the same handler, the next n - 1 handlers would also be deleted.

My first thought:
You'd need to add a sanity check for whether the GVAR(PFHhandles) value is already nil (meaning the handle has already been deleted that frame). However, this would only work assuming the handle index hasn't been refilled by another call to addPerFrameHandler between the duplicated execNextFrame calls (unsure if this can happen, I'll assume it probably can).

My next thought:
It'd be a hell of a lot simpler and actually foolproof to just check if the code is already {} in the scope above before the execNextFrame is even added.

@jokoho48
Copy link
Member

jokoho48 commented Jul 3, 2018

I like the base idea over what I have done before. but what I dislike is that you run over every PFH Multiple times when more than 1 PFH got remove per frame. so you would have both systems combined in a way.
so what I would do is still save the deletedIndices and only add 1 execNextFrame and use the removing Method I implemented just in the execNextFrame and checking if a remove already happened

@commy2
Copy link
Contributor Author

commy2 commented Jul 4, 2018

@SilentSpike Can you think of a way to potential bring this issue about? Reading the code again after sleep, everything looks fine, even if the same ID is removed twice.
@jokoho48

but what I dislike is that you run over every PFH Multiple times when more than 1 PFH got remove per frame.

This almost never happens though. Removing multiple PFH in the same frame.

@dedmen
Copy link
Contributor

dedmen commented Jul 4, 2018

but what I dislike is that you run over every PFH Multiple times when more than 1 PFH got remove per frame.

I still prefer that over the alternative of executing some code every Frame even if it's not needed 99% of the time.

@jokoho48
Copy link
Member

jokoho48 commented Jul 4, 2018

This almost never happens though. Removing multiple PFH in the same frame.

it does that is why I bringing this up. and also the check happens I frame After the PFH is removed

I still prefer that over the alternative of executing some code every Frame even if it's not needed 99% of the time.

then you don't read my post correctly. I sad this is a better solution but I think that it could be more optimized. in the way that we could combine both ideas and use the execNextFrame for the base removal but still save the indices that are deleted

[{
params ["_handle"];

GVAR(perFrameHandlerArray) deleteAt (GVAR(PFHhandles) select _handle);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@commy2 Yeah reading again after a sleep I don't think it would break anymore (since this line becomes deleteAt nil on any duplicated calls - which I assume won't error?).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only exception would be, if you were to remove the same handle twice in the same frame and also addEventHandler in the next frame, would it be possible that the same index (_handle) could be refilled in between the two execNextFrame calls? Resulting in the newly added EH being deleted immediately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all changed now.

@commy2
Copy link
Contributor Author

commy2 commented Jul 4, 2018

What about this? Tested it a bit with laptop, and it seems to work as expected.


GVAR(perFrameHandlerArray) deleteAt (GVAR(PFHhandles) select _handle);
GVAR(PFHhandles) set [_handle, nil];
if (GVAR(perFrameHandlersToRemove) isEqualTo []) then {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing ! ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah never mind I see how it works now, because it's next frame and only runs once due to this

@jokoho48
Copy link
Member

jokoho48 commented Jul 4, 2018

that is the same way I have it implemented. like it

Copy link
Contributor

@kymckay kymckay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@commy2 commy2 merged commit d6afdf6 into master Jul 23, 2018
@commy2 commy2 deleted the fixSkippingPFHWhenRemoved branch July 23, 2018 10:01
@PabstMirror
Copy link
Contributor

we've rewritten this fix many times but this one is the best; no run-time performance hit

ViperMaul added a commit that referenced this pull request Jul 27, 2018
* origin/master:
  XEH - Compatiblity for Encore (1.84) (#953)
  indicate settings that need a mission restart (#894)
  don't skip next PFH if current one is removed while iterating through (#950)
  change color of name of temporarily changed settings (#952)
  handle input gracefully in keybinding editKey ui function (#951)
  Update fnc_deleteEntity.sqf (#949)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants