~aleteoryx/muditaos

ref: c424b6728020563f3d0cf6dc25fb12f9ada14b4f muditaos/module-services/service-time/AlarmOperations.hpp -rw-r--r-- 9.6 KiB
c424b672 — Mateusz Piesta [BH-1515] Revert bedtime changes 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "AlarmRepository.hpp"
#include "SnoozedAlarmEventRecord.hpp"

#include <service-time/AlarmHandlerFactory.hpp>
#include <service-time/AlarmStatus.hpp>

#include <module-db/Interface/AlarmEventRecord.hpp>

#include <Service/Service.hpp>

namespace alarms
{
    class IAlarmOperations
    {
      public:
        using OnGetAlarmProcessed           = std::function<void(AlarmEventRecord)>;
        using OnGetAlarmWithStatusProcessed = std::function<void(std::pair<AlarmEventRecord, AlarmStatus>)>;
        using OnGetAlarmsInRangeProcessed   = std::function<void(std::pair<std::vector<AlarmEventRecord>, uint32_t>)>;
        using OnAddAlarmProcessed           = std::function<void(bool)>;
        using OnUpdateAlarmProcessed        = std::function<void(bool)>;
        using OnRemoveAlarmProcessed        = std::function<void(bool)>;
        using OnGetFirstNextSingleProcessed = std::function<void(SingleEventRecord)>;
        using OnGetAlarmsProcessed          = std::function<void(std::vector<SingleEventRecord>)>;
        using OnSnoozeRingingAlarm          = std::function<void(bool)>;
        using OnTurnOffRingingAlarm         = std::function<void(bool)>;
        using OnGetSnoozedAlarms            = std::function<void(std::vector<SingleEventRecord>)>;
        using OnSnoozedAlarmsCountChange    = std::function<void(unsigned)>;
        using OnActiveAlarmCountChange      = std::function<void(bool)>;
        using OnToggleAllProcessed          = std::function<void(bool)>;

        virtual ~IAlarmOperations() noexcept = default;

        using GetCurrentTime = std::function<TimePoint()>;

        virtual void updateEventsCache(TimePoint now) = 0;

