summaryrefslogtreecommitdiff
path: root/src/hooks.cc
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2014-12-21 16:06:49 +0100
committerBardur Arantsson <bardur@scientician.net>2014-12-23 12:09:35 +0100
commitbc77660df705f46e55c8c733a924c5cc85dcdc48 (patch)
tree1c7f5506b5aebed0990d7cdd9f80789a0883f8c7 /src/hooks.cc
parent95c915c371a4cb44ccc150a09ac6573ac50e9687 (diff)
Remove old-style hooks code
Diffstat (limited to 'src/hooks.cc')
-rw-r--r--src/hooks.cc298
1 files changed, 55 insertions, 243 deletions
diff --git a/src/hooks.cc b/src/hooks.cc
index 3f2bc422..77b93cf7 100644
--- a/src/hooks.cc
+++ b/src/hooks.cc
@@ -7,281 +7,93 @@
*/
#include "hooks.h"
#include "angband.h"
+
+#include <algorithm>
#include <assert.h>
+#include <unordered_map>
+#include <vector>
/******** Hooks stuff *********/
-#define MAX_ARGS 50
-
-static hooks_chain *hooks_heads[MAX_HOOKS];
-/* Wipe hooks and init them with quest hooks */
-void wipe_hooks()
+struct hook_data
{
- int i;
-
- for (i = 0; i < MAX_HOOKS; i++)
- {
- hooks_heads[i] = NULL;
+private:
+ hook_func_t m_hook_func;
+ void *m_hook_data;
+public:
+ hook_data(hook_func_t hook_func, void *hook_data)
+ : m_hook_func(hook_func)
+ , m_hook_data(hook_data) {
}
-}
-void init_hooks()
-{
- int i;
- for (i = 0; i < MAX_Q_IDX; i++)
- {
- if (quest[i].init != NULL)
- {
- quest[i].init(i);
- }
- }
-}
+ hook_data() = delete;
-/* Add a hook */
-hooks_chain* add_hook(int h_idx, hook_type hook, cptr name)
-{
- hooks_chain *new_, *c = hooks_heads[h_idx];
-
- /* Find it */
- while ((c != NULL) && (strcmp(c->name, name)))
- {
- c = c->next;
+ /**
+ * Check if the given hook points to the given function.
+ */
+ bool is(hook_func_t hook_func) const {
+ return m_hook_func == hook_func;
}
- /* If not already in the list, add it */
- if (c == NULL)
- {
- new_ = new hooks_chain();
- memset(new_, 0, sizeof(hooks_chain));
- new_->hook = hook;
- sprintf(new_->name, "%s", name);
- new_->next = hooks_heads[h_idx];
- hooks_heads[h_idx] = new_;
- return (new_);
+ /**
+ * Invoke the hook with the given input and output pointers.
+ */
+ bool_ invoke(void *in, void *out) const {
+ return m_hook_func(m_hook_data, in, out);
}
- else return (c);
-}
+};
-void add_hook_new(int h_idx, bool_ (*hook_f)(void *, void *, void *), cptr name, void *data)
+std::unordered_map<size_t, std::vector<hook_data>> &hooks_instance()
{
- hooks_chain *c = add_hook(h_idx, NULL, name);
- c->hook_f = hook_f;
- c->hook_data = data;
- c->type = HOOK_TYPE_NEW;
+ static auto instance = new std::unordered_map<size_t, std::vector<hook_data>>();
+ return *instance;
}
-/* Remove a hook */
-void del_hook(int h_idx, hook_type hook)
-{
- hooks_chain *c = hooks_heads[h_idx], *p = NULL;
-
- /* Find it */
- while ((c != NULL) && (c->hook != hook))
- {
- p = c;
- c = c->next;
- }
-
- /* Remove it */
- if (c != NULL)
- {
- if (p == NULL)
- {
- hooks_heads[h_idx] = c->next;
- delete c;
- }
- else
- {
- p->next = c->next;
- delete c;
- }
- }
-}
-
-void del_hook_new(int h_idx, bool_ (*hook_f)(void *, void *, void *))
-{
- hooks_chain *c = hooks_heads[h_idx], *p = NULL;
-
- /* Find it */
- while ((c != NULL) && (c->hook_f != hook_f))
- {
- p = c;
- c = c->next;
- }
-
- /* Remove it */
- if (c != NULL)
- {
- if (p == NULL)
- {
- hooks_heads[h_idx] = c->next;
- delete c;
- }
- else
- {
- p->next = c->next;
- delete c;
- }
- }
-};
+int process_hooks_restart = FALSE;
-/* get the next argument */
-static hook_return param_pile[MAX_ARGS];
-static int get_next_arg_pos = 0;
-static int get_next_arg_pile_pos = 0;
-s32b get_next_arg(const char *fmt)
+static std::vector<hook_data>::iterator find_hook(std::vector<hook_data> &hooks, hook_func_t hook_func)
{
- while (TRUE)
- {
- switch (fmt[get_next_arg_pos++])
- {
- case 'd':
- case 'l':
- return (param_pile[get_next_arg_pile_pos++].num);
- case ')':
- get_next_arg_pos--;
- return 0;
- case '(':
- case ',':
- break;
- }
- }
+ return std::find_if(hooks.begin(),
+ hooks.end(),
+ [&](const hook_data &hook_data) {
+ return hook_data.is(hook_func);
+ });
}
-char* get_next_arg_str(const char *fmt)
+
+void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data)
{
- while (TRUE)
- {
- switch (fmt[get_next_arg_pos++])
- {
- case 's':
- return (char*)(param_pile[get_next_arg_pile_pos++].str);
- case ')':
- get_next_arg_pos--;
- return 0;
- case '(':
- case ',':
- break;
- }
+ auto &hooks = hooks_instance()[h_idx];
+ // Only insert if not already present.
+ if (find_hook(hooks, hook_func) == hooks.end()) {
+ hooks.emplace_back(hook_func, data);
}
}
-object_type* get_next_arg_obj() {
- object_type *o_ptr = param_pile[get_next_arg_pile_pos++].o_ptr;
- assert(o_ptr != NULL);
- return o_ptr;
-}
-
-/* Actually process the hooks */
-int process_hooks_restart = FALSE;
-hook_return process_hooks_return[20];
-static bool_ vprocess_hooks_return (int h_idx, const char *ret, const char *fmt, va_list *ap)
+void del_hook_new(int h_idx, hook_func_t hook_func)
{
- hooks_chain *c = hooks_heads[h_idx];
- va_list real_ap;
+ auto &hooks = hooks_instance()[h_idx];
- while (c != NULL)
+ /* Find it */
+ auto found_it = find_hook(hooks, hook_func);
+ if (found_it != hooks.end())
{
- if (c->type == HOOK_TYPE_C)
- {
- int i = 0, nb = 0;
-
- /* Push all args in the pile */
- i = 0;
- memcpy(&real_ap, ap, sizeof(va_list));
- while (fmt[i])
- {
- switch (fmt[i])
- {
- case 'O':
- param_pile[nb++].o_ptr = va_arg(real_ap, object_type *);
- break;
- case 's':
- param_pile[nb++].str = va_arg(real_ap, char *);
- break;
- case 'd':
- case 'l':
- param_pile[nb++].num = va_arg(real_ap, s32b);
- break;
- case '(':
- case ')':
- case ',':
- break;
- }
- i++;
- }
-
- get_next_arg_pos = 0;
- get_next_arg_pile_pos = 0;
- if (c->hook(fmt))
- {
- return TRUE;
- }
-
- /* Should we restart ? */
- if (process_hooks_restart)
- {
- c = hooks_heads[h_idx];
- process_hooks_restart = FALSE;
- }
- else
- {
- c = c->next;
- }
- }
- else if (c->type == HOOK_TYPE_NEW)
- {
- /* Skip; handled in process_hooks_new */
- c = c->next;
- }
- else
- {
- msg_format("Unkown hook type %d, name %s", c->type, c->name);
- c = c->next;
- }
+ hooks.erase(found_it);
}
-
- return FALSE;
-}
-
-bool_ process_hooks_ret(int h_idx, const char *ret, const char *fmt, ...)
-{
- va_list ap;
- bool_ r;
-
- va_start(ap, fmt);
- r = vprocess_hooks_return (h_idx, ret, fmt, &ap);
- va_end(ap);
- return (r);
-}
-
-bool_ process_hooks(int h_idx, const char *fmt, ...)
-{
- va_list ap;
- bool_ ret;
-
- va_start(ap, fmt);
- ret = vprocess_hooks_return (h_idx, "", fmt, &ap);
- va_end(ap);
- return (ret);
}
bool_ process_hooks_new(int h_idx, void *in, void *out)
{
- hooks_chain *c = hooks_heads[h_idx];
+ auto const &hooks = hooks_instance()[h_idx];
- while (c != NULL)
+ auto hooks_it = hooks.begin();
+ while (hooks_it != hooks.end())
{
- /* Only new-style hooks; skip the rest. */
- if (c->type != HOOK_TYPE_NEW)
- {
- c = c->next;
- continue;
- }
+ auto &hook_data = *hooks_it;
- /* Invoke hook function; stop processing if
- the hook returns TRUE */
- if (c->hook_f(c->hook_data, in, out))
+ /* Invoke hook function; stop processing if the hook
+ returns TRUE */
+ if (hook_data.invoke(in, out))
{
return TRUE;
}
@@ -289,12 +101,12 @@ bool_ process_hooks_new(int h_idx, void *in, void *out)
/* Should we restart processing at the beginning? */
if (process_hooks_restart)
{
- c = hooks_heads[h_idx];
+ hooks_it = hooks.begin();
process_hooks_restart = FALSE;
}
else
{
- c = c->next;
+ hooks_it++;
}
}