ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
registration.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <boost/mpi/collectives/all_reduce.hpp>
23#include <boost/mpi/communicator.hpp>
24
25#include <functional>
26#include <memory>
27#include <optional>
28#include <variant>
29
30namespace System {
31class System;
32}
33
34template <typename Variant, typename T, class F>
35void add_actor(boost::mpi::communicator const &comm,
36 std::shared_ptr<System::System> const &system,
37 std::optional<Variant> &active_actor,
38 std::shared_ptr<T> const &actor, F &&on_actor_change) {
39 std::optional<Variant> other = actor;
40 auto const activate = [&system](auto &leaf) {
41 leaf->bind_system(system);
42 leaf->on_activation();
43 };
44 auto const deactivate = [&system](auto &leaf) {
45 leaf->detach_system(system);
46 };
47 auto const cleanup_if_any_rank_failed = [&](bool failed) {
48 if (boost::mpi::all_reduce(comm, failed, std::logical_or<>())) {
49 deactivate(actor);
50 active_actor.swap(other);
51 if (active_actor) {
52 std::visit([&](auto &leaf) { activate(leaf); }, *active_actor);
53 }
54 on_actor_change();
55 }
56 };
57 try {
58 active_actor.swap(other);
59 if (other) {
60 std::visit([&](auto &leaf) { deactivate(leaf); }, *other);
61 }
62 activate(actor);
63 on_actor_change();
64 cleanup_if_any_rank_failed(false);
65 } catch (...) {
66 cleanup_if_any_rank_failed(true);
67 throw;
68 }
69}
void add_actor(boost::mpi::communicator const &comm, std::shared_ptr< System::System > const &system, std::optional< Variant > &active_actor, std::shared_ptr< T > const &actor, F &&on_actor_change)