~aleteoryx/muditaos

074b33a6459740ac9a6762ef74c93ebfebbfe8ff — Adam Wulkiewicz 3 years ago 496e53b
[MOS-685] Make small improvements in various places of the code

- Forward arguments
- Remove unused code
- Remove auto return type when it's not needed
- Add const to member functions
- Use startsWith and endsWith from utils
- Allow instantiation of operators only for specific types
- Caluclate key mask in compile time
M module-apps/application-alarm-clock/models/AlarmsRepository.cpp => module-apps/application-alarm-clock/models/AlarmsRepository.cpp +2 -2
@@ 35,9 35,9 @@ namespace app::alarmClock
    }

    template <class Request, class Result, typename... Args>
    void AlarmsDBRepository::GetQuery(const AbstractAlarmsRepository::OnResultCallback &callback, Args... args)
    void AlarmsDBRepository::GetQuery(const AbstractAlarmsRepository::OnResultCallback &callback, Args &&...args)
    {
        auto task = async(std::make_unique<Request>(args...), service::name::service_time);
        auto task = async(std::make_unique<Request>(std::forward<Args>(args)...), service::name::service_time);
        auto cb   = [callback](auto response) {
            auto result = dynamic_cast<Result *>(response);
            if (result == nullptr) {

M module-apps/application-alarm-clock/models/AlarmsRepository.hpp => module-apps/application-alarm-clock/models/AlarmsRepository.hpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 33,7 33,7 @@ namespace app::alarmClock
        // void GetQuery(std::unique_ptr<sys::DataMessage> query, const AbstractAlarmsRepository::OnResultCallback
        // &callback);
        template <class QueryType, class ResultType, typename... Args>
        void GetQuery(const AbstractAlarmsRepository::OnResultCallback &callback, Args... args);
        void GetQuery(const AbstractAlarmsRepository::OnResultCallback &callback, Args &&...args);
        void add(const AlarmEventRecord &alarm, const OnResultCallback &callback) override;
        void remove(const AlarmEventRecord &alarm, const OnResultCallback &callback) override;
        void update(const AlarmEventRecord &alarm, const OnResultCallback &callback) override;

M module-apps/apps-common/widgets/spinners/StringOutputSpinner.hpp => module-apps/apps-common/widgets/spinners/StringOutputSpinner.hpp +1 -20
@@ 8,25 8,6 @@
#include <string>
#include <type_traits>

namespace details
{
    template <typename T, typename = void>
    struct container_data
    {
        using value = T;
    };

    template <typename T>
    struct container_data<T, std::enable_if_t<not std::is_fundamental_v<T>>>
    {
        using value = typename T::value_type;
    };

    template <class T>
    using container_data_v = typename container_data<T>::value;

} // namespace details

namespace gui
{
    // This spinner operates on container elements and transforms the current container into a string.


@@ 38,7 19,7 @@ namespace gui
    {
      public:
        using range      = typename Container::range;
        using value_type = details::container_data_v<Container>;
        using value_type = typename Container::value_type;

        explicit StringOutputSpinner(Container &&container, Orientation orientation = Orientation::Vertical)
            : container{std::move(container)}, orientation{orientation}

M module-db/Database/DatabaseInitializer.cpp => module-db/Database/DatabaseInitializer.cpp +5 -3
@@ 3,6 3,9 @@

#include "DatabaseInitializer.hpp"

#include <log/log.hpp>
#include <Utils.hpp>

#include <algorithm>
#include <cstdio>
#include <memory>


@@ 11,7 14,6 @@
#include <string>
#include <sstream>
#include <array>
#include <log/log.hpp>

DatabaseInitializer::DatabaseInitializer(Database *db) : db(db)
{}


@@ 76,11 78,11 @@ std::vector<std::string> DatabaseInitializer::readCommands(std::filesystem::path
            line += c;
        }
        else {
            if (line.empty() || starts_with(line, std::string("--"))) {
            if (line.empty() || utils::startsWith(line, "--")) {
                line.clear();
                continue;
            }
            if (ends_with(line, std::string(";"))) {
            if (utils::endsWith(line, ";")) {
                statements.push_back(currentStatement + line);
                currentStatement.clear();
                line.clear();

M module-db/Database/DatabaseInitializer.hpp => module-db/Database/DatabaseInitializer.hpp +0 -18
@@ 7,24 7,6 @@
#include <fstream>
#include <filesystem>

namespace
{
    template <typename T>
    inline bool starts_with(const T &str, const T &start)
    {
        if (start.size() > str.size())
            return false;
        return str.compare(0, start.size(), start) == 0;
    }
    template <typename T>
    inline bool ends_with(const T &str, const T &end)
    {
        if (end.size() > str.size())
            return false;
        return std::equal(end.rbegin(), end.rend(), str.rbegin());
    }
} // namespace

class DatabaseInitializer
{
    class ScopedFile

M module-db/tests/DbInitializer.cpp => module-db/tests/DbInitializer.cpp +5 -3
@@ 3,10 3,12 @@

#include "module-db/Database/DatabaseInitializer.hpp"

#include <log/log.hpp>
#include <Utils.hpp>

#include <algorithm>
#include <set>
#include <array>
#include <log/log.hpp>

DatabaseInitializer::DatabaseInitializer(Database *db) : db(db)
{}


@@ 62,11 64,11 @@ std::vector<std::string> DatabaseInitializer::readCommands(std::filesystem::path
            line += c;
        }
        else {
            if (line.empty() || starts_with(line, std::string("--"))) {
            if (line.empty() || utils::startsWith(line, "--")) {
                line.clear();
                continue;
            }
            if (ends_with(line, std::string(";"))) {
            if (utils::endsWith(line, ";")) {
                statements.push_back(currentStatement + line);
                currentStatement.clear();
                line.clear();

M module-gui/gui/Common.hpp => module-gui/gui/Common.hpp +55 -52
@@ 79,60 79,63 @@ namespace gui
        Horizontal
    };

    template <class T>
    bool operator&(const T &lhs, const T &rhs)
    // This namespace exists to prevent instantiation of operators for other classes from namespace gui
    namespace rectangle_enums
    {
        return static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs);
    }
    template <class T>
    T operator|(const T &lhs, const T &rhs)
    {
        return static_cast<T>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
    }
    template <class T>
    T operator|=(const T &lhs, const T &rhs)
    {
        lhs = lhs | rhs;
        return lhs;
    }

    enum class RectangleEdge
    {
        None   = 0x00,
        Top    = 0x01,
        Bottom = 0x02,
        Left   = 0x04,
        Right  = 0x08,
        All    = 0x0F
    };

    enum class RectangleRoundedCorner
    {
        None        = 0x00,
        TopLeft     = 0x10,
        TopRight    = 0x20,
        BottomLeft  = 0x40,
        BottomRight = 0x80,
        All         = 0xF0,
    };

    enum class RectangleFlatEdge
    {
        None        = 0x00,
        TopLeft     = 0x01,
        TopRight    = 0x02,
        BottomLeft  = 0x04,
        BottomRight = 0x08
    };
        enum class RectangleEdge
        {
            None   = 0x00,
            Top    = 0x01,
            Bottom = 0x02,
            Left   = 0x04,
            Right  = 0x08,
            All    = 0x0F
        };

        enum class RectangleFlatEdge
        {
            None        = 0x00,
            TopLeft     = 0x01,
            TopRight    = 0x02,
            BottomLeft  = 0x04,
            BottomRight = 0x08
        };

        enum class RectangleRoundedCorner
        {
            None        = 0x00,
            TopLeft     = 0x10,
            TopRight    = 0x20,
            BottomLeft  = 0x40,
            BottomRight = 0x80,
            All         = 0xF0,
        };

        enum class RectangleYap
        {
            None        = 0x00,
            TopLeft     = 0x10,
            TopRight    = 0x20,
            BottomLeft  = 0x40,
            BottomRight = 0x80,
        };

        template <class T>
        inline bool operator&(const T &lhs, const T &rhs)
        {
            return static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs);
        }
        template <class T>
        inline T operator|(const T &lhs, const T &rhs)
        {
            return static_cast<T>(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
        }
    } // namespace rectangle_enums

    enum class RectangleYap
    {
        None        = 0x00,
        TopLeft     = 0x10,
        TopRight    = 0x20,
        BottomLeft  = 0x40,
        BottomRight = 0x80,
    };
    using rectangle_enums::RectangleEdge;
    using rectangle_enums::RectangleFlatEdge;
    using rectangle_enums::RectangleRoundedCorner;
    using rectangle_enums::RectangleYap;

    enum class Boundaries
    {

M module-gui/gui/widgets/BoxLayout.cpp => module-gui/gui/widgets/BoxLayout.cpp +5 -10
@@ 411,12 411,7 @@ namespace gui

    std::list<Item *>::iterator BoxLayout::nextNavigationItem(std::list<Item *>::iterator from)
    {
        return std::find_if(from, this->children.end(), [](auto &el) -> bool {
            if (el->isActive()) {
                return true;
            }
            return false;
        });
        return std::find_if(from, this->children.end(), [](const auto &el) { return el->isActive(); });
    }

    std::list<Item *>::iterator BoxLayout::getNavigationFocusedItem()


@@ 465,7 460,7 @@ namespace gui
    }

    template <Axis axis>
    auto BoxLayout::handleRequestResize(const Item *child, Length request_w, Length request_h) -> Size
    Size BoxLayout::handleRequestResize(const Item *child, Length request_w, Length request_h)
    {
        if (parent != nullptr) {
            auto [w, h] = requestSize(request_w, request_h);


@@ 570,7 565,7 @@ namespace gui
        return nullptr;
    }

    auto BoxLayout::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool
    bool BoxLayout::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
    {
        addFromOutOfDrawAreaList();
        resizeItems();


@@ 613,7 608,7 @@ namespace gui
        BoxLayout::addWidget<Axis::X>(item);
    }

    auto HBox::handleRequestResize(const Item *child, Length request_w, Length request_h) -> Size
    Size HBox::handleRequestResize(const Item *child, Length request_w, Length request_h)
    {
        return BoxLayout::handleRequestResize<Axis::X>(child, request_w, request_h);
    }


@@ 639,7 634,7 @@ namespace gui
        BoxLayout::addWidget<Axis::Y>(item);
    }

    auto VBox::handleRequestResize(const Item *child, Length request_w, Length request_h) -> Size
    Size VBox::handleRequestResize(const Item *child, Length request_w, Length request_h)
    {
        return BoxLayout::handleRequestResize<Axis::Y>(child, request_w, request_h);
    }

M module-gui/gui/widgets/BoxLayout.hpp => module-gui/gui/widgets/BoxLayout.hpp +4 -4
@@ 130,8 130,8 @@ namespace gui
        bool setFocusOnElement(unsigned int elementNumber);
        void setFocusOnLastElement();
        template <Axis axis>
        auto handleRequestResize(const Item *, Length request_w, Length request_h) -> Size;
        auto onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) -> bool override;
        Size handleRequestResize(const Item *, Length request_w, Length request_h);
        bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
        void handleContentChanged() override;
        /// Get primary sizes used in axis dominant layouts
        Length getPrimarySizeLeft();


@@ 146,7 146,7 @@ namespace gui
        HBox(Item *parent, const uint32_t &x = 0, const uint32_t &y = 0, const uint32_t &w = 0, const uint32_t &h = 0);
        virtual ~HBox() = default;
        virtual void addWidget(Item *item) override;
        auto handleRequestResize(const Item *, Length request_w, Length request_h) -> Size override;
        Size handleRequestResize(const Item *, Length request_w, Length request_h) override;
    };

    class VBox : public BoxLayout


@@ 157,7 157,7 @@ namespace gui
        VBox(Item *parent, const uint32_t &x = 0, const uint32_t &y = 0, const uint32_t &w = 0, const uint32_t &h = 0);
        virtual ~VBox() = default;
        virtual void addWidget(Item *item) override;
        auto handleRequestResize(const Item *, Length request_w, Length request_h) -> Size override;
        Size handleRequestResize(const Item *, Length request_w, Length request_h) override;
    };

} /* namespace gui */

M module-gui/gui/widgets/Item.cpp => module-gui/gui/widgets/Item.cpp +4 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "Item.hpp"


@@ 157,7 157,7 @@ namespace gui
        setArea({widgetArea.x, y, widgetArea.w, widgetArea.h});
    }

    auto Item::requestSize(Length request_w, Length request_h) -> Size
    Size Item::requestSize(Length request_w, Length request_h)
    {
        if (parent == nullptr) {
            setSize(request_w, request_h);


@@ 166,7 166,7 @@ namespace gui
        return parent->handleRequestResize(this, request_w, request_h);
    }

    auto Item::handleRequestResize(const Item *it, Length request_w, Length request_h) -> Size
    Size Item::handleRequestResize(const Item *it, Length request_w, Length request_h)
    {
        if (it == nullptr) {
            return {0, 0};


@@ 530,7 530,7 @@ namespace gui
        return false;
    }

    auto Item::onTimer(sys::Timer &timer) -> bool
    bool Item::onTimer(sys::Timer &timer)
    {
        if (timerCallback != nullptr) {
            return timerCallback(*this, timer);

M module-gui/gui/widgets/Item.hpp => module-gui/gui/widgets/Item.hpp +5 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 79,7 79,7 @@ namespace gui
        BoundingBox drawArea; // drawableArea would be more accurate
                              // maximal bounding box size
        /// gets bounding box for selected area
        auto area(Area which = Area::Normal) -> BoundingBox &
        BoundingBox &area(Area which = Area::Normal)
        {
            switch (which) {
            case Area::Min:


@@ 268,7 268,7 @@ namespace gui
        /// requests bigger size from parent if parent available
        /// if no parent available - sets size
        /// @return true if handled positively
        virtual auto requestSize(Length request_w, Length request_h) -> Size final;
        virtual Size requestSize(Length request_w, Length request_h) final;
        /// handle for layouts to implement to resize on demand ( i.e. when it needs to expand after
        /// addition/removal of chars )
        ///


@@ 282,7 282,7 @@ namespace gui
        /// should be handled without infinite loop on resize ( item->setSize -> notify Layout -> layout: item->setSize
        /// )
        /// @return bool requested size granted {w,h}
        virtual auto handleRequestResize(const Item *, Length request_w, Length request_h) -> Size;
        virtual Size handleRequestResize(const Item *, Length request_w, Length request_h);

        /// flag informing that content has changed
        bool contentChanged = false;


@@ 392,7 392,7 @@ namespace gui

        /// simple check function to determine if item is active && visible.
        /// @return true if item is active and visible. Otherwise false.
        inline bool isActive()
        inline bool isActive() const
        {
            return (activeItem && visible);
        }

M module-services/service-time/AlarmServiceAPI.cpp => module-services/service-time/AlarmServiceAPI.cpp +2 -2
@@ 14,9 14,9 @@ namespace alarms
    namespace AlarmServiceAPI
    {
        template <class requestType, typename... Types>
        bool sendRequest(sys::Service *serv, Types... messageArgs)
        bool sendRequest(sys::Service *serv, Types &&...messageArgs)
        {
            auto msg = std::make_shared<requestType>(messageArgs...);
            auto msg = std::make_shared<requestType>(std::forward<Types>(messageArgs)...);
            return serv->bus.sendUnicast(msg, service::name::service_time);
        }


M module-utils/utility/Utils.hpp => module-utils/utility/Utils.hpp +6 -2
@@ 75,10 75,14 @@ namespace utils
        return bytes;
    }

    inline bool startsWith(std::string const &str, std::string const &prefix)
    {
        return prefix.size() <= str.size() && std::equal(prefix.begin(), prefix.end(), str.begin());
    }

    inline bool endsWith(std::string const &str, std::string const &suffix)
    {
        return str.size() >= suffix.size() &&
               std::equal(str.begin() + (str.size() - suffix.size()), str.end(), suffix.begin());
        return suffix.size() <= str.size() && std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
    }

    static inline std::string removeNewLines(const std::string &s)

M module-utils/utility/tests/unittest_utils.cpp => module-utils/utility/tests/unittest_utils.cpp +47 -4
@@ 526,6 526,44 @@ TEST_CASE("Byte to hex")
    }
}

TEST_CASE("Starts with")
{
    SECTION("Empty string")
    {
        REQUIRE((utils::startsWith("", "abc") == false));
    }

    SECTION("Empty prefix")
    {
        REQUIRE((utils::startsWith("abc", "") == true));
    }

    SECTION("Empty string and prefix")
    {
        REQUIRE((utils::startsWith("", "") == true));
    }

    SECTION("Prefix almost at the beginning of string")
    {
        REQUIRE((utils::startsWith("Abcde", "bcd") == false));
    }

    SECTION("Prefix containing the beginning of string and more")
    {
        REQUIRE((utils::startsWith("Abcde", "AAbc") == false));
    }

    SECTION("Prefix at the beginning of string")
    {
        REQUIRE((utils::startsWith("Abcde", "Ab") == true));
    }

    SECTION("Equal string and prefix")
    {
        REQUIRE((utils::startsWith("Abc", "Abc") == true));
    }
}

TEST_CASE("Ends with")
{
    SECTION("Empty string")


@@ 538,22 576,27 @@ TEST_CASE("Ends with")
        REQUIRE((utils::endsWith("abc", "") == true));
    }

    SECTION("Both empty")
    SECTION("Empty string and suffix")
    {
        REQUIRE((utils::endsWith("", "") == true));
    }

    SECTION("No")
    SECTION("Suffix almost at the end of string")
    {
        REQUIRE((utils::endsWith("Abcde", "cd") == false));
    }

    SECTION("Suffix containing the end of string and more")
    {
        REQUIRE((utils::endsWith("Abcde", "def") == false));
    }

    SECTION("Yes")
    SECTION("Suffix at the end of string")
    {
        REQUIRE((utils::endsWith("Abcde", "de") == true));
    }

    SECTION("Equal")
    SECTION("Equal string and suffix")
    {
        REQUIRE((utils::endsWith("Abc", "Abc") == true));
    }

M products/BellHybrid/keymap/include/keymap/KeyMap.hpp => products/BellHybrid/keymap/include/keymap/KeyMap.hpp +5 -14
@@ 61,29 61,20 @@ struct KeyStates
    {
        states.set(magic_enum::enum_integer(key), value);
    }
    bool state(KeyMap key)
    bool state(KeyMap key) const
    {
        return states.test(magic_enum::enum_integer(key));
    }

    std::size_t count()
    std::size_t count() const
    {
        return states.count();
    }

    template <typename... Args>
    bool ifOnlySet(Args... args)
    template <KeyMap... keys>
    bool ifOnlySet() const
    {
        const auto mask = (... | [](auto x) { return KeySet{1UL << magic_enum::enum_integer(x)}; }(args));
        return (states | mask) == mask;
    }

    template <std::size_t N>
    bool ifOnlySet(std::array<KeyMap, N> keys)
    {
        const auto mask = std::accumulate(keys.begin(), keys.end(), KeySet{}, [](auto m, auto val) {
            return m | KeySet{1UL << magic_enum::enum_integer(val)};
        });
        constexpr auto mask = KeySet{(... | (1UL << magic_enum::enum_integer(keys)))};
        return (states | mask) == mask;
    }


M products/BellHybrid/services/evtmgr/internal/key_sequences/GenericLongPressSequence.hpp => products/BellHybrid/services/evtmgr/internal/key_sequences/GenericLongPressSequence.hpp +3 -4
@@ 13,7 13,8 @@
template <KeyMap... keys>
class GenericLongPressSequence : public AbstractKeySequence
{
    using Keys = std::array<KeyMap, sizeof...(keys)>;
    static constexpr auto keysToScanCount = sizeof...(keys);

    enum class State
    {
        Idle,


@@ 32,7 33,7 @@ class GenericLongPressSequence : public AbstractKeySequence

        switch (state) {
        case State::Idle:
            if (keyStates.count() == keysToScanCount && keyStates.ifOnlySet(keysToScan)) {
            if (keyStates.count() == keysToScanCount && keyStates.ifOnlySet<keys...>()) {
                switch_to_in_progress();
            }
            break;


@@ 80,8 81,6 @@ class GenericLongPressSequence : public AbstractKeySequence
        timer.start();
    }

    static constexpr Keys keysToScan      = {keys...};
    static constexpr auto keysToScanCount = keysToScan.size();
    State state                           = State::Idle;
    KeyStates keyStates;
    sys::TimerHandle timer;