src/core/messenger/Messenger.hpp

Send objects between modules using a messenger. More…

Namespaces

Name
allpix
Helper class to hold support layers for a detector model.

Classes

Name
class allpix::Messenger
Manager responsible for setting up communication between modules and sending messages between them.
class allpix::LocalMessenger
Responsible for the actual handling of messages between Modules.

Detailed Description

Send objects between modules using a messenger.

Copyright: Copyright (c) 2017-2024 CERN and the Allpix Squared authors. This software is distributed under the terms of the MIT License, copied verbatim in the file “LICENSE.md”. In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. SPDX-License-Identifier: MIT

Source code


#ifndef ALLPIX_MESSENGER_H
#define ALLPIX_MESSENGER_H

#include <list>
#include <memory>
#include <typeindex>
#include <unordered_map>
#include <utility>

#include "Message.hpp"
#include "core/module/Event.hpp"
#include "core/module/Module.hpp"
#include "core/module/exceptions.h"
#include "delegates.h"

namespace allpix {
    class Event;
    class LocalMessenger;

    class Messenger {
        friend class Module;
        friend class Event;
        friend class LocalMessenger;

    public:
        Messenger();
        ~Messenger();


        Messenger(const Messenger&) = delete;
        Messenger& operator=(const Messenger&) = delete;


        Messenger(Messenger&&) = delete;
        Messenger& operator=(Messenger&&) = delete;

        template <typename T>
        void registerFilter(T* receiver,
                            bool (T::*filter)(const std::shared_ptr<BaseMessage>&, const std::string& name) const,
                            MsgFlags flags = MsgFlags::IGNORE_NAME);

        template <typename T, typename R>
        void
        registerFilter(T* receiver, bool (T::*filter)(const std::shared_ptr<R>&) const, MsgFlags flags = MsgFlags::NONE);

        template <typename T> void bindSingle(Module* receiver, MsgFlags flags = MsgFlags::NONE);

        template <typename T> void bindMulti(Module* receiver, MsgFlags flags = MsgFlags::NONE);

        template <typename T>
        void dispatchMessage(Module* module, std::shared_ptr<T> message, Event* event, const std::string& name = "-");

        template <typename T> std::shared_ptr<T> fetchMessage(Module* module, Event* event);

        template <typename T> std::vector<std::shared_ptr<T>> fetchMultiMessage(Module* module, Event* event);

        std::vector<std::pair<std::shared_ptr<BaseMessage>, std::string>> fetchFilteredMessages(Module* module,
                                                                                                Event* event);

        bool hasReceiver(Module* source, const std::shared_ptr<BaseMessage>& message);

        bool isSatisfied(BaseDelegate* delegate, Event* event) const;

    private:
        void add_delegate(const std::type_info& message_type, Module* module, const std::shared_ptr<BaseDelegate>& delegate);

        void remove_delegate(BaseDelegate* delegate);

        using DelegateMap = std::map<std::type_index, std::map<std::string, std::list<std::shared_ptr<BaseDelegate>>>>;
        using DelegateIteratorMap =
            std::map<BaseDelegate*,
                     std::tuple<std::type_index, std::string, std::list<std::shared_ptr<BaseDelegate>>::iterator>>;

        DelegateMap delegates_;
        DelegateIteratorMap delegate_to_iterator_;

        mutable std::mutex mutex_;
    };

    class LocalMessenger {
    public:
        explicit LocalMessenger(Messenger& global_messenger);

        void dispatchMessage(Module* source, std::shared_ptr<BaseMessage> message, std::string name);
        bool dispatchMessage(Module* source,
                             const std::shared_ptr<BaseMessage>& message,
                             const std::string& name,
                             const std::string& id);

        bool isSatisfied(BaseDelegate* delegate) const;

        template <typename T> std::shared_ptr<T> fetchMessage(Module* module);

        template <typename T> std::vector<std::shared_ptr<T>> fetchMultiMessage(Module* module);

        std::vector<std::pair<std::shared_ptr<BaseMessage>, std::string>> fetchFilteredMessages(Module* module);

    private:
        // The global messenger which contains the shared delegate information
        const Messenger& global_messenger_;

        std::unordered_map<std::string, std::unordered_map<std::type_index, DelegateTypes>> messages_;
        std::vector<std::shared_ptr<BaseMessage>> sent_messages_;
    };
} // namespace allpix

// Include template members
#include "Messenger.tpp"

#endif /* ALLPIX_MESSENGER_H */

Updated on 2024-12-13 at 08:31:37 +0000