1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
/*
* Copyright (c) 2001 James E. Wilson, Robert A. Koeneke, DarkGod
*
* This software may be copied and distributed for educational, research, and
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
#include "hooks.hpp"
#include <algorithm>
#include <assert.h>
#include <unordered_map>
#include <vector>
/******** Hooks stuff *********/
struct hook_data
{
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) {
}
hook_data() = delete;
/**
* Check if the given hook points to the given function.
*/
bool is(hook_func_t hook_func) const {
return m_hook_func == hook_func;
}
/**
* 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);
}
};
std::unordered_map<size_t, std::vector<hook_data>> &hooks_instance()
{
static auto instance = new std::unordered_map<size_t, std::vector<hook_data>>();
return *instance;
}
int process_hooks_restart = FALSE;
static std::vector<hook_data>::iterator find_hook(std::vector<hook_data> &hooks, hook_func_t hook_func)
{
return std::find_if(hooks.begin(),
hooks.end(),
[&](const hook_data &hook_data) {
return hook_data.is(hook_func);
});
}
void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data)
{
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);
}
}
void del_hook_new(int h_idx, hook_func_t hook_func)
{
auto &hooks = hooks_instance()[h_idx];
/* Find it */
auto found_it = find_hook(hooks, hook_func);
if (found_it != hooks.end())
{
hooks.erase(found_it);
}
}
bool_ process_hooks_new(int h_idx, void *in, void *out)
{
auto const &hooks = hooks_instance()[h_idx];
auto hooks_it = hooks.begin();
while (hooks_it != hooks.end())
{
auto &hook_data = *hooks_it;
/* Invoke hook function; stop processing if the hook
returns TRUE */
if (hook_data.invoke(in, out))
{
return TRUE;
}
/* Should we restart processing at the beginning? */
if (process_hooks_restart)
{
hooks_it = hooks.begin();
process_hooks_restart = FALSE;
}
else
{
hooks_it++;
}
}
return FALSE;
}
|