11#include " components/ble/NotificationManager.h"
22#include < cstring>
33#include < algorithm>
4+ #include < cassert>
45
56using namespace Pinetime ::Controllers;
67
@@ -9,73 +10,117 @@ constexpr uint8_t NotificationManager::MessageSize;
910void NotificationManager::Push (NotificationManager::Notification&& notif) {
1011 notif.id = GetNextId ();
1112 notif.valid = true ;
12- notifications[writeIndex] = std::move (notif);
13- writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0 ;
14- if (!empty)
15- readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0 ;
16- else
17- empty = false ;
18-
1913 newNotification = true ;
20- }
21-
22- NotificationManager::Notification NotificationManager::GetLastNotification () {
23- NotificationManager::Notification notification = notifications[readIndex];
24- notification.index = 1 ;
25- return notification;
14+ if (beginIdx > 0 ) {
15+ --beginIdx;
16+ } else {
17+ beginIdx = notifications.size () - 1 ;
18+ }
19+ notifications[beginIdx] = std::move (notif);
20+ if (size < notifications.size ()) {
21+ size++;
22+ }
2623}
2724
2825NotificationManager::Notification::Id NotificationManager::GetNextId () {
2926 return nextId++;
3027}
3128
32- NotificationManager::Notification NotificationManager::GetNext (NotificationManager::Notification::Id id) {
33- auto currentIterator = std::find_if (notifications.begin (), notifications.end (), [id](const Notification& n) {
34- return n.valid && n.id == id;
35- });
36- if (currentIterator == notifications.end () || currentIterator->id != id)
37- return Notification {};
38-
39- auto & lastNotification = notifications[readIndex];
40-
41- NotificationManager::Notification result;
42-
43- if (currentIterator == (notifications.end () - 1 ))
44- result = *(notifications.begin ());
45- else
46- result = *(currentIterator + 1 );
47-
48- if (result.id <= id)
29+ NotificationManager::Notification NotificationManager::GetLastNotification () const {
30+ if (this ->IsEmpty ()) {
4931 return {};
32+ }
33+ return this ->At (0 );
34+ }
5035
51- result.index = (lastNotification.id - result.id ) + 1 ;
52- return result;
36+ const NotificationManager::Notification& NotificationManager::At (NotificationManager::Notification::Idx idx) const {
37+ if (idx >= notifications.size ()) {
38+ assert (false );
39+ return notifications.at (beginIdx); // this should not happen
40+ }
41+ size_t read_idx = (beginIdx + idx) % notifications.size ();
42+ return notifications.at (read_idx);
5343}
5444
55- NotificationManager::Notification NotificationManager::GetPrevious (NotificationManager::Notification::Id id) {
56- auto currentIterator = std::find_if (notifications.begin (), notifications.end (), [id](const Notification& n) {
57- return n.valid && n.id == id;
58- });
59- if (currentIterator == notifications.end () || currentIterator->id != id)
60- return Notification {};
45+ NotificationManager::Notification& NotificationManager::At (NotificationManager::Notification::Idx idx) {
46+ if (idx >= notifications.size ()) {
47+ assert (false );
48+ return notifications.at (beginIdx); // this should not happen
49+ }
50+ size_t read_idx = (beginIdx + idx) % notifications.size ();
51+ return notifications.at (read_idx);
52+ }
6153
62- auto & lastNotification = notifications[readIndex];
54+ NotificationManager::Notification::Idx NotificationManager::IndexOf (NotificationManager::Notification::Id id) const {
55+ for (NotificationManager::Notification::Idx idx = 0 ; idx < this ->size ; idx++) {
56+ const NotificationManager::Notification& notification = this ->At (idx);
57+ if (notification.id == id) {
58+ return idx;
59+ }
60+ }
61+ return size;
62+ }
6363
64- NotificationManager::Notification result;
64+ NotificationManager::Notification NotificationManager::Get (NotificationManager::Notification::Id id) const {
65+ NotificationManager::Notification::Idx idx = this ->IndexOf (id);
66+ if (idx == this ->size ) {
67+ return {};
68+ }
69+ return this ->At (idx);
70+ }
6571
66- if (currentIterator == notifications.begin ())
67- result = *(notifications.end () - 1 );
68- else
69- result = *(currentIterator - 1 );
72+ NotificationManager::Notification NotificationManager::GetNext (NotificationManager::Notification::Id id) const {
73+ NotificationManager::Notification::Idx idx = this ->IndexOf (id);
74+ if (idx == this ->size ) {
75+ return {};
76+ }
77+ if (idx == 0 || idx > notifications.size ()) {
78+ return {};
79+ }
80+ return this ->At (idx - 1 );
81+ }
7082
71- if (result.id >= id)
83+ NotificationManager::Notification NotificationManager::GetPrevious (NotificationManager::Notification::Id id) const {
84+ NotificationManager::Notification::Idx idx = this ->IndexOf (id);
85+ if (idx == this ->size ) {
86+ return {};
87+ }
88+ if (static_cast <size_t >(idx + 1 ) >= notifications.size ()) {
7289 return {};
90+ }
91+ return this ->At (idx + 1 );
92+ }
93+
94+ void NotificationManager::DismissIdx (NotificationManager::Notification::Idx idx) {
95+ if (this ->IsEmpty ()) {
96+ return ;
97+ }
98+ if (idx >= size) {
99+ assert (false );
100+ return ; // this should not happen
101+ }
102+ if (idx == 0 ) { // just remove the first element, don't need to change the other elements
103+ notifications.at (beginIdx).valid = false ;
104+ beginIdx = (beginIdx + 1 ) % notifications.size ();
105+ } else {
106+ // overwrite the specified entry by moving all later messages one index to the front
107+ for (size_t i = idx; i < size - 1 ; ++i) {
108+ this ->At (i) = this ->At (i + 1 );
109+ }
110+ this ->At (size - 1 ).valid = false ;
111+ }
112+ --size;
113+ }
73114
74- result.index = (lastNotification.id - result.id ) + 1 ;
75- return result;
115+ void NotificationManager::Dismiss (NotificationManager::Notification::Id id) {
116+ NotificationManager::Notification::Idx idx = this ->IndexOf (id);
117+ if (idx == this ->size ) {
118+ return ;
119+ }
120+ this ->DismissIdx (idx);
76121}
77122
78- bool NotificationManager::AreNewNotificationsAvailable () {
123+ bool NotificationManager::AreNewNotificationsAvailable () const {
79124 return newNotification;
80125}
81126
@@ -84,9 +129,7 @@ bool NotificationManager::ClearNewNotificationFlag() {
84129}
85130
86131size_t NotificationManager::NbNotifications () const {
87- return std::count_if (notifications.begin (), notifications.end (), [](const Notification& n) {
88- return n.valid ;
89- });
132+ return size;
90133}
91134
92135const char * NotificationManager::Notification::Message () const {
0 commit comments