NeoMutt  2020-06-26-89-g172cd3
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 "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, 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...
 

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 49 of file notify.c.

50 {
51  struct Notify *notify = mutt_mem_calloc(1, sizeof(*notify));
52 
53  STAILQ_INIT(&notify->observers);
54 
55  return notify;
56 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define STAILQ_INIT(head)
Definition: queue.h:369
struct ObserverList observers
Definition: notify.c:42
Notification API.
Definition: notify.c:39
+ 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 62 of file notify.c.

63 {
64  if (!ptr || !*ptr)
65  return;
66 
67  struct Notify *notify = *ptr;
68  // NOTIFY observers
69 
70  notify_observer_remove(notify, NULL, NULL);
71 
72  FREE(ptr);
73 }
Notification API.
Definition: notify.c:39
#define FREE(x)
Definition: memory.h:40
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:185
+ 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 82 of file notify.c.

83 {
84  if (!notify)
85  return;
86 
87  notify->parent = parent;
88 }
struct Notify * parent
Definition: notify.c:41
+ 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
trueIf successfully 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.

Definition at line 104 of file notify.c.

106 {
107  if (!source || !current)
108  return false;
109 
110  // mutt_debug(LL_NOTIFY, "send: %d, %ld\n", event_type, event_data);
111  struct ObserverNode *np = NULL;
112  struct ObserverNode *tmp = NULL;
113  // We use the `_SAFE` version in case an event causes an observer to be deleted
114  STAILQ_FOREACH_SAFE(np, &current->observers, entries, tmp)
115  {
116  struct Observer *o = np->observer;
117 
119  o->callback(&nc);
120  }
121 
122  if (current->parent)
123  return send(source, current->parent, event_type, event_subtype, event_data);
124  return true;
125 }
Data passed to a notification function.
Definition: observer.h:39
struct Observer * observer
An Observer.
Definition: observer.h:69
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:104
void * global_data
Private data to pass to callback.
Definition: observer.h:61
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:42
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:41
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:359
struct Notify * parent
Definition: notify.c:41
struct ObserverList observers
Definition: notify.c:42
An observer of notifications.
Definition: observer.h:58
List of Observers.
Definition: observer.h:67
void * event_data
Data from notify_send()
Definition: observer.h:43
observer_t callback
Callback function for events.
Definition: observer.h:60
+ 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
trueIf successfully sent

See send() for more details.

Definition at line 137 of file notify.c.

139 {
140  return send(notify, notify, event_type, event_subtype, event_data);
141 }
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:104
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:42
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:41
void * event_data
Data from notify_send()
Definition: observer.h:43
+ 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,
observer_t  callback,
void *  global_data 
)

Add an observer to an object.

Parameters
notifyNotification handler
callbackFunction to call on a matching event, see observer_t
global_dataPrivate data associated with the observer
Return values
trueIf successful

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

Definition at line 153 of file notify.c.

154 {
155  if (!notify || !callback)
156  return false;
157 
158  struct ObserverNode *np = NULL;
159  STAILQ_FOREACH(np, &notify->observers, entries)
160  {
161  if (np->observer->callback == callback)
162  return true;
163  }
164 
165  struct Observer *o = mutt_mem_calloc(1, sizeof(*o));
166  o->callback = callback;
168 
169  np = mutt_mem_calloc(1, sizeof(*np));
170  np->observer = o;
171  STAILQ_INSERT_HEAD(&notify->observers, np, entries);
172 
173  return true;
174 }
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:69
void * global_data
Private data to pass to callback.
Definition: observer.h:61
struct ObserverList observers
Definition: notify.c:42
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:380
An observer of notifications.
Definition: observer.h:58
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
List of Observers.
Definition: observer.h:67
observer_t callback
Callback function for events.
Definition: observer.h:60
+ 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
trueIf successful

If callback is NULL, all the observers will be removed.

Definition at line 185 of file notify.c.

186 {
187  if (!notify)
188  return false;
189 
190  bool result = false;
191  struct ObserverNode *np = NULL;
192  struct ObserverNode *tmp = NULL;
193  STAILQ_FOREACH_SAFE(np, &notify->observers, entries, tmp)
194  {
195  if (!callback || ((np->observer->callback == callback) &&
196  (np->observer->global_data == global_data)))
197  {
198  STAILQ_REMOVE(&notify->observers, np, ObserverNode, entries);
199  FREE(&np->observer);
200  FREE(&np);
201  result = true;
202  if (callback)
203  break;
204  }
205  }
206 
207  return result;
208 }
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:399
struct Observer * observer
An Observer.
Definition: observer.h:69
void * global_data
Private data to pass to callback.
Definition: observer.h:61
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:359
struct ObserverList observers
Definition: notify.c:42
List of Observers.
Definition: observer.h:67
#define FREE(x)
Definition: memory.h:40
observer_t callback
Callback function for events.
Definition: observer.h:60
+ Here is the caller graph for this function: