5#include "../DeviceBackend.h"
6#include "../VersionNumber.h"
10#include <boost/make_shared.hpp>
13 class MuxedInterruptDistributorFactory;
14 class MuxedInterruptDistributor;
17 template<
typename UserType>
18 class AsyncNDRegisterAccessor;
21 template<
typename UserType,
typename BackendSpecificDataType>
32 template<
typename BackendSpecificDataType>
33 class SubDomain :
public boost::enable_shared_from_this<SubDomain<BackendSpecificDataType>> {
35 SubDomain(boost::shared_ptr<DeviceBackend> backend, std::vector<size_t> qualifiedAsyncId,
36 boost::shared_ptr<MuxedInterruptDistributor> parent, boost::shared_ptr<Domain> domain);
49 template<
typename DistributorType>
50 boost::shared_ptr<AsyncAccessorManager>
getAccessorManager(std::vector<size_t>
const& qualifiedSubDomainId);
56 template<
typename UserType>
57 boost::shared_ptr<AsyncNDRegisterAccessor<UserType>>
subscribe(
61 std::vector<size_t>
_id;
67 boost::shared_ptr<MuxedInterruptDistributor>
_parent;
70 template<
typename UserType,
typename BackendDataType>
80 template<
typename UserType,
typename BackendSpecificDataType>
83 static boost::shared_ptr<AsyncNDRegisterAccessor<UserType>>
subscribeTo(
92 template<
typename BackendSpecificDataType>
94 std::vector<size_t> qualifiedAsyncId, boost::shared_ptr<MuxedInterruptDistributor> parent,
95 boost::shared_ptr<Domain> domain)
96 : _id(
std::move(qualifiedAsyncId)), _backend(backend), _parent(
std::move(parent)), _domain(
std::move(domain)) {}
99 template<
typename BackendSpecificDataType>
100 template<
typename UserType>
104 *
this, name, numberOfWords, wordOffsetInRegister, flags);
109 template<
typename BackendSpecificDataType>
110 template<
typename DistributorType>
112 std::vector<size_t>
const& qualifiedSubDomainId) {
113 if(qualifiedSubDomainId.size() == 1) {
116 boost::weak_ptr<DistributorType>* weakDistributor{
119 if constexpr(std::is_same<DistributorType, TriggeredPollDistributor>::value) {
120 weakDistributor = &_pollDistributor;
122 else if constexpr(std::is_same<DistributorType, VariableDistributor<BackendSpecificDataType>>::value) {
123 weakDistributor = &_variableDistributor;
129 auto distributor = weakDistributor->lock();
131 distributor = boost::make_shared<DistributorType>(_backend, this->shared_from_this(), _domain);
132 *weakDistributor = distributor;
133 if(_domain->unsafeGetIsActive()) {
150 if constexpr(std::is_same<BackendSpecificDataType, std::nullptr_t>::value) {
154 distributor->distribute(
nullptr, {});
168 auto muxedInterruptDistributor = _muxedInterruptDistributor.lock();
169 if(!muxedInterruptDistributor) {
170 muxedInterruptDistributor =
172 _muxedInterruptDistributor = muxedInterruptDistributor;
173 if(_domain->unsafeGetIsActive()) {
176 muxedInterruptDistributor->activate({});
180 return muxedInterruptDistributor->getAccessorManager<DistributorType>(
181 {++qualifiedSubDomainId.begin(), qualifiedSubDomainId.end()});
186 template<
typename BackendSpecificDataType>
188 if(!_domain->unsafeGetIsActive()) {
191 auto pollDistributor = _pollDistributor.lock();
192 if(pollDistributor) {
196 version = pollDistributor->distribute(
nullptr, version);
198 auto muxedInterruptDistributor = _muxedInterruptDistributor.lock();
199 if(muxedInterruptDistributor) {
200 muxedInterruptDistributor->handle(version);
202 auto variableDistributor = _variableDistributor.lock();
203 if(variableDistributor) {
204 variableDistributor->distribute(data, version);
210 template<
typename BackendSpecificDataType>
212 auto pollDistributor = _pollDistributor.lock();
213 if(pollDistributor) {
214 version = pollDistributor->distribute(
nullptr, version);
216 auto muxedInterruptDidstributor = _muxedInterruptDistributor.lock();
217 if(muxedInterruptDidstributor) {
218 muxedInterruptDidstributor->activate(version);
220 auto variableDistributor = _variableDistributor.lock();
221 if(variableDistributor) {
222 variableDistributor->distribute(data, version);
228 template<
typename BackendSpecificDataType>
230 auto pollDistributor = _pollDistributor.lock();
231 if(pollDistributor) {
232 pollDistributor->sendException(e);
234 auto muxedInterruptDistributor = _muxedInterruptDistributor.lock();
235 if(muxedInterruptDistributor) {
236 muxedInterruptDistributor->sendException(e);
238 auto variableDistributor = _variableDistributor.lock();
239 if(variableDistributor) {
240 variableDistributor->sendException(e);
248 template<
typename UserType,
typename BackendSpecificDataType>
249 boost::shared_ptr<AsyncNDRegisterAccessor<UserType>> SubDomainSubscriptionImplementor<UserType,
251 size_t numberOfWords,
size_t wordOffsetInRegister,
AccessModeFlags flags) {
252 auto registerInfo = subDomain.
_backend->getRegisterCatalogue().getRegister(name);
255 boost::shared_ptr<AsyncAccessorManager> distributor;
256 if constexpr(std::is_same<BackendSpecificDataType, std::nullptr_t>::value) {
260 distributor = subDomain.template getAccessorManager<VariableDistributor<std::nullptr_t>>(
261 registerInfo.getQualifiedAsyncId());
265 subDomain.template getAccessorManager<TriggeredPollDistributor>(registerInfo.getQualifiedAsyncId());
271 distributor = subDomain.template getAccessorManager<VariableDistributor<BackendSpecificDataType>>(
272 registerInfo.getQualifiedAsyncId());
275 return distributor->template subscribe<UserType>(name, numberOfWords, wordOffsetInRegister, flags);
#define INSTANTIATE_MULTI_TEMPLATE_FOR_CHIMERATK_USER_TYPES(TemplateClass,...)
Set of AccessMode flags with additional functionality for an easier handling.
Class to store a register path name.
Class for generating and holding version numbers without exposing a numeric representation.
static MuxedInterruptDistributorFactory & getInstance()
boost::shared_ptr< MuxedInterruptDistributor > createMuxedInterruptDistributor(boost::shared_ptr< SubDomain< std::nullptr_t > > parent)
Send backend-specific asynchronous data to different distributors:
boost::weak_ptr< MuxedInterruptDistributor > _muxedInterruptDistributor
std::vector< size_t > getId()
boost::weak_ptr< VariableDistributor< std::nullptr_t > > _variableDistributor
boost::shared_ptr< Domain > getDomain()
boost::shared_ptr< Domain > _domain
SubDomain(boost::shared_ptr< DeviceBackend > backend, std::vector< size_t > qualifiedAsyncId, boost::shared_ptr< MuxedInterruptDistributor > parent, boost::shared_ptr< Domain > domain)
void sendException(const std::exception_ptr &e)
boost::shared_ptr< AsyncAccessorManager > getAccessorManager(std::vector< size_t > const &qualifiedSubDomainId)
Get an AsyncAccessorManager for a specific SubDomain.
boost::shared_ptr< DeviceBackend > _backend
boost::shared_ptr< AsyncNDRegisterAccessor< UserType > > subscribe(RegisterPath name, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
boost::weak_ptr< TriggeredPollDistributor > _pollDistributor
boost::shared_ptr< DeviceBackend > getBackend()
std::vector< size_t > _id
boost::shared_ptr< MuxedInterruptDistributor > _parent
void distribute(BackendSpecificDataType, VersionNumber v)
void activate(BackendSpecificDataType, VersionNumber v)
static boost::shared_ptr< AsyncNDRegisterAccessor< UserType > > subscribeTo(SubDomain< BackendSpecificDataType > &subDomain, RegisterPath name, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
Exception thrown when a logic error has occured.