diff --git a/slsDetectorSoftware/include/sls/Result.h b/slsDetectorSoftware/include/sls/Result.h index 2578ad2ba..73e5fc332 100644 --- a/slsDetectorSoftware/include/sls/Result.h +++ b/slsDetectorSoftware/include/sls/Result.h @@ -16,6 +16,7 @@ #include #include "sls/ToString.h" +#include "sls/TypeTraits.h" #include "sls/container_utils.h" namespace sls { @@ -128,6 +129,25 @@ template > class Result { /** Test whether all elements of the result are equal */ bool equal() const noexcept { return allEqual(vec); } + /** Test whether any element of the result are equal to a value */ + bool any(const T &value) const noexcept { return anyEqualTo(vec, value); } + + template > + typename std::enable_if::value, bool>::type + contains_only(const V &a, const Args &...args) const noexcept { + auto values = {a, args...}; + for (const auto &element : vec) { + int found = 0; + for (const auto &value : values) { + if (value == element) + found++; + } + if (!found) + return false; + } + return true; + } + /** Convert Result to std::vector */ operator std::vector() { return vec; } }; diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 6ab1d8911..b813f80e9 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -18,6 +18,7 @@ #include #include +#include #include namespace sls { @@ -848,18 +849,25 @@ void Detector::startDetectorReadout() { void Detector::stopDetector(Positions pos) { - // stop and check status X times int retries{0}; - // avoid default construction of runStatus::IDLE on squash - auto status = getDetectorStatus().squash(defs::runStatus::RUNNING); - while (status != defs::runStatus::IDLE && - status != defs::runStatus::STOPPED) { - if (status == defs::runStatus::ERROR) { - throw RuntimeError( - "Could not stop detector. Returned error status."); + auto status = getDetectorStatus(pos); + + // jf sync fix: status [stopped or idle] = [stopped] + // sync issue: (master idle sometimes, slaves stopped) + + // eiger fix: stop multiple times from multi client till all modules stopped + // issue: asynchronous start and stop scripts with a module being started + // (stop before) and waiting for the other to be done. So a module that was + // idle before stopping will return running (after async start script) when + // getting status after, which will then be stopped again. + + while (!status.contains_only(defs::runStatus::IDLE, defs::runStatus::STOPPED)){ + if (status.any(defs::runStatus::ERROR)) { + throw RuntimeError("Could not stop detector. At least one module " + "returned error status."); } pimpl->stopDetector(pos); - status = getDetectorStatus().squash(defs::runStatus::RUNNING); + status = getDetectorStatus(pos); ++retries; if (retries == 10) @@ -878,7 +886,7 @@ void Detector::stopDetector(Positions pos) { for (auto it : res) { maxVal = std::max(maxVal, it); } - setNextFrameNumber(maxVal + 1); + setNextFrameNumber(maxVal + 1, pos); } } break; default: diff --git a/slsDetectorSoftware/tests/test-Result.cpp b/slsDetectorSoftware/tests/test-Result.cpp index 6763a43d0..30a735f28 100644 --- a/slsDetectorSoftware/tests/test-Result.cpp +++ b/slsDetectorSoftware/tests/test-Result.cpp @@ -196,4 +196,24 @@ TEST_CASE("String conversions") { "[{one: 1}, {one: 1, three: 3, two: 2}, {one: 1}]"); } +TEST_CASE("Any element is equal"){ + Result r{1,2,3,4,5}; + REQUIRE(r.any(3)); + REQUIRE_FALSE(r.any(9)); +} + +TEST_CASE("Result contains only the specified elements"){ + Result r{1,1,1}; + REQUIRE(r.contains_only(1)); + REQUIRE(r.contains_only(1,1)); +} + +TEST_CASE("Only with multiple values"){ + Result r{1,1,2,1,2,1,1}; + REQUIRE_FALSE(r.contains_only(1)); + REQUIRE_FALSE(r.contains_only(2)); + REQUIRE(r.contains_only(1,2)); + REQUIRE(r.contains_only(2,1)); +} + } // namespace sls diff --git a/slsSupportLib/include/sls/TypeTraits.h b/slsSupportLib/include/sls/TypeTraits.h index cbbeb7bea..80bee0b44 100644 --- a/slsSupportLib/include/sls/TypeTraits.h +++ b/slsSupportLib/include/sls/TypeTraits.h @@ -103,4 +103,14 @@ template struct is_vector : public std::false_type {}; template struct is_vector> : public std::true_type {}; + + +template struct Conjunction : std::true_type {}; +template struct Conjunction : B1 {}; +template +struct Conjunction + : std::conditional, B1>::type {}; + +template +using AllSame = typename std::enable_if...>::value>::type; } // namespace sls \ No newline at end of file