        virtual void getAlarm(const std::uint32_t alarmId, OnGetAlarmProcessed callback)                     = 0;
        virtual void getAlarmWithStatus(const std::uint32_t alarmId, OnGetAlarmWithStatusProcessed callback) = 0;
        virtual void addAlarm(AlarmEventRecord record, OnAddAlarmProcessed callback)                         = 0;
        virtual void updateAlarm(AlarmEventRecord record, OnUpdateAlarmProcessed callback)                   = 0;
        virtual void removeAlarm(const std::uint32_t alarmId, OnRemoveAlarmProcessed callback)               = 0;
        virtual void getAlarmsInRange(std::uint32_t offset,
                                      std::uint32_t limit,
                                      OnGetAlarmsInRangeProcessed callback)                                  = 0;
        virtual void getNextSingleEvents(TimePoint start, OnGetAlarmsProcessed callback)                     = 0;
        virtual void turnOffRingingAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback)             = 0;
        virtual void turnOffSnoozedAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback)             = 0;
        virtual void snoozeRingingAlarm(const std::uint32_t id,
                                        const TimePoint nextAlarmTime,
                                        OnSnoozeRingingAlarm callback)                                       = 0;
        virtual void postponeSnooze(const std::uint32_t id,
                                    const TimePoint nextAlarmTime,
                                    OnSnoozeRingingAlarm callback)                                           = 0;
        virtual void minuteUpdated(TimePoint now)                                                            = 0;
        virtual void addAlarmExecutionHandler(const alarms::AlarmType type,
                                              const std::shared_ptr<alarms::AlarmHandler> handler)           = 0;
        virtual void stopAllSnoozedAlarms()                                                                  = 0;
        virtual void addSnoozedAlarmsCountChangeCallback(OnSnoozedAlarmsCountChange)                         = 0;
        virtual void addActiveAlarmCountChangeCallback(OnActiveAlarmCountChange)                             = 0;
        virtual void toggleAll(bool toggle, OnToggleAll callback)                                            = 0;
        virtual void getSnoozedAlarms(OnGetSnoozedAlarms callback)                                           = 0;
    };

    class IAlarmOperationsFactory
    {
      public:
        virtual ~IAlarmOperationsFactory() noexcept = default;

        virtual std::unique_ptr<IAlarmOperations> create(
            sys::Service *service,
            std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
            IAlarmOperations::GetCurrentTime getCurrentTimeCallback) const = 0;
    };

    class AlarmOperationsCommon : public IAlarmOperations
    {
      public:
        AlarmOperationsCommon(std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
                              GetCurrentTime getCurrentTimeCallback);

        void updateEventsCache(TimePoint now) override;

        void getAlarm(const std::uint32_t alarmId, OnGetAlarmProcessed callback) override;
        void getAlarmWithStatus(const std::uint32_t alarmId, OnGetAlarmWithStatusProcessed callback) override;
        void addAlarm(AlarmEventRecord record, OnAddAlarmProcessed callback) override;
        void updateAlarm(AlarmEventRecord record, OnUpdateAlarmProcessed callback) override;
        void removeAlarm(const std::uint32_t alarmId, OnRemoveAlarmProcessed callback) override;
        void getAlarmsInRange(std::uint32_t offset, std::uint32_t limit, OnGetAlarmsInRangeProcessed callback) override;
        void getNextSingleEvents(TimePoint start, OnGetAlarmsProcessed callback) override;
        void turnOffRingingAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback) override;
        void turnOffSnoozedAlarm(const std::uint32_t id, OnTurnOffRingingAlarm callback) override;
        void snoozeRingingAlarm(const std::uint32_t id,
                                const TimePoint nextAlarmTime,
                                OnSnoozeRingingAlarm callback) override;
        void postponeSnooze(const std::uint32_t id,
                            const TimePoint nextAlarmTime,
                            OnSnoozeRingingAlarm callback) override;
        void minuteUpdated(TimePoint now) override;
        void addAlarmExecutionHandler(const alarms::AlarmType type,
                                      const std::shared_ptr<alarms::AlarmHandler> handler) override;
        void stopAllSnoozedAlarms() override;
        void addSnoozedAlarmsCountChangeCallback(OnSnoozedAlarmsCountChange callback) override;
        void addActiveAlarmCountChangeCallback(OnActiveAlarmCountChange callback) override;
        void toggleAll(bool toggle, OnToggleAll callback) override;
        void getSnoozedAlarms(OnGetSnoozedAlarms callback) override;

      protected:
        std::unique_ptr<AbstractAlarmEventsRepository> alarmEventsRepo;
        AlarmHandlerFactory alarmHandlerFactory;

        // Events we are waiting for (on one timepoint)
        std::vector<std::unique_ptr<SingleEventRecord>> nextSingleEvents;
        std::vector<std::unique_ptr<SingleEventRecord>> ongoingSingleEvents;
        std::vector<std::unique_ptr<SnoozedAlarmEventRecord>> snoozedSingleEvents;

        alarms::AlarmType getAlarmEventType(const SingleEventRecord &event);
        virtual void handleAlarmEvent(const std::shared_ptr<AlarmEventRecord> &event,
                                      alarms::AlarmType alarmType,
                                      bool newStateOn);

      private:
        GetCurrentTime getCurrentTimeCallback;
        OnSnoozedAlarmsCountChange onSnoozedAlarmsCountChangeCallback = nullptr;
        OnActiveAlarmCountChange onActiveAlarmCountChangeCallback     = nullptr;

        // Max 100 alarms for one minute seems reasonable, next events will be dropped
        constexpr static auto getNextSingleEventsOffset = 0;
        constexpr static auto getNextSingleEventsLimit  = 100;

        void onRepoGetFirstNextSingeResponse(OnGetFirstNextSingleProcessed handledCallback,
                                             TimePoint start,
                                             std::vector<AlarmEventRecord> records);
        void onRepoGetAlarmsResponse(TimePoint start,
                                     std::vector<AlarmEventRecord> records,
                                     OnGetAlarmsProcessed handledCallback);
        void checkAndUpdateCache(AlarmEventRecord record);
        void switchAlarmExecution(const SingleEventRecord &singleAlarmEvent, bool newStateOn);
        void processEvents(TimePoint now);
        void processOngoingEvents();
        void processNextEventsQueue(const TimePoint now);
        void processSnoozedEventsQueue(const TimePoint now);
        virtual void onAlarmTurnedOff(const std::shared_ptr<AlarmEventRecord> &event, alarms::AlarmType alarmType);

        TimePoint getCurrentTime();
        void handleSnoozedAlarmsCountChange();
        void handleActiveAlarmsCountChange();
    };

    class CommonAlarmOperationsFactory : public IAlarmOperationsFactory
    {
      public:
        std::unique_ptr<IAlarmOperations> create(
            sys::Service *service,
            std::unique_ptr<AbstractAlarmEventsRepository> &&alarmEventsRepo,
            IAlarmOperations::GetCurrentTime getCurrentTimeCallback) const override;
    };

    auto findSingleEventById(std::vector<std::unique_ptr<SingleEventRecord>> &events, const std::uint32_t id)
        -> std::vector<std::unique_ptr<SingleEventRecord>>::iterator;
    auto findSnoozedEventById(std::vector<std::unique_ptr<SnoozedAlarmEventRecord>> &events, const std::uint32_t id)
        -> std::vector<std::unique_ptr<SnoozedAlarmEventRecord>>::iterator;
} // namespace alarms