Commit 51785aeb0923a4444c08c921768b1d13e2e020aa

Authored by Jojo-1000
Committed by Moritz Wirger
1 parent 967b7515

Make transaction usable without chain calls.

include/hueplusplus/StateTransaction.h
@@ -42,6 +42,22 @@ namespace hueplusplus @@ -42,6 +42,22 @@ namespace hueplusplus
42 //! \note The transaction has an internal reference to the light state. 42 //! \note The transaction has an internal reference to the light state.
43 //! You must not cause a refresh of the state between creating and committing the transaction 43 //! You must not cause a refresh of the state between creating and committing the transaction
44 //! (e.g. non-const getters/setters), because that invalidates the reference. 44 //! (e.g. non-const getters/setters), because that invalidates the reference.
  45 +//!
  46 +//! <h3>Advanced usage</h3>
  47 +//! Another way to use the transaction is by storing it and building up the calls separately.
  48 +//! \code
  49 +//! hueplusplus::StateTransaction t = light.transaction();
  50 +//! if(shouldTurnOn)
  51 +//! t.setOn(true);
  52 +//! t.commit();
  53 +//! \endcode
  54 +//! In this case, it is especially important that the light and the state of the light MUST NOT invalidate.
  55 +//! That means
  56 +//! \li the light variable has to live longer than the transaction
  57 +//! \li especially no non-const method calls on the light while the transaction is open,
  58 +//! or committing other transactions
  59 +//!
  60 +//! In general, this method is easier to screw up and should only be used when really necessary.
