Skip to content

Commit 2ed8bcd

Browse files
committed
mw/com/impl: Add get/set to field
Added Get/Set support to ProxyField. Issue: SWP-249574
1 parent a9c1aa0 commit 2ed8bcd

13 files changed

Lines changed: 605 additions & 52 deletions

score/mw/com/impl/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ cc_library(
208208
":proxy_event",
209209
":proxy_event_binding",
210210
":proxy_field_base",
211+
"//score/mw/com/impl/methods:proxy_method",
211212
"//score/mw/com/impl/mocking:i_proxy_event",
212213
"//score/mw/com/impl/plumbing:field",
213214
"@score_baselibs//score/language/futurecpp",
@@ -964,6 +965,7 @@ cc_gtest_unit_test(
964965
deps = [
965966
":impl",
966967
":runtime_mock",
968+
"//score/mw/com/impl/mocking:proxy_event_mock",
967969
"//score/mw/com/impl/plumbing:proxy_field_binding_factory_mock",
968970
"//score/mw/com/impl/test:binding_factory_resources",
969971
"//score/mw/com/impl/test:proxy_resources",

score/mw/com/impl/methods/proxy_method_with_in_args_and_return.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
namespace score::mw::com::impl
4040
{
4141

42+
template <typename, bool, bool, bool>
43+
class ProxyField;
44+
4245
/// \brief Partial specialization of ProxyMethod for function signatures with arguments and non-void return
4346
/// \tparam ReturnType return type of the method
4447
/// \tparam ArgTypes argument types of the method
@@ -51,6 +54,16 @@ class ProxyMethod<ReturnType(ArgTypes...)> final : public ProxyMethodBase
5154
// coverity[autosar_cpp14_a11_3_1_violation]
5255
friend class ProxyMethodView;
5356

57+
friend class ProxyField<ReturnType, true, true, true>;
58+
friend class ProxyField<ReturnType, true, true, false>;
59+
friend class ProxyField<ReturnType, false, true, false>;
60+
friend class ProxyField<ReturnType, false, true, true>;
61+
62+
// Empty struct that is used to make the non-registering ctor only accessible to ProxyField (as it is a friend).
63+
struct FieldOnlyConstructorEnabler
64+
{
65+
};
66+
5467
public:
5568
ProxyMethod(ProxyBase& proxy_base, std::string_view method_name) noexcept
5669
: ProxyMethodBase(
@@ -85,6 +98,26 @@ class ProxyMethod<ReturnType(ArgTypes...)> final : public ProxyMethodBase
8598
}
8699
}
87100

101+
/// \brief Ctor for ProxyMethod that is used by ProxyField for the "dispatch method" of a field-setter. This method
102+
/// does not register the method in the ProxyBase's method map, since registration in the correct field map is done
103+
/// by ProxyField ctor. This is achieved by the FieldOnlyConstructorEnabler tag type, which makes clear, that this
104+
/// ctor should only be used by ProxyField (this is enforced by FieldOnlyConstructorEnabler only visible to
105+
/// ProxyField due to it being a friend).
106+
ProxyMethod(ProxyBase& proxy_base,
107+
std::unique_ptr<ProxyMethodBinding> proxy_method_binding,
108+
std::string_view method_name,
109+
FieldOnlyConstructorEnabler) noexcept
110+
: ProxyMethodBase(proxy_base, std::move(proxy_method_binding), method_name),
111+
are_in_arg_ptrs_active_(kCallQueueSize)
112+
{
113+
auto proxy_base_view = ProxyBaseView{proxy_base};
114+
if (binding_ == nullptr)
115+
{
116+
proxy_base_view.MarkServiceElementBindingInvalid();
117+
return;
118+
}
119+
}
120+
88121
~ProxyMethod() final = default;
89122

90123
/// \brief A ProxyMethod shall not be copyable.

score/mw/com/impl/methods/proxy_method_with_return_type.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
namespace score::mw::com::impl
3636
{
3737

38+
template <typename, bool, bool, bool>
39+
class ProxyField;
40+
3841
/// \brief Partial specialization of ProxyMethod for function signatures with no arguments and non-void return
3942
/// \tparam ReturnType return type of the method
4043
template <typename ReturnType>
@@ -45,6 +48,15 @@ class ProxyMethod<ReturnType()> final : public ProxyMethodBase
4548
// This enables us to hide unnecessary internals from the end-user.
4649
// coverity[autosar_cpp14_a11_3_1_violation]
4750
friend class ProxyMethodView;
51+
friend class ProxyField<ReturnType, true, true, true>;
52+
friend class ProxyField<ReturnType, true, false, false>;
53+
friend class ProxyField<ReturnType, true, true, false>;
54+
friend class ProxyField<ReturnType, true, false, true>;
55+
56+
// Empty struct that is used to make the non-registering ctor only accessible to ProxyField (as it is a friend).
57+
struct FieldOnlyConstructorEnabler
58+
{
59+
};
4860

4961
public:
5062
ProxyMethod(ProxyBase& proxy_base, std::string_view method_name) noexcept
@@ -77,6 +89,25 @@ class ProxyMethod<ReturnType()> final : public ProxyMethodBase
7789
}
7890
}
7991

92+
/// \brief Ctor for ProxyMethod that is used by ProxyField for the "dispatch method" of a field-getter. This method
93+
/// does not register the method in the ProxyBase's method map, since registration in the correct field map is done
94+
/// by ProxyField ctor. This is achieved by the FieldOnlyConstructorEnabler tag type, which makes clear, that this
95+
/// ctor should only be used by ProxyField (this is enforced by FieldOnlyConstructorEnabler only visible to
96+
/// ProxyField due to it being a friend).
97+
ProxyMethod(ProxyBase& proxy_base,
98+
std::unique_ptr<ProxyMethodBinding> proxy_method_binding,
99+
std::string_view method_name,
100+
FieldOnlyConstructorEnabler) noexcept
101+
: ProxyMethodBase(proxy_base, std::move(proxy_method_binding), method_name)
102+
{
103+
auto proxy_base_view = ProxyBaseView{proxy_base};
104+
if (binding_ == nullptr)
105+
{
106+
proxy_base_view.MarkServiceElementBindingInvalid();
107+
return;
108+
}
109+
}
110+
80111
~ProxyMethod() final = default;
81112

82113
/// \brief A ProxyMethod shall not be copyable.

score/mw/com/impl/mocking/proxy_wrapper_class_test_view_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ TEST_F(ProxyWrapperTestClassCreateFixture, CallingFunctionsOnMockProxyDispatches
170170
auto& proxy_field_mock = std::get<0>(fields_tuple).mock;
171171
proxy.some_event.InjectMock(proxy_event_mock);
172172
proxy.some_event_2.InjectMock(proxy_event_mock_2);
173-
proxy.some_field.InjectMock(proxy_field_mock);
173+
proxy.some_field.InjectEventMock(proxy_field_mock);
174174

175175
// Expecting that OfferService will be called on the Proxy mock and Unsubscribe on the event and field mocks
176176
EXPECT_CALL(proxy_event_mock, Unsubscribe());
@@ -254,7 +254,7 @@ TEST_F(ProxyWrapperTestClassFieldsOnlyCreateFixture, CallingFunctionsOnMockProxy
254254
// and given a mocked proxy was created
255255
auto proxy = ProxyWrapperClassTestView<FieldOnlyProxy>::Create(fields_tuple);
256256
auto& proxy_field_mock = (std::get<0>(fields_tuple).mock);
257-
proxy.some_field.InjectMock(proxy_field_mock);
257+
proxy.some_field.InjectEventMock(proxy_field_mock);
258258

259259
// Expecting that Unsubscribe is called on the field
260260
EXPECT_CALL(proxy_field_mock, Unsubscribe());

score/mw/com/impl/plumbing/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ cc_library(
302302
tags = ["FFI"],
303303
deps = [
304304
":i_proxy_field_binding_factory",
305+
":proxy_method_binding_factory_impl",
305306
":proxy_service_element_binding_factory_impl",
306307
"@score_baselibs//score/language/futurecpp",
307308
],

score/mw/com/impl/plumbing/i_proxy_field_binding_factory.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SCORE_MW_COM_IMPL_PLUMBING_I_PROXY_FIELD_BINDING_FACTORY_H
1515

1616
#include "score/mw/com/impl/instance_identifier.h"
17+
#include "score/mw/com/impl/methods/proxy_method_binding.h"
1718
#include "score/mw/com/impl/proxy_base.h"
1819
#include "score/mw/com/impl/proxy_event_binding.h"
1920

@@ -45,6 +46,20 @@ class IProxyFieldBindingFactory
4546
/// \return An instance of ProxyEventBinding or nullptr in case of an error.
4647
virtual auto CreateEventBinding(ProxyBase& parent, const std::string_view field_name) noexcept
4748
-> std::unique_ptr<ProxyEventBinding<SampleType>> = 0;
49+
50+
///
51+
/// @param parent
52+
/// @param field_name
53+
/// @return
54+
virtual auto CreateGetMethodBinding(ProxyBase& parent, const std::string_view field_name) noexcept
55+
-> std::unique_ptr<ProxyMethodBinding> = 0;
56+
57+
///
58+
/// @param parent
59+
/// @param field_name
60+
/// @return
61+
virtual auto CreateSetMethodBinding(ProxyBase& parent, const std::string_view field_name) noexcept
62+
-> std::unique_ptr<ProxyMethodBinding> = 0;
4863
};
4964
} // namespace score::mw::com::impl
5065

score/mw/com/impl/plumbing/proxy_field_binding_factory.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SCORE_MW_COM_IMPL_PLUMBING_PROXY_FIELD_BINDING_FACTORY_H
1414
#define SCORE_MW_COM_IMPL_PLUMBING_PROXY_FIELD_BINDING_FACTORY_H
1515

16+
#include "score/mw/com/impl/methods/proxy_method_binding.h"
1617
#include "score/mw/com/impl/plumbing/i_proxy_field_binding_factory.h"
1718
#include "score/mw/com/impl/plumbing/proxy_field_binding_factory_impl.h"
1819
#include "score/mw/com/impl/proxy_base.h"
@@ -39,6 +40,18 @@ class ProxyFieldBindingFactory final
3940
return instance().CreateEventBinding(parent, field_name);
4041
}
4142

43+
static std::unique_ptr<ProxyMethodBinding> CreateGetMethodBinding(ProxyBase& parent,
44+
std::string_view field_name) noexcept
45+
{
46+
return instance().CreateGetMethodBinding(parent, field_name);
47+
}
48+
49+
static std::unique_ptr<ProxyMethodBinding> CreateSetMethodBinding(ProxyBase& parent,
50+
std::string_view field_name) noexcept
51+
{
52+
return instance().CreateSetMethodBinding(parent, field_name);
53+
}
54+
4255
/// \brief Inject a mock IProxyFieldBindingFactory. If a mock is injected, then all calls on
4356
/// ProxyFieldBindingFactory will be dispatched to the mock.
4457
static void InjectMockBinding(IProxyFieldBindingFactory<SampleType>* const mock) noexcept

score/mw/com/impl/plumbing/proxy_field_binding_factory_impl.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,25 @@
1313
#ifndef SCORE_MW_COM_IMPL_PLUMBING_PROXY_FIELD_BINDING_FACTORY_IMPL_H
1414
#define SCORE_MW_COM_IMPL_PLUMBING_PROXY_FIELD_BINDING_FACTORY_IMPL_H
1515

16-
#include "score/mw/com/impl/bindings/lola/element_fq_id.h"
1716
#include "score/mw/com/impl/bindings/lola/proxy_event.h"
1817
#include "score/mw/com/impl/plumbing/i_proxy_field_binding_factory.h"
18+
#include "score/mw/com/impl/plumbing/proxy_method_binding_factory_impl.h"
1919
#include "score/mw/com/impl/plumbing/proxy_service_element_binding_factory_impl.h"
2020
#include "score/mw/com/impl/proxy_base.h"
2121
#include "score/mw/com/impl/proxy_event_binding.h"
2222

23-
#include <score/overload.hpp>
24-
2523
#include <memory>
2624
#include <string_view>
2725

2826
namespace score::mw::com::impl
2927
{
3028

29+
namespace detail
30+
{
31+
constexpr char kGetMethodName[] = "Get";
32+
constexpr char kSetMethodName[] = "Set";
33+
} // namespace detail
34+
3135
/// \brief Factory class that dispatches calls to the appropriate binding based on binding information in the
3236
/// deployment configuration.
3337
template <typename SampleType>
@@ -42,11 +46,17 @@ class ProxyFieldBindingFactoryImpl final : public IProxyFieldBindingFactory<Samp
4246
std::unique_ptr<ProxyEventBinding<SampleType>> CreateEventBinding(
4347
ProxyBase& parent,
4448
const std::string_view field_name) noexcept override;
49+
50+
std::unique_ptr<ProxyMethodBinding> CreateGetMethodBinding(ProxyBase& parent,
51+
const std::string_view field_name) noexcept override;
52+
53+
std::unique_ptr<ProxyMethodBinding> CreateSetMethodBinding(ProxyBase& parent,
54+
const std::string_view field_name) noexcept override;
4555
};
4656

4757
template <typename SampleType>
4858
// Suppress "AUTOSAR C++14 A15-5-3" rule finding. This rule states: "The std::terminate() function shall
49-
// not be called implicitly.". std::visit Throws std::bad_variant_access if
59+
// not be called implicitly". std::visit Throws std::bad_variant_access if
5060
// as-variant(vars_i).valueless_by_exception() is true for any variant vars_i in vars. The variant may only become
5161
// valueless if an exception is thrown during different stages. Since we don't throw exceptions, it's not possible
5262
// that the variant can return true from valueless_by_exception and therefore not possible that std::visit throws
@@ -62,6 +72,24 @@ inline std::unique_ptr<ProxyEventBinding<SampleType>> ProxyFieldBindingFactoryIm
6272
ServiceElementType::FIELD>(parent, field_name);
6373
}
6474

75+
template <typename SampleType>
76+
inline std::unique_ptr<ProxyMethodBinding> ProxyFieldBindingFactoryImpl<SampleType>::CreateGetMethodBinding(
77+
ProxyBase& parent,
78+
const std::string_view field_name) noexcept
79+
{
80+
return ProxyMethodBindingFactoryImpl<SampleType()>::Create(
81+
parent.GetHandle(), ProxyBaseView{parent}.GetBinding(), detail::kGetMethodName);
82+
}
83+
84+
template <typename SampleType>
85+
inline std::unique_ptr<ProxyMethodBinding> ProxyFieldBindingFactoryImpl<SampleType>::CreateSetMethodBinding(
86+
ProxyBase& parent,
87+
const std::string_view field_name) noexcept
88+
{
89+
return ProxyMethodBindingFactoryImpl<SampleType(SampleType)>::Create(
90+
parent.GetHandle(), ProxyBaseView{parent}.GetBinding(), detail::kSetMethodName);
91+
}
92+
6593
} // namespace score::mw::com::impl
6694

