Skip to content

Commit

Permalink
breaking change in TypeDefinition
Browse files Browse the repository at this point in the history
  • Loading branch information
facontidavide committed Feb 16, 2024
1 parent f5c297b commit 54dcf2b
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 201 deletions.
2 changes: 1 addition & 1 deletion data_tamer_cpp/benchmarks/data_tamer_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static void DT_Doubles(benchmark::State& state)

static void DT_PoseType(benchmark::State& state)
{
std::vector<Pose> poses(size_t(state.range(0)));
std::vector<TestTypes::Pose> poses(size_t(state.range(0)));

auto registry = ChannelsRegistry();
auto channel = registry.getChannel("channel");
Expand Down
6 changes: 6 additions & 0 deletions data_tamer_cpp/examples/custom_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@

#include "geometry_types.hpp"

struct Bar
{
int a;
};

int main()
{
using namespace TestTypes;
using namespace DataTamer;

auto dummy_sink = std::make_shared<DummySink>();
Expand Down
93 changes: 42 additions & 51 deletions data_tamer_cpp/examples/geometry_types.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "data_tamer/custom_types.hpp"

namespace TestTypes
{
struct Point3D
{
double x;
Expand All @@ -21,10 +23,11 @@ struct Pose
Quaternion rot;
};

// Sometimes a field of a type is hidden as a private member and can be
// accesses only by const reference.
// This case is also supported but must be registered differently (see below).
// Classese of this type are commonly found in libraries like Eigen
} // end namespace TestTypes

namespace PseudoEigen
{

class Vector2d
{
double _x = 0;
Expand All @@ -41,64 +44,52 @@ class Vector2d
double& y() { return _y; }
};

namespace DataTamer
} // end namespace TestTypes

namespace TestTypes
{

template <>
struct TypeDefinition<Point3D>
template <typename AddField>
std::string_view TypeDefinition(Point3D& point, AddField& add)
{
std::string typeName() const { return "Point3D"; }

template <class Function>
void typeDef(Function& addField)
{
addField("x", &Point3D::x);
addField("y", &Point3D::y);
addField("z", &Point3D::z);
}
add("x", &point.x);
add("y", &point.y);
add("z", &point.z);
return "Point3D";
};

template <>
struct TypeDefinition<Quaternion>
//--------------------------------------------------------------
// We must specialize the function TypeDefinition
// This must be done in the same namespace of the original type

template <typename AddField>
std::string_view TypeDefinition(Quaternion& quat, AddField& add)
{
std::string typeName() const { return "Quaternion"; }

template <class Function>
void typeDef(Function& addField)
{
addField("w", &Quaternion::w);
addField("x", &Quaternion::x);
addField("y", &Quaternion::y);
addField("z", &Quaternion::z);
}
add("w", &quat.w);
add("x", &quat.x);
add("y", &quat.y);
add("z", &quat.z);
return "Quaternion";
};

template <>
struct TypeDefinition<Pose>
template <typename AddField>
std::string_view TypeDefinition(Pose& pose, AddField& add)
{
std::string typeName() const { return "Pose"; }

template <class Function>
void typeDef(Function& addField)
{
addField("position", &Pose::pos);
addField("rotation", &Pose::rot);
}
add("position", &pose.pos);
add("rotation", &pose.rot);
return "Pose";
};

template <>
struct TypeDefinition<Vector2d>
} // end namespace TestTypes

namespace PseudoEigen
{
template <typename AddField>
std::string_view TypeDefinition(Vector2d& vect, AddField& add)
{
std::string typeName() const { return "Vector2d"; }

// typeDef must use a different overload and x() and y() must return const reference to
// a class attribute
template <class Function>
void typeDef(const Vector2d& vect, Function& addField)
{
addField("x", &vect.x());
addField("y", &vect.y());
}
add("x", &vect.x());
add("y", &vect.y());
return "Vector2d";
};

} // namespace DataTamer
} // end namespace PseudoEigen
4 changes: 2 additions & 2 deletions data_tamer_cpp/examples/mcap_writer_sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ int main()
std::array<float, 4> v2 = {1, 2, 3, 4};
int32_t v3 = 5;
uint16_t v4 = 6;
Pose pose;
TestTypes::Pose pose;
pose.pos = {1, 2, 3};
pose.rot = {0.4, 0.5, 0.6, 0.7};

Expand All @@ -35,7 +35,7 @@ int main()
uint16_t v6 = 11;
std::vector<uint8_t> v7(4, 12);
std::array<uint32_t, 3> v8 = {13, 14, 15};
std::vector<Point3D> points(2);
std::vector<TestTypes::Point3D> points(2);
points[0] = {1, 2, 3};
points[1] = {4, 5, 6};

Expand Down
50 changes: 23 additions & 27 deletions data_tamer_cpp/include/data_tamer/channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ void LogChannel::updateTypeRegistryImpl(FieldsVector& fields, const char* field_

if constexpr (GetBasicType<T>() == BasicType::OTHER)
{
field.type_name = TypeDefinition<T>().typeName();
field.type_name = CustomTypeName<T>::get();

if constexpr (container_info<T>::is_container)
{
Expand All @@ -288,40 +288,36 @@ void LogChannel::updateTypeRegistryImpl(FieldsVector& fields, const char* field_
template <typename T>
inline void LogChannel::updateTypeRegistry()
{
FieldsVector fields;
if constexpr(IsNumericType<T>() )
{
return;
}
using namespace SerializeMe;
static_assert(has_TypeDefinition<T>(), "Missing TypeDefinition");

if constexpr (!IsNumericType<T>())
{
const auto& type_name = DataTamer::TypeDefinition<T>().typeName();
auto added_serializer = _type_registry.addType<T>(type_name, true);
if (added_serializer)
{
if constexpr (has_typedef_with_object<T>())
{
auto func = [this, &fields](const char* field_name, const auto* member) {
using MemberType =
typename std::remove_cv_t<std::remove_reference_t<decltype(*member)>>;
updateTypeRegistryImpl<MemberType>(fields, field_name);
};
TypeDefinition<T>().typeDef({}, func);
}
else
{
auto func = [this, &fields](const char* field_name, const auto& member) {
using MemberType = decltype(getPointerType(member));
this->updateTypeRegistryImpl<MemberType>(fields, field_name);
};
TypeDefinition<T>().typeDef(func);
}
addCustomType(type_name, fields);
}
FieldsVector fields;
const std::string type_name(CustomTypeName<T>::get());
if (auto added_serializer = _type_registry.addType<T>(type_name, true))
{
auto func = [this, &fields](const char* field_name, const auto* member) {
using MemberType =
typename std::remove_cv_t<std::remove_reference_t<decltype(*member)>>;
updateTypeRegistryImpl<MemberType>(fields, field_name);
};
T dummy;
TypeDefinition(dummy, func);
addCustomType(type_name, fields);
}
}

template <typename T>
inline RegistrationID LogChannel::registerValue(const std::string& name,
const T* value_ptr)
{
using namespace SerializeMe;
static_assert(has_TypeDefinition<T>() || IsNumericType<T>(),
"Missing TypeDefinition");

if constexpr (IsNumericType<T>())
{
return registerValueImpl(name, ValuePtr(value_ptr), {});
Expand Down
49 changes: 36 additions & 13 deletions data_tamer_cpp/include/data_tamer/contrib/SerializeMe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,21 +229,38 @@ inline T EndianSwap(T t)
}
}

template <class Type>
struct TypeDefinition
{
std::string typeName() const;
template <class Function>
void typeDef(const Type& obj, Function& addField);
};
// Custom types requires the implementation of:
//
// template <typename AddField>
// std::string_view TypeDefinition(MyType& object, AddField& add)
//
// Example:
//
// struct Point2D {
// double x;
// double y;
// };
//
// template <typename AddField>
// std::string_view TypeDefinition(Point2D& point, AddField& add) {
// add("x", &point.x);
// add("y", &point.y);
// return "Point2D";
// }

template <typename T, class = void>
struct is_serializer_specialized : std::false_type
struct has_TypeDefinition : std::false_type
{
};

const auto EmptyFuncion = [](const char*, void*){};
using EmptyFunc = decltype(EmptyFuncion);

template <typename T1, typename T2>
using enable_if_same_t = std::enable_if_t<std::is_same_v<T1, T2>>;

template <typename T>
struct is_serializer_specialized<T, decltype(TypeDefinition<T>(), void())>
struct has_TypeDefinition<T, enable_if_same_t<std::string_view, decltype(TypeDefinition(std::declval<T&>(), std::declval<EmptyFunc&>()))>>
: std::true_type
{
};
Expand Down Expand Up @@ -312,6 +329,8 @@ inline constexpr bool is_vector()
template <typename T>
inline size_t BufferSize(const T& val)
{
static_assert(is_number<T>() || has_TypeDefinition<T>(), "Missing TypeDefinition");

if constexpr (is_number<T>())
{
return sizeof(T);
Expand All @@ -323,7 +342,7 @@ inline size_t BufferSize(const T& val)
total_size += BufferSize(*field);
};

TypeDefinition<T>().typeDef(val, func);
TypeDefinition(const_cast<T&>(val), func);
return total_size;
}
}
Expand Down Expand Up @@ -365,7 +384,9 @@ inline size_t BufferSize(const Container<T, TArgs...>& vect)
template <typename T>
inline void DeserializeFromBuffer(SpanBytesConst& buffer, T& dest)
{
if constexpr (std::is_arithmetic_v<T> || std::is_same_v<T, std::byte>)
static_assert(is_number<T>() || has_TypeDefinition<T>(), "Missing TypeDefinition");

if constexpr (is_number<T>())
{
auto const S = sizeof(T);
if (S > buffer.size())
Expand All @@ -384,7 +405,7 @@ inline void DeserializeFromBuffer(SpanBytesConst& buffer, T& dest)
auto func = [&buffer](const char*, const auto* field) {
DeserializeFromBuffer(buffer, *field);
};
TypeDefinition<T>().typeDef(dest, func);
TypeDefinition(dest, func);
}
}

Expand Down Expand Up @@ -469,6 +490,8 @@ inline void DeserializeFromBuffer(SpanBytesConst& buffer, Container<T, TArgs...>
template <typename T>
inline void SerializeIntoBuffer(SpanBytes& buffer, T const& value)
{
static_assert(is_number<T>() || has_TypeDefinition<T>(), "Missing TypeDefinition");

if constexpr (is_number<T>())
{
const size_t S = sizeof(T);
Expand All @@ -488,7 +511,7 @@ inline void SerializeIntoBuffer(SpanBytes& buffer, T const& value)
auto func = [&buffer](const char*, const auto* field) {
SerializeIntoBuffer(buffer, *field);
};
TypeDefinition<T>().typeDef(value, func);
TypeDefinition(const_cast<T&>(value), func);
}
}

Expand Down
Loading

0 comments on commit 54dcf2b

Please sign in to comment.