29 this->component = component;
35 std::vector<MemoryID> bos;
43 std::stringstream
error;
47 for (
const auto& [subscription, subCallbacks] : this->
callbacks)
49 std::vector<MemoryID> matchingSnapshotIDs;
51 for (
const MemoryID& updatedSnapshotID : updatedSnapshotIDs)
55 if (
contains(subscription, updatedSnapshotID))
58 matchingSnapshotIDs.push_back(updatedSnapshotID);
68 error <<
"Error when comparing subscribed ID " << subscription
69 <<
" with updated ID " << updatedSnapshotID <<
":\n"
70 << e.what() <<
"\n\n";
74 if (not matchingSnapshotIDs.empty())
76 ARMARX_DEBUG <<
"Calling " << subCallbacks.size() <<
" callbacks"
77 <<
" subscribing " << subscription <<
" with "
78 << matchingSnapshotIDs.size() <<
" snapshot IDs ...";
79 for (
auto& managedCallback : subCallbacks)
83 managedCallback.callback(subscription, matchingSnapshotIDs);
85 catch (
const armarx::LocalException& e)
87 error <<
"Calling callback subscribing " << subscription <<
" failed."
88 <<
"\nCaught armarx::LocalException:"
90 << e.getReason() <<
"\n Stacktrace: \n"
91 << e.generateBacktrace() <<
"\n";
93 catch (
const std::exception& e)
95 error <<
"Calling callback subscribing " << subscription <<
" failed."
96 <<
"\nCaught armarx::Exception:"
102 error <<
"Calling callback subscribing " << subscription <<
" failed."
103 <<
"\nCaught unknown exception."
109 if (
error.str().size() > 0)
111 ARMARX_WARNING <<
"The following issues were encountered during MemoryListener::"
112 << __FUNCTION__ <<
"(): \n\n"
121 <<
"The memoryName must be specified to subscribe";
131 callbacks[memoryID].push_back({id, callback});
143 [callback](
const MemoryID&,
const std::vector<MemoryID>& updatedSnapshotIDs)
144 { callback(updatedSnapshotIDs); });
150 if (not handle.valid)
154 handle.valid =
false;
159 auto it = std::find_if(
callbacks[handle.memoryID].begin(),
163 std::iter_swap(it,
callbacks[handle.memoryID].end() - 1);
#define ARMARX_CHECK_NOT_EMPTY(c)
The ManagedIceObject is the base class for all ArmarX objects.
void unsubscribe(SubscriptionHandle &subscriptionHandle)
void updated(const std::vector< MemoryID > &updatedIDs) const
Function handling updates from the MemoryListener ice topic.
std::mutex subscribeMutex
std::unordered_map< MemoryID, std::vector< ManagedCallback > > callbacks
SubscriptionHandle subscribe(const MemoryID &subscriptionID, Callback Callback)
MemoryListener(ManagedIceObject *component=nullptr)
std::unordered_map< std::string, int > memoryRefCount
memoryName -> callbacks needing memory topic
std::function< void(const MemoryID &subscriptionID, const std::vector< MemoryID > &updatedSnapshotIDs)> Callback
std::function< void(const std::vector< MemoryID > &updatedSnapshotIDs)> CallbackUpdatedOnly
static std::string MakeMemoryTopicName(const MemoryID &memoryID)
void setComponent(ManagedIceObject *component)
Indicates that a memory ID is invalid, e.g.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
bool contains(const MemoryID &general, const MemoryID &specific)
Indicates whether general is "less specific" than, or equal to, specific, i.e.
void fromIce(const std::map< IceKeyT, IceValueT > &iceMap, boost::container::flat_map< CppKeyT, CppValueT > &cppMap)