mirror of
https://github.com/matrix-construct/construct
synced 2024-10-31 19:08:59 +01:00
ircd:Ⓜ️ Add templated payload for hook.
This commit is contained in:
parent
9a697783a9
commit
0d833cda4f
19 changed files with 406 additions and 245 deletions
|
@ -11,23 +11,33 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_M_HOOK_H
|
||||
|
||||
namespace ircd::m
|
||||
namespace ircd::m::hook
|
||||
{
|
||||
struct hook;
|
||||
}
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
|
||||
struct ircd::m::hook
|
||||
:instance_list<hook>
|
||||
{
|
||||
struct site;
|
||||
struct base;
|
||||
struct maps;
|
||||
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
template<class data = void> struct hook;
|
||||
template<class data = void> struct site;
|
||||
|
||||
template<> struct hook<void>;
|
||||
template<> struct site<void>;
|
||||
}
|
||||
|
||||
namespace ircd::m
|
||||
{
|
||||
template<class data = void> using hookfn = m::hook::hook<data>;
|
||||
}
|
||||
|
||||
struct ircd::m::hook::base
|
||||
:instance_list<base>
|
||||
{
|
||||
struct site;
|
||||
|
||||
json::strung _feature;
|
||||
json::object feature;
|
||||
m::event matching;
|
||||
std::function<void (const m::event &)> function;
|
||||
bool registered {false};
|
||||
size_t matchers {0};
|
||||
size_t calls {0};
|
||||
|
@ -35,44 +45,124 @@ struct ircd::m::hook
|
|||
string_view site_name() const;
|
||||
site *find_site() const;
|
||||
|
||||
public:
|
||||
hook(const json::members &, decltype(function));
|
||||
hook(decltype(function), const json::members &);
|
||||
hook(hook &&) = delete;
|
||||
hook(const hook &) = delete;
|
||||
virtual ~hook() noexcept;
|
||||
protected:
|
||||
base(const json::members &);
|
||||
base(base &&) = delete;
|
||||
base(const base &) = delete;
|
||||
virtual ~base() noexcept;
|
||||
};
|
||||
|
||||
/// The hook::site is the call-site for a hook. Each hook site is named
|
||||
/// and registers itself with the master extern hook::site::list. Each hook
|
||||
/// then registers itself with a hook::site. The site contains internal
|
||||
/// state to manage the efficient calling of the participating hooks.
|
||||
///
|
||||
/// A hook::site can be created or destroyed at any time (for example if it's
|
||||
/// in a module which is reloaded) while being agnostic to the hooks it
|
||||
/// cooperates with.
|
||||
struct ircd::m::hook::site
|
||||
struct ircd::m::hook::base::site
|
||||
:instance_list<site>
|
||||
{
|
||||
friend class hook;
|
||||
|
||||
json::strung _feature;
|
||||
json::object feature;
|
||||
size_t count {0};
|
||||
std::unique_ptr<hook::maps> maps;
|
||||
std::set<hook *> hooks;
|
||||
std::unique_ptr<struct maps> maps;
|
||||
std::set<base *> hooks;
|
||||
size_t matchers {0};
|
||||
|
||||
friend class base;
|
||||
string_view name() const;
|
||||
bool add(hook &);
|
||||
bool del(hook &);
|
||||
bool add(base &);
|
||||
bool del(base &);
|
||||
|
||||
void call(hook &, const event &);
|
||||
void match(const event &, const std::function<bool (base &)> &);
|
||||
|
||||
protected:
|
||||
site(const json::members &);
|
||||
site(site &&) = delete;
|
||||
site(const site &) = delete;
|
||||
virtual ~site() noexcept;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ircd::m::hook::hook<void>
|
||||
final
|
||||
:base
|
||||
{
|
||||
std::function<void (const m::event &)> function;
|
||||
|
||||
public:
|
||||
hook(const json::members &feature, decltype(function) function);
|
||||
hook(decltype(function) function, const json::members &feature);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ircd::m::hook::site<void>
|
||||
final
|
||||
:base::site
|
||||
{
|
||||
void call(hook<void> &, const event &);
|
||||
|
||||
public:
|
||||
void operator()(const event &);
|
||||
|
||||
site(const json::members &);
|
||||
site(site &&) = delete;
|
||||
site(const site &) = delete;
|
||||
~site() noexcept;
|
||||
site(const json::members &feature);
|
||||
};
|
||||
|
||||
template<class data>
|
||||
struct ircd::m::hook::hook
|
||||
:base
|
||||
{
|
||||
std::function<void (const m::event &, data)> function;
|
||||
|
||||
public:
|
||||
hook(const json::members &feature, decltype(function) function)
|
||||
:base{feature}
|
||||
,function{std::move(function)}
|
||||
{}
|
||||
|
||||
hook(decltype(function) function, const json::members &feature)
|
||||
:base{feature}
|
||||
,function{std::move(function)}
|
||||
{}
|
||||
};
|
||||
|
||||
template<class data>
|
||||
struct ircd::m::hook::site
|
||||
:base::site
|
||||
{
|
||||
void call(hook<data> &hfn, const event &event, data d);
|
||||
|
||||
public:
|
||||
void operator()(const event &event, data d);
|
||||
|
||||
site(const json::members &feature)
|
||||
:base::site{feature}
|
||||
{}
|
||||
};
|
||||
|
||||
template<class data>
|
||||
void
|
||||
ircd::m::hook::site<data>::operator()(const event &event,
|
||||
data d)
|
||||
{
|
||||
match(event, [this, &event, &d]
|
||||
(base &base)
|
||||
{
|
||||
call(dynamic_cast<hook<data> &>(base), event, d);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
template<class data>
|
||||
void
|
||||
ircd::m::hook::site<data>::call(hook<data> &hfn,
|
||||
const event &event,
|
||||
data d)
|
||||
try
|
||||
{
|
||||
++hfn.calls;
|
||||
hfn.function(event, d);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::critical
|
||||
{
|
||||
"Unhandled hookfn(%p) %s error :%s",
|
||||
&hfn,
|
||||
string_view{hfn.feature},
|
||||
e.what()
|
||||
};
|
||||
}
|
||||
|
|
432
ircd/m/m.cc
432
ircd/m/m.cc
|
@ -2983,26 +2983,175 @@ namespace ircd::m
|
|||
static json::strung _hook_make_feature(const json::members &);
|
||||
}
|
||||
|
||||
//
|
||||
// hook::maps
|
||||
//
|
||||
|
||||
struct ircd::m::hook::maps
|
||||
{
|
||||
std::multimap<string_view, base *> origin;
|
||||
std::multimap<string_view, base *> room_id;
|
||||
std::multimap<string_view, base *> sender;
|
||||
std::multimap<string_view, base *> state_key;
|
||||
std::multimap<string_view, base *> type;
|
||||
std::vector<base *> always;
|
||||
|
||||
size_t match(const event &match, const std::function<bool (base &)> &) const;
|
||||
size_t add(base &hook, const event &matching);
|
||||
size_t del(base &hook, const event &matching);
|
||||
|
||||
maps();
|
||||
~maps() noexcept;
|
||||
};
|
||||
|
||||
ircd::m::hook::maps::maps()
|
||||
{
|
||||
}
|
||||
|
||||
ircd::m::hook::maps::~maps()
|
||||
noexcept
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::hook::maps::add(base &hook,
|
||||
const event &matching)
|
||||
{
|
||||
size_t ret{0};
|
||||
const auto map{[&hook, &ret]
|
||||
(auto &map, const string_view &value)
|
||||
{
|
||||
map.emplace(value, &hook);
|
||||
++ret;
|
||||
}};
|
||||
|
||||
if(json::get<"origin"_>(matching))
|
||||
map(origin, at<"origin"_>(matching));
|
||||
|
||||
if(json::get<"room_id"_>(matching))
|
||||
map(room_id, at<"room_id"_>(matching));
|
||||
|
||||
if(json::get<"sender"_>(matching))
|
||||
map(sender, at<"sender"_>(matching));
|
||||
|
||||
if(json::get<"state_key"_>(matching))
|
||||
map(state_key, at<"state_key"_>(matching));
|
||||
|
||||
if(json::get<"type"_>(matching))
|
||||
map(type, at<"type"_>(matching));
|
||||
|
||||
// Hook had no mappings which means it will match everything.
|
||||
// We don't increment the matcher count for this case.
|
||||
if(!ret)
|
||||
always.emplace_back(&hook);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::hook::maps::del(base &hook,
|
||||
const event &matching)
|
||||
{
|
||||
size_t ret{0};
|
||||
const auto unmap{[&hook, &ret]
|
||||
(auto &map, const string_view &key)
|
||||
{
|
||||
auto pit{map.equal_range(key)};
|
||||
for(; pit.first != pit.second; ++pit.first)
|
||||
if(pit.first->second == &hook)
|
||||
{
|
||||
++ret;
|
||||
return map.erase(pit.first);
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return end(map);
|
||||
}};
|
||||
|
||||
// Unconditional attempt to remove from always.
|
||||
std::remove(begin(always), end(always), &hook);
|
||||
|
||||
if(json::get<"origin"_>(matching))
|
||||
unmap(origin, at<"origin"_>(matching));
|
||||
|
||||
if(json::get<"room_id"_>(matching))
|
||||
unmap(room_id, at<"room_id"_>(matching));
|
||||
|
||||
if(json::get<"sender"_>(matching))
|
||||
unmap(sender, at<"sender"_>(matching));
|
||||
|
||||
if(json::get<"state_key"_>(matching))
|
||||
unmap(state_key, at<"state_key"_>(matching));
|
||||
|
||||
if(json::get<"type"_>(matching))
|
||||
unmap(type, at<"type"_>(matching));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::m::hook::maps::match(const event &event,
|
||||
const std::function<bool (base &)> &callback)
|
||||
const
|
||||
{
|
||||
std::set<base *> matching
|
||||
{
|
||||
begin(always), end(always)
|
||||
};
|
||||
|
||||
const auto site_match{[&matching]
|
||||
(auto &map, const string_view &key)
|
||||
{
|
||||
auto pit{map.equal_range(key)};
|
||||
for(; pit.first != pit.second; ++pit.first)
|
||||
matching.emplace(pit.first->second);
|
||||
}};
|
||||
|
||||
if(json::get<"origin"_>(event))
|
||||
site_match(origin, at<"origin"_>(event));
|
||||
|
||||
if(json::get<"room_id"_>(event))
|
||||
site_match(room_id, at<"room_id"_>(event));
|
||||
|
||||
if(json::get<"sender"_>(event))
|
||||
site_match(sender, at<"sender"_>(event));
|
||||
|
||||
if(json::get<"type"_>(event))
|
||||
site_match(type, at<"type"_>(event));
|
||||
|
||||
if(json::get<"state_key"_>(event))
|
||||
site_match(state_key, at<"state_key"_>(event));
|
||||
|
||||
auto it(begin(matching));
|
||||
while(it != end(matching))
|
||||
{
|
||||
const base &hook(**it);
|
||||
if(!_hook_match(hook.matching, event))
|
||||
it = matching.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
size_t ret{0};
|
||||
for(auto it(begin(matching)); it != end(matching); ++it, ++ret)
|
||||
if(!callback(**it))
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
// hook::base
|
||||
//
|
||||
|
||||
/// Instance list linkage for all hooks
|
||||
template<>
|
||||
decltype(ircd::util::instance_list<ircd::m::hook>::list)
|
||||
ircd::util::instance_list<ircd::m::hook>::list
|
||||
decltype(ircd::util::instance_list<ircd::m::hook::base>::list)
|
||||
ircd::util::instance_list<ircd::m::hook::base>::list
|
||||
{};
|
||||
|
||||
/// Alternative hook ctor simply allowing the the function argument
|
||||
/// first and description after.
|
||||
ircd::m::hook::hook(decltype(function) function,
|
||||
const json::members &members)
|
||||
:hook
|
||||
{
|
||||
members, std::move(function)
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
/// Primary hook ctor
|
||||
ircd::m::hook::hook(const json::members &members,
|
||||
decltype(function) function)
|
||||
ircd::m::hook::base::base(const json::members &members)
|
||||
try
|
||||
:_feature
|
||||
{
|
||||
|
@ -3016,10 +3165,6 @@ try
|
|||
{
|
||||
feature
|
||||
}
|
||||
,function
|
||||
{
|
||||
std::move(function)
|
||||
}
|
||||
{
|
||||
site *site;
|
||||
if((site = find_site()))
|
||||
|
@ -3035,7 +3180,7 @@ catch(...)
|
|||
site->del(*this);
|
||||
}
|
||||
|
||||
ircd::m::hook::~hook()
|
||||
ircd::m::hook::base::~base()
|
||||
noexcept
|
||||
{
|
||||
if(!registered)
|
||||
|
@ -3046,8 +3191,8 @@ noexcept
|
|||
site->del(*this);
|
||||
}
|
||||
|
||||
ircd::m::hook::site *
|
||||
ircd::m::hook::find_site()
|
||||
ircd::m::hook::base::site *
|
||||
ircd::m::hook::base::find_site()
|
||||
const
|
||||
{
|
||||
const auto &site_name
|
||||
|
@ -3058,7 +3203,7 @@ const
|
|||
if(!site_name)
|
||||
return nullptr;
|
||||
|
||||
for(auto *const &site : m::hook::site::list)
|
||||
for(auto *const &site : m::hook::base::site::list)
|
||||
if(site->name() == site_name)
|
||||
return site;
|
||||
|
||||
|
@ -3066,7 +3211,7 @@ const
|
|||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::hook::site_name()
|
||||
ircd::m::hook::base::site_name()
|
||||
const try
|
||||
{
|
||||
return unquote(feature.at("_site"));
|
||||
|
@ -3079,47 +3224,21 @@ catch(const std::out_of_range &e)
|
|||
};
|
||||
}
|
||||
|
||||
//
|
||||
// hook::maps
|
||||
//
|
||||
|
||||
struct ircd::m::hook::maps
|
||||
{
|
||||
std::multimap<string_view, hook *> origin;
|
||||
std::multimap<string_view, hook *> room_id;
|
||||
std::multimap<string_view, hook *> sender;
|
||||
std::multimap<string_view, hook *> state_key;
|
||||
std::multimap<string_view, hook *> type;
|
||||
std::vector<hook *> always;
|
||||
|
||||
maps();
|
||||
~maps() noexcept;
|
||||
};
|
||||
|
||||
ircd::m::hook::maps::maps()
|
||||
{
|
||||
}
|
||||
|
||||
ircd::m::hook::maps::~maps()
|
||||
noexcept
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// hook::site
|
||||
//
|
||||
|
||||
/// Instance list linkage for all hook sites
|
||||
template<>
|
||||
decltype(ircd::util::instance_list<ircd::m::hook::site>::list)
|
||||
ircd::util::instance_list<ircd::m::hook::site>::list
|
||||
decltype(ircd::util::instance_list<ircd::m::hook::base::site>::list)
|
||||
ircd::util::instance_list<ircd::m::hook::base::site>::list
|
||||
{};
|
||||
|
||||
//
|
||||
// hook::site::site
|
||||
//
|
||||
|
||||
ircd::m::hook::site::site(const json::members &members)
|
||||
ircd::m::hook::base::site::site(const json::members &members)
|
||||
:_feature
|
||||
{
|
||||
members
|
||||
|
@ -3130,7 +3249,7 @@ ircd::m::hook::site::site(const json::members &members)
|
|||
}
|
||||
,maps
|
||||
{
|
||||
std::make_unique<hook::maps>()
|
||||
std::make_unique<struct maps>()
|
||||
}
|
||||
{
|
||||
for(const auto &site : list)
|
||||
|
@ -3144,15 +3263,15 @@ ircd::m::hook::site::site(const json::members &members)
|
|||
|
||||
// Find and register all of the orphan hooks which were constructed before
|
||||
// this site was constructed.
|
||||
for(auto *const &hook : m::hook::list)
|
||||
if(hook->site_name() == name())
|
||||
for(auto *const &hook : m::hook::base::list)
|
||||
if(hook->site_name() == name())
|
||||
add(*hook);
|
||||
}
|
||||
|
||||
ircd::m::hook::site::~site()
|
||||
ircd::m::hook::base::site::~site()
|
||||
noexcept
|
||||
{
|
||||
const std::vector<hook *> hooks
|
||||
const std::vector<base *> hooks
|
||||
{
|
||||
begin(this->hooks), end(this->hooks)
|
||||
};
|
||||
|
@ -3162,71 +3281,14 @@ noexcept
|
|||
}
|
||||
|
||||
void
|
||||
ircd::m::hook::site::operator()(const event &event)
|
||||
ircd::m::hook::base::site::match(const event &event,
|
||||
const std::function<bool (base &)> &callback)
|
||||
{
|
||||
std::set<hook *> matching //TODO: allocator
|
||||
{
|
||||
begin(maps->always), end(maps->always)
|
||||
};
|
||||
|
||||
const auto site_match{[&matching]
|
||||
(auto &map, const string_view &key)
|
||||
{
|
||||
auto pit{map.equal_range(key)};
|
||||
for(; pit.first != pit.second; ++pit.first)
|
||||
matching.emplace(pit.first->second);
|
||||
}};
|
||||
|
||||
if(json::get<"origin"_>(event))
|
||||
site_match(maps->origin, at<"origin"_>(event));
|
||||
|
||||
if(json::get<"room_id"_>(event))
|
||||
site_match(maps->room_id, at<"room_id"_>(event));
|
||||
|
||||
if(json::get<"sender"_>(event))
|
||||
site_match(maps->sender, at<"sender"_>(event));
|
||||
|
||||
if(json::get<"type"_>(event))
|
||||
site_match(maps->type, at<"type"_>(event));
|
||||
|
||||
if(json::get<"state_key"_>(event))
|
||||
site_match(maps->state_key, at<"state_key"_>(event));
|
||||
|
||||
auto it(begin(matching));
|
||||
while(it != end(matching))
|
||||
{
|
||||
const hook &hook(**it);
|
||||
if(!_hook_match(hook.matching, event))
|
||||
it = matching.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for(const auto &hook : matching)
|
||||
call(*hook, event);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::hook::site::call(hook &hook,
|
||||
const event &event)
|
||||
try
|
||||
{
|
||||
++hook.calls;
|
||||
hook.function(event);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::critical
|
||||
{
|
||||
"Unhandled hookfn(%p) %s error :%s",
|
||||
&hook,
|
||||
string_view{hook.feature},
|
||||
e.what()
|
||||
};
|
||||
maps->match(event, callback);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::hook::site::add(hook &hook)
|
||||
ircd::m::hook::base::site::add(base &hook)
|
||||
{
|
||||
assert(!hook.registered);
|
||||
assert(hook.site_name() == name());
|
||||
|
@ -3242,91 +3304,46 @@ ircd::m::hook::site::add(hook &hook)
|
|||
return false;
|
||||
}
|
||||
|
||||
const auto map{[&hook]
|
||||
(auto &map, const string_view &value)
|
||||
assert(maps);
|
||||
const size_t matched
|
||||
{
|
||||
map.emplace(value, &hook);
|
||||
++hook.matchers;
|
||||
}};
|
||||
maps->add(hook, hook.matching)
|
||||
};
|
||||
|
||||
if(json::get<"origin"_>(hook.matching))
|
||||
map(maps->origin, at<"origin"_>(hook.matching));
|
||||
|
||||
if(json::get<"room_id"_>(hook.matching))
|
||||
map(maps->room_id, at<"room_id"_>(hook.matching));
|
||||
|
||||
if(json::get<"sender"_>(hook.matching))
|
||||
map(maps->sender, at<"sender"_>(hook.matching));
|
||||
|
||||
if(json::get<"state_key"_>(hook.matching))
|
||||
map(maps->state_key, at<"state_key"_>(hook.matching));
|
||||
|
||||
if(json::get<"type"_>(hook.matching))
|
||||
map(maps->type, at<"type"_>(hook.matching));
|
||||
|
||||
// Hook had no mappings which means it will match everything.
|
||||
// We don't increment the matcher count for this case.
|
||||
if(!hook.matchers)
|
||||
maps->always.emplace_back(&hook);
|
||||
|
||||
++count;
|
||||
hook.matchers = matched;
|
||||
hook.registered = true;
|
||||
matchers += matched;
|
||||
++count;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::hook::site::del(hook &hook)
|
||||
ircd::m::hook::base::site::del(base &hook)
|
||||
{
|
||||
assert(hook.registered);
|
||||
assert(hook.site_name() == name());
|
||||
|
||||
const auto unmap{[&hook]
|
||||
(auto &map, const string_view &key)
|
||||
const size_t matched
|
||||
{
|
||||
auto pit{map.equal_range(key)};
|
||||
for(; pit.first != pit.second; ++pit.first)
|
||||
if(pit.first->second == &hook)
|
||||
{
|
||||
--hook.matchers;
|
||||
return map.erase(pit.first);
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return end(map);
|
||||
}};
|
||||
|
||||
// Unconditional attempt to remove from always.
|
||||
std::remove(begin(maps->always), end(maps->always), &hook);
|
||||
|
||||
if(json::get<"origin"_>(hook.matching))
|
||||
unmap(maps->origin, at<"origin"_>(hook.matching));
|
||||
|
||||
if(json::get<"room_id"_>(hook.matching))
|
||||
unmap(maps->room_id, at<"room_id"_>(hook.matching));
|
||||
|
||||
if(json::get<"sender"_>(hook.matching))
|
||||
unmap(maps->sender, at<"sender"_>(hook.matching));
|
||||
|
||||
if(json::get<"state_key"_>(hook.matching))
|
||||
unmap(maps->state_key, at<"state_key"_>(hook.matching));
|
||||
|
||||
if(json::get<"type"_>(hook.matching))
|
||||
unmap(maps->type, at<"type"_>(hook.matching));
|
||||
maps->del(hook, hook.matching)
|
||||
};
|
||||
|
||||
const auto erased
|
||||
{
|
||||
hooks.erase(&hook)
|
||||
};
|
||||
|
||||
assert(erased);
|
||||
assert(hook.matchers == 0);
|
||||
--count;
|
||||
hook.matchers -= matched;
|
||||
hook.registered = false;
|
||||
matchers -= matched;
|
||||
--count;
|
||||
assert(hook.matchers == 0);
|
||||
assert(erased);
|
||||
return true;
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::hook::site::name()
|
||||
ircd::m::hook::base::site::name()
|
||||
const try
|
||||
{
|
||||
return unquote(feature.at("name"));
|
||||
|
@ -3339,6 +3356,59 @@ catch(const std::out_of_range &e)
|
|||
};
|
||||
}
|
||||
|
||||
//
|
||||
// hook<void>
|
||||
//
|
||||
|
||||
ircd::m::hook::hook<void>::hook(const json::members &feature,
|
||||
decltype(function) function)
|
||||
:base{feature}
|
||||
,function{std::move(function)}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::m::hook::hook<void>::hook(decltype(function) function,
|
||||
const json::members &feature)
|
||||
:base{feature}
|
||||
,function{std::move(function)}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::m::hook::site<void>::site(const json::members &feature)
|
||||
:base::site{feature}
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::hook::site<void>::operator()(const event &event)
|
||||
{
|
||||
match(event, [this, &event]
|
||||
(base &base)
|
||||
{
|
||||
call(dynamic_cast<hook<void> &>(base), event);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::hook::site<void>::call(hook<void> &hfn,
|
||||
const event &event)
|
||||
try
|
||||
{
|
||||
++hfn.calls;
|
||||
hfn.function(event);
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::critical
|
||||
{
|
||||
"Unhandled hookfn(%p) %s error :%s",
|
||||
&hfn,
|
||||
string_view{hfn.feature},
|
||||
e.what()
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// hook internal
|
||||
//
|
||||
|
|
|
@ -241,7 +241,7 @@ room_alias_fetch(const mutable_buffer &out,
|
|||
return response;
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_create_alias_room
|
||||
{
|
||||
{
|
||||
|
@ -249,6 +249,7 @@ _create_alias_room
|
|||
{ "room_id", "!ircd" },
|
||||
{ "type", "m.room.create" },
|
||||
},
|
||||
|
||||
[](const m::event &)
|
||||
{
|
||||
m::create(alias_room_id, m::me.user_id);
|
||||
|
|
|
@ -387,7 +387,7 @@ handle_my_presence_changed(const m::event &event)
|
|||
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
my_presence_changed
|
||||
{
|
||||
handle_my_presence_changed,
|
||||
|
|
|
@ -389,7 +389,7 @@ handle_my_profile_changed(const m::event &event)
|
|||
return handle_my_profile_changed__avatar_url(event);
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
my_profile_changed
|
||||
{
|
||||
handle_my_profile_changed,
|
||||
|
|
|
@ -164,7 +164,7 @@ _create_public_room(const m::event &)
|
|||
/// Create the public rooms room at the appropriate time on startup.
|
||||
/// The startup event chosen here is when @ircd joins the !ircd room,
|
||||
/// which is a fundamental notification toward the end of init.
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_create_public_hook
|
||||
{
|
||||
_create_public_room,
|
||||
|
|
|
@ -655,7 +655,7 @@ console_cmd__conf__rehash(opt &out, const string_view &line)
|
|||
bool
|
||||
console_cmd__hook__list(opt &out, const string_view &line)
|
||||
{
|
||||
for(const auto &site : m::hook::site::list)
|
||||
for(const auto &site : m::hook::base::site::list)
|
||||
{
|
||||
out << std::setw(24) << std::left << site->name()
|
||||
<< std::endl;
|
||||
|
|
|
@ -389,7 +389,7 @@ create_my_key(const m::event &)
|
|||
cache_set(json::strung{my_key});
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
create_my_key_hook
|
||||
{
|
||||
create_my_key,
|
||||
|
|
|
@ -35,7 +35,7 @@ presence_valid_state(const string_view &state)
|
|||
static void handle_edu_m_presence_(const m::event &, const m::edu::m_presence &edu);
|
||||
static void handle_edu_m_presence(const m::event &);
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_m_presence_eval
|
||||
{
|
||||
handle_edu_m_presence,
|
||||
|
|
|
@ -22,7 +22,7 @@ static void handle_m_receipt_m_read(const m::room::id &, const json::object &);
|
|||
static void handle_m_receipt(const m::room::id &, const json::object &);
|
||||
static void handle_edu_m_receipt(const m::event &);
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_m_receipt_eval
|
||||
{
|
||||
handle_edu_m_receipt,
|
||||
|
|
|
@ -36,7 +36,7 @@ _can_create_room(const m::event &event)
|
|||
};
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_can_create_room_hookfn
|
||||
{
|
||||
_can_create_room,
|
||||
|
@ -63,7 +63,7 @@ _created_room(const m::event &event)
|
|||
send(m::my_room, at<"sender"_>(event), "ircd.room", room_id, json::object{});
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_created_room_hookfn
|
||||
{
|
||||
_created_room,
|
||||
|
|
|
@ -18,7 +18,7 @@ IRCD_MODULE
|
|||
|
||||
namespace ircd::m
|
||||
{
|
||||
extern hook::site visible_hook;
|
||||
extern hook::site<> visible_hook;
|
||||
}
|
||||
|
||||
decltype(ircd::m::visible_hook)
|
||||
|
@ -56,7 +56,7 @@ _changed_visibility(const m::event &event)
|
|||
};
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_changed_visibility_hookfn
|
||||
{
|
||||
_changed_visibility,
|
||||
|
@ -72,7 +72,7 @@ _event_visible(const m::event &event)
|
|||
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_event_visible_hookfn
|
||||
{
|
||||
_event_visible,
|
||||
|
|
|
@ -40,7 +40,7 @@ _changed_rules(const m::event &event)
|
|||
send(public_room, sender, "ircd.room", room_id, json::strung{event});
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_changed_rules_hookfn
|
||||
{
|
||||
_changed_rules,
|
||||
|
|
|
@ -43,7 +43,7 @@ affect_user_room(const m::event &event)
|
|||
send(user_room, sender, "ircd.member", room_id, at<"content"_>(event));
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
affect_user_room_hookfn
|
||||
{
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ _can_join_room(const m::event &event)
|
|||
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_can_join_room_hookfn
|
||||
{
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ _join_room(const m::event &event)
|
|||
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_join_room_hookfn
|
||||
{
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ invite_foreign(const m::event &event)
|
|||
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
invite_foreign_hookfn
|
||||
{
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@ IRCD_MODULE
|
|||
static void _handle_edu_m_typing(const m::event &, const m::edu::m_typing &edu);
|
||||
static void handle_edu_m_typing(const m::event &);
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
_m_typing_eval
|
||||
{
|
||||
handle_edu_m_typing,
|
||||
|
|
|
@ -107,7 +107,7 @@ catch(const std::exception &e)
|
|||
};
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
conf_updated_hook
|
||||
{
|
||||
conf_updated,
|
||||
|
@ -133,7 +133,7 @@ init_conf_items(const m::event &)
|
|||
});
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
init_conf_items_hook
|
||||
{
|
||||
init_conf_items,
|
||||
|
@ -181,7 +181,7 @@ create_conf_room(const m::event &)
|
|||
}
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
create_conf_room_hook
|
||||
{
|
||||
create_conf_room,
|
||||
|
|
|
@ -105,7 +105,7 @@ catch(const std::exception &e)
|
|||
notice(control_room, e.what());
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
command_control_hook
|
||||
{
|
||||
command_control,
|
||||
|
@ -134,7 +134,7 @@ create_control_room(const m::event &)
|
|||
notice(control_room, m::me.user_id, "I am the daemon. You can talk to me in this room by highlighting me.");
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
create_control_hook
|
||||
{
|
||||
create_control_room,
|
||||
|
|
|
@ -54,7 +54,7 @@ create_my_node_room(const m::event &)
|
|||
create(m::my_node.room_id(), m::me.user_id);
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
create_my_node_hook
|
||||
{
|
||||
create_my_node_room,
|
||||
|
@ -71,7 +71,7 @@ create_nodes_room(const m::event &)
|
|||
create(nodes_room, m::me.user_id);
|
||||
}
|
||||
|
||||
const m::hook
|
||||
const m::hookfn<>
|
||||
create_nodes_hook
|
||||
{
|
||||
create_nodes_room,
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
namespace ircd::m::vm
|
||||
{
|
||||
extern log::log log;
|
||||
extern hook::site commit_hook;
|
||||
extern hook::site eval_hook;
|
||||
extern hook::site notify_hook;
|
||||
extern hook::site<> commit_hook;
|
||||
extern hook::site<> eval_hook;
|
||||
extern hook::site<> notify_hook;
|
||||
|
||||
static void write(eval &);
|
||||
static fault _eval_edu(eval &, const event &);
|
||||
|
|
Loading…
Reference in a new issue