blob: f94345ae6b092bacb41e16a373e8f4d1353a6f32 [file] [log] [blame]
Shawn McCarneyc69a2752019-10-30 17:37:30 -05001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
Shawn McCarneyc69a2752019-10-30 17:37:30 -050018#include "id_map.hpp"
Shawn McCarneyc69a2752019-10-30 17:37:30 -050019
20#include <cstddef> // for size_t
Shawn McCarney0fd07d72020-03-06 17:16:24 -060021#include <optional>
Shawn McCarneyc69a2752019-10-30 17:37:30 -050022#include <stdexcept>
23#include <string>
24
Shawn McCarneyea7385b2019-11-07 12:19:32 -060025namespace phosphor::power::regulators
Shawn McCarneyc69a2752019-10-30 17:37:30 -050026{
27
Shawn McCarney494ef032019-11-07 15:56:50 -060028// Forward declarations to avoid circular dependencies
29class Device;
30class Rule;
31
Shawn McCarneyc69a2752019-10-30 17:37:30 -050032/**
33 * @class ActionEnvironment
34 *
35 * The current environment when executing actions.
36 *
37 * The ActionEnvironment contains the following information:
38 * - current device ID
39 * - current volts value (if any)
40 * - mapping from device and rule IDs to the corresponding objects
41 * - rule call stack depth (to detect infinite recursion)
42 */
43class ActionEnvironment
44{
45 public:
46 // Specify which compiler-generated methods we want
47 ActionEnvironment() = delete;
48 ActionEnvironment(const ActionEnvironment&) = delete;
49 ActionEnvironment(ActionEnvironment&&) = delete;
50 ActionEnvironment& operator=(const ActionEnvironment&) = delete;
51 ActionEnvironment& operator=(ActionEnvironment&&) = delete;
52 ~ActionEnvironment() = default;
53
54 /**
55 * Maximum rule call stack depth. Used to detect infinite recursion.
56 */
57 static constexpr size_t maxRuleDepth{30};
58
59 /**
60 * Constructor.
61 *
62 * @param idMap mapping from IDs to the associated Device/Rule objects
63 * @param deviceID current device ID
64 */
65 explicit ActionEnvironment(const IDMap& idMap,
66 const std::string& deviceID) :
67 idMap{idMap},
68 deviceID{deviceID}
69 {
70 }
71
72 /**
73 * Decrements the rule call stack depth by one.
74 *
75 * Should be used when a call to a rule returns. Does nothing if depth is
76 * already 0.
77 */
78 void decrementRuleDepth()
79 {
80 if (ruleDepth > 0)
81 {
82 --ruleDepth;
83 }
84 }
85
86 /**
87 * Returns the device with the current device ID.
88 *
89 * Throws invalid_argument if no device is found with current ID.
90 *
91 * @return device with current device ID
92 */
93 Device& getDevice() const
94 {
95 return idMap.getDevice(deviceID);
96 }
97
98 /**
99 * Returns the current device ID.
100 *
101 * @return current device ID
102 */
103 const std::string& getDeviceID() const
104 {
105 return deviceID;
106 }
107
108 /**
109 * Returns the rule with the specified ID.
110 *
111 * Throws invalid_argument if no rule is found with specified ID.
112 *
113 * @param id rule ID
114 * @return rule with specified ID
115 */
116 Rule& getRule(const std::string& id) const
117 {
118 return idMap.getRule(id);
119 }
120
121 /**
122 * Returns the current rule call stack depth.
123 *
124 * The depth is 0 if no rules have been called.
125 *
126 * @return rule call stack depth
127 */
128 size_t getRuleDepth() const
129 {
130 return ruleDepth;
131 }
132
133 /**
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600134 * Returns the current volts value, if set.
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500135 *
136 * @return current volts value
137 */
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600138 std::optional<double> getVolts() const
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500139 {
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500140 return volts;
141 }
142
143 /**
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500144 * Increments the rule call stack depth by one.
145 *
146 * Should be used when a rule is called.
147 *
148 * Throws runtime_error if the new depth exceeds maxRuleDepth. This
149 * indicates that infinite recursion has probably occurred (rule A -> rule B
150 * -> rule A).
Shawn McCarney2134ca62019-11-11 13:06:18 -0600151 *
152 * @param ruleID ID of the rule that is being called
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500153 */
Shawn McCarney2134ca62019-11-11 13:06:18 -0600154 void incrementRuleDepth(const std::string& ruleID)
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500155 {
156 if (ruleDepth >= maxRuleDepth)
157 {
Shawn McCarney2134ca62019-11-11 13:06:18 -0600158 throw std::runtime_error("Maximum rule depth exceeded by rule " +
159 ruleID + '.');
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500160 }
161 ++ruleDepth;
162 }
163
164 /**
165 * Sets the current device ID.
166 *
167 * @param id device ID
168 */
169 void setDeviceID(const std::string& id)
170 {
171 deviceID = id;
172 }
173
174 /**
175 * Sets the current volts value.
176 *
177 * @param volts new volts value.
178 */
179 void setVolts(double volts)
180 {
181 this->volts = volts;
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500182 }
183
184 private:
185 /**
186 * Mapping from string IDs to the associated Device and Rule objects.
187 */
Shawn McCarney494ef032019-11-07 15:56:50 -0600188 const IDMap& idMap;
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500189
190 /**
191 * Current device ID.
192 */
193 std::string deviceID{};
194
195 /**
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500196 * Current volts value (if set).
197 */
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600198 std::optional<double> volts{};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500199
200 /**
201 * Rule call stack depth.
202 */
203 size_t ruleDepth{0};
204};
205
Shawn McCarneyea7385b2019-11-07 12:19:32 -0600206} // namespace phosphor::power::regulators