Skip to content
Snippets Groups Projects
Commit b8b16988 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Tidy frame template code

parent 2b8ee2a3
No related branches found
No related tags found
1 merge request!314New Frame Class
Pipeline #27395 passed
...@@ -92,7 +92,7 @@ class Frame { ...@@ -92,7 +92,7 @@ class Frame {
inline size_t size() const { return data_.size(); } inline size_t size() const { return data_.size(); }
inline bool has(ftl::codecs::Channel c) const; bool has(ftl::codecs::Channel c) const;
inline bool hasOwn(ftl::codecs::Channel c) const; inline bool hasOwn(ftl::codecs::Channel c) const;
...@@ -157,8 +157,6 @@ class Frame { ...@@ -157,8 +157,6 @@ class Frame {
template <typename T> template <typename T>
T &createChange(ftl::codecs::Channel c, ftl::data::ChangeType t, std::vector<uint8_t> &data); T &createChange(ftl::codecs::Channel c, ftl::data::ChangeType t, std::vector<uint8_t> &data);
std::any &createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t);
const std::vector<uint8_t> &getEncoded(ftl::codecs::Channel c) const; const std::vector<uint8_t> &getEncoded(ftl::codecs::Channel c) const;
template <typename T, typename ...ARGS> template <typename T, typename ...ARGS>
...@@ -237,6 +235,13 @@ class Frame { ...@@ -237,6 +235,13 @@ class Frame {
inline MUTEX &mutex(); inline MUTEX &mutex();
protected:
std::any &createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t);
std::any &createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t, std::vector<uint8_t> &data);
std::any &createAny(ftl::codecs::Channel c);
private: private:
struct ChannelData { struct ChannelData {
ChannelStatus status=ChannelStatus::INVALID; ChannelStatus status=ChannelStatus::INVALID;
...@@ -301,15 +306,6 @@ class Session : public Frame { ...@@ -301,15 +306,6 @@ class Session : public Frame {
MUTEX &ftl::data::Frame::mutex() { return parent_->mutex(); } MUTEX &ftl::data::Frame::mutex() { return parent_->mutex(); }
bool ftl::data::Frame::has(ftl::codecs::Channel c) const {
const auto &i = data_.find(c);
if (i != data_.end() && i->second.status != ftl::data::ChannelStatus::INVALID) {
return true;
} else {
return (parent_ && parent_->has(c));
}
}
bool ftl::data::Frame::hasOwn(ftl::codecs::Channel c) const { bool ftl::data::Frame::hasOwn(ftl::codecs::Channel c) const {
const auto &i = data_.find(c); const auto &i = data_.find(c);
return (i != data_.end() && i->second.status != ftl::data::ChannelStatus::INVALID); return (i != data_.end() && i->second.status != ftl::data::ChannelStatus::INVALID);
...@@ -367,7 +363,6 @@ template <typename T> ...@@ -367,7 +363,6 @@ template <typename T>
const T &ftl::data::Frame::get(ftl::codecs::Channel c) const { const T &ftl::data::Frame::get(ftl::codecs::Channel c) const {
const auto &d = _getData(c); const auto &d = _getData(c);
if (d.status != ftl::data::ChannelStatus::INVALID) { if (d.status != ftl::data::ChannelStatus::INVALID) {
if (!d.data.has_value()) throw FTL_Error("Missing value in channel 'any' structure");
auto *p = std::any_cast<T>(&d.data); auto *p = std::any_cast<T>(&d.data);
if (!p) throw FTL_Error("'get' wrong type for channel (" << static_cast<unsigned int>(c) << ")"); if (!p) throw FTL_Error("'get' wrong type for channel (" << static_cast<unsigned int>(c) << ")");
return *p; return *p;
...@@ -377,63 +372,34 @@ const T &ftl::data::Frame::get(ftl::codecs::Channel c) const { ...@@ -377,63 +372,34 @@ const T &ftl::data::Frame::get(ftl::codecs::Channel c) const {
// Non-list version // Non-list version
template <typename T, std::enable_if_t<!is_list<T>::value,int> = 0> template <typename T, std::enable_if_t<!is_list<T>::value,int> = 0>
T &ftl::data::Frame::create(ftl::codecs::Channel c) { T &ftl::data::Frame::create(ftl::codecs::Channel c) {
if (status_ != FrameStatus::STORED) throw FTL_Error("Cannot modify before store");
if (isAggregate(c)) throw FTL_Error("Aggregate channels must be of list type"); if (isAggregate(c)) throw FTL_Error("Aggregate channels must be of list type");
size_t t = getChannelType(c); ftl::data::verifyChannelType<T>(c);
if (t > 0 && t != typeid(T).hash_code()) throw FTL_Error("Incorrect type for channel " << static_cast<unsigned int>(c));
auto &d = data_[c]; std::any &a = createAny(c);
if (d.status != ftl::data::ChannelStatus::FLUSHED) { if (!isType<T>(c)) return a.emplace<T>();
d.status = ftl::data::ChannelStatus::VALID; else return *std::any_cast<T>(&a);
d.encoded.clear();
touch(c);
if (!isType<T>(c)) return d.data.emplace<T>();
else return *std::any_cast<T>(&d.data);
} else {
throw FTL_Error("Channel is flushed and read-only: " << static_cast<unsigned int>(c));
}
} }
// List version // List version
template <typename T, std::enable_if_t<is_list<T>::value,int> = 0> template <typename T, std::enable_if_t<is_list<T>::value,int> = 0>
ftl::data::Aggregator<T> ftl::data::Frame::create(ftl::codecs::Channel c) { ftl::data::Aggregator<T> ftl::data::Frame::create(ftl::codecs::Channel c) {
if (status_ != FrameStatus::STORED) throw FTL_Error("Cannot modify before store"); ftl::data::verifyChannelType<T>(c);
size_t t = getChannelType(c);
if (t > 0 && t != typeid(T).hash_code()) throw FTL_Error("Incorrect type for channel " << static_cast<unsigned int>(c));
auto &d = data_[c]; std::any &a = createAny(c);
if (d.status != ftl::data::ChannelStatus::FLUSHED) { if (!isType<T>(c)) a.emplace<T>();
d.status = ftl::data::ChannelStatus::VALID; return ftl::data::Aggregator<T>{*std::any_cast<T>(&a), isAggregate(c)};
d.encoded.clear();
touch(c);
if (!isType<T>(c)) {
d.data.emplace<T>();
return ftl::data::Aggregator<T>{*std::any_cast<T>(&d.data), isAggregate(c)};
} else return ftl::data::Aggregator<T>{*std::any_cast<T>(&d.data), isAggregate(c)};
} else {
throw FTL_Error("Channel is flushed and read-only: " << static_cast<unsigned int>(c));
}
} }
template <typename T> template <typename T>
T &ftl::data::Frame::createChange(ftl::codecs::Channel c, ftl::data::ChangeType type, std::vector<uint8_t> &data) { T &ftl::data::Frame::createChange(ftl::codecs::Channel c, ftl::data::ChangeType type, std::vector<uint8_t> &data) {
if (!bool(is_list<T>{}) && isAggregate(c)) throw FTL_Error("Aggregate channels must be of list type"); if (!bool(is_list<T>{}) && isAggregate(c)) throw FTL_Error("Aggregate channels must be of list type");
size_t t = getChannelType(c); ftl::data::verifyChannelType<T>(c);
if (t > 0 && t != typeid(T).hash_code()) throw FTL_Error("Incorrect type for channel " << static_cast<unsigned int>(c));
auto &d = data_[c]; std::any &a = createAnyChange(c, type, data);
if (d.status != ftl::data::ChannelStatus::FLUSHED) { if (!isType<T>(c)) return a.emplace<T>();
d.status = ftl::data::ChannelStatus::DISPATCHED; else return *std::any_cast<T>(&a);
d.encoded = std::move(data);
touch(c, type);
if (!isType<T>(c)) return d.data.emplace<T>();
else return *std::any_cast<T>(&d.data);
} else {
throw FTL_Error("Channel is flushed and read-only: " << static_cast<unsigned int>(c));
}
} }
// Non-list version // Non-list version
......
...@@ -55,7 +55,17 @@ Frame::~Frame() { ...@@ -55,7 +55,17 @@ Frame::~Frame() {
if (status_ != FrameStatus::RELEASED && pool_) pool_->release(*this); if (status_ != FrameStatus::RELEASED && pool_) pool_->release(*this);
}; };
bool ftl::data::Frame::has(ftl::codecs::Channel c) const {
const auto &i = data_.find(c);
if (i != data_.end() && i->second.status != ftl::data::ChannelStatus::INVALID) {
return true;
} else {
return (parent_ && parent_->has(c));
}
}
Frame::ChannelData &Frame::_getData(ftl::codecs::Channel c) { Frame::ChannelData &Frame::_getData(ftl::codecs::Channel c) {
if (status_ == FrameStatus::RELEASED) throw FTL_Error("Reading a released frame");
const auto &i = data_.find(c); const auto &i = data_.find(c);
if (i != data_.end()) { if (i != data_.end()) {
return i->second; return i->second;
...@@ -65,6 +75,7 @@ Frame::ChannelData &Frame::_getData(ftl::codecs::Channel c) { ...@@ -65,6 +75,7 @@ Frame::ChannelData &Frame::_getData(ftl::codecs::Channel c) {
} }
const Frame::ChannelData &Frame::_getData(ftl::codecs::Channel c) const { const Frame::ChannelData &Frame::_getData(ftl::codecs::Channel c) const {
if (status_ == FrameStatus::RELEASED) throw FTL_Error("Reading a released frame");
const auto &i = data_.find(c); const auto &i = data_.find(c);
if (i != data_.end()) { if (i != data_.end()) {
return i->second; return i->second;
...@@ -79,6 +90,21 @@ std::any &Frame::createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t ...@@ -79,6 +90,21 @@ std::any &Frame::createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t
auto &d = data_[c]; auto &d = data_[c];
if (d.status != ftl::data::ChannelStatus::FLUSHED) { if (d.status != ftl::data::ChannelStatus::FLUSHED) {
d.status = ftl::data::ChannelStatus::DISPATCHED; d.status = ftl::data::ChannelStatus::DISPATCHED;
d.encoded.clear();
touch(c, t);
return d.data;
} else {
throw FTL_Error("Channel is flushed and read-only: " << static_cast<unsigned int>(c));
}
}
std::any &Frame::createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t, std::vector<uint8_t> &data) {
if (status_ != FrameStatus::CREATED) throw FTL_Error("Cannot apply change after store " << static_cast<int>(status_));
auto &d = data_[c];
if (d.status != ftl::data::ChannelStatus::FLUSHED) {
d.status = ftl::data::ChannelStatus::DISPATCHED;
d.encoded = std::move(data);
touch(c, t); touch(c, t);
return d.data; return d.data;
} else { } else {
...@@ -86,6 +112,20 @@ std::any &Frame::createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t ...@@ -86,6 +112,20 @@ std::any &Frame::createAnyChange(ftl::codecs::Channel c, ftl::data::ChangeType t
} }
} }
std::any &Frame::createAny(ftl::codecs::Channel c) {
if (status_ != FrameStatus::STORED) throw FTL_Error("Cannot create before store or after flush");
auto &d = data_[c];
if (d.status != ftl::data::ChannelStatus::FLUSHED) {
d.status = ftl::data::ChannelStatus::VALID;
d.encoded.clear();
touch(c);
return d.data;
} else {
throw FTL_Error("Channel is flushed and read-only: " << static_cast<unsigned int>(c));
}
}
std::any &Frame::getAnyMutable(ftl::codecs::Channel c) { std::any &Frame::getAnyMutable(ftl::codecs::Channel c) {
auto &d = _getData(c); auto &d = _getData(c);
return d.data; return d.data;
......
...@@ -9,6 +9,8 @@ target_include_directories(nframe_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../in ...@@ -9,6 +9,8 @@ target_include_directories(nframe_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../in
target_link_libraries(nframe_unit target_link_libraries(nframe_unit
ftlcommon ftlcodecs) ftlcommon ftlcodecs)
add_test(NFrameUnitTest nframe_unit)
### Pool Unit ################################################################## ### Pool Unit ##################################################################
add_executable(pool_unit add_executable(pool_unit
$<TARGET_OBJECTS:CatchTest> $<TARGET_OBJECTS:CatchTest>
...@@ -19,3 +21,5 @@ add_executable(pool_unit ...@@ -19,3 +21,5 @@ add_executable(pool_unit
target_include_directories(pool_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include") target_include_directories(pool_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")
target_link_libraries(pool_unit target_link_libraries(pool_unit
ftlcommon ftlcodecs) ftlcommon ftlcodecs)
add_test(MemPoolUnitTest pool_unit)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment