diff --git a/include/hueplusplus/StateTransaction.h b/include/hueplusplus/StateTransaction.h index 459825e..a265154 100644 --- a/include/hueplusplus/StateTransaction.h +++ b/include/hueplusplus/StateTransaction.h @@ -42,6 +42,22 @@ namespace hueplusplus //! \note The transaction has an internal reference to the light state. //! You must not cause a refresh of the state between creating and committing the transaction //! (e.g. non-const getters/setters), because that invalidates the reference. +//! +//!

Advanced usage

+//! Another way to use the transaction is by storing it and building up the calls separately. +//! \code +//! hueplusplus::StateTransaction t = light.transaction(); +//! if(shouldTurnOn) +//! t.setOn(true); +//! t.commit(); +//! \endcode +//! In this case, it is especially important that the light and the state of the light MUST NOT invalidate. +//! That means +//! \li the light variable has to live longer than the transaction +//! \li especially no non-const method calls on the light while the transaction is open, +//! or committing other transactions +//! +//! In general, this method is easier to screw up and should only be used when really necessary. class StateTransaction { public: @@ -67,109 +83,109 @@ public: //! \throws HueException when response contains no body //! \throws HueAPIResponseException when response contains an error //! \throws nlohmann::json::parse_error when response could not be parsed - bool commit(bool trimRequest = true) &&; + bool commit(bool trimRequest = true); //! \brief Create a ScheduleCommand from the transaction //! \returns A ScheduleCommand that can be used to execute this transaction on a Schedule. - ScheduleCommand toScheduleCommand() &&; + ScheduleCommand toScheduleCommand(); //! \brief Turn light on or off. //! \param on true for on, false for off //! \returns This transaction for chaining calls - StateTransaction&& setOn(bool on) &&; + StateTransaction& setOn(bool on); //! \brief Set light brightness. //! \param brightness Brightness from 0 = off to 254 = fully lit. //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have brightness control. //! \note Brightness 0 will also turn off the light if nothing else is specified, //! any other value will also turn on the light. - StateTransaction&& setBrightness(uint8_t brightness) &&; + StateTransaction& setBrightness(uint8_t brightness); //! \brief Set light hue. //! \param hue Color hue from 0 to 65535 //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. //! \note Will also turn on the light if nothing else is specified - StateTransaction&& setColorHue(uint16_t hue) &&; + StateTransaction& setColorHue(uint16_t hue); //! \brief Set light saturation. //! \param saturation Color saturation from 0 to 254 //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. //! \note Will also turn on the light if nothing else is specified - StateTransaction&& setColorSaturation(uint8_t saturation) &&; + StateTransaction& setColorSaturation(uint8_t saturation); //! \brief Set light color in hue and saturation //! \param hueSat Color in hue and saturation //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. //! \note Will also turn on the light if nothing else is specified - StateTransaction&& setColor(const HueSaturation& hueSat); + StateTransaction& setColor(const HueSaturation& hueSat); //! \brief Set light color in xy space (without brightness). //! \param xy x and y coordinates in CIE color space //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. //! \note Will also turn on the light if nothing else is specified - StateTransaction&& setColor(const XY& xy) &&; + StateTransaction& setColor(const XY& xy); //! \brief Set light color and brightness in xy space //! \param xy x,y and brightness in CIE color space //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. //! \note Will also turn on the light if nothing else is specified - StateTransaction&& setColor(const XYBrightness& xy) &&; + StateTransaction& setColor(const XYBrightness& xy); //! \brief Set light color temperature. //! \param mired Color temperature in mired from 153 to 500 //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have color temperature control. //! \note Will also turn on the light if nothing else is specified - StateTransaction&& setColorTemperature(unsigned int mired) &&; + StateTransaction& setColorTemperature(unsigned int mired); //! \brief Enables or disables color loop. //! \param on true to enable, false to disable color loop. //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. //! \note Will also turn on the light if nothing else is specified - StateTransaction&& setColorLoop(bool on) &&; + StateTransaction& setColorLoop(bool on); //! \brief Increment/Decrement brightness. //! \param increment Brightness change from -254 to 254. //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have brightness control. - StateTransaction&& incrementBrightness(int increment) &&; + StateTransaction& incrementBrightness(int increment); //! \brief Increment/Decrement saturaction. //! \param increment Saturation change from -254 to 254. //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. - StateTransaction&& incrementSaturation(int increment) &&; + StateTransaction& incrementSaturation(int increment); //! \brief Increment/Decrement hue. //! \param increment Hue change from -65535 to 65535. //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. - StateTransaction&& incrementHue(int increment) &&; + StateTransaction& incrementHue(int increment); //! \brief Increment/Decrement color temperature. //! \param increment Color temperature change in mired from -65535 to 65535. //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have color temperature control. - StateTransaction&& incrementColorTemperature(int increment) &&; + StateTransaction& incrementColorTemperature(int increment); //! \brief Increment/Decrement color xy. //! \param xInc x color coordinate change from -0.5 to 0.5. //! \param yInc y color coordinate change from -0.5 to 0.5. //! \returns This transaction for chaining calls //! \note If this transaction is for a light, the light needs to have rgb color control. - StateTransaction&& incrementColorXY(float xInc, float yInc) &&; + StateTransaction& incrementColorXY(float xInc, float yInc); //! \brief Set transition time for the request. //! \param transition Transition time in 100ms, default for any request is 400ms. //! \returns This transaction for chaining calls //! \note The transition only applies to the current request. //! A request without any changes only containing a transition is pointless and is not sent. - StateTransaction&& setTransition(uint16_t transition) &&; + StateTransaction& setTransition(uint16_t transition); //! \brief Trigger an alert. //! //! The light performs one breathe cycle. //! \returns This transaction for chaining calls - StateTransaction&& alert() &&; + StateTransaction& alert(); //! \brief Trigger a long alert (15s). //! \returns This transaction for chaining calls - StateTransaction&& longAlert() &&; + StateTransaction& longAlert(); //! \brief Stop an ongoing long alert. //! \returns This transaction for chaining calls - StateTransaction&& stopAlert() &&; + StateTransaction& stopAlert(); protected: //! \brief Remove parts from request that are already set in state diff --git a/src/StateTransaction.cpp b/src/StateTransaction.cpp index 8d6edb4..e106a8d 100644 --- a/src/StateTransaction.cpp +++ b/src/StateTransaction.cpp @@ -34,7 +34,7 @@ StateTransaction::StateTransaction(const HueCommandAPI& commands, const std::str : commands(commands), path(path), state(currentState), request(nlohmann::json::object()) {} -bool StateTransaction::commit(bool trimRequest) && +bool StateTransaction::commit(bool trimRequest) { const nlohmann::json& stateJson = (state != nullptr) ? *state : nlohmann::json::object(); // Check this before request is trimmed @@ -83,126 +83,126 @@ bool StateTransaction::commit(bool trimRequest) && return true; } -ScheduleCommand StateTransaction::toScheduleCommand() && +ScheduleCommand StateTransaction::toScheduleCommand() { nlohmann::json command {{"method", "PUT"}, {"address", commands.combinedPath(path)}, {"body", request}}; return ScheduleCommand(command); } -StateTransaction&& StateTransaction::setOn(bool on) && +StateTransaction& StateTransaction::setOn(bool on) { request["on"] = on; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setBrightness(uint8_t brightness) && +StateTransaction& StateTransaction::setBrightness(uint8_t brightness) { uint8_t clamped = std::min(brightness, 254); request["bri"] = clamped; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setColorSaturation(uint8_t saturation) && +StateTransaction& StateTransaction::setColorSaturation(uint8_t saturation) { uint8_t clamped = std::min(saturation, 254); request["sat"] = clamped; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setColorHue(uint16_t hue) && +StateTransaction& StateTransaction::setColorHue(uint16_t hue) { request["hue"] = hue; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setColor(const HueSaturation& hueSat) +StateTransaction& StateTransaction::setColor(const HueSaturation& hueSat) { request["hue"] = std::max(0, std::min(hueSat.hue, (1 << 16) - 1)); request["sat"] = std::max(0, std::min(hueSat.saturation, 254)); - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setColor(const XY& xy) && +StateTransaction& StateTransaction::setColor(const XY& xy) { float clampedX = std::max(0.f, std::min(xy.x, 1.f)); float clampedY = std::max(0.f, std::min(xy.y, 1.f)); request["xy"] = {clampedX, clampedY}; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setColor(const XYBrightness& xy) && +StateTransaction& StateTransaction::setColor(const XYBrightness& xy) { int clamped = std::max(0, std::min(static_cast(std::round(xy.brightness * 254.f)), 254)); request["bri"] = clamped; - return std::move(*this).setColor(xy.xy); + return this->setColor(xy.xy); } -StateTransaction&& StateTransaction::setColorTemperature(unsigned int mired) && +StateTransaction& StateTransaction::setColorTemperature(unsigned int mired) { unsigned int clamped = std::max(153u, std::min(mired, 500u)); request["ct"] = clamped; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setColorLoop(bool on) && +StateTransaction& StateTransaction::setColorLoop(bool on) { request["effect"] = on ? "colorloop" : "none"; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::incrementBrightness(int increment) && +StateTransaction& StateTransaction::incrementBrightness(int increment) { request["bri_inc"] = std::max(-254, std::min(increment, 254)); - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::incrementSaturation(int increment) && +StateTransaction& StateTransaction::incrementSaturation(int increment) { request["sat_inc"] = std::max(-254, std::min(increment, 254)); - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::incrementHue(int increment) && +StateTransaction& StateTransaction::incrementHue(int increment) { request["hue_inc"] = std::max(-65534, std::min(increment, 65534)); - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::incrementColorTemperature(int increment) && +StateTransaction& StateTransaction::incrementColorTemperature(int increment) { request["ct_inc"] = std::max(-65534, std::min(increment, 65534)); - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::incrementColorXY(float xInc, float yInc) && +StateTransaction& StateTransaction::incrementColorXY(float xInc, float yInc) { request["xy_inc"] = {std::max(-0.5f, std::min(xInc, 0.5f)), std::max(-0.5f, std::min(yInc, 0.5f))}; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::setTransition(uint16_t transition) && +StateTransaction& StateTransaction::setTransition(uint16_t transition) { if (transition != 4) { request["transitiontime"] = transition; } - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::alert() && +StateTransaction& StateTransaction::alert() { request["alert"] = "select"; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::longAlert() && +StateTransaction& StateTransaction::longAlert() { request["alert"] = "lselect"; - return std::move(*this); + return *this; } -StateTransaction&& StateTransaction::stopAlert() && +StateTransaction& StateTransaction::stopAlert() { request["alert"] = "none"; - return std::move(*this); + return *this; } void StateTransaction::trimRequest() diff --git a/test/TestTransaction.h b/test/TestTransaction.h index 71b71eb..489cafb 100644 --- a/test/TestTransaction.h +++ b/test/TestTransaction.h @@ -33,7 +33,7 @@ class TestTransaction : public hueplusplus::StateTransaction { public: - TestTransaction(hueplusplus::StateTransaction&& t) : hueplusplus::StateTransaction(std::move(t)) {} + TestTransaction(hueplusplus::StateTransaction& t) : hueplusplus::StateTransaction(std::move(t)) {} nlohmann::json getRequest() const { return request; } nlohmann::json getResponse() const