Skip to content

Commit

Permalink
Added support for the comms::option::def::DisplayOffset option.
Browse files Browse the repository at this point in the history
  • Loading branch information
arobenko committed Oct 27, 2024
1 parent e32f175 commit 65d38ee
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 2 deletions.
27 changes: 26 additions & 1 deletion include/comms/field/IntValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace field
/// @li @ref comms::option::def::AvailableLengthLimit
/// @li @ref comms::option::def::DefaultValueInitialiser or @ref comms::option::def::DefaultNumValue.
/// @li comms::option::def::EmptySerialization
/// @li @ref comms::option::def::DisplayOffset
/// @li @ref comms::option::def::FailOnInvalid
/// @li @ref comms::option::def::FieldType
/// @li @ref comms::option::def::FixedBitLength
Expand Down Expand Up @@ -183,7 +184,14 @@ class IntValue : public details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>
static constexpr bool hasFixedValue()
{
return ParsedOptions::HasFixedValue;
}
}

/// @brief Compile time inquiry of whether @ref comms::option::def::DisplayOffset option
/// has been used.
static constexpr bool hasDisplayOffset()
{
return ParsedOptions::HasDisplayOffset;
}

/// @brief Scales value according to ratio specified in provided
/// @ref comms::option::def::ScalingRatio option.
Expand Down Expand Up @@ -258,6 +266,23 @@ class IntValue : public details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>
BaseImpl::setValue(std::forward<U>(val));
}

/// @brief Get display value
/// @details Retrieving value by taking into account the display offset provided by the @ref comms::option::def::DisplayOffset option
/// if such was used.
ValueType getDisplayValue() const
{
return static_cast<ValueType>(getValue() + BaseImpl::displayOffset());
}

/// @brief Set display value
/// @details Updating inner value by taking into account the display offset provided by the @ref comms::option::def::DisplayOffset option
/// if such was used.
template <typename U>
void setDisplayValue(U&& val)
{
setValue(val - BaseImpl::displayOffset());
}

/// @brief Get maximal numeric value the field can hold.
static constexpr ValueType maxValue()
{
Expand Down
44 changes: 44 additions & 0 deletions include/comms/field/adapter/DisplayOffset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Copyright 2019 - 2024 (C). Alex Robenko. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include <cstdint>
#include <type_traits>

namespace comms
{

namespace field
{

namespace adapter
{


template <std::intmax_t TOffset, typename TBase>
class DisplayOffset : public TBase
{
using BaseImpl = TBase;
public:
using DisplayOffsetType = typename TBase::DisplayOffsetType;

static constexpr DisplayOffsetType displayOffset()
{
return static_cast<DisplayOffsetType>(TOffset);
}
};

} // namespace adapter

} // namespace field

} // namespace comms




6 changes: 6 additions & 0 deletions include/comms/field/basic/IntValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class IntValue : public TFieldBase
using SerialisedType = ValueType;
using ScalingRatio = std::ratio<1, 1>;
using CommsTag = comms::field::tag::Int;
using DisplayOffsetType = typename std::make_signed<ValueType>::type;

IntValue() = default;

Expand Down Expand Up @@ -130,6 +131,11 @@ class IntValue : public TFieldBase
BaseImpl::writeData(toSerialised(value_), iter);
}

static constexpr DisplayOffsetType displayOffset()
{
return static_cast<DisplayOffsetType>(0);
}

private:
ValueType value_ = static_cast<ValueType>(0);
};
Expand Down
5 changes: 4 additions & 1 deletion include/comms/field/details/AdaptBasicField.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,11 @@ class AdaptBasicField
using SerOffsetAdapted =
typename ParsedOptions::template AdaptSerOffset<VersionStorageAdapted>;

using DisplayOffsetAdapted =
typename ParsedOptions::template AdaptDisplayOffset<SerOffsetAdapted>;

using VersionsRangeAdapted =
typename ParsedOptions::template AdaptVersionsRange<SerOffsetAdapted>;
typename ParsedOptions::template AdaptVersionsRange<DisplayOffsetAdapted>;

using FixedLengthLimitAdapted =
typename ParsedOptions::template AdaptFixedLengthLimit<VersionsRangeAdapted>;
Expand Down
16 changes: 16 additions & 0 deletions include/comms/field/details/OptionsParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class OptionsParser<>
static constexpr bool HasVariantCustomResetOnDestruct = false;
static constexpr bool HasVersionDependentMembersForced = false;
static constexpr bool HasFixedValue = false;
static constexpr bool HasDisplayOffset = false;

using UnitsType = void;
using ScalingRatio = std::ratio<1, 1>;
Expand Down Expand Up @@ -194,6 +195,9 @@ class OptionsParser<>

template <typename TField>
using AdaptFixedValue = TField;

template <typename TField>
using AdaptDisplayOffset = TField;
};

template <typename... TOptions>
Expand Down Expand Up @@ -808,6 +812,18 @@ class OptionsParser<
using AdaptFixedValue = comms::field::adapter::FixedValue<TField>;
};

template <std::intmax_t TOffset, typename... TOptions>
class OptionsParser<
comms::option::def::DisplayOffset<TOffset>,
TOptions...> : public OptionsParser<TOptions...>
{
public:
static constexpr bool HasDisplayOffset = true;
static constexpr std::intmax_t DisplayOffset = TOffset;

template <typename TField>
using AdaptDisplayOffset = comms::field::adapter::DisplayOffset<TOffset, TField>;
};

template <typename... TOptions>
class OptionsParser<
Expand Down
1 change: 1 addition & 0 deletions include/comms/field/details/adapters.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "comms/field/adapter/CustomRefreshWrap.h"
#include "comms/field/adapter/CustomWriteWrap.h"
#include "comms/field/adapter/DefaultValueInitialiser.h"
#include "comms/field/adapter/DisplayOffset.h"
#include "comms/field/adapter/EmptySerialization.h"
#include "comms/field/adapter/ExistsBetweenVersions.h"
#include "comms/field/adapter/FailOnInvalid.h"
Expand Down
6 changes: 6 additions & 0 deletions include/comms/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,12 @@ struct HasVersionDependentMembers {};
/// @brief Remove an ability to update field's value by the client code
struct FixedValue {};

/// @brief Option used to specify display offset for the @ref comms::field::IntValue field.
/// @tparam TOffset Display offset.
/// @headerfile comms/options.h
template <std::intmax_t TOffset>
struct DisplayOffset {};

} // namespace def

namespace app
Expand Down
18 changes: 18 additions & 0 deletions test/Fields2.th
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public:
void test34();
void test35();
void test36();
void test37();

private:
template <typename TField>
Expand Down Expand Up @@ -2220,6 +2221,23 @@ void FieldsTestSuite2::test36()
TS_ASSERT_EQUALS(static_cast<std::size_t>(std::distance(&Buf[0], readIter)), BufSize)
}

void FieldsTestSuite2::test37()
{
using Field =
comms::field::IntValue<
comms::Field<BigEndianOpt>,
std::uint16_t,
comms::option::def::DisplayOffset<2>
>;

Field field;

TS_ASSERT_EQUALS(field.getDisplayValue(), 2U);
field.setDisplayValue(10U);
TS_ASSERT_EQUALS(field.getDisplayValue(), 10U);
TS_ASSERT_EQUALS(field.getValue(), 8U);
}

template <typename TField>
void FieldsTestSuite2::writeField(
const TField& field,
Expand Down

0 comments on commit 65d38ee

Please sign in to comment.