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>
81 class SubDomainSubscriptionImplementor {
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;
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) {
193 pollDistributor->distribute(
nullptr, version);
195 auto muxedInterruptDistributor = _muxedInterruptDistributor.lock();
196 if(muxedInterruptDistributor) {
197 muxedInterruptDistributor->handle(version);
199 auto variableDistributor = _variableDistributor.lock();
200 if(variableDistributor) {
201 variableDistributor->distribute(data, version);
207 template<
typename BackendSpecificDataType>
209 auto pollDistributor = _pollDistributor.lock();
210 if(pollDistributor) {
211 pollDistributor->distribute(
nullptr, version);
213 auto muxedInterruptDidstributor = _muxedInterruptDistributor.lock();
214 if(muxedInterruptDidstributor) {
215 muxedInterruptDidstributor->activate(version);
217 auto variableDistributor = _variableDistributor.lock();
218 if(variableDistributor) {
219 variableDistributor->distribute(data, version);
225 template<
typename BackendSpecificDataType>
227 auto pollDistributor = _pollDistributor.lock();
228 if(pollDistributor) {
229 pollDistributor->sendException(e);
231 auto muxedInterruptDistributor = _muxedInterruptDistributor.lock();
232 if(muxedInterruptDistributor) {
233 muxedInterruptDistributor->sendException(e);
235 auto variableDistributor = _variableDistributor.lock();
236 if(variableDistributor) {
237 variableDistributor->sendException(e);
245 template<
typename UserType,
typename BackendSpecificDataType>
246 boost::shared_ptr<AsyncNDRegisterAccessor<UserType>> SubDomainSubscriptionImplementor<UserType,
248 size_t numberOfWords,
size_t wordOffsetInRegister,
AccessModeFlags flags) {
249 auto registerInfo = subDomain.
_backend->getRegisterCatalogue().getRegister(name);
252 boost::shared_ptr<AsyncAccessorManager> distributor;
253 if constexpr(std::is_same<BackendSpecificDataType, std::nullptr_t>::value) {
257 distributor = subDomain.template getAccessorManager<VariableDistributor<std::nullptr_t>>(
258 registerInfo.getQualifiedAsyncId());
262 subDomain.template getAccessorManager<TriggeredPollDistributor>(registerInfo.getQualifiedAsyncId());
268 distributor = subDomain.template getAccessorManager<VariableDistributor<BackendSpecificDataType>>(
269 registerInfo.getQualifiedAsyncId());
272 return distributor->template subscribe<UserType>(name, numberOfWords, wordOffsetInRegister, flags);