-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Expand file tree
/
Copy pathcallback_impl.h
More file actions
72 lines (59 loc) · 2.03 KB
/
callback_impl.h
File metadata and controls
72 lines (59 loc) · 2.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#pragma once
#include <functional>
#include <list>
#include "envoy/common/callback.h"
#include "common/common/assert.h"
namespace Envoy {
namespace Common {
/**
* Utility class for managing callbacks.
*/
template <typename... CallbackArgs> class CallbackManager {
public:
using Callback = std::function<void(CallbackArgs...)>;
/**
* Add a callback.
* @param callback supplies the callback to add.
* @return CallbackHandle* a handle that can be used to remove the callback.
*/
CallbackHandle* add(Callback callback) {
callbacks_.emplace_back(*this, callback);
return &callbacks_.back();
}
/**
* Run all registered callbacks.
* NOTE: This code is currently safe if a callback deletes ITSELF from within a callback. It is
* not safe if a callback deletes other callbacks. If that is required the code will need
* to change (specifically, it will crash if the next callback in the list is deleted).
* @param args supplies the callback arguments.
*/
void runCallbacks(CallbackArgs... args) {
for (auto it = callbacks_.cbegin(); it != callbacks_.cend();) {
auto current = it++;
current->cb_(args...);
}
}
private:
struct CallbackHolder : public CallbackHandle {
CallbackHolder(CallbackManager& parent, Callback cb) : parent_(parent), cb_(cb) {}
// CallbackHandle
void remove() override { parent_.remove(this); }
CallbackManager& parent_;
Callback cb_;
};
/**
* Remove a member update callback added via add().
* @param handle supplies the callback handle to remove.
*/
void remove(CallbackHandle* handle) {
ASSERT(std::find_if(callbacks_.begin(), callbacks_.end(),
[handle](const CallbackHolder& holder) -> bool {
return handle == &holder;
}) != callbacks_.end());
callbacks_.remove_if(
[handle](const CallbackHolder& holder) -> bool { return handle == &holder; });
}
std::list<CallbackHolder> callbacks_;
};
} // namespace Common
} // namespace Envoy