45 class StateTransaction 61 class StateTransaction
46 { 62 {
47 public: 63 public:
@@ -67,109 +83,109 @@ public: @@ -67,109 +83,109 @@ public:
67 //! \throws HueException when response contains no body 83 //! \throws HueException when response contains no body
68 //! \throws HueAPIResponseException when response contains an error 84 //! \throws HueAPIResponseException when response contains an error
69 //! \throws nlohmann::json::parse_error when response could not be parsed 85 //! \throws nlohmann::json::parse_error when response could not be parsed
70 - bool commit(bool trimRequest = true) &&; 86 + bool commit(bool trimRequest = true);
71 87
72 //! \brief Create a ScheduleCommand from the transaction 88 //! \brief Create a ScheduleCommand from the transaction
73 //! \returns A ScheduleCommand that can be used to execute this transaction on a Schedule. 89 //! \returns A ScheduleCommand that can be used to execute this transaction on a Schedule.
74 - ScheduleCommand toScheduleCommand() &&; 90 + ScheduleCommand toScheduleCommand();
75 91
76 //! \brief Turn light on or off. 92 //! \brief Turn light on or off.
77 //! \param on true for on, false for off 93 //! \param on true for on, false for off
78 //! \returns This transaction for chaining calls 94 //! \returns This transaction for chaining calls
79 - StateTransaction&& setOn(bool on) &&; 95 + StateTransaction& setOn(bool on);
80 //! \brief Set light brightness. 96 //! \brief Set light brightness.
81 //! \param brightness Brightness from 0 = off to 254 = fully lit. 97 //! \param brightness Brightness from 0 = off to 254 = fully lit.
82 //! \returns This transaction for chaining calls 98 //! \returns This transaction for chaining calls
83 //! \note If this transaction is for a light, the light needs to have brightness control. 99 //! \note If this transaction is for a light, the light needs to have brightness control.
84 //! \note Brightness 0 will also turn off the light if nothing else is specified, 100 //! \note Brightness 0 will also turn off the light if nothing else is specified,
85 //! any other value will also turn on the light. 101 //! any other value will also turn on the light.
86 - StateTransaction&& setBrightness(uint8_t brightness) &&; 102 + StateTransaction& setBrightness(uint8_t brightness);
87 //! \brief Set light hue. 103 //! \brief Set light hue.
88 //! \param hue Color hue from 0 to 65535 104 //! \param hue Color hue from 0 to 65535
89 //! \returns This transaction for chaining calls 105 //! \returns This transaction for chaining calls
90 //! \note If this transaction is for a light, the light needs to have rgb color control. 106 //! \note If this transaction is for a light, the light needs to have rgb color control.
91 //! \note Will also turn on the light if nothing else is specified 107 //! \note Will also turn on the light if nothing else is specified
92 - StateTransaction&& setColorHue(uint16_t hue) &&; 108 + StateTransaction& setColorHue(uint16_t hue);
93 //! \brief Set light saturation. 109 //! \brief Set light saturation.
94 //! \param saturation Color saturation from 0 to 254 110 //! \param saturation Color saturation from 0 to 254
95 //! \returns This transaction for chaining calls 111 //! \returns This transaction for chaining calls
96 //! \note If this transaction is for a light, the light needs to have rgb color control. 112 //! \note If this transaction is for a light, the light needs to have rgb color control.
97 //! \note Will also turn on the light if nothing else is specified 113 //! \note Will also turn on the light if nothing else is specified
98 - StateTransaction&& setColorSaturation(uint8_t saturation) &&; 114 + StateTransaction& setColorSaturation(uint8_t saturation);
99 //! \brief Set light color in hue and saturation 115 //! \brief Set light color in hue and saturation
100 //! \param hueSat Color in hue and saturation 116 //! \param hueSat Color in hue and saturation
101 //! \returns This transaction for chaining calls 117 //! \returns This transaction for chaining calls
102 //! \note If this transaction is for a light, the light needs to have rgb color control. 118 //! \note If this transaction is for a light, the light needs to have rgb color control.
103 //! \note Will also turn on the light if nothing else is specified 119 //! \note Will also turn on the light if nothing else is specified
104 - StateTransaction&& setColor(const HueSaturation& hueSat); 120 + StateTransaction& setColor(const HueSaturation& hueSat);
105 121
106 //! \brief Set light color in xy space (without brightness). 122 //! \brief Set light color in xy space (without brightness).
107 //! \param xy x and y coordinates in CIE color space 123 //! \param xy x and y coordinates in CIE color space
108 //! \returns This transaction for chaining calls 124 //! \returns This transaction for chaining calls
109 //! \note If this transaction is for a light, the light needs to have rgb color control. 125 //! \note If this transaction is for a light, the light needs to have rgb color control.
110 //! \note Will also turn on the light if nothing else is specified 126 //! \note Will also turn on the light if nothing else is specified
111 - StateTransaction&& setColor(const XY& xy) &&; 127 + StateTransaction& setColor(const XY& xy);
112 //! \brief Set light color and brightness in xy space 128 //! \brief Set light color and brightness in xy space
113 //! \param xy x,y and brightness in CIE color space 129 //! \param xy x,y and brightness in CIE color space
114 //! \returns This transaction for chaining calls 130 //! \returns This transaction for chaining calls
115 //! \note If this transaction is for a light, the light needs to have rgb color control. 131 //! \note If this transaction is for a light, the light needs to have rgb color control.
116 //! \note Will also turn on the light if nothing else is specified 132 //! \note Will also turn on the light if nothing else is specified
117 - StateTransaction&& setColor(const XYBrightness& xy) &&; 133 + StateTransaction& setColor(const XYBrightness& xy);
118 //! \brief Set light color temperature. 134 //! \brief Set light color temperature.
119 //! \param mired Color temperature in mired from 153 to 500 135 //! \param mired Color temperature in mired from 153 to 500
120 //! \returns This transaction for chaining calls 136 //! \returns This transaction for chaining calls
121 //! \note If this transaction is for a light, the light needs to have color temperature control. 137 //! \note If this transaction is for a light, the light needs to have color temperature control.
122 //! \note Will also turn on the light if nothing else is specified 138 //! \note Will also turn on the light if nothing else is specified
123 - StateTransaction&& setColorTemperature(unsigned int mired) &&; 139 + StateTransaction& setColorTemperature(unsigned int mired);
124 //! \brief Enables or disables color loop. 140 //! \brief Enables or disables color loop.
125 //! \param on true to enable, false to disable color loop. 141 //! \param on true to enable, false to disable color loop.
126 //! \returns This transaction for chaining calls 142 //! \returns This transaction for chaining calls
127 //! \note If this transaction is for a light, the light needs to have rgb color control. 143 //! \note If this transaction is for a light, the light needs to have rgb color control.
128 //! \note Will also turn on the light if nothing else is specified 144 //! \note Will also turn on the light if nothing else is specified
129 - StateTransaction&& setColorLoop(bool on) &&; 145 + StateTransaction& setColorLoop(bool on);
130 //! \brief Increment/Decrement brightness. 146 //! \brief Increment/Decrement brightness.
131 //! \param increment Brightness change from -254 to 254. 147 //! \param increment Brightness change from -254 to 254.
132 //! \returns This transaction for chaining calls 148 //! \returns This transaction for chaining calls
133 //! \note If this transaction is for a light, the light needs to have brightness control. 149 //! \note If this transaction is for a light, the light needs to have brightness control.
134 - StateTransaction&& incrementBrightness(int increment) &&; 150 + StateTransaction& incrementBrightness(int increment);
135 //! \brief Increment/Decrement saturaction. 151 //! \brief Increment/Decrement saturaction.
136 //! \param increment Saturation change from -254 to 254. 152 //! \param increment Saturation change from -254 to 254.
137 //! \returns This transaction for chaining calls 153 //! \returns This transaction for chaining calls
138 //! \note If this transaction is for a light, the light needs to have rgb color control. 154 //! \note If this transaction is for a light, the light needs to have rgb color control.
139 - StateTransaction&& incrementSaturation(int increment) &&; 155 + StateTransaction& incrementSaturation(int increment);
140 //! \brief Increment/Decrement hue. 156 //! \brief Increment/Decrement hue.
141 //! \param increment Hue change from -65535 to 65535. 157 //! \param increment Hue change from -65535 to 65535.
142 //! \returns This transaction for chaining calls 158 //! \returns This transaction for chaining calls
143 //! \note If this transaction is for a light, the light needs to have rgb color control. 159 //! \note If this transaction is for a light, the light needs to have rgb color control.
144 - StateTransaction&& incrementHue(int increment) &&; 160 + StateTransaction& incrementHue(int increment);
145 //! \brief Increment/Decrement color temperature. 161 //! \brief Increment/Decrement color temperature.
146 //! \param increment Color temperature change in mired from -65535 to 65535. 162 //! \param increment Color temperature change in mired from -65535 to 65535.
147 //! \returns This transaction for chaining calls 163 //! \returns This transaction for chaining calls
148 //! \note If this transaction is for a light, the light needs to have color temperature control. 164 //! \note If this transaction is for a light, the light needs to have color temperature control.
149 - StateTransaction&& incrementColorTemperature(int increment) &&; 165 + StateTransaction& incrementColorTemperature(int increment);
150 //! \brief Increment/Decrement color xy. 166 //! \brief Increment/Decrement color xy.
151 //! \param xInc x color coordinate change from -0.5 to 0.5. 167 //! \param xInc x color coordinate change from -0.5 to 0.5.
152 //! \param yInc y color coordinate change from -0.5 to 0.5. 168 //! \param yInc y color coordinate change from -0.5 to 0.5.
153 //! \returns This transaction for chaining calls 169 //! \returns This transaction for chaining calls
154 //! \note If this transaction is for a light, the light needs to have rgb color control. 170 //! \note If this transaction is for a light, the light needs to have rgb color control.
155 - StateTransaction&& incrementColorXY(float xInc, float yInc) &&; 171 + StateTransaction& incrementColorXY(float xInc, float yInc);
156 //! \brief Set transition time for the request. 172 //! \brief Set transition time for the request.
157 //! \param transition Transition time in 100ms, default for any request is 400ms. 173 //! \param transition Transition time in 100ms, default for any request is 400ms.
158 //! \returns This transaction for chaining calls 174 //! \returns This transaction for chaining calls
159 //! \note The transition only applies to the current request. 175 //! \note The transition only applies to the current request.
160 //! A request without any changes only containing a transition is pointless and is not sent. 176 //! A request without any changes only containing a transition is pointless and is not sent.
161 - StateTransaction&& setTransition(uint16_t transition) &&; 177 + StateTransaction& setTransition(uint16_t transition);
162 //! \brief Trigger an alert. 178 //! \brief Trigger an alert.
163 //! 179 //!
164 //! The light performs one breathe cycle. 180 //! The light performs one breathe cycle.
165 //! \returns This transaction for chaining calls 181 //! \returns This transaction for chaining calls
166 - StateTransaction&& alert() &&; 182 + StateTransaction& alert();
167 //! \brief Trigger a long alert (15s). 183 //! \brief Trigger a long alert (15s).
168 //! \returns This transaction for chaining calls 184 //! \returns This transaction for chaining calls
169 - StateTransaction&& longAlert() &&; 185 + StateTransaction& longAlert();
170 //! \brief Stop an ongoing long alert. 186 //! \brief Stop an ongoing long alert.
171 //! \returns This transaction for chaining calls 187 //! \returns This transaction for chaining calls
172 - StateTransaction&& stopAlert() &&; 188 + StateTransaction& stopAlert();
173 189
174 protected: 190 protected:
175 //! \brief Remove parts from request that are already set in state 191 //! \brief Remove parts from request that are already set in state
src/StateTransaction.cpp
@@ -34,7 +34,7 @@ StateTransaction::StateTransaction(const HueCommandAPI&amp; commands, const std::str @@ -34,7 +34,7 @@ StateTransaction::StateTransaction(const HueCommandAPI&amp; commands, const std::str
34 : commands(commands), path(path), state(currentState), request(nlohmann::json::object()) 34 : commands(commands), path(path), state(currentState), request(nlohmann::json::object())
35 {} 35 {}
36 36
37 -bool StateTransaction::commit(bool trimRequest) && 37 +bool StateTransaction::commit(bool trimRequest)
38 { 38 {
39 const nlohmann::json& stateJson = (state != nullptr) ? *state : nlohmann::json::object(); 39 const nlohmann::json& stateJson = (state != nullptr) ? *state : nlohmann::json::object();
40 // Check this before request is trimmed 40 // Check this before request is trimmed
@@ -83,126 +83,126 @@ bool StateTransaction::commit(bool trimRequest) &amp;&amp; @@ -83,126 +83,126 @@ bool StateTransaction::commit(bool trimRequest) &amp;&amp;
83 return true; 83 return true;
84 } 84 }
85 85
86 -ScheduleCommand StateTransaction::toScheduleCommand() && 86 +ScheduleCommand StateTransaction::toScheduleCommand()
87 { 87 {
88 nlohmann::json command {{"method", "PUT"}, {"address", commands.combinedPath(path)}, {"body", request}}; 88 nlohmann::json command {{"method", "PUT"}, {"address", commands.combinedPath(path)}, {"body", request}};
89 return ScheduleCommand(command); 89 return ScheduleCommand(command);
90 } 90 }
91 91
92 -StateTransaction&& StateTransaction::setOn(bool on) && 92 +StateTransaction& StateTransaction::setOn(bool on)
93 { 93 {
94 request["on"] = on; 94 request["on"] = on;
95 - return std::move(*this); 95 + return *this;
96 } 96 }
97 97
98 -StateTransaction&& StateTransaction::setBrightness(uint8_t brightness) && 98 +StateTransaction& StateTransaction::setBrightness(uint8_t brightness)
99 { 99 {
100 uint8_t clamped = std::min<uint8_t>(brightness, 254); 100 uint8_t clamped = std::min<uint8_t>(brightness, 254);
101 request["bri"] = clamped; 101 request["bri"] = clamped;
102 - return std::move(*this); 102 + return *this;
103 } 103 }
104 104
105 -StateTransaction&& StateTransaction::setColorSaturation(uint8_t saturation) && 105 +StateTransaction& StateTransaction::setColorSaturation(uint8_t saturation)
106 { 106 {
107 uint8_t clamped = std::min<uint8_t>(saturation, 254); 107 uint8_t clamped = std::min<uint8_t>(saturation, 254);
108 request["sat"] = clamped; 108 request["sat"] = clamped;
109 - return std::move(*this); 109 + return *this;
110 } 110 }
111 111
112 -StateTransaction&& StateTransaction::setColorHue(uint16_t hue) && 112 +StateTransaction& StateTransaction::setColorHue(uint16_t hue)
113 { 113 {
114 request["hue"] = hue; 114 request["hue"] = hue;
115 - return std::move(*this); 115 + return *this;
116 } 116 }
117 117
118 -StateTransaction&& StateTransaction::setColor(const HueSaturation& hueSat) 118 +StateTransaction& StateTransaction::setColor(const HueSaturation& hueSat)
119 { 119 {
120 request["hue"] = std::max(0, std::min(hueSat.hue, (1 << 16) - 1)); 120 request["hue"] = std::max(0, std::min(hueSat.hue, (1 << 16) - 1));
121 request["sat"] = std::max(0, std::min(hueSat.saturation, 254)); 121 request["sat"] = std::max(0, std::min(hueSat.saturation, 254));
122 - return std::move(*this); 122 + return *this;
123 } 123 }
124 124
125 -StateTransaction&& StateTransaction::setColor(const XY& xy) && 125 +StateTransaction& StateTransaction::setColor(const XY& xy)
126 { 126 {
127 float clampedX = std::max(0.f, std::min(xy.x, 1.f)); 127 float clampedX = std::max(0.f, std::min(xy.x, 1.f));
128 float clampedY = std::max(0.f, std::min(xy.y, 1.f)); 128 float clampedY = std::max(0.f, std::min(xy.y, 1.f));
129 request["xy"] = {clampedX, clampedY}; 129 request["xy"] = {clampedX, clampedY};
130 - return std::move(*this); 130 + return *this;
131 } 131 }
132 132
133 -StateTransaction&& StateTransaction::setColor(const XYBrightness& xy) && 133 +StateTransaction& StateTransaction::setColor(const XYBrightness& xy)
134 { 134 {
135 int clamped = std::max(0, std::min(static_cast<int>(std::round(xy.brightness * 254.f)), 254)); 135 int clamped = std::max(0, std::min(static_cast<int>(std::round(xy.brightness * 254.f)), 254));
136 request["bri"] = clamped; 136 request["bri"] = clamped;
137 137
138 - return std::move(*this).setColor(xy.xy); 138 + return this->setColor(xy.xy);
139 } 139 }
140 140
141 -StateTransaction&& StateTransaction::setColorTemperature(unsigned int mired) && 141 +StateTransaction& StateTransaction::setColorTemperature(unsigned int mired)
142 { 142 {
143 unsigned int clamped = std::max(153u, std::min(mired, 500u)); 143 unsigned int clamped = std::max(153u, std::min(mired, 500u));
144 request["ct"] = clamped; 144 request["ct"] = clamped;
145 - return std::move(*this); 145 + return *this;
146 } 146 }
147 147
148 -StateTransaction&& StateTransaction::setColorLoop(bool on) && 148 +StateTransaction& StateTransaction::setColorLoop(bool on)
149 { 149 {
150 request["effect"] = on ? "colorloop" : "none"; 150 request["effect"] = on ? "colorloop" : "none";
151 - return std::move(*this); 151 + return *this;
152 } 152 }
153 153
154 -StateTransaction&& StateTransaction::incrementBrightness(int increment) && 154 +StateTransaction& StateTransaction::incrementBrightness(int increment)
155 { 155 {
156 request["bri_inc"] = std::max(-254, std::min(increment, 254)); 156 request["bri_inc"] = std::max(-254, std::min(increment, 254));
157 - return std::move(*this); 157 + return *this;
158 } 158 }
159 159
160 -StateTransaction&& StateTransaction::incrementSaturation(int increment) && 160 +StateTransaction& StateTransaction::incrementSaturation(int increment)
161 { 161 {
162 request["sat_inc"] = std::max(-254, std::min(increment, 254)); 162 request["sat_inc"] = std::max(-254, std::min(increment, 254));
163 - return std::move(*this); 163 + return *this;
164 } 164 }
165 165
166 -StateTransaction&& StateTransaction::incrementHue(int increment) && 166 +StateTransaction& StateTransaction::incrementHue(int increment)
167 { 167 {
168 request["hue_inc"] = std::max(-65534, std::min(increment, 65534)); 168 request["hue_inc"] = std::max(-65534, std::min(increment, 65534));
169 - return std::move(*this); 169 + return *this;
170 } 170 }
171 171
172 -StateTransaction&& StateTransaction::incrementColorTemperature(int increment) && 172 +StateTransaction& StateTransaction::incrementColorTemperature(int increment)
173 { 173 {
174 request["ct_inc"] = std::max(-65534, std::min(increment, 65534)); 174 request["ct_inc"] = std::max(-65534, std::min(increment, 65534));
175 - return std::move(*this); 175 + return *this;
176 } 176 }
177 177
178 -StateTransaction&& StateTransaction::incrementColorXY(float xInc, float yInc) && 178 +StateTransaction& StateTransaction::incrementColorXY(float xInc, float yInc)
179 { 179 {
180 request["xy_inc"] = {std::max(-0.5f, std::min(xInc, 0.5f)), std::max(-0.5f, std::min(yInc, 0.5f))}; 180 request["xy_inc"] = {std::max(-0.5f, std::min(xInc, 0.5f)), std::max(-0.5f, std::min(yInc, 0.5f))};
181 - return std::move(*this); 181 + return *this;
182 } 182 }
183 183
184 -StateTransaction&& StateTransaction::setTransition(uint16_t transition) && 184 +StateTransaction& StateTransaction::setTransition(uint16_t transition)
185 { 185 {
186 if (transition != 4) 186 if (transition != 4)
187 { 187 {
188 request["transitiontime"] = transition; 188 request["transitiontime"] = transition;
189 } 189 }
190 - return std::move(*this); 190 + return *this;
191 } 191 }
192 -StateTransaction&& StateTransaction::alert() && 192 +StateTransaction& StateTransaction::alert()
193 { 193 {
194 request["alert"] = "select"; 194 request["alert"] = "select";
195 - return std::move(*this); 195 + return *this;
196 } 196 }
197 -StateTransaction&& StateTransaction::longAlert() && 197 +StateTransaction& StateTransaction::longAlert()
198 { 198 {
199 request["alert"] = "lselect"; 199 request["alert"] = "lselect";
200 - return std::move(*this); 200 + return *this;
201 } 201 }
202 -StateTransaction&& StateTransaction::stopAlert() && 202 +StateTransaction& StateTransaction::stopAlert()
203 { 203 {
204 request["alert"] = "none"; 204 request["alert"] = "none";
205 - return std::move(*this); 205 + return *this;
206 } 206 }
207 207
208 void StateTransaction::trimRequest() 208 void StateTransaction::trimRequest()
test/TestTransaction.h
@@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
33 class TestTransaction : public hueplusplus::StateTransaction 33 class TestTransaction : public hueplusplus::StateTransaction
34 { 34 {
35 public: 35 public:
36 - TestTransaction(hueplusplus::StateTransaction&& t) : hueplusplus::StateTransaction(std::move(t)) {} 36 + TestTransaction(hueplusplus::StateTransaction& t) : hueplusplus::StateTransaction(std::move(t)) {}
37 37
38 nlohmann::json getRequest() const { return request; } 38 nlohmann::json getRequest() const { return request; }
39 nlohmann::json getResponse() const 39 nlohmann::json getResponse() const