[Interest] Design question: providing loop status

Fabian Vogt fabian at ritter-vogt.de
Thu Apr 21 16:41:16 CEST 2022


Am Donnerstag, 21. April 2022, 15:55:08 CEST schrieb Sean Murphy via Interest:
> I've got an existing class that will be used in both Qt and non-Qt/non-UI applications. One of that functions within that class parses large text files with what is essentially a while(!file.eof()) loop. I'd like to add functionality to the class that would provide some sort of parsing status back to anyone using the class - for example "currently on loop X of N". Essentially I'd like to add the equivalent of a Qt signal.
> Ideas I've got so far:
> 1. Use a bunch of #ifdefs to conditionally turn this class into something that inherits from QObject and provide the signal. The downsides to this are currently this is just a POD class, and we make copies of this instances of this class all over the place currently. Since you can't copy QObjects, that would add some complexity. And then it also wouldn't be able to provide status back in non-Qt uses since that would be #ifdef'd out.
> 2. Modify the class to take an optional progress function pointer with a signature like "void progress(int currentValue, int totalLoops)", and then within the parsing loop, if that function pointer isn't null, call it with the current value and total. If the function pointer is null, the class would behave as it does now - silently parsing without providing any status back. Then whatever code is instantiating one of these classes can supply their own progress function.
> I'm curious how other people have handled something like this? Right now I'm leaning more toward the function pointer solution since that would work for both Qt and non-Qt cases. I'm sure there's other ideas I haven't considered.

The most generic and flexible interface is to only do a certain number of
iterations per function call, then the caller can do whatever is necessary
for progress reporting and could even interrupt the process, e.g.:

int lines = 0;
while(thing.canParse()) {
    lines += thing.parseLines(5);
    Q_EMIT parsedLines(lines);

This requires moving state from the function itself to the class instance,
which can be easy or hard depending on the content. Or if you can use C++20,
maybe try coroutines? Those are basically a language feature for that.


> Thanks in advance!
> Sean

More information about the Interest mailing list