6795
#endif // SCORE_MW_COM_IMPL_PLUMBING_PROXY_FIELD_BINDING_FACTORY_IMPL_H

score/mw/com/impl/plumbing/proxy_service_element_binding_factory_impl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
namespace score::mw::com::impl
3636
{
3737

38-
template <typename ProxyServiceElementBinding, typename ProxyServiceElement, ServiceElementType element_type>
38+
template <typename ProxyServiceElementBindingInterface, typename ProxyServiceElementBinding, ServiceElementType element_type>
3939
// "AUTOSAR C++14 A15-5-3" triggered by std::bad_variant_access.
4040
// Additionally the variant might be valueless_by_exception, which would also cause a std::bad_variant_access, this
4141
// can only happen if any of the variants throw exception during construction. Since we do not throw exceptions,
@@ -49,11 +49,11 @@ template <typename ProxyServiceElementBinding, typename ProxyServiceElement, Ser
4949
//
5050
// coverity[autosar_cpp14_a15_5_3_violation]
5151
// coverity[autosar_cpp14_a8_2_1_violation]
52-
std::unique_ptr<ProxyServiceElementBinding> CreateProxyServiceElement(
52+
std::unique_ptr<ProxyServiceElementBindingInterface> CreateProxyServiceElement(
5353
ProxyBase& parent,
5454
const std::string_view service_element_name) noexcept
5555
{
56-
using ReturnType = std::unique_ptr<ProxyServiceElementBinding>;
56+
using ReturnType = std::unique_ptr<ProxyServiceElementBindingInterface>;
5757

5858
const HandleType& handle = parent.GetHandle();
5959
const auto& type_deployment = handle.GetServiceTypeDeployment();
@@ -80,7 +80,7 @@ std::unique_ptr<ProxyServiceElementBinding> CreateProxyServiceElement(
8080
lola_service_element_id,
8181
lola_service_instance_id->GetId(),
8282
element_type};
83-
return std::make_unique<ProxyServiceElement>(*lola_parent, element_fq_id, service_element_name);
83+
return std::make_unique<ProxyServiceElementBinding>(*lola_parent, element_fq_id, service_element_name);
8484
},
8585
[](const score::cpp::blank&) noexcept -> ReturnType {
8686
return nullptr;

score/mw/com/impl/proxy_event.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace score::mw::com::impl
4040
// False Positive: this is a normal forward declaration.
4141
// Which is used to avoid cyclic dependency with proxy_field.h
4242
// coverity[autosar_cpp14_m3_2_3_violation]
43-
template <typename>
43+
template <typename, bool, bool, bool>
4444
class ProxyField;
4545

4646
/// \brief This is the user-visible class of an event that is part of a proxy. It contains ProxyEvent functionality that
@@ -54,15 +54,22 @@ template <typename SampleDataType>
5454
class ProxyEvent final : public ProxyEventBase
5555
{
5656
template <typename T>
57-
// Design decission: This friend class provides a view on the internals of ProxyEvent.
58-
// This enables us to hide unncecessary internals from the enduser.
57+
// Design decision: This friend class provides a view on the internals of ProxyEvent.
58+
// This enables us to hide unnecessary internals from the end user.
5959
// coverity[autosar_cpp14_a11_3_1_violation]
6060
friend class ProxyEventView;
6161

62-
// Design decission: ProxyField uses composition pattern to reuse code from ProxyEvent. These two classes also have
62+
// Design decision: ProxyField uses composition pattern to reuse code from ProxyEvent. These two classes also have
6363
// shared private APIs which necessitates the use of the friend keyword.
6464
// coverity[autosar_cpp14_a11_3_1_violation]
65-
friend class ProxyField<SampleDataType>;
65+
friend class ProxyField<SampleDataType, true, true, true>;
66+
friend class ProxyField<SampleDataType, true, false, false>;
67+
friend class ProxyField<SampleDataType, true, true, false>;
68+
friend class ProxyField<SampleDataType, true, false, true>;
69+
friend class ProxyField<SampleDataType, false, true, true>;
70+
friend class ProxyField<SampleDataType, false, false, false>;
71+
friend class ProxyField<SampleDataType, false, true, false>;
72+
friend class ProxyField<SampleDataType, false, false, true>;
6673

6774
// Empty struct that is used to make the second constructor only accessible to ProxyField (as it is a friend).
6875
struct FieldOnlyConstructorEnabler

0 commit comments

Comments
 (0)