NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
notify.c File Reference

Notification API. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include "notify.h"
#include "logging.h"
#include "memory.h"
#include "queue.h"
+ Include dependency graph for notify.c:

Go to the source code of this file.

Data Structures

struct  Notify
 Notification API. More...
 

Functions

struct Notifynotify_new (void)
 Create a new notifications handler. More...
 
void notify_free (struct Notify **ptr)
 Free a notification handler. More...
 
void notify_set_parent (struct Notify *notify, struct Notify *parent)
 Set the parent notification handler. More...
 
static bool send (struct Notify *source, struct Notify *current, enum NotifyType event_type, int event_subtype, void *event_data)
 Send out a notification message. More...
 
bool notify_send (struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
 Send out a notification message. More...
 
bool notify_observer_add (struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
 Add an observer to an object. More...
 
bool notify_observer_remove (struct Notify *notify, observer_t callback, void *global_data)
 Remove an observer from an object. More...
 
void notify_observer_remove_all (struct Notify *notify)
 Remove all the observers from an object. More...
 

Variables

static char * NotifyTypeNames []
 Lookup table for NotifyType Must be the same size and order as NotifyType. More...
 

Detailed Description

Notification API.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file notify.c.

Function Documentation

◆ notify_new()

struct Notify* notify_new ( void  )

Create a new notifications handler.

Return values
ptrNew notification handler

Definition at line 60 of file notify.c.

61 {
62  struct Notify *notify = mutt_mem_calloc(1, sizeof(*notify));
63 
64  STAILQ_INIT(&notify->observers);
65 
66  return notify;
67 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
struct Notify * notify
Notifications: ColorId, EventColor.
Definition: color.c:95
#define STAILQ_INIT(head)
Definition: queue.h:372
struct ObserverList observers
Definition: notify.c:53
Notification API.
Definition: notify.c:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ notify_free()

void notify_free ( struct Notify **  ptr)

Free a notification handler.

Parameters
ptrNotification handler to free

Definition at line 73 of file notify.c.

74 {
75  if (!ptr || !*ptr)
76  return;
77 
78  struct Notify *notify = *ptr;
79  // NOTIFY observers
80 
82 
83  FREE(ptr);
84 }
struct Notify * notify
Notifications: ColorId, EventColor.
Definition: color.c:95
Notification API.
Definition: notify.c:50
void notify_observer_remove_all(struct Notify *notify)
Remove all the observers from an object.
Definition: notify.c:253
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ notify_set_parent()

void notify_set_parent ( struct Notify notify,
struct Notify parent 
)

Set the parent notification handler.

Parameters
notifyNotification handler to alter
parentParent notification handler

Notifications are passed up the tree of handlers.

Definition at line 93 of file notify.c.

94 {
95  if (!notify)
96  return;
97 
98  notify->parent = parent;
99 }
struct Notify * parent
Definition: notify.c:52
+ Here is the caller graph for this function:

◆ send()

static bool send ( struct Notify source,
struct Notify current,
enum NotifyType  event_type,
int  event_subtype,
void *  event_data 
)
static

Send out a notification message.

Parameters
sourceSource of the event, e.g. Account
currentCurrent handler, e.g. NeoMutt
event_typeType of event, e.g. NT_ACCOUNT
event_subtypeSubtype, e.g. NT_ACCOUNT_ADD
event_dataPrivate data associated with the event type
Return values
trueSuccessfully sent

Notifications are sent to all observers of the object, then propagated up the handler tree. For example a "new email" notification would be sent to the Mailbox that owns it, the Account (owning the Mailbox) and finally the NeoMutt object.

Note
If Observers call notify_observer_remove(), then we garbage-collect any dead list entries after we've finished.

Definition at line 118 of file notify.c.

120 {
121  if (!source || !current)
122  return false;
123 
124  mutt_debug(LL_NOTIFY, "send: %d, %ld\n", event_type, event_data);
125  struct ObserverNode *np = NULL;
126  STAILQ_FOREACH(np, &current->observers, entries)
127  {
128  struct Observer *o = np->observer;
129  if (!o)
130  continue;
131 
132  if ((o->type == NT_ALL) || (event_type == o->type))
133  {
135  event_data, o->global_data };
136  if (o->callback(&nc) < 0)
137  {
138  mutt_debug(LL_DEBUG1, "failed to send notification: %s/%d, global %p, event %p\n",
140  }
141  }
142  }
143 
144  if (current->parent)
145  return send(source, current->parent, event_type, event_subtype, event_data);
146 
147  // Garbage collection time
148  struct ObserverNode *tmp = NULL;
149  STAILQ_FOREACH_SAFE(np, &current->observers, entries, tmp)
150  {
151  if (np->observer)
152  continue;
153 
154  STAILQ_REMOVE(&current->observers, np, ObserverNode, entries);
155  FREE(&np);
156  }
157 
158  return true;
159 }
static char * NotifyTypeNames[]
Lookup table for NotifyType Must be the same size and order as NotifyType.
Definition: notify.c:39
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
Data passed to a notification function.
Definition: observer.h:39
Log of notifications.
Definition: logging.h:45
struct Observer * observer
An Observer.
Definition: observer.h:75
static bool send(struct Notify *source, struct Notify *current, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:118
void * global_data
Private data to pass to callback.
Definition: observer.h:67
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:43
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
enum NotifyType type
Notification type to observe, e.g. NT_WINDOW.
Definition: observer.h:65
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
struct Notify * parent
Definition: notify.c:52
struct ObserverList observers
Definition: notify.c:53
An observer of notifications.
Definition: observer.h:63
struct Notify * current
Notify object being observed.
Definition: observer.h:41
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
List of Observers.
Definition: observer.h:73
void * event_data
Data from notify_send()
Definition: observer.h:44
Log at debug level 1.
Definition: logging.h:40
Register for all notifications.
Definition: notify_type.h:33
#define FREE(x)
Definition: memory.h:40
observer_t callback
Callback function for events.
Definition: observer.h:66
+ Here is the caller graph for this function:

◆ notify_send()

bool notify_send ( struct Notify notify,
enum NotifyType  event_type,
int  event_subtype,
void *  event_data 
)

Send out a notification message.

Parameters
notifyNotification handler
event_typeType of event, e.g. NT_ACCOUNT
event_subtypeSubtype, e.g. NT_ACCOUNT_ADD
event_dataPrivate data associated with the event
Return values
trueSuccessfully sent

See send() for more details.

Definition at line 171 of file notify.c.

173 {
174  mutt_debug(LL_NOTIFY, "sending: %s/%d\n", NotifyTypeNames[event_type], event_subtype);
175  return send(notify, notify, event_type, event_subtype, event_data);
176 }
static char * NotifyTypeNames[]
Lookup table for NotifyType Must be the same size and order as NotifyType.
Definition: notify.c:39
Log of notifications.
Definition: logging.h:45
static bool send(struct Notify *source, struct Notify *current, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:118
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ notify_observer_add()

bool notify_observer_add ( struct Notify notify,
enum NotifyType  type,
observer_t  callback,
void *  global_data 
)

Add an observer to an object.

Parameters
notifyNotification handler
typeNotification type to observe, e.g. NT_WINDOW
callbackFunction to call on a matching event, see observer_t
global_dataPrivate data associated with the observer
Return values
trueSuccessful

New observers are added to the front of the list, giving them higher priority than existing observers.

Definition at line 189 of file notify.c.

191 {
192  if (!notify || !callback)
193  return false;
194 
195  struct ObserverNode *np = NULL;
196  STAILQ_FOREACH(np, &notify->observers, entries)
197  {
198  if (!np->observer)
199  continue;
200 
201  if ((np->observer->callback == callback) && (np->observer->global_data == global_data))
202  return true;
203  }
204 
205  struct Observer *o = mutt_mem_calloc(1, sizeof(*o));
206  o->type = type;
207  o->callback = callback;
209 
210  np = mutt_mem_calloc(1, sizeof(*np));
211  np->observer = o;
212  STAILQ_INSERT_HEAD(&notify->observers, np, entries);
213 
214  return true;
215 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
struct Observer * observer
An Observer.
Definition: observer.h:75
void * global_data
Private data to pass to callback.
Definition: observer.h:67
enum NotifyType type
Notification type to observe, e.g. NT_WINDOW.
Definition: observer.h:65
struct ObserverList observers
Definition: notify.c:53
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:383
An observer of notifications.
Definition: observer.h:63
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
static void * global_data
Original opaque data in fallback implementation.
Definition: qsort_r.c:41
List of Observers.
Definition: observer.h:73
observer_t callback
Callback function for events.
Definition: observer.h:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ notify_observer_remove()

bool notify_observer_remove ( struct Notify notify,
observer_t  callback,
void *  global_data 
)

Remove an observer from an object.

Parameters
notifyNotification handler
callbackFunction to call on a matching event, see observer_t
global_dataPrivate data to match specific callback
Return values
trueSuccessful
Note
This function frees the Observer, but doesn't free the ObserverNode. If send() is present higher up the call stack, removing multiple entries from the list will cause it to crash.

Definition at line 228 of file notify.c.

229 {
230  if (!notify || !callback)
231  return false;
232 
233  struct ObserverNode *np = NULL;
234  STAILQ_FOREACH(np, &notify->observers, entries)
235  {
236  if (!np->observer)
237  continue;
238 
239  if ((np->observer->callback == callback) && (np->observer->global_data == global_data))
240  {
241  FREE(&np->observer);
242  return true;
243  }
244  }
245 
246  return false;
247 }
struct Observer * observer
An Observer.
Definition: observer.h:75
void * global_data
Private data to pass to callback.
Definition: observer.h:67
struct ObserverList observers
Definition: notify.c:53
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
static void * global_data
Original opaque data in fallback implementation.
Definition: qsort_r.c:41
List of Observers.
Definition: observer.h:73
#define FREE(x)
Definition: memory.h:40
observer_t callback
Callback function for events.
Definition: observer.h:66
+ Here is the caller graph for this function:

◆ notify_observer_remove_all()

void notify_observer_remove_all ( struct Notify notify)

Remove all the observers from an object.

Parameters
notifyNotification handler

Definition at line 253 of file notify.c.

254 {
255  if (!notify)
256  return;
257 
258  struct ObserverNode *np = NULL;
259  struct ObserverNode *tmp = NULL;
260  STAILQ_FOREACH_SAFE(np, &notify->observers, entries, tmp)
261  {
262  STAILQ_REMOVE(&notify->observers, np, ObserverNode, entries);
263  FREE(&np->observer);
264  FREE(&np);
265  }
266 }
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
struct Observer * observer
An Observer.
Definition: observer.h:75
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
struct ObserverList observers
Definition: notify.c:53
List of Observers.
Definition: observer.h:73
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

Variable Documentation

◆ NotifyTypeNames

char* NotifyTypeNames[]
static
Initial value:
= {
"NT_ALL", "NT_ACCOUNT", "NT_ALIAS", "NT_ALTERN", "NT_ATTACH",
"NT_BINDING", "NT_COLOR", "NT_COMMAND", "NT_COMPOSE", "NT_CONFIG",
"NT_CONTEXT", "NT_EMAIL", "NT_GLOBAL", "NT_HEADER", "NT_INDEX",
"NT_MAILBOX", "NT_MENU", "NT_PAGER", "NT_SCORE", "NT_SUBJRX",
"NT_WINDOW",
}

Lookup table for NotifyType Must be the same size and order as NotifyType.

Definition at line 39 of file notify.c.