From 0a1a35fdf4f250b3356c8666a43dfb5e52eff688 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 12 Apr 2018 14:10:03 -0700 Subject: [PATCH] ircd::m::room::members: Improve interface; add user::id specific iteration closure. --- include/ircd/m/room.h | 11 ++++- ircd/m/room.cc | 108 +++++++++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 36 deletions(-) diff --git a/include/ircd/m/room.h b/include/ircd/m/room.h index 2d4836eca..4ab7a75e1 100644 --- a/include/ircd/m/room.h +++ b/include/ircd/m/room.h @@ -275,6 +275,9 @@ struct ircd::m::room::state::opts /// struct ircd::m::room::members { + using closure = std::function; + using closure_bool = std::function; + m::room room; size_t count() const; @@ -283,8 +286,12 @@ struct ircd::m::room::members bool test(const string_view &membership, const event::closure_bool &view) const; bool test(const event::closure_bool &view) const; - void for_each(const string_view &membership, const event::closure &view) const; - void for_each(const event::closure &view) const; + void for_each(const string_view &membership, const event::closure &) const; + bool for_each(const string_view &membership, const closure_bool &) const; + void for_each(const string_view &membership, const closure &) const; + void for_each(const event::closure &) const; + bool for_each(const closure_bool &) const; + void for_each(const closure &) const; members(const m::room &room) :room{room} diff --git a/ircd/m/room.cc b/ircd/m/room.cc index 681d3ee0b..5c6ed3024 100644 --- a/ircd/m/room.cc +++ b/ircd/m/room.cc @@ -954,56 +954,95 @@ const // void -ircd::m::room::members::for_each(const event::closure &view) +ircd::m::room::members::for_each(const closure &closure) const { - test([&view](const m::event &event) + for_each(string_view{}, closure); +} + +bool +ircd::m::room::members::for_each(const closure_bool &closure) +const +{ + return for_each(string_view{}, closure); +} + +void +ircd::m::room::members::for_each(const event::closure &closure) +const +{ + for_each(string_view{}, closure); +} + +bool +ircd::m::room::members::test(const event::closure_bool &closure) +const +{ + const room::state state{room}; + return state.test("m.room.member", event::closure_bool{[&closure] + (const m::event &event) { - view(event); - return false; - }); + return closure(event); + }}); } void ircd::m::room::members::for_each(const string_view &membership, - const event::closure &view) + const closure &closure) const { - test(membership, [&view](const m::event &event) + for_each(membership, closure_bool{[&closure] + (const user::id &user_id) { - view(event); + closure(user_id); + return true; + }}); +} + +bool +ircd::m::room::members::for_each(const string_view &membership, + const closure_bool &closure) +const +{ + return !test(membership, event::closure_bool{[&closure] + (const event &event) + { + const user::id &user_id + { + at<"state_key"_>(event) + }; + + return !closure(user_id); + }}); +} + +void +ircd::m::room::members::for_each(const string_view &membership, + const event::closure &closure) +const +{ + test(membership, [&closure] + (const event &event) + { + closure(event); return false; }); } -bool -ircd::m::room::members::test(const event::closure_bool &view) -const -{ - const room::state state - { - room - }; - - return state.test("m.room.member", event::closure_bool{[&view] - (const m::event &event) - { - return view(event); - }}); -} - bool ircd::m::room::members::test(const string_view &membership, - const event::closure_bool &view) + const event::closure_bool &closure) const { + if(empty(membership)) + return test(closure); + // joined members optimization. Only possible when seeking // membership="join" on the present state of the room. if(!room.event_id && membership == "join") { - const room::state state{room}; const room::origins origins{room}; - return origins._test_([&view, &state] + return origins._test_([&closure, this] (const string_view &key) { const string_view &member @@ -1012,24 +1051,25 @@ const }; bool ret{false}; - state.get(std::nothrow, "m.room.member", member, [&view, &ret] - (const m::event &event) + room.get(std::nothrow, "m.room.member", member, event::closure{[&closure, &ret] + (const event &event) { - ret = view(event); - }); + ret = closure(event); + }}); return ret; }); } - return test([&membership, &view](const event &event) + return test(event::closure_bool{[&membership, &closure] + (const event &event) { if(at<"membership"_>(event) == membership) - if(view(event)) + if(closure(event)) return true; return false; - }); + }}); } size_t