algorithm.hpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #ifndef SIMPLE_MOTION_ALGORITHM_HPP
  2. #define SIMPLE_MOTION_ALGORITHM_HPP
  3. #include <utility>
  4. #include "common.hpp"
  5. namespace simple::motion
  6. {
  7. // welcome to proper looping
  8. template <typename Motion, typename Target>
  9. int loop(Target&& target, Motion& motion, typename Motion::duration delta)
  10. {
  11. int count = 0;
  12. while(auto result =
  13. motion.move(std::forward<Target>(target), delta))
  14. {
  15. motion.reset();
  16. delta = result.remaining;
  17. ++count;
  18. }
  19. return count;
  20. }
  21. // and proper sequencing
  22. // NOTE: The done flag indicates that the last updated motion is done, not necessarily the whole input sequence.
  23. template <typename Stepper, typename Duration, typename Function>
  24. constexpr
  25. multi_advance_result<Duration, Stepper>
  26. sequence(Stepper begin, Stepper end, Duration delta, Function&& advance)
  27. {
  28. assert(begin != end);
  29. support::range<Stepper> updated{begin, begin};
  30. do
  31. {
  32. auto result = std::apply(
  33. std::forward<Function>(advance),
  34. std::forward_as_tuple(begin, delta)
  35. );
  36. ++updated.upper();
  37. if(result.remaining <= Duration{})
  38. return {result, updated};
  39. delta = result.remaining;
  40. ++begin;
  41. }
  42. while(begin != end);
  43. return {true, delta, updated};
  44. }
  45. } // namespace simple::motion
  46. #endif /* end of include guard */