Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d5c0a79
mw::com : Change order of args in constructors
KrishaDeshkool Apr 24, 2026
0a071ad
mw/com: Remove excess ProxyField constructors
KrishaDeshkool Apr 24, 2026
4f5547a
mw/com: add field_tags.h with WithGetter/WithSetter/WithNotifier defi…
KrishaDeshkool May 29, 2026
6e34d31
mw/com: update forward declarations for variadic field template packs
KrishaDeshkool May 29, 2026
a15f82d
mw/com: migrate ProxyField and SkeletonField to tag-based dispatch
KrishaDeshkool May 31, 2026
31a6b7e
mw/com: remove obsolete Enable*Tag types from method_type.h
KrishaDeshkool May 31, 2026
3bed17e
mw/com: update tests and interfaces for tag-based field syntax
KrishaDeshkool May 29, 2026
74e7277
mw/com: add compile-time tests for ProxyField SFINAE gating
KrishaDeshkool May 29, 2026
8afdec3
mw/com: allow null dispatch in ProxyFieldBase when WithNotifier is ab…
KrishaDeshkool May 29, 2026
3bf2886
mw/com: make NamedSkeletonFieldMock variadic to carry field tags
KrishaDeshkool May 26, 2026
91b9fd0
mw/com: add field_tags.h with WithGetter/WithSetter/WithNotifier defi…
KrishaDeshkool May 29, 2026
44486ad
mw/com: migrate ProxyField and SkeletonField to tag-based dispatch
KrishaDeshkool May 31, 2026
d32eaeb
mw/com: remove unused UniqueMethodIdentifier type
KrishaDeshkool Jun 2, 2026
dd51830
mw/com: refactor proxy event/field binding factories
KrishaDeshkool Jun 3, 2026
9bca118
mw/com: move lola proxy-element lookup out of plumbing
KrishaDeshkool Jun 11, 2026
2399d63
mw/com: replace LoLaProxyElementBuildingBlocks with lola lookup helpers
KrishaDeshkool Jun 11, 2026
b94953a
mw/com: rename VerifyAllMethodsRegistered to VerifyAllMethodHandlersR…
KrishaDeshkool Jun 9, 2026
3eff4e8
mw::com: refactor GetMethodIdAndQueueSizeForEnabledMethods
KrishaDeshkool Jun 9, 2026
1693ac2
mw::com: make WithRegisteredProxyMethods register field get/set methods
KrishaDeshkool Jun 11, 2026
974170e
mw::com: add unit tests for field method setup in the proxy
KrishaDeshkool Jun 11, 2026
4f2a5ad
mw::com: remove outdated skip checks in verify method
KrishaDeshkool Jun 9, 2026
93c1e06
mw::com: remove unreachable checks and update doc string
KrishaDeshkool Jun 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions score/mw/com/impl/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ cc_library(
"//score/mw/com:__subpackages__",
],
deps = [
":field_tags",
":method_type",
":skeleton_event",
":skeleton_field_base",
Expand All @@ -289,6 +290,7 @@ cc_library(
"//score/mw/com:__subpackages__",
],
deps = [
":field_tags",
":flag_owner",
":proxy_base",
":proxy_event",
Expand Down Expand Up @@ -328,6 +330,7 @@ cc_library(
"//score/mw/com:__subpackages__",
],
deps = [
":field_tags",
":method_type",
":proxy_event",
":proxy_event_binding",
Expand Down Expand Up @@ -735,6 +738,23 @@ cc_library(
visibility = ["//score/mw/com:__subpackages__"],
)

cc_library(
name = "field_tags",
srcs = ["field_tags.cpp"],
hdrs = ["field_tags.h"],
features = COMPILER_WARNING_FEATURES,
tags = ["FFI"],
visibility = ["//score/mw/com:__subpackages__"],
)

cc_unit_test(
name = "field_tags_test",
srcs = ["field_tags_test.cpp"],
deps = [
":field_tags",
],
)

cc_library(
name = "service_element_type",
srcs = ["service_element_type.cpp"],
Expand Down
24 changes: 24 additions & 0 deletions score/mw/com/impl/bindings/lola/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,30 @@ cc_library(
],
)

cc_library(
name = "proxy_element_lookup",
srcs = ["proxy_element_lookup.cpp"],
hdrs = ["proxy_element_lookup.h"],
features = COMPILER_WARNING_FEATURES,
implementation_deps = [
":proxy",
"//score/mw/com/impl/configuration",
"@score_baselibs//score/language/futurecpp",
"@score_baselibs//score/mw/log",
],
tags = ["FFI"],
visibility = [
"//score/mw/com/impl/bindings/lola:__subpackages__",
"//score/mw/com/impl/plumbing:__subpackages__",
],
deps = [
":element_fq_id",
"//score/mw/com/impl:handle_type",
"//score/mw/com/impl:proxy_binding",
"//score/mw/com/impl:service_element_type",
],
)

cc_library(
name = "sample_ptr",
srcs = ["sample_ptr.cpp"],
Expand Down
126 changes: 81 additions & 45 deletions score/mw/com/impl/bindings/lola/proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,83 @@ score::Result<void> ExecutePartialRestartLogic(const QualityType quality_type,
return {};
}

template <typename>
struct ServiceElementTypeFor;

template <>
struct ServiceElementTypeFor<LolaMethodInstanceDeployment>
{
static constexpr ServiceElementType kType = ServiceElementType::METHOD;
};

template <>
struct ServiceElementTypeFor<LolaFieldInstanceDeployment>
{
static constexpr ServiceElementType kType = ServiceElementType::FIELD;
};

constexpr LolaMethodInstanceDeployment::QueueSize kFieldMethodQueueSize{1U};

template <typename T>
constexpr bool always_false_v = false;

template <typename LolaInstanceDeploymentType>
std::vector<std::pair<MethodType, LolaMethodInstanceDeployment::QueueSize>> GetEnabledMethodEntries(
const LolaInstanceDeploymentType& deployment)
{
std::vector<std::pair<MethodType, LolaMethodInstanceDeployment::QueueSize>> entries;

if constexpr (std::is_same_v<LolaInstanceDeploymentType, LolaFieldInstanceDeployment>)
{
for (const auto& [use_if_available, method_type] :
{std::pair{deployment.use_get_if_available_, MethodType::kGet},
std::pair{deployment.use_set_if_available_, MethodType::kSet}})
{
if (use_if_available.value_or(false))
{
entries.emplace_back(method_type, kFieldMethodQueueSize);
}
}
}
else if constexpr (std::is_same_v<LolaInstanceDeploymentType, LolaMethodInstanceDeployment>)
{
if (deployment.enabled_.value_or(false))
{
SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(
deployment.queue_size_.has_value(),
"Method instance deployment must contain queue_size on proxy side!");
entries.emplace_back(MethodType::kMethod, deployment.queue_size_.value());
}
}
else
{
// Defensive programming: This branch should never be hit as this function is only instantiated for
// LolaFieldInstanceDeployment and LolaMethodInstanceDeployment.
static_assert(always_false_v<LolaInstanceDeploymentType>,
"GetEnabledMethodEntries is not implemented for this type");
}
return entries;
}

template <typename DeploymentMap>
void AppendEnabledMethodIds(
const DeploymentMap& deployment_map,
std::vector<std::pair<UniqueMethodIdentifier, LolaMethodInstanceDeployment::QueueSize>>& result,
const LolaServiceTypeDeployment& service_type_deployment)
{
using ElementDeployment = typename DeploymentMap::mapped_type;
constexpr auto kElementType = ServiceElementTypeFor<ElementDeployment>::kType;

for (const auto& [name, deployment] : deployment_map)
{
const auto element_id = GetServiceElementId<kElementType>(service_type_deployment, name);
for (const auto& [method_type, queue_size] : GetEnabledMethodEntries(deployment))
{
result.emplace_back(UniqueMethodIdentifier{element_id, method_type}, queue_size);
}
}
}

} // namespace

namespace detail_proxy
Expand Down Expand Up @@ -630,35 +707,6 @@ score::Result<void> Proxy::SetupMethods()
{
auto enabled_method_data = GetMethodIdAndQueueSizeForEnabledMethods();

// Add field Get/Set methods to the enabled method data.
// TODO(Ticket-250429): Replace these constants with actual per-field configuration flags
// once the field get/set availability is added to the deployment configuration.
constexpr bool kUseGetIfAvailable = true;
constexpr bool kUseSetIfAvailable = true;

// TODO : This would also be replaced with the actual queue size configuration from the config files once we support
// queue size > 1.
constexpr LolaMethodInstanceDeployment::QueueSize kFieldMethodQueueSize{1U};

const auto& lola_service_type_deployment = GetLoLaServiceTypeDeployment(handle_);
const auto& lola_service_instance_deployment = GetLoLaInstanceDeployment(handle_);
{
std::lock_guard lock{proxy_method_registration_mutex_};
for (const auto& [field_name, field_instance_deployment] : lola_service_instance_deployment.fields_)
{
const auto field_id =
GetServiceElementId<ServiceElementType::FIELD>(lola_service_type_deployment, field_name);

if (kUseGetIfAvailable && proxy_methods_.count({field_id, MethodType::kGet}) != 0U)
{
enabled_method_data.push_back({{field_id, MethodType::kGet}, kFieldMethodQueueSize});
}
if (kUseSetIfAvailable && proxy_methods_.count({field_id, MethodType::kSet}) != 0U)
{
enabled_method_data.push_back({{field_id, MethodType::kSet}, kFieldMethodQueueSize});
}
}
}
// This check has be done after looping over the fields to add the field methods to the enabled method data because,
// if we did this before then even when the fields are configured and when the enabled_method_names are empty we
// would do an early return and miss setting up the fields shm.
Expand Down Expand Up @@ -790,23 +838,11 @@ Proxy::GetMethodIdAndQueueSizeForEnabledMethods() const
const auto& lola_service_instance_deployment = GetLoLaInstanceDeployment(handle_);
const auto& lola_service_type_deployment = GetLoLaServiceTypeDeployment(handle_);

// Get enabled methods from config and build method data
for (const auto& [method_name, method_deployment] : lola_service_instance_deployment.methods_)
{
if (method_deployment.enabled_.has_value() && method_deployment.enabled_.value())
{
const auto method_id =
GetServiceElementId<ServiceElementType::METHOD>(lola_service_type_deployment, method_name);

SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(
method_deployment.queue_size_.has_value(),
"Method instance deployment must contain queue_size on proxy side!");
const auto queue_size = method_deployment.queue_size_.value();
AppendEnabledMethodIds(
lola_service_instance_deployment.methods_, enabled_method_ids_and_queue_sizes, lola_service_type_deployment);

enabled_method_ids_and_queue_sizes.emplace_back(UniqueMethodIdentifier{method_id, MethodType::kMethod},
queue_size);
}
}
AppendEnabledMethodIds(
lola_service_instance_deployment.fields_, enabled_method_ids_and_queue_sizes, lola_service_type_deployment);

return enabled_method_ids_and_queue_sizes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#include "score/mw/com/impl/plumbing/lola_proxy_element_building_blocks.h"
#include "score/mw/com/impl/bindings/lola/proxy_element_lookup.h"

#include "score/mw/com/impl/bindings/lola/proxy.h"
#include "score/mw/com/impl/configuration/binding_service_type_deployment.h"
#include "score/mw/com/impl/configuration/lola_service_instance_id.h"
#include "score/mw/com/impl/configuration/lola_service_type_deployment.h"
#include "score/mw/log/logging.h"

Expand All @@ -23,24 +25,22 @@
#include <string>
#include <variant>

namespace score::mw::com::impl
namespace score::mw::com::impl::lola
{

namespace
Proxy* GetLolaProxyBinding(ProxyBinding* const parent_binding) noexcept
{
return dynamic_cast<Proxy*>(parent_binding);
}

std::optional<LoLaProxyElementBuildingBlocks> LookupForLola(const HandleType& handle,
ProxyBinding* parent_binding,
const LolaServiceTypeDeployment& lola_type_deployment,
const std::string_view name,
const ServiceElementType element_type) noexcept
namespace
{
auto* const lola_parent = dynamic_cast<lola::Proxy*>(parent_binding);
if (lola_parent == nullptr)
{
return std::nullopt;
}

std::optional<ElementFqId> GetElementFqIdForLola(const HandleType& handle,
const LolaServiceTypeDeployment& lola_type_deployment,
const std::string_view name,
const ServiceElementType element_type) noexcept
{
const auto instance_id = handle.GetInstanceId();
const auto* const lola_instance_id = std::get_if<LolaServiceInstanceId>(&(instance_id.binding_info_));
SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(lola_instance_id != nullptr,
Expand All @@ -67,10 +67,7 @@ std::optional<LoLaProxyElementBuildingBlocks> LookupForLola(const HandleType& ha
return std::nullopt;
}

const lola::ElementFqId element_fq_id{
lola_type_deployment.service_id_, element_id, lola_instance_id->GetId(), element_type};

return LoLaProxyElementBuildingBlocks{*lola_parent, lola_instance_id->GetId(), element_fq_id};
return ElementFqId{lola_type_deployment.service_id_, element_id, lola_instance_id->GetId(), element_type};
}

} // namespace
Expand All @@ -79,23 +76,21 @@ std::optional<LoLaProxyElementBuildingBlocks> LookupForLola(const HandleType& ha
// if the variant is valueless_by_exception, which cannot happen here because we do not throw
// exceptions during construction of the alternatives.
// coverity[autosar_cpp14_a15_5_3_violation : FALSE]
std::optional<LoLaProxyElementBuildingBlocks> LookupLolaProxyElement(const HandleType& handle,
ProxyBinding* parent_binding,
const std::string_view service_element_name,
const ServiceElementType element_type) noexcept
std::optional<ElementFqId> GetElementFqId(const HandleType& handle,
const std::string_view service_element_name,
const ServiceElementType element_type) noexcept
{
const auto& type_deployment = handle.GetServiceTypeDeployment();

auto visitor = score::cpp::overload(
[&handle, parent_binding, service_element_name, element_type](
const LolaServiceTypeDeployment& lola_deployment) {
return LookupForLola(handle, parent_binding, lola_deployment, service_element_name, element_type);
[&handle, service_element_name, element_type](const LolaServiceTypeDeployment& lola_deployment) {
return GetElementFqIdForLola(handle, lola_deployment, service_element_name, element_type);
},
[](const score::cpp::blank&) noexcept -> std::optional<LoLaProxyElementBuildingBlocks> {
[](const score::cpp::blank&) noexcept -> std::optional<ElementFqId> {
return std::nullopt;
});

return std::visit(visitor, type_deployment.binding_info_);
}

} // namespace score::mw::com::impl
} // namespace score::mw::com::impl::lola
43 changes: 43 additions & 0 deletions score/mw/com/impl/bindings/lola/proxy_element_lookup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#ifndef SCORE_MW_COM_IMPL_BINDINGS_LOLA_PROXY_ELEMENT_LOOKUP_H
#define SCORE_MW_COM_IMPL_BINDINGS_LOLA_PROXY_ELEMENT_LOOKUP_H

#include "score/mw/com/impl/bindings/lola/element_fq_id.h"
#include "score/mw/com/impl/handle_type.h"
#include "score/mw/com/impl/proxy_binding.h"
#include "score/mw/com/impl/service_element_type.h"

#include <optional>
#include <string_view>

namespace score::mw::com::impl::lola
{

class Proxy;

/// \brief Returns the parent binding cast to a lola::Proxy.
/// \return The lola proxy, or nullptr if the binding is null or not a lola binding.
Proxy* GetLolaProxyBinding(ProxyBinding* parent_binding) noexcept;

/// \brief Resolves a named service element against the lola deployment contained in the given handle.
/// \return The fully qualified element id, or std::nullopt for a non-lola (blank) deployment.
/// \note Fatally asserts on a malformed instance id, an invalid element type, or an element name that is not present
/// in the deployment.
std::optional<ElementFqId> GetElementFqId(const HandleType& handle,
std::string_view service_element_name,
ServiceElementType element_type) noexcept;

} // namespace score::mw::com::impl::lola

#endif // SCORE_MW_COM_IMPL_BINDINGS_LOLA_PROXY_ELEMENT_LOOKUP_H
Loading