summaryrefslogtreecommitdiff
path: root/src
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
parent95c915c371a4cb44ccc150a09ac6573ac50e9687 (diff)
Remove old-style hooks code
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/defines.h3
-rw-r--r--src/dungeon.cc3
-rw-r--r--src/hooks.cc298
-rw-r--r--src/hooks.h16
-rw-r--r--src/init2.cc2
-rw-r--r--src/quest.cc15
-rw-r--r--src/quest.h11
-rw-r--r--src/types.h22
-rw-r--r--src/types_fwd.h1
10 files changed, 88 insertions, 285 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index dbe722ad..df64bbf2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,7 +15,7 @@ SET(SRCS
q_nirna.cc q_eol.cc q_god.cc q_dragons.cc q_poison.cc
q_spider.cc q_wolves.cc q_shroom.cc q_nazgul.cc q_wight.cc
q_troll.cc q_hobbit.cc q_thief.cc q_ultrae.cc q_ultrag.cc
- q_one.cc q_main.cc q_rand.cc
+ q_one.cc q_main.cc q_rand.cc quest.cc
object1.cc object2.cc randart.cc squeltch.cc traps.cc
monster1.cc monster2.cc monster3.cc
xtra1.cc xtra2.cc skills.cc powers.cc gods.cc
diff --git a/src/defines.h b/src/defines.h
index 0f8504da..dc8a841b 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -4388,9 +4388,6 @@
#define HOOK_FORBID_TRAVEL 75
#define MAX_HOOKS 77
-#define HOOK_TYPE_C 0
-#define HOOK_TYPE_NEW 2
-
/*
* Defines for loadsave.c
* Why 3 and 7? So if it's uninitialized, the code will be able to catch it, as
diff --git a/src/dungeon.cc b/src/dungeon.cc
index c1d0bdaf..80ec167d 100644
--- a/src/dungeon.cc
+++ b/src/dungeon.cc
@@ -14,6 +14,7 @@
#include <assert.h>
+#include "quest.h"
#include "quark.h"
#include "hooks.h"
#include "spell_type.h"
@@ -5539,7 +5540,7 @@ void play_game(bool_ new_game)
if (init_v_info()) quit("Cannot initialize vaults");
/* Initialize hooks */
- init_hooks();
+ init_hooks_quests();
init_hooks_help();
init_hooks_module();
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++;
}
}
diff --git a/src/hooks.h b/src/hooks.h
index 51da4adf..76587faf 100644
--- a/src/hooks.h
+++ b/src/hooks.h
@@ -6,19 +6,11 @@
extern "C" {
#endif
-extern void wipe_hooks(void);
-extern void init_hooks(void);
-extern hooks_chain* add_hook(int h_idx, hook_type hook, cptr name);
-extern void add_hook_new(int h_idx, bool_ (*hook_f)(void *, void *, void *), cptr name, void *data);
-extern void del_hook(int h_idx, hook_type hook);
-extern void del_hook_new(int h_idx, bool_ (*hook_f)(void *, void *, void *));
-extern s32b get_next_arg(const char *fmt);
-extern char* get_next_arg_str(const char *fmt);
-extern object_type *get_next_arg_obj();
+typedef bool_ (*hook_func_t)(void *, void *, void *);
+
+extern void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data);
+extern void del_hook_new(int h_idx, hook_func_t hook_func);
extern int process_hooks_restart;
-extern hook_return process_hooks_return[20];
-extern bool_ process_hooks_ret(int h_idx, const char *ret, const char *fmt, ...);
-extern bool_ process_hooks(int h_idx, const char *fmt, ...);
extern bool_ process_hooks_new(int h_idx, void *in, void *out);
#ifdef __cplusplus
diff --git a/src/init2.cc b/src/init2.cc
index 97e91cdf..7eedef84 100644
--- a/src/init2.cc
+++ b/src/init2.cc
@@ -2338,8 +2338,6 @@ void init_angband(void)
note("[Initialising values... (misc)]");
if (init_misc()) quit("Cannot initialise misc. values");
- wipe_hooks();
-
/* Initialise some other arrays */
note("[Initialising scripting... (script)]");
init_lua_init();
diff --git a/src/quest.cc b/src/quest.cc
new file mode 100644
index 00000000..301fc4f9
--- /dev/null
+++ b/src/quest.cc
@@ -0,0 +1,15 @@
+#include "quest.h"
+#include "angband.h"
+#include <cstddef>
+
+void init_hooks_quests()
+{
+ for (std::size_t i = 0; i < MAX_Q_IDX; i++)
+ {
+ if (quest[i].init != NULL)
+ {
+ quest[i].init(i);
+ }
+ }
+}
+
diff --git a/src/quest.h b/src/quest.h
new file mode 100644
index 00000000..58ff98e4
--- /dev/null
+++ b/src/quest.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void init_hooks_quests();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/types.h b/src/types.h
index 7ab40816..efc83a64 100644
--- a/src/types.h
+++ b/src/types.h
@@ -2183,8 +2183,6 @@ struct power_type
};
/* Hooks */
-typedef bool_ (*hook_type)(const char *fmt);
-
typedef struct hook_move_in hook_move_in;
struct hook_move_in {
int y;
@@ -2436,26 +2434,6 @@ struct birther
bool_ quick_ok;
};
-typedef struct hooks_chain hooks_chain;
-struct hooks_chain
-{
- hook_type hook;
- bool_ (*hook_f)(void *, void *, void *);
- void *hook_data;
- char name[40];
- byte type;
- hooks_chain *next;
-};
-
-typedef union hook_return hook_return;
-union hook_return
-{
- s32b num;
- cptr str;
- object_type *o_ptr;
- monster_type *m_ptr;
-};
-
/*
* Forward declare
*/
diff --git a/src/types_fwd.h b/src/types_fwd.h
index 35b39368..7bf933ab 100644
--- a/src/types_fwd.h
+++ b/src/types_fwd.h
@@ -76,7 +76,6 @@ struct monster_power;
struct tval_desc;
struct between_exit;
struct birther;
-struct hooks_chain;
struct hist_type;
struct set_type;
struct cli_comm;