src/core/messenger/delegates.h
List of internal messenger delegates. More…
Namespaces
Name |
---|
allpix Helper class to hold support layers for a detector model. |
Classes
Name | |
---|---|
struct | allpix::DelegateTypes Container of the different delegate types. |
class | allpix::BaseDelegate Base for all delegates. |
class | allpix::ModuleDelegate Base for all delegates operating on modules. |
class | allpix::StoreDelegate Delegate to store the message in memory for fetching the history. |
class | allpix::FilterDelegate Delegate for filtering messages using a function. |
class | allpix::FilterAllDelegate Delegate for invoking a filter listening to all messages also getting the name. |
class | allpix::SingleBindDelegate Delegate for binding a single message. |
class | allpix::VectorBindDelegate Delegate for binding multiple message to a vector. |
Types
Name | |
---|---|
enum class uint32_t | MsgFlags { NONE = 0, REQUIRED = (1 « 0), ALLOW_OVERWRITE = (1 « 1), IGNORE_NAME = (1 « 2), UNNAMED_ONLY = (1 « 3)} Flags to change the behaviour of delegates. |
Functions
Name | |
---|---|
MsgFlags | **[operator |
MsgFlags | operator&(MsgFlags f1, MsgFlags f2) Give the set of flags present in both sets of message flags. |
Detailed Description
List of internal messenger delegates.
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
Types Documentation
enum MsgFlags
Enumerator | Value | Description |
---|---|---|
NONE | 0 | No enabled flags. |
REQUIRED | (1 « 0) | Require a message before running a module. |
ALLOW_OVERWRITE | (1 « 1) | Allow overwriting a previous message. |
IGNORE_NAME | (1 « 2) | Listen to all ignoring message name (equal to * as a input configuration parameter) |
UNNAMED_ONLY | (1 « 3) | Listen to all messages without explicit name (equal to ? as configuration parameter) |
Flags to change the behaviour of delegates.
All flags are distinct and can be combined using the | (OR) operator. The flags should be passed to the Messenger when registering a filter or when binding either a single or multiple messages. It depends on the delegate which combination of flags is valid.
Functions Documentation
function operator|
inline MsgFlags operator|(
MsgFlags f1,
MsgFlags f2
)
Combine two sets of message flags.
Parameters:
- f1 First set of flag
- f2 Second set of flag
Return: New set of flag representing the combination of the two given sets
function operator&
inline MsgFlags operator&(
MsgFlags f1,
MsgFlags f2
)
Give the set of flags present in both sets of message flags.
Parameters:
- f1 First flag
- f2 Second flag
Return: New flag representing the flags present in both sets of flags
Source code
#ifndef ALLPIX_DELEGATE_H
#define ALLPIX_DELEGATE_H
#include <cassert>
#include <memory>
#include <typeinfo>
#include <utility>
#include "Message.hpp"
#include "core/geometry/Detector.hpp"
#include "core/messenger/exceptions.h"
// TODO [doc] This should partly move to a source file
namespace allpix {
struct DelegateTypes { // NOLINT
std::shared_ptr<BaseMessage> single;
std::vector<std::shared_ptr<BaseMessage>> multi;
std::vector<std::pair<std::shared_ptr<BaseMessage>, std::string>> filter_multi;
};
// TODO [doc] Is DelegateFlags or MessengerFlags a better name (and in separate file?)
enum class MsgFlags : uint32_t {
NONE = 0,
REQUIRED = (1 << 0),
ALLOW_OVERWRITE = (1 << 1),
IGNORE_NAME = (1 << 2),
UNNAMED_ONLY = (1 << 3)
};
inline MsgFlags operator|(MsgFlags f1, MsgFlags f2) {
return static_cast<MsgFlags>(static_cast<uint32_t>(f1) | static_cast<uint32_t>(f2));
}
inline MsgFlags operator&(MsgFlags f1, MsgFlags f2) {
return static_cast<MsgFlags>(static_cast<uint32_t>(f1) & static_cast<uint32_t>(f2));
}
class BaseDelegate {
public:
explicit BaseDelegate(MsgFlags flags) : flags_(flags) {}
virtual ~BaseDelegate() = default;
BaseDelegate(const BaseDelegate&) = delete;
BaseDelegate& operator=(const BaseDelegate&) = delete;
BaseDelegate(BaseDelegate&&) = default;
BaseDelegate& operator=(BaseDelegate&&) = default;
bool isRequired() const { return (getFlags() & MsgFlags::REQUIRED) != MsgFlags::NONE; }
MsgFlags getFlags() const { return flags_; }
virtual std::shared_ptr<Detector> getDetector() const = 0;
virtual std::string getUniqueName() = 0;
virtual void process(std::shared_ptr<BaseMessage> msg, std::string name, DelegateTypes& dest) = 0;
protected:
MsgFlags flags_;
};
template <typename T> class ModuleDelegate : public BaseDelegate {
public:
explicit ModuleDelegate(MsgFlags flags, T* obj) : BaseDelegate(flags), obj_(obj) {}
std::string getUniqueName() override { return obj_->getUniqueName(); }
std::shared_ptr<Detector> getDetector() const override { return obj_->getDetector(); }
protected:
T* const obj_;
};
template <typename T> class StoreDelegate : public ModuleDelegate<T> {
public:
StoreDelegate(MsgFlags flags, T* obj) : ModuleDelegate<T>(flags, obj) {}
void process(std::shared_ptr<BaseMessage> msg, std::string, DelegateTypes&) override {
// Store the message and mark as processed
messages_.push_back(msg);
}
private:
std::vector<std::shared_ptr<BaseMessage>> messages_;
};
template <typename T, typename R> class FilterDelegate : public ModuleDelegate<T> {
public:
using FilterFunction = bool (T::*)(const std::shared_ptr<R>&) const;
FilterDelegate(MsgFlags flags, T* obj, FilterFunction filter) : ModuleDelegate<T>(flags, obj), filter_(filter) {}
void process(std::shared_ptr<BaseMessage> msg, std::string, DelegateTypes& dest) override {
#ifndef NDEBUG
// The type names should have been correctly resolved earlier
const BaseMessage* inst = msg.get();
assert(typeid(*inst) == typeid(R));
#endif
// Filter the message, and store it if it should be kept
if((this->obj_->*filter_)(std::static_pointer_cast<R>(msg))) {
dest.filter_multi.emplace_back(std::static_pointer_cast<R>(msg), "");
}
}
private:
FilterFunction filter_;
};
template <typename T> class FilterAllDelegate : public ModuleDelegate<T> {
public:
using FilterFunction = bool (T::*)(const std::shared_ptr<BaseMessage>&, const std::string&) const;
FilterAllDelegate(MsgFlags flags, T* obj, FilterFunction filter) : ModuleDelegate<T>(flags, obj), filter_(filter) {}
void process(std::shared_ptr<BaseMessage> msg, std::string name, DelegateTypes& dest) override {
// Filter the message, and store it if it should be kept
if((this->obj_->*filter_)(std::static_pointer_cast<BaseMessage>(msg), name)) {
dest.filter_multi.emplace_back(std::static_pointer_cast<BaseMessage>(msg), name);
}
}
private:
FilterFunction filter_;
};
template <typename T, typename R> class SingleBindDelegate : public ModuleDelegate<T> {
public:
SingleBindDelegate(MsgFlags flags, T* obj) : ModuleDelegate<T>(flags, obj) {}
void process(std::shared_ptr<BaseMessage> msg, std::string, DelegateTypes& dest) override {
#ifndef NDEBUG
// The type names should have been correctly resolved earlier
const BaseMessage* inst = msg.get();
assert(typeid(*inst) == typeid(R));
#endif
// Raise an error if the message is overwritten (unless it is allowed)
if(dest.single != nullptr && (this->getFlags() & MsgFlags::ALLOW_OVERWRITE) == MsgFlags::NONE) {
throw UnexpectedMessageException(this->obj_->getUniqueName(), typeid(R));
}
// Save the message
dest.single = std::static_pointer_cast<R>(msg);
}
};
template <typename T, typename R> class VectorBindDelegate : public ModuleDelegate<T> {
public:
VectorBindDelegate(MsgFlags flags, T* obj) : ModuleDelegate<T>(flags, obj) {}
void process(std::shared_ptr<BaseMessage> msg, std::string, DelegateTypes& dest) override {
#ifndef NDEBUG
// The type names should have been correctly resolved earlier
const BaseMessage* inst = msg.get();
assert(typeid(*inst) == typeid(R));
#endif
// Add the message to the vector
dest.multi.push_back(std::static_pointer_cast<R>(msg));
}
};
} // namespace allpix
#endif /* ALLPIX_DELEGATE_H */
Updated on 2025-02-27 at 14:14:46 +0000