Commit 07889707 authored by Quentin Khan's avatar Quentin Khan

Refactor FBasicParticleContainer serialisation implementation

FBasicParticleContainer's implementation of FAbrastractSendable
interface was buggy:
 - getSavedSize did not return the right result;
 - the extra attributes (type pack `OtherTypes`) were not saved.

The whole interface implementation has been moved to the base class
FVariadicParticleContainer and is now correct.

The undelying variadic_vector is modified to expose the integer_sequence
holding the indices for its types. This allows derived classes to use it
to act on all its data.
parent 443d39ce
#ifndef FVARIADICPARTICLECONTAINER_H
#define FVARIADICPARTICLECONTAINER_H
#include "Utils/FGlobal.hpp"
#include "Utils/FPoint.hpp"
#include "Utils/variadic_container.hpp"
#include "Utils/FAlignedAllocator.hpp"
......@@ -33,8 +36,8 @@ public:
using FBase::FBase;
/** \brief Get particle count in the container
/**
* \brief Get particle count in the container
*
* \return Particle count
*/
......@@ -43,14 +46,16 @@ public:
}
//DELETE
/** \brief Clears the container
/**
* \brief Clears the container
*/
[[gnu::deprecated]]
[[gnu::deprecated("Use clear() method instead")]]
void resetNumberOfParticles() {
FBase::clear();
}
/** \brief Push a particle in the conainer
/**
* \brief Push a particle in the container
*
* \param particle Particle to push
*/
......@@ -58,7 +63,8 @@ public:
this->push_back(static_cast<typename Particle::data_t>(particle));
}
/** \brief Push a particle in the container
/**
* \brief Push a particle in the container
*
* \tparam Args Parameter pack of types convertible to the Attribute type.
*
......@@ -74,19 +80,102 @@ public:
this->push(Particle(position, args...));
}
/*
template<typename... Ts>
void push(const position_t& pos, Ts&&... args) {
this->push_impl(std::make_index_sequence<position_t::Dim>(),
pos, std::forward<Ts>(args)...);
/**
* \brief Get size to send the container
*
* \return The size of the serialised particle container in bytes
*
* \note Implementation is #getSavedSize_impl
*/
FSize getSavedSize() const {
return this->getSavedSize_impl(this->data());
}
private:
/**
* \brief Implementation of #getSavedSize
*
* \tparam Types The container types
*
* \return The size of the serialised particle container in bytes
*/
template<class... Types>
FSize getSavedSize_impl(std::tuple<Types*...>) const {
FSize tmp = sizeof(this->size());
// Sum, for T in Types, of (sizeof(T) * this->size())
auto l = {(tmp += sizeof(Types) * this->size(), 0)..., 0};
(void)l;
return tmp;
}
public:
/**
* \brief Serialize particle container to buffer
*
* \tparam BufferWriter Buffer class
*
* \param buffer Buffer in which to save the container
*
* \note Implementation is #save_impl
*/
template<class BufferWriter>
void save(BufferWriter& buffer) const {
this->save_impl(buffer, FBase::indices);
}
private:
/**
* \brief Implementation of #save
*
* \tparam BufferWriter Buffer class
* \tparam Is Index pack for the container types
*
* \note Writes #getSavedSize bytes into the buffer
*/
template<class BufferWriter, std::size_t ... Is>
void save_impl(BufferWriter& buffer, inria::index_sequence<Is...>) const {
buffer << this->size();
// For each sub-array `s`, write `s` to the buffer
auto l = {
(buffer.write(std::get<Is>(this->data()), this->size()),0)...,
0};
(void)l;
}
public:
/** \brief Restore container content from a buffer
*
* \tparam BufferReader Buffer class
*
* \param buffer Buffer from which to restore the buffer
*
* \note Implementation is #restore_impl
*/
template<class BufferReader>
void restore(BufferReader& buffer) {
this->restore_impl(buffer, FBase::indices);
}
private:
/**
* \brief Implementation of #restore
*
* \tparam BufferReader Buffer class
* \tparam Is Index pack for the container types
*
* \note Reads #getSavedSize bytes from the buffer
*/
template<class BufferReader, std::size_t ... Is>
void restore_impl(BufferReader& buffer, inria::index_sequence<Is...>) {
FSize particle_count = 0;
buffer >> particle_count;
template<typename... Ts, std::size_t... Is>
void push_impl(std::index_sequence<Is...>, const position_t& pos, Ts&&... args) {
this->push_back(pos[Is]..., std::forward<Ts>(args)...);
this->resize(particle_count);
auto l = {
(buffer.fillArray(std::get<Is>(this->data()), this->size()),0)...,
0};
(void)l;
}
*/
};
......
......@@ -378,68 +378,6 @@ public:
memset(p, 0, sizeof(Attribute) * this->size());
}
/** \brief Get size to send the container
*
* \return The size of the data array
*/
FSize getSavedSize() const {
return FSize(sizeof(this->size())
// Last element of the attribute/position array
+ (reinterpret_cast<const char*>(std::get<Dim+OtherCount+AttributeCount-1>(this->data()))
// First element of the attribute/position array
- reinterpret_cast<const char*>(std::get<0>(this->data())+this->size())));
//return FSize(sizeof(this->size()) + this->size() * (Dim * sizeof(FReal) + AttributeCount * sizeof(Attribute)));
}
/** \brief Save particle container
*
* \tparam BufferWriterClass Buffer class
*
* \param buffer Buffer in which to save the container
*/
template <class BufferWriterClass>
void save(BufferWriterClass& buffer) const{
buffer << this->size();
for(int idx = 0 ; idx < Dim ; ++idx){
buffer.write(_positions[idx], this->size());
}
for(unsigned idx = 0 ; idx < AttributeCount ; ++idx){
buffer.write(getAttribute(idx), this->size());
}
}
/** \brief Restore container content from a buffer
*
* \tparam BufferReaderClass Buffer class
*
* \param buffer Buffer from which to restore the buffer
*/
template <class BufferReaderClass>
void restore(BufferReaderClass& buffer) {
FSize particleCount;
buffer >> particleCount;
this->resize(particleCount);
// Update proxies if memory was allocated by resize
this->getPositions();
this->getAttribute(0);
for(int idx = 0 ; idx < Dim ; ++idx){
for(int valIdx = 0; valIdx < particleCount; ++valIdx) {
buffer.fillValue(&(_positions[idx][valIdx]));
}
}
for(unsigned idx = 0 ; idx < AttributeCount ; ++idx){
for(int valIdx = 0; valIdx < particleCount; ++valIdx) {
buffer.fillValue(&(getAttribute(idx)[valIdx]));
}
}
}
private:
template <typename AttributeTuple, std::size_t I = AttributeCount - 1 >
......
......@@ -90,12 +90,12 @@ public:
using allocator_type_tuple = std::tuple<typename Allocator::template rebind<Types>...>;
constexpr static auto indices = inria::make_index_sequence<sizeof...(Types)>();
private:
template<typename T>
using result_tuple = std::tuple<decltype((std::declval<Types*>(), std::declval<T>()))...>;
constexpr static auto indices = inria::make_index_sequence<sizeof...(Types)>();
/// Allocator for the data block
typename Allocator::template rebind<char>::other _data_allocator;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment