#include "Dlog.hpp"
#include <mutex>
-#include <chrono>
#include <thread>
#include <fstream>
#include <cmath>
}, { { "name" }, { "roles", EvaluationValueSet() }, { "states", EvaluationValueSet() } } };
}
- void insertWaits()
+ class EvaluationValueWaitImpl : public EvaluationValueWaitInterface
{
- struct WaitTTSImpl : public EvaluationValueWaitInterface {
- TestExecutor *self;
- std::chrono::high_resolution_clock::time_point untilMoment;
- std::string pattern;
- bool success = false;
+ public:
+ EvaluationValueWaitImpl(TestExecutor *executor, std::chrono::milliseconds timeout)
+ : self(executor), timeout(std::chrono::high_resolution_clock::now() + timeout)
+ {}
- void join() override
- {
- if (success) return;
- auto h = self->ttsInfo.lock();
- success = h.waitForCondition(untilMoment, [&]() {
- return h->mode == TTSInfo::Mode::found;
- });
- if (!success) {
- h->mode = TTSInfo::Mode::ignore;
- throw EvaluationFailure{} << "wait for dlog ('" << pattern << "'): operation timeouted";
- }
- h->mode = TTSInfo::Mode::ignore;
- }
- bool isSatisfied() override
- {
- if (success) return true;
- auto h = self->ttsInfo.lock();
- return success = (h->mode == TTSInfo::Mode::found);
- }
- };
+ void join() override
+ {
+ if (success) return;
+
+ success = waitForPredicate();
+ }
- auto waitTTSImpl = [&](std::string pattern) -> EvaluationValue {
+ protected:
+ virtual bool waitForPredicate() = 0;
+
+ TestExecutor *self;
+ std::chrono::high_resolution_clock::time_point timeout;
+ bool success = false;
+ };
+
+ class WaitTTS : public EvaluationValueWaitImpl
+ {
+ public:
+ WaitTTS(TestExecutor *executor, std::chrono::milliseconds timeout, std::string pattern)
+ : EvaluationValueWaitImpl(executor, timeout)
+ {
std::regex regex;
- if (!pattern.empty())
- {
+ if (!pattern.empty()) {
try {
regex = std::regex {
pattern,
}
}
{
- auto h = ttsInfo.lock();
+ auto h = self->ttsInfo.lock();
if (!pattern.empty())
h->searchLine = std::move(regex);
h->mode = TTSInfo::Mode::search;
}
- auto impl = std::make_shared<WaitTTSImpl>();
- impl->self = this;
- impl->untilMoment = std::chrono::high_resolution_clock::now() + 3s;
- impl->pattern = std::move(pattern);
- return EvaluationValue{ impl };
- };
- variables["tts"] = EvaluationValueFunction{ std::move(waitTTSImpl), { { "pattern", EvaluationValue{ "" } } } };
+ this->pattern = std::move(pattern);
+ }
- struct WaitGuiImpl : public EvaluationValueWaitInterface {
- TestExecutor *self;
- std::chrono::high_resolution_clock::time_point untilMoment;
- std::string name;
- std::string currentRootName;
- bool success = false, searchForAnyChange = false;
+ private:
+ bool waitForPredicate() override
+ {
+ auto h = self->ttsInfo.lock();
+ auto res = h.waitForCondition(timeout, [&]() {
+ return h->mode == TTSInfo::Mode::found;
+ });
- void join() override
- {
- if (success) return;
- auto h = self->contextInfo.lock();
- success = h.waitForCondition(untilMoment, [&]() {
- return
- (searchForAnyChange && currentRootName != h->rootName) ||
- (!searchForAnyChange && h->rootName == name);
- });
- if (!success) {
- throw EvaluationFailure{} << "wait for gui ('" << name << "'): operation timeouted, " <<
- "current root name is '" << h->rootName << "'";
- }
+ if (!res) {
+ h->mode = TTSInfo::Mode::ignore;
+ throw EvaluationFailure{} << "wait for dlog ('" << pattern << "'): operation timeouted";
}
- bool isSatisfied() override
- {
- if (success) return true;
+ h->mode = TTSInfo::Mode::ignore;
+
+ return res;
+ }
+
+ std::string pattern;
+ };
+
+ class WaitGui : public EvaluationValueWaitImpl
+ {
+ public:
+ WaitGui(TestExecutor *executor, std::chrono::milliseconds timeout, std::string name)
+ : EvaluationValueWaitImpl(executor, timeout)
+ {
+ if (name.empty()) {
auto h = self->contextInfo.lock();
- return success = (h->rootName == name);
+ name = h->rootName;
+ searchForAnyChange = true;
+ } else {
+ this->name = std::move(name);
}
- };
+ }
- auto waitGuiImpl = [&](std::string name) -> EvaluationValue {
- auto impl = std::make_shared<WaitGuiImpl>();
- impl->self = this;
- impl->untilMoment = std::chrono::high_resolution_clock::now() + 3s;
- impl->name = std::move(name);
- if (impl->name.empty())
- {
- auto h = contextInfo.lock();
- impl->currentRootName = h->rootName;
- impl->searchForAnyChange = true;
+ private:
+ bool waitForPredicate() override
+ {
+ auto h = self->contextInfo.lock();
+ auto res = h.waitForCondition(timeout, [&]() {
+ return (searchForAnyChange && name != h->rootName) || (!searchForAnyChange && name == h->rootName);
+ });
+
+ if (!res) {
+ throw EvaluationFailure{} << "wait for gui ('" << name << "'): operation timeouted, " <<
+ "current root name is '" << h->rootName << "'";
}
+
+ return res;
+ }
+
+ std::string name;
+ bool searchForAnyChange = false;
+ };
+
+ void insertWaits()
+ {
+ auto waitTTS = [&](std::string pattern, double timeout) -> EvaluationValue {
+ auto impl = std::make_shared<WaitTTS>(this, std::chrono::milliseconds{ static_cast<size_t>(timeout * 1000) }, std::move(pattern));
+ return EvaluationValue{ impl };
+ };
+ variables["tts"] = EvaluationValueFunction{ std::move(waitTTS), { { "pattern", "" }, { "timeout", 3.0 } } };
+
+ auto waitGui = [&](std::string name, double timeout) -> EvaluationValue {
+ auto impl = std::make_shared<WaitGui>(this, std::chrono::milliseconds{ static_cast<size_t>(timeout * 1000) }, std::move(name));
return EvaluationValue{ impl };
};
- variables["gui"] = EvaluationValueFunction{ std::move(waitGuiImpl), { { "name", EvaluationValue{ "" } } } };
+ variables["gui"] = EvaluationValueFunction{ std::move(waitGui), { { "name", "" }, { "timeout", 3.0 } } };
}
void insertActivities()