]> granicus.if.org Git - neomutt/commitdiff
config notify
authorRichard Russon <rich@flatcap.org>
Tue, 21 May 2019 09:31:22 +0000 (10:31 +0100)
committerRichard Russon <rich@flatcap.org>
Mon, 3 Jun 2019 10:54:19 +0000 (11:54 +0100)
13 files changed:
config/bool.c
config/quad.c
config/set.c
config/set.h
index.c
main.c
menu.c
mutt_history.c
mutt_history.h
mutt_logging.c
mutt_logging.h
mutt_menu.h
protos.h

index ec9449ace5a59b22a2c20d979ecf6ea893c201da..a37bc474c5f9bef23411ea9521af7d9513d42797 100644 (file)
@@ -226,7 +226,7 @@ int bool_he_toggle(struct ConfigSet *cs, struct HashElem *he, struct Buffer *err
 
   *(char *) var = !value;
 
-  cs_notify_observers(cs, he, he->key.strkey, CE_SET);
+  cs_notify_observers(cs, he, he->key.strkey, NT_CONFIG_SET);
   return CSR_SUCCESS;
 }
 
index 15a69e5da53afc7cb5f271c73774a93ef2d327f9..2382836fb11d82afe39d41add474935498d2889f 100644 (file)
@@ -242,6 +242,6 @@ int quad_he_toggle(struct ConfigSet *cs, struct HashElem *he, struct Buffer *err
 
   *(char *) var = quad_toggle(value);
 
-  cs_notify_observers(cs, he, he->key.strkey, CE_SET);
+  cs_notify_observers(cs, he, he->key.strkey, NT_CONFIG_SET);
   return CSR_SUCCESS;
 }
index 4389d753ed5993d0ee1864a33e269af13408740a..461e6954499a991adb9f52669f7a375cb6cdbeeb 100644 (file)
@@ -164,6 +164,7 @@ void cs_init(struct ConfigSet *cs, size_t size)
   memset(cs, 0, sizeof(*cs));
   cs->hash = mutt_hash_new(size, MUTT_HASH_NO_FLAGS);
   mutt_hash_set_destructor(cs->hash, destroy, (intptr_t) cs);
+  cs->notify = notify_new(cs, NT_CONFIG);
 }
 
 /**
@@ -307,56 +308,6 @@ struct HashElem *cs_inherit_variable(const struct ConfigSet *cs,
   return he;
 }
 
-/**
- * cs_add_observer - Add a observer (callback function)
- * @param cs Config items
- * @param fn Observer callback function
- */
-void cs_add_observer(struct ConfigSet *cs, cs_observer fn)
-{
-  if (!cs || !fn)
-    return;
-
-  for (size_t i = 0; i < mutt_array_size(cs->observers); i++)
-  {
-    if (cs->observers[i] == fn)
-    {
-      mutt_debug(LL_DEBUG1, "Observer was already registered\n");
-      return;
-    }
-  }
-
-  for (size_t i = 0; i < mutt_array_size(cs->observers); i++)
-  {
-    if (!cs->observers[i])
-    {
-      cs->observers[i] = fn;
-      return;
-    }
-  }
-}
-
-/**
- * cs_remove_observer - Remove a observer (callback function)
- * @param cs Config items
- * @param fn Observer callback function
- */
-void cs_remove_observer(struct ConfigSet *cs, cs_observer fn)
-{
-  if (!cs || !fn)
-    return;
-
-  for (size_t i = 0; i < mutt_array_size(cs->observers); i++)
-  {
-    if (cs->observers[i] == fn)
-    {
-      cs->observers[i] = NULL;
-      return;
-    }
-  }
-  mutt_debug(LL_DEBUG1, "Observer wasn't registered\n");
-}
-
 /**
  * cs_notify_observers - Notify all observers of an event
  * @param cs   Config items
@@ -365,18 +316,13 @@ void cs_remove_observer(struct ConfigSet *cs, cs_observer fn)
  * @param ev   Type of event
  */
 void cs_notify_observers(const struct ConfigSet *cs, struct HashElem *he,
-                         const char *name, enum ConfigEvent ev)
+                         const char *name, enum NotifyConfig ev)
 {
   if (!cs || !he || !name)
     return;
 
-  for (size_t i = 0; i < mutt_array_size(cs->observers); i++)
-  {
-    if (!cs->observers[i])
-      return;
-
-    cs->observers[i](cs, he, name, ev);
-  }
+  struct EventConfig ec = { cs, he, name };
+  notify_send(cs->notify, NT_CONFIG, ev, IP & ec);
 }
 
 /**
@@ -422,7 +368,7 @@ int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *
   }
 
   if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE))
-    cs_notify_observers(cs, he, he->key.strkey, CE_RESET);
+    cs_notify_observers(cs, he, he->key.strkey, NT_CONFIG_RESET);
   return rc;
 }
 
@@ -485,7 +431,7 @@ int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he,
   if (CSR_RESULT(rc) != CSR_SUCCESS)
     return rc;
 
-  cs_notify_observers(cs, he, he->key.strkey, CE_INITIAL_SET);
+  cs_notify_observers(cs, he, he->key.strkey, NT_CONFIG_INITIAL_SET);
   return CSR_SUCCESS;
 }
 
@@ -630,7 +576,7 @@ int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he,
     he->type = i->parent->type | DT_INHERITED;
   }
   if (!(rc & CSR_SUC_NO_CHANGE))
-    cs_notify_observers(cs, he, he->key.strkey, CE_SET);
+    cs_notify_observers(cs, he, he->key.strkey, NT_CONFIG_SET);
   return rc;
 }
 
@@ -772,7 +718,7 @@ int cs_he_native_set(const struct ConfigSet *cs, struct HashElem *he,
     if (he->type & DT_INHERITED)
       he->type = cdef->type | DT_INHERITED;
     if (!(rc & CSR_SUC_NO_CHANGE))
-      cs_notify_observers(cs, he, cdef->name, CE_SET);
+      cs_notify_observers(cs, he, cdef->name, NT_CONFIG_SET);
   }
 
   return rc;
@@ -826,7 +772,7 @@ int cs_str_native_set(const struct ConfigSet *cs, const char *name,
     if (he->type & DT_INHERITED)
       he->type = cdef->type | DT_INHERITED;
     if (!(rc & CSR_SUC_NO_CHANGE))
-      cs_notify_observers(cs, he, cdef->name, CE_SET);
+      cs_notify_observers(cs, he, cdef->name, NT_CONFIG_SET);
   }
 
   return rc;
index 82cc98ad3fd49137bfd1bc7b6dd4323768a9c05f..cf2c73f770c53b37e2ea4f5e7e0030710a62c487 100644 (file)
@@ -33,13 +33,13 @@ struct HashElem;
 struct ConfigDef;
 
 /**
- * enum ConfigEvent - Config notification types
+ * enum NotifyConfig - Config notification types
  */
-enum ConfigEvent
+enum NotifyConfig
 {
-  CE_SET = 1,     ///< Config item has been set
-  CE_RESET,       ///< Config item has been reset to initial, or parent, value
-  CE_INITIAL_SET, ///< Config item's initial value has been set
+  NT_CONFIG_SET = 1,     ///< Config item has been set
+  NT_CONFIG_RESET,       ///< Config item has been reset to initial, or parent, value
+  NT_CONFIG_INITIAL_SET, ///< Config item's initial value has been set
 };
 
 /* Config Set Results */
@@ -70,15 +70,6 @@ enum CsObserverAction
   CSOA_STOP,         ///< Stop notifying observers
 };
 
-/**
- * typedef cs_observer - Listen for config changes
- * @param cs   Config items
- * @param he   HashElem representing config item
- * @param name Name of the config item
- * @param ev   Event type, e.g. #CE_SET
- * @retval true Continue notifying
- */
-typedef bool    (*cs_observer)   (const struct ConfigSet *cs, struct HashElem *he, const char *name, enum ConfigEvent ev);
 /**
  * typedef cs_validator - Validate the "charset" config variable
  * @param cs    Config items
@@ -195,9 +186,21 @@ struct ConfigSetType
  */
 struct ConfigSet
 {
-  struct Hash *hash;              /**< HashTable storing the config itesm */
-  struct ConfigSetType types[18]; /**< All the defined config types */
-  cs_observer observers[8];       /**< Observers for notifications of changes to config items */
+  struct Hash *hash;              ///< HashTable storing the config items
+  struct ConfigSetType types[18]; ///< All the defined config types
+  struct Notify *notify;          ///< Notifications system
+};
+
+/**
+ * struct EventConfig - A config-change event
+ *
+ * Events such as #NT_CONFIG_SET
+ */
+struct EventConfig
+{
+  const struct ConfigSet *cs; ///< Config set
+  struct HashElem *he;        ///< Config item that changed
+  const char *name;           ///< Name of config item that changed
 };
 
 struct ConfigSet *cs_new(size_t size);
@@ -211,9 +214,7 @@ bool             cs_register_type(struct ConfigSet *cs, unsigned int type, const
 bool             cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], int flags);
 struct HashElem *cs_inherit_variable(const struct ConfigSet *cs, struct HashElem *parent, const char *name);
 
-void cs_add_observer(struct ConfigSet *cs, cs_observer fn);
-void cs_remove_observer(struct ConfigSet *cs, cs_observer fn);
-void cs_notify_observers(const struct ConfigSet *cs, struct HashElem *he, const char *name, enum ConfigEvent ev);
+void cs_notify_observers(const struct ConfigSet *cs, struct HashElem *he, const char *name, enum NotifyConfig ev);
 
 int      cs_he_initial_get (const struct ConfigSet *cs, struct HashElem *he,                    struct Buffer *result);
 int      cs_he_initial_set (const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err);
diff --git a/index.c b/index.c
index 22c5d1ef88a4d5433d098813350a2b2cd960668e..be8513b916f3ee4ccbff8a4e40acd4974f250fc0 100644 (file)
--- a/index.c
+++ b/index.c
@@ -3658,16 +3658,20 @@ void mutt_set_header_color(struct Mailbox *m, struct Email *e)
 }
 
 /**
- * mutt_reply_observer - Listen for config changes to "reply_regex" - Implements ::cs_observer()
+ * mutt_reply_observer - Listen for config changes to "reply_regex" - Implements ::observer_t()
  */
-bool mutt_reply_observer(const struct ConfigSet *cs, struct HashElem *he,
-                         const char *name, enum ConfigEvent ev)
+int mutt_reply_observer(struct NotifyCallback *nc)
 {
-  if (mutt_str_strcmp(name, "reply_regex") != 0)
-    return true;
+  if (!nc)
+    return -1;
+
+  struct EventConfig *ec = (struct EventConfig *) nc->event;
+
+  if (mutt_str_strcmp(ec->name, "reply_regex") != 0)
+    return 0;
 
   if (!Context)
-    return true;
+    return 0;
 
   regmatch_t pmatch[1];
 
@@ -3688,5 +3692,5 @@ bool mutt_reply_observer(const struct ConfigSet *cs, struct HashElem *he,
   }
 
   OptResortInit = true; /* trigger a redraw of the index */
-  return true;
+  return 0;
 }
diff --git a/main.c b/main.c
index e8db95102059f69395e575b3c6683fa0c01d5faf..a999fa3b0e6e09668b089b46817fa30f69633b98 100644 (file)
--- a/main.c
+++ b/main.c
@@ -604,6 +604,7 @@ int main(int argc, char *argv[], char *envp[])
   Config = init_config(500);
   if (!Config)
     goto main_curses;
+  notify_set_parent(Config->notify, NeoMutt->notify);
 
   if (!get_user_info(Config))
     goto main_exit;
@@ -825,10 +826,10 @@ int main(int argc, char *argv[], char *envp[])
     goto main_ok; // TEST22: neomutt -B
   }
 
-  cs_add_observer(Config, mutt_hist_observer);
-  cs_add_observer(Config, mutt_log_observer);
-  cs_add_observer(Config, mutt_menu_observer);
-  cs_add_observer(Config, mutt_reply_observer);
+  notify_observer_add(Config->notify, NT_CONFIG, 0, mutt_hist_observer, 0);
+  notify_observer_add(Config->notify, NT_CONFIG, 0, mutt_log_observer, 0);
+  notify_observer_add(Config->notify, NT_CONFIG, 0, mutt_menu_observer, 0);
+  notify_observer_add(Config->notify, NT_CONFIG, 0, mutt_reply_observer, 0);
 
   if (sendflags & SEND_POSTPONED)
   {
diff --git a/menu.c b/menu.c
index 58ad7d3da081b0938ed162dd100ef7b6fc4d6ac5..02400f0d16c396f3aedd4c580d2acfcc7b8bc101 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -1595,16 +1595,20 @@ int mutt_menu_loop(struct Menu *menu)
 }
 
 /**
- * mutt_menu_observer - Listen for config changes affecting the menu - Implements ::cs_observer()
+ * mutt_menu_observer - Listen for config changes affecting the menu - Implements ::observer_t()
  */
-bool mutt_menu_observer(const struct ConfigSet *cs, struct HashElem *he,
-                        const char *name, enum ConfigEvent ev)
+int mutt_menu_observer(struct NotifyCallback *nc)
 {
-  const struct ConfigDef *cdef = he->data;
+  if (!nc)
+    return -1;
+
+  struct EventConfig *ec = (struct EventConfig *) nc->event;
+
+  const struct ConfigDef *cdef = ec->he->data;
   ConfigRedrawFlags flags = cdef->flags;
 
   if (flags == 0)
-    return true;
+    return 0;
 
   if (flags & R_INDEX)
     mutt_menu_set_redraw_full(MENU_MAIN);
@@ -1634,5 +1638,5 @@ bool mutt_menu_observer(const struct ConfigSet *cs, struct HashElem *he,
   if (flags & R_MENU)
     mutt_menu_set_current_redraw_full();
 
-  return true;
+  return 0;
 }
index 38726adf3709d45441b3c08a7574ea1ceb6d8914..d03c9600e72e670edf0f620139aaf424458a628b 100644 (file)
@@ -144,14 +144,18 @@ void mutt_hist_complete(char *buf, size_t buflen, enum HistoryClass hclass)
 }
 
 /**
- * mutt_hist_observer - Listen for config changes affecting the history - Implements ::cs_observer()
+ * mutt_hist_observer - Listen for config changes affecting the history - Implements ::observer_t()
  */
-bool mutt_hist_observer(const struct ConfigSet *cs, struct HashElem *he,
-                        const char *name, enum ConfigEvent ev)
+int mutt_hist_observer(struct NotifyCallback *nc)
 {
-  if (mutt_str_strcmp(name, "history") != 0)
-    return true;
+  if (!nc)
+    return -1;
+
+  struct EventConfig *ec = (struct EventConfig *) nc->event;
+
+  if (mutt_str_strcmp(ec->name, "history") != 0)
+    return 0;
 
   mutt_hist_init();
-  return true;
+  return 0;
 }
index 587a63605baf68d86fe299ad64aee09294a1efdb..03a162cc2f41025731634ff8fbc93db15cf34881 100644 (file)
@@ -27,6 +27,6 @@
 #include "mutt/mutt.h"
 
 void mutt_hist_complete(char *buf, size_t buflen, enum HistoryClass hclass);
-bool mutt_hist_observer(const struct ConfigSet *cs, struct HashElem *he, const char *name, enum ConfigEvent ev);
+int mutt_hist_observer(struct NotifyCallback *nc);
 
 #endif /* MUTT_MUTT_HISTORY_H */
index 1ffe7637b68824c27735d0ec4c4b2ea9375a20f7..fe45f87cbe0308aacd658c0e2afe9b809301815f 100644 (file)
@@ -335,15 +335,19 @@ int level_validator(const struct ConfigSet *cs, const struct ConfigDef *cdef,
 }
 
 /**
- * mutt_log_observer - Listen for config changes affecting the log file - Implements ::cs_observer()
+ * mutt_log_observer - Listen for config changes affecting the log file - Implements ::observer_t()
  */
-bool mutt_log_observer(const struct ConfigSet *cs, struct HashElem *he,
-                       const char *name, enum ConfigEvent ev)
+int mutt_log_observer(struct NotifyCallback *nc)
 {
-  if (mutt_str_strcmp(name, "debug_file") == 0)
+  if (!nc)
+    return -1;
+
+  struct EventConfig *ec = (struct EventConfig *) nc->event;
+
+  if (mutt_str_strcmp(ec->name, "debug_file") == 0)
     mutt_log_set_file(C_DebugFile, true);
-  else if (mutt_str_strcmp(name, "debug_level") == 0)
+  else if (mutt_str_strcmp(ec->name, "debug_level") == 0)
     mutt_log_set_level(C_DebugLevel, true);
 
-  return true;
+  return 0;
 }
index ad41a6a505671350688a48e1696c8bd494da8fce..dee7ec1d529d844ccc829e39d982e82b66fcbfed 100644 (file)
@@ -37,7 +37,7 @@ int  mutt_log_start(void);
 void mutt_log_stop(void);
 int  mutt_log_set_level(int level, bool verbose);
 int  mutt_log_set_file(const char *file, bool verbose);
-bool mutt_log_observer(const struct ConfigSet *cs, struct HashElem *he, const char *name, enum ConfigEvent ev);
+int  mutt_log_observer(struct NotifyCallback *nc);
 int  level_validator(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err);
 
 void mutt_clear_error(void);
index 7e31805a630313b0a914fdf510565e08737538bc..f451b3c340030f17852b4ade2c9325df3abc22f2 100644 (file)
@@ -189,6 +189,6 @@ void         mutt_menu_set_current_redraw(MuttRedrawFlags redraw);
 void         mutt_menu_set_redraw_full(int menu_type);
 void         mutt_menu_set_redraw(int menu_type, MuttRedrawFlags redraw);
 
-bool mutt_menu_observer(const struct ConfigSet *cs, struct HashElem *he, const char *name, enum ConfigEvent ev);
+int mutt_menu_observer(struct NotifyCallback *nc);
 
 #endif /* MUTT_MENU_H */
index 29f6e579cdc266a3e16b055ef706771fc69ca6ee..42f744f045777a27a69bf4f41c02dc2d0a9eb687 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -86,7 +86,6 @@ int mutt_is_quote_line(char *buf, regmatch_t *pmatch);
 int wcscasecmp(const wchar_t *a, const wchar_t *b);
 #endif
 
-bool mutt_reply_observer(const struct ConfigSet *cs, struct HashElem *he,
-                         const char *name, enum ConfigEvent ev);
+int mutt_reply_observer(struct NotifyCallback *nc);
 
 #endif /* MUTT_PROTOS_H */