xref: /openbmc/phosphor-dbus-monitor/src/callback.hpp (revision b97bfff73e44e53571f8a00b80ec947496930d7b)
1 #pragma once
2 
3 #include "data_types.hpp"
4 
5 namespace phosphor
6 {
7 namespace dbus
8 {
9 namespace monitoring
10 {
11 
12 /** @class Callback
13  *  @brief Callback interface.
14  *
15  *  Callbacks of any type can be run.
16  */
17 class Callback
18 {
19     public:
20         Callback() = default;
21         Callback(const Callback&) = delete;
22         Callback(Callback&&) = default;
23         Callback& operator=(const Callback&) = delete;
24         Callback& operator=(Callback&&) = default;
25         virtual ~Callback() = default;
26 
27         /** @brief Run the callback. */
28         virtual void operator()() = 0;
29 };
30 
31 /** @class Conditional
32  *  @brief Condition interface.
33  *
34  *  Conditions of any type can be tested for true or false.
35  */
36 class Conditional
37 {
38     public:
39         Conditional() = default;
40         Conditional(const Conditional&) = delete;
41         Conditional(Conditional&&) = default;
42         Conditional& operator=(const Conditional&) = delete;
43         Conditional& operator=(Conditional&&) = default;
44         virtual ~Conditional() = default;
45 
46         /** @brief Test the condition. */
47         virtual bool operator()() = 0;
48 };
49 
50 /** @class IndexedConditional
51  *  @brief Condition with an index.
52  */
53 class IndexedConditional : public Conditional
54 {
55     public:
56         IndexedConditional() = delete;
57         IndexedConditional(const IndexedConditional&) = delete;
58         IndexedConditional(IndexedConditional&&) = default;
59         IndexedConditional& operator=(const IndexedConditional&) = delete;
60         IndexedConditional& operator=(IndexedConditional&&) = default;
61         virtual ~IndexedConditional() = default;
62 
63         explicit IndexedConditional(const PropertyIndex& conditionIndex)
64             : Conditional(), index(conditionIndex) {}
65 
66         /** @brief Test the condition. */
67         virtual bool operator()() override = 0;
68 
69     protected:
70 
71         /** @brief Property names and their associated storage. */
72         const PropertyIndex& index;
73 };
74 
75 /** @class IndexedCallback
76  *  @brief Callback with an index.
77  */
78 class IndexedCallback : public Callback
79 {
80     public:
81         IndexedCallback() = delete;
82         IndexedCallback(const IndexedCallback&) = delete;
83         IndexedCallback(IndexedCallback&&) = default;
84         IndexedCallback& operator=(const IndexedCallback&) = delete;
85         IndexedCallback& operator=(IndexedCallback&&) = default;
86         virtual ~IndexedCallback() = default;
87         explicit IndexedCallback(const PropertyIndex& callbackIndex)
88             : Callback(), index(callbackIndex) {}
89 
90         /** @brief Run the callback. */
91         virtual void operator()() override = 0;
92 
93     protected:
94 
95         /** @brief Property names and their associated storage. */
96         const PropertyIndex& index;
97 };
98 
99 /** @class GroupOfCallbacks
100  *  @brief Invoke multiple callbacks.
101  *
102  *  A group of callbacks is implemented as a vector of array indicies
103  *  into an external array  of callbacks.  The group function call
104  *  operator traverses the vector of indicies, invoking each
105  *  callback.
106  *
107  *  @tparam CallbackAccess - Access to the array of callbacks.
108  */
109 template <typename CallbackAccess>
110 class GroupOfCallbacks : public Callback
111 {
112     public:
113         GroupOfCallbacks() = delete;
114         GroupOfCallbacks(const GroupOfCallbacks&) = delete;
115         GroupOfCallbacks(GroupOfCallbacks&&) = default;
116         GroupOfCallbacks& operator=(const GroupOfCallbacks&) = delete;
117         GroupOfCallbacks& operator=(GroupOfCallbacks&&) = default;
118         ~GroupOfCallbacks() = default;
119         explicit GroupOfCallbacks(
120             const std::vector<size_t>& graphEntry)
121             : graph(graphEntry) {}
122 
123         /** @brief Run the callbacks. */
124         void operator()() override
125         {
126             for (auto e : graph)
127             {
128                 (*CallbackAccess::get()[e])();
129             }
130         }
131 
132     private:
133         /** @brief The offsets of the callbacks in the group. */
134         const std::vector<size_t>& graph;
135 };
136 
137 /** @class ConditionalCallback
138  *  @brief Callback adaptor that asssociates a condition with a callback.
139  */
140 template <typename CallbackAccess>
141 class ConditionalCallback: public Callback
142 {
143     public:
144         ConditionalCallback() = delete;
145         ConditionalCallback(const ConditionalCallback&) = delete;
146         ConditionalCallback(ConditionalCallback&&) = default;
147         ConditionalCallback& operator=(const ConditionalCallback&) = delete;
148         ConditionalCallback& operator=(ConditionalCallback&&) = default;
149         ~ConditionalCallback() = default;
150         ConditionalCallback(
151             const std::vector<size_t>& graphEntry,
152             Conditional& cond)
153             : graph(graphEntry), condition(cond) {}
154 
155         /** @brief Run the callback if the condition is satisfied. */
156         void operator()() override
157         {
158             if (condition())
159             {
160                 (*CallbackAccess::get()[graph[0]])();
161             }
162         }
163 
164     private:
165         /** @brief The index of the callback to conditionally invoke. */
166         const std::vector<size_t>& graph;
167 
168         /** @brief The condition to test. */
169         Conditional& condition;
170 };
171 
172 } // namespace monitoring
173 } // namespace dbus
174 } // namespace phosphor
175