GazeTargetWaiter.h
Go to the documentation of this file.
1#pragma once
2
3#include <condition_variable>
4#include <functional>
5#include <map>
6#include <mutex>
7#include <optional>
8#include <string>
9
11
13
15
17{
19
20 /**
21 * @brief Blocks until the gaze is fixed on a requested target.
22 *
23 * The analogue of navigation's client::Navigator::waitForStop, with two differences that matter
24 * here:
25 *
26 * - An expectation is armed *before* the target is committed, so a status that arrives while
27 * the caller is still on its way into wait() is not lost. (navigation::client::Navigator
28 * documents this as an open race.)
29 * - Waiting sleeps on a condition variable rather than spinning on a future, and re-checks the
30 * abort predicate on a fixed tick.
31 *
32 * One instance serves a whole client: expectations are keyed by target name, which is also the
33 * memory entity name, so concurrently running skills necessarily use distinct keys.
34 */
36 {
37 public:
38 struct Result
39 {
41
42 /// Why the wait ended, if it did not end on a status update.
43 std::string message;
44
45 /**
46 * @brief Whether the gaze was fixed on the target at some point.
47 *
48 * Not `status == Reached`: a target that was reached and then superseded reports
49 * Released, and a client that only observes that last snapshot must still count its
50 * request as fulfilled. The scheduler accumulates the timestamps precisely so this
51 * single test is sufficient.
52 */
53 explicit operator bool() const;
54 };
55
57
58 /// Start collecting updates for this target. Call before committing it.
59 void expect(const std::string& targetName);
60
61 /// Narrow the expectation to the exact request snapshot, once the commit returned its ID.
62 void bind(const std::string& targetName, const armem::MemoryID& gazeTargetID);
63
64 /// Drop an expectation without waiting for it.
65 void forget(const std::string& targetName);
66
67 /**
68 * @brief Block until the target is reached, ends, the abort predicate fires or the timeout
69 * expires. Consumes the expectation.
70 *
71 * @param timeout A non-positive duration waits indefinitely.
72 * @param shouldAbort Polled regularly; typically the skill's shouldSkillTerminate().
73 */
74 Result wait(const std::string& targetName,
75 const armarx::Duration& timeout,
76 const std::function<bool()>& shouldAbort);
77
78 private:
79 struct Expectation
80 {
81 /// Set once the commit's snapshot ID is known; until then updates match by name alone.
82 std::optional<armem::MemoryID> gazeTargetID;
83
84 /// Most recent matching update.
86
87 /// Whether the outcome is decided: reached, or terminal.
88 bool settled = false;
89 };
90
91 void handleStatus(const gaze_targets::GazeTargetStatus& status);
92
93 std::mutex mutex;
94
95 std::condition_variable condition;
96
97 std::map<std::string, Expectation> expectations;
98 };
99
100} // namespace armarx::view_selection::client
Represents a duration.
Definition Duration.h:17
void expect(const std::string &targetName)
Start collecting updates for this target. Call before committing it.
void bind(const std::string &targetName, const armem::MemoryID &gazeTargetID)
Narrow the expectation to the exact request snapshot, once the commit returned its ID.
GazeTargetWaiter(StatusHandlerInterface &handler)
Result wait(const std::string &targetName, const armarx::Duration &timeout, const std::function< bool()> &shouldAbort)
Block until the target is reached, ends, the abort predicate fires or the timeout expires.
void forget(const std::string &targetName)
Drop an expectation without waiting for it.
Registration of callbacks for gaze target lifecycle updates.
Business Object (BO) class of GazeTargetStatus: the lifecycle of one gaze target request,...
std::string message
Why the wait ended, if it did not end on a status update.