improved Lambda support

This commit is contained in:
Günter Obiltschnig
2020-01-26 08:41:22 +01:00
parent 14e58b7fea
commit 958387b6ba
6 changed files with 122 additions and 43 deletions

View File

@@ -154,12 +154,19 @@ public:
/// Starts the thread with the given target and parameter.
template <class Functor>
void startFunc(Functor fn)
void startFunc(const Functor& fn)
/// Starts the thread with the given functor object or lambda.
{
startImpl(new FunctorRunnable<Functor>(fn));
}
template <class Functor>
void startFunc(Functor&& fn)
/// Starts the thread with the given functor object or lambda.
{
startImpl(new FunctorRunnable<Functor>(std::move(fn)));
}
void join();
/// Waits until the thread completes execution.
/// If multiple threads try to join the same
@@ -242,6 +249,11 @@ protected:
{
}
FunctorRunnable(Functor&& functor):
_functor(std::move(functor))
{
}
~FunctorRunnable()
{
}

View File

@@ -383,20 +383,19 @@ void ThreadTest::testThreadFunctor()
assertTrue (!thread.isRunning());
#if __cplusplus >= 201103L
Thread thread2;
assertTrue (!thread2.isRunning());
MyRunnable::_staticVar = 0;
thread.startFunc([] () {MyRunnable::_staticVar++;});
thread.startFunc([] ()
{
MyRunnable::_staticVar++;
});
thread.join();
assertTrue (1 == MyRunnable::_staticVar);
assertTrue (!thread2.isRunning());
#endif
}

View File

@@ -41,6 +41,15 @@ class Util_API Timer: protected Poco::Runnable
/// Timer is safe for multithreaded use - multiple threads can schedule
/// new tasks simultaneously.
///
/// Via the func() helper function template, a functor or
/// lambda can be used as timer task:
///
/// timer.schedule(Timer::func([]()
/// {
/// std::cout << "Timer!\n";
/// }),
/// Poco::Clock());
///
/// Acknowledgement: The interface of this class has been inspired by
/// the java.util.Timer class from Java 1.3.
{
@@ -150,6 +159,22 @@ public:
/// If task execution takes longer than the given interval,
/// further executions are delayed.
template <typename Fn>
static TimerTask::Ptr func(const Fn& fn)
/// Helper function template to use a functor or lambda
/// with Timer::schedule() and Timer::scheduleAtFixedRate().
{
return new TimerFunc<Fn>(fn);
}
template <typename Fn>
static TimerTask::Ptr func(Fn&& fn)
/// Helper function template to use a functor or lambda
/// with Timer::schedule() and Timer::scheduleAtFixedRate().
{
return new TimerFunc<Fn>(std::move(fn));
}
protected:
void run();
static void validateTask(const TimerTask::Ptr& pTask);

View File

@@ -77,6 +77,32 @@ private:
};
template <typename Fn>
class TimerFunc: public TimerTask
/// A simple adapter that allows using a functor or lambda
/// with Poco::Util::Timer, used by timerFunc().
{
public:
explicit TimerFunc(const Fn& fn):
_fn(fn)
{
}
explicit TimerFunc(Fn&& fn):
_fn(std::move(fn))
{
}
void run()
{
_fn();
}
private:
Fn _fn;
};
//
// inlines
//

View File

@@ -260,6 +260,21 @@ void TimerTest::testCancelAllWaitStop()
}
void TimerTest::testFunc()
{
Timer timer;
int count = 0;
timer.schedule(Timer::func([&count]()
{
count++;
}), Poco::Clock());
Poco::Thread::sleep(100);
assertTrue (count == 1);
}
void TimerTest::setUp()
{
}
@@ -290,6 +305,7 @@ CppUnit::Test* TimerTest::suite()
CppUnit_addTest(pSuite, TimerTest, testCancel);
CppUnit_addTest(pSuite, TimerTest, testCancelAllStop);
CppUnit_addTest(pSuite, TimerTest, testCancelAllWaitStop);
CppUnit_addTest(pSuite, TimerTest, testFunc);
return pSuite;
}

View File

@@ -35,6 +35,7 @@ public:
void testCancel();
void testCancelAllStop();
void testCancelAllWaitStop();
void testFunc();
void setUp();
void tearDown();