From 0d833cda4f879ea5124714eca1231ad27512148e Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 26 May 2018 22:05:56 -0700 Subject: [PATCH] ircd::m: Add templated payload for hook. --- include/ircd/m/hook.h | 160 +++++++--- ircd/m/m.cc | 432 ++++++++++++++++----------- modules/client/directory/room.cc | 3 +- modules/client/presence.cc | 2 +- modules/client/profile.cc | 2 +- modules/client/publicrooms.cc | 2 +- modules/console.cc | 2 +- modules/key/keys.cc | 2 +- modules/m_presence.cc | 2 +- modules/m_receipt.cc | 2 +- modules/m_room_create.cc | 4 +- modules/m_room_history_visibility.cc | 6 +- modules/m_room_join_rules.cc | 2 +- modules/m_room_member.cc | 8 +- modules/m_typing.cc | 2 +- modules/s_conf.cc | 6 +- modules/s_control.cc | 4 +- modules/s_node.cc | 4 +- modules/vm.cc | 6 +- 19 files changed, 406 insertions(+), 245 deletions(-) diff --git a/include/ircd/m/hook.h b/include/ircd/m/hook.h index ca3e47d3c..d52706bdb 100644 --- a/include/ircd/m/hook.h +++ b/include/ircd/m/hook.h @@ -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 -{ - struct site; + struct base; struct maps; - IRCD_EXCEPTION(ircd::error, error) + template struct hook; + template struct site; + + template<> struct hook; + template<> struct site; +} + +namespace ircd::m +{ + template using hookfn = m::hook::hook; +} + +struct ircd::m::hook::base +:instance_list +{ + struct site; json::strung _feature; json::object feature; m::event matching; - std::function 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 { - friend class hook; - json::strung _feature; json::object feature; size_t count {0}; - std::unique_ptr maps; - std::set hooks; + std::unique_ptr maps; + std::set 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 &); + + protected: + site(const json::members &); + site(site &&) = delete; + site(const site &) = delete; + virtual ~site() noexcept; +}; + +template<> +struct ircd::m::hook::hook +final +:base +{ + std::function function; + + public: + hook(const json::members &feature, decltype(function) function); + hook(decltype(function) function, const json::members &feature); +}; + +template<> +struct ircd::m::hook::site +final +:base::site +{ + void call(hook &, 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 +struct ircd::m::hook::hook +:base +{ + std::function 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 +struct ircd::m::hook::site +:base::site +{ + void call(hook &hfn, const event &event, data d); + + public: + void operator()(const event &event, data d); + + site(const json::members &feature) + :base::site{feature} + {} +}; + +template +void +ircd::m::hook::site::operator()(const event &event, + data d) +{ + match(event, [this, &event, &d] + (base &base) + { + call(dynamic_cast &>(base), event, d); + return true; + }); +} + +template +void +ircd::m::hook::site::call(hook &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() + }; +} diff --git a/ircd/m/m.cc b/ircd/m/m.cc index e589f8810..9c6b07b22 100644 --- a/ircd/m/m.cc +++ b/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 origin; + std::multimap room_id; + std::multimap sender; + std::multimap state_key; + std::multimap type; + std::vector always; + + size_t match(const event &match, const std::function &) 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 &callback) +const +{ + std::set 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::list) -ircd::util::instance_list::list +decltype(ircd::util::instance_list::list) +ircd::util::instance_list::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 origin; - std::multimap room_id; - std::multimap sender; - std::multimap state_key; - std::multimap type; - std::vector 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::list) -ircd::util::instance_list::list +decltype(ircd::util::instance_list::list) +ircd::util::instance_list::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() + std::make_unique() } { 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 hooks + const std::vector 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 &callback) { - std::set 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 +// + +ircd::m::hook::hook::hook(const json::members &feature, + decltype(function) function) +:base{feature} +,function{std::move(function)} +{ +} + +ircd::m::hook::hook::hook(decltype(function) function, + const json::members &feature) +:base{feature} +,function{std::move(function)} +{ +} + +ircd::m::hook::site::site(const json::members &feature) +:base::site{feature} +{ +} + +void +ircd::m::hook::site::operator()(const event &event) +{ + match(event, [this, &event] + (base &base) + { + call(dynamic_cast &>(base), event); + return true; + }); +} + +void +ircd::m::hook::site::call(hook &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 // diff --git a/modules/client/directory/room.cc b/modules/client/directory/room.cc index 536cf2c06..1fdb8455a 100644 --- a/modules/client/directory/room.cc +++ b/modules/client/directory/room.cc @@ -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); diff --git a/modules/client/presence.cc b/modules/client/presence.cc index b1cb89aa3..a0745b057 100644 --- a/modules/client/presence.cc +++ b/modules/client/presence.cc @@ -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, diff --git a/modules/client/profile.cc b/modules/client/profile.cc index 1365b254c..35c234e09 100644 --- a/modules/client/profile.cc +++ b/modules/client/profile.cc @@ -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, diff --git a/modules/client/publicrooms.cc b/modules/client/publicrooms.cc index 430948472..7390dc53e 100644 --- a/modules/client/publicrooms.cc +++ b/modules/client/publicrooms.cc @@ -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, diff --git a/modules/console.cc b/modules/console.cc index 3fe465f75..b0b4813da 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -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; diff --git a/modules/key/keys.cc b/modules/key/keys.cc index 2769366fb..ff056b4a2 100644 --- a/modules/key/keys.cc +++ b/modules/key/keys.cc @@ -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, diff --git a/modules/m_presence.cc b/modules/m_presence.cc index 6f96e7eed..ecbfe6cce 100644 --- a/modules/m_presence.cc +++ b/modules/m_presence.cc @@ -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, diff --git a/modules/m_receipt.cc b/modules/m_receipt.cc index 963e5af61..fb562dc7a 100644 --- a/modules/m_receipt.cc +++ b/modules/m_receipt.cc @@ -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, diff --git a/modules/m_room_create.cc b/modules/m_room_create.cc index e232c049e..1850209ad 100644 --- a/modules/m_room_create.cc +++ b/modules/m_room_create.cc @@ -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, diff --git a/modules/m_room_history_visibility.cc b/modules/m_room_history_visibility.cc index 77856a2b3..a11062984 100644 --- a/modules/m_room_history_visibility.cc +++ b/modules/m_room_history_visibility.cc @@ -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, diff --git a/modules/m_room_join_rules.cc b/modules/m_room_join_rules.cc index 0d9fb4cc3..f338991b8 100644 --- a/modules/m_room_join_rules.cc +++ b/modules/m_room_join_rules.cc @@ -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, diff --git a/modules/m_room_member.cc b/modules/m_room_member.cc index 496d19780..3622697ee 100644 --- a/modules/m_room_member.cc +++ b/modules/m_room_member.cc @@ -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 { { diff --git a/modules/m_typing.cc b/modules/m_typing.cc index ec01cfb9e..8b72d7b5d 100644 --- a/modules/m_typing.cc +++ b/modules/m_typing.cc @@ -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, diff --git a/modules/s_conf.cc b/modules/s_conf.cc index fb9d110f5..1d41d8dfd 100644 --- a/modules/s_conf.cc +++ b/modules/s_conf.cc @@ -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, diff --git a/modules/s_control.cc b/modules/s_control.cc index f0464b792..3cf1afdf1 100644 --- a/modules/s_control.cc +++ b/modules/s_control.cc @@ -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, diff --git a/modules/s_node.cc b/modules/s_node.cc index c14c95152..27117d53d 100644 --- a/modules/s_node.cc +++ b/modules/s_node.cc @@ -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, diff --git a/modules/vm.cc b/modules/vm.cc index a2a1105b1..71069b64a 100644 --- a/modules/vm.cc +++ b/modules/vm.cc @@ -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 &);