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

STYLE: Call SetNthOutput(i, MakeOutput(i)) in a for loop #4687

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

N-Dekker
Copy link
Contributor

@N-Dekker N-Dekker commented May 21, 2024

Reduced duplicate code by replacing manual SetNthOutput(i, MakeOutput(i)) calls for i = 0, 1, 2 with the corresponding for loops.

Reduced duplicate code by replacing manual `SetNthOutput(i, MakeOutput(i)` calls
for i = 0, 1, 2 with the corresponding `for` loops.
@github-actions github-actions bot added area:Filtering Issues affecting the Filtering module area:Segmentation Issues affecting the Segmentation module type:Style Style changes: no logic impact (indentation, comments, naming) area:Numerics Issues affecting the Numerics module labels May 21, 2024
@N-Dekker N-Dekker changed the title STYLE: Call SetNthOutput(i, MakeOutput(i) in a for loop STYLE: Call SetNthOutput(i, MakeOutput(i)) in a for loop May 21, 2024
@N-Dekker
Copy link
Contributor Author

N-Dekker commented May 21, 2024

@blowekamp Following our discussion at #4654 (comment) I'm still trying to get clear in which particular scenario's MakeOutput(i) is actually useful, within a default-constructor. Is this an example use case? I mean, the ability to call it iteratively in a for loop?

@N-Dekker
Copy link
Contributor Author

OK, so this could be a nice use case, being able to call Self::MakeOutput(i) is a for loop. Still I'm interested to hear if calling Self::MakeOutput(i) is also useful outside the constructor of a class (the class Self).

@blowekamp
Copy link
Member

@blowekamp Following our discussion at #4654 (comment) I'm still trying to get clear in which particular scenario's MakeOutput(i) is actually useful, within a default-constructor. Is this an example use case? I mean, the ability to call it iteratively in a for loop?

Thanks for the continued investigation and the discussion. These filters have multiple outputs of different types. These different output types are not represented by the template parameters. Hence the MakeOutput method has been overloaded to create the correct "nth" output. This is important because the base class ImageSource just creates all outputs of the same type. Having the correctly typed output was a hard issue to track down with forced casted and failed dynamic casts. The pattern used in as many places possible was to use the MakeOutput method as the generic way to create the outputs.

Note: An incorrectly casted image type can work a surprising long time as the wrong type.

@blowekamp
Copy link
Member

Still I'm interested to hear if calling Self::MakeOutput(i) is also useful outside the constructor of a class (the class Self).

It is also used here:

DataObjectPointer newOutput = this->MakeOutput(key);

Which indirectly gets called when operations the "ReleaseDataFlagOn" or "DisconnectPipeline" are called and the output created in the constructor is created again.

@N-Dekker
Copy link
Contributor Author

It is also used here:

DataObjectPointer newOutput = this->MakeOutput(key);

Interesting, thanks! Apparently SetOutput(name, output) creates a new output by calling MakeOutput, if the output argument passed by the user is NULL. I did not know that. 🤷

Comment on lines +36 to +40
// distance map, voronoi map, distance vectors
for (unsigned int i{}; i < numberOfRequiredOutputs; ++i)
{
ProcessObject::SetNthOutput(i, Self::MakeOutput(i));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we can make this more generic, like:

ProcessObject::SetRequiredOutputs(*this, numberOfRequiredOutputs);

This new function, SetRequiredOutputs would then set the numberOfRequiredOutputs and do the for loop. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

For the constructors we are in a bit of a hard place where the methods called be the constructor should not be virtual. That is the virtual MakeOutput should not be called by base classes in the constructor.

This is more of a design issue, maybe the output should only be created on demand? or Maybe a separate "virtual Initialize" method is needed.

Then there is the idea of having a base class take multiple template parameters for inputs and outputs.... But for the few filters it's likely not worth the refactor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:Filtering Issues affecting the Filtering module area:Numerics Issues affecting the Numerics module area:Segmentation Issues affecting the Segmentation module type:Style Style changes: no logic impact (indentation, comments, naming)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants