You could use a private
std::promise that is initialized in
onStart(), and calls it's
set_value() method in
onStop().
Then, provide a function that returns the
std::future from the
std::promise's
get_future() method. Then all your working function (ie:
main()) has to do is call the
std::future's
wait() (or one of the timeout versions) method.
Reusing and modifying your code:
#include <future>
#include <iostream>
#include <SFML/Audio.hpp>
struct CRecorder : sf::SoundRecorder
{
CRecorder() { }
~CRecorder() { stop(); }
bool onProcessSamples(const int16_t* samples, const size_t sampleCount)
{
std::cout << "CustomRecorder::onProcessSamples() [samples:" << sampleCount << ", done: ";
// collect samples
count += sampleCount;
// return false when 22050 or more have been collected, otherwise return true
// note that onProcessSamples may be called again (sometimes) even though we return false
return count < 22050;
}
bool onStart()
{
std::cout << "CustomRecorder::onStart();" << std::endl;
// reset the promise so it can be reused
complete = std::promise<void>{};
setProcessingInterval(sf::milliseconds(25));
return true;
}
void onStop()
{
std::cout << "CustomRecorder::onStop();" << std::endl;
// tell any listeners we're all done
complete.set_value();
}
std::future<void> getCompleteSignal()
{
return complete.get_future();
}
size_t count = 0;
private:
std::promise<void> complete;
};
int main()
{
CRecorder r;
std::cout << "starting audio capture" << std::endl;
r.start();
std::future<void> complete = r.getCompleteSignal();
// do some other work if desired
// ...
// if a timeout is desired, wait_for() or wait_until() can be used instead
complete.wait();
std::cout << "done waiting" << std::endl;
return 0;
}
Benefit of this method, is the thread calling
std::future<T>::wait() can sleep, or busy wait, depending on the std library implementation.
If you'd want to be able to notify multiple threads, see
std::shared_futureAnother option would be
std::condition_variable