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

onFree callback for uiControl instances #250

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

cdosoftei
Copy link
Contributor

This pull request concerns the destroying of UI controls, the issue being some controls could be destroyed outside of the purview of the embedding application, possibly leading to memory safety issues. In order to keep the implementing application aware of controls' lifecycle/status, the PR implements an onFree callback for uiControl structures (and its corresponding context as onFreeData).

This topic was originally discussed here.

int unitTestTeardown(void **_state)
{
struct state *state = *_state;

uiControlOnFree(uiControl(state->w), unitControlOnFree, state);
Copy link
Contributor

Choose a reason for hiding this comment

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

This test doesn't prove that unitControlOnFree() is ever actually called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed; I'm unsure how to address it without some sort of state tracking. Since there's already a state variable, I've added a flag to its struct definition and using it to explicitly check whether the onFree callback is indeed called or not.

Copy link
Contributor

@szanni szanni left a comment

Choose a reason for hiding this comment

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

I still struggle to understand why the Ardillo PHP binding needs an OnFree callback. How has this not come up as an issue for other bindings? Do they not care and simply leak memory? Or is the need for OnFree rather the need stemming from design choices made within the Ardillo binding? Because I would be surprised if PHP is too limited in language features to do without - when compared to other bindings.

Apart from that, thanks for providing unit tests!
This is sadly however not the way to test this.
For guaranteeing the invocation of a function call you want to use expect_function_calls(unitControlOnFree, 1); and function_called();. I provided hints in the PR review on how to do so with cmocka.

I personally am not really a fan of intermingling this testing with the setup and tear down of each individual test. I would prefer this to be done for each control individually. There may be a discussion to be had around this in general. I am facing the same dilemma in #245 which implements drag and drop for each uiControl.

Maybe there is a way to create a controlUnitTest setup and teardown that can be called by each individual uiControl as the first unit test case? Otherwise we'll have the entire test suite break in case something around the onFree callback goes wrong.

@@ -31,6 +31,7 @@ int progressBarRunUnitTests(void);
struct state {
uiWindow *w;
uiControl *c;
int onFreeCalled;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
int onFreeCalled;

uiWindowSetChild(state->w, uiControl(state->c));
uiControlShow(uiControl(state->w));
//uiMain();
uiMainSteps();
uiMainStep(1);
uiControlDestroy(uiControl(state->w));
assert_int_equal(state->onFreeCalled, 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert_int_equal(state->onFreeCalled, 1);

int unitTestTeardown(void **_state)
{
struct state *state = *_state;

uiControlOnFree(uiControl(state->w), unitControlOnFree, state);
state->onFreeCalled = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
state->onFreeCalled = 0;

Comment on lines +37 to +40
assert_non_null(c);
assert_non_null(data);
assert_ptr_equal(c, ((struct state *)data)->w);
((struct state *)data)->onFreeCalled = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert_non_null(c);
assert_non_null(data);
assert_ptr_equal(c, ((struct state *)data)->w);
((struct state *)data)->onFreeCalled = 1;
function_called();

int unitTestTeardown(void **_state)
{
struct state *state = *_state;

uiControlOnFree(uiControl(state->w), unitControlOnFree, state);
state->onFreeCalled = 0;
uiWindowSetChild(state->w, uiControl(state->c));
uiControlShow(uiControl(state->w));
//uiMain();
uiMainSteps();
uiMainStep(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
uiMainStep(1);
uiMainStep(1);
expect_function_calls(unitControlOnFree, 1);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants