| 351 | |
| 352 | template <class T, class F> |
| 353 | bool OpSub::RawSubscribe( |
| 354 | aimrt::channel::SubscriberRef subscriber, |
| 355 | aimrt::executor::ExecutorRef exe, |
| 356 | F&& callback) { |
| 357 | auto type_support = aimrt::GetMessageTypeSupport<T>(); |
| 358 | |
| 359 | auto cb_ptr = std::make_shared<typename Context::ChannelCallback<T>>(std::forward<F>(callback)); |
| 360 | auto ctx = details::GetCurrentContext(); |
| 361 | |
| 362 | if (!exe) { |
| 363 | return subscriber.Subscribe( |
| 364 | type_support, |
| 365 | [cb_ptr, ctx_ptr = ctx->shared_from_this()]( |
| 366 | const aimrt_channel_context_base_t* chn_ctx_ptr, |
| 367 | const void* msg_ptr, |
| 368 | aimrt_function_base_t* release_callback_base) mutable { |
| 369 | channel::SubscriberReleaseCallback release_callback(release_callback_base); |
| 370 | ctx_ptr->LetMe(); |
| 371 | |
| 372 | if (!ctx_ptr->Running() || ctx_ptr->GetSubState() != context::ChannelState::kOn) [[unlikely]] { |
| 373 | ctx_ptr->log().Trace("Subscriber is not ready."); |
| 374 | release_callback(); |
| 375 | return; |
| 376 | } |
| 377 | (*cb_ptr)( |
| 378 | aimrt::channel::ContextRef(chn_ctx_ptr), |
| 379 | std::shared_ptr<const T>( |
| 380 | static_cast<const T*>(msg_ptr), |
| 381 | [release_callback{std::move(release_callback)}](const T*) { release_callback(); })); |
| 382 | }); |
| 383 | } |
| 384 | |
| 385 | return subscriber.Subscribe( |
| 386 | type_support, |
| 387 | [ctx_ptr = ctx->shared_from_this(), exeref = std::move(exe), cb_ptr = std::move(cb_ptr)]( |
| 388 | const aimrt_channel_context_base_t* chn_ctx_ptr, |
| 389 | const void* msg_ptr, |
| 390 | aimrt_function_base_t* release_callback_base) mutable { |
| 391 | if (!ctx_ptr->Running() || ctx_ptr->GetSubState() != context::ChannelState::kOn) [[unlikely]] { |
| 392 | ctx_ptr->log().Trace("Subscriber is not ready."); |
| 393 | return; |
| 394 | } |
| 395 | |
| 396 | channel::SubscriberReleaseCallback release_callback(release_callback_base); |
| 397 | auto msg = std::shared_ptr<const T>( |
| 398 | static_cast<const T*>(msg_ptr), |
| 399 | [release_callback{std::move(release_callback)}](const T*) { release_callback(); }); |
| 400 | exeref.Execute([cb_ptr, ctx_ptr, chn_ctx_ptr, msg = std::move(msg)]() mutable { |
| 401 | ctx_ptr->LetMe(); |
| 402 | if (!ctx_ptr->Running() || ctx_ptr->GetSubState() != context::ChannelState::kOn) [[unlikely]] { |
| 403 | ctx_ptr->log().Trace("Subscriber is not ready."); |
| 404 | return; |
| 405 | } |
| 406 | (*cb_ptr)(aimrt::channel::ContextRef(chn_ctx_ptr), std::move(msg)); |
| 407 | }); |
| 408 | }); |
| 409 | } |
| 410 |
nothing calls this directly
no test coverage detected