diff --git a/components/structures/include/ftl/data/new_frame.hpp b/components/structures/include/ftl/data/new_frame.hpp index 3eb1af3ee148b24f53e65318c5baafb0c6773879..9fa92ed140776c7cf2683c3b484dce61f21a5921 100644 --- a/components/structures/include/ftl/data/new_frame.hpp +++ b/components/structures/include/ftl/data/new_frame.hpp @@ -132,10 +132,10 @@ struct Aggregator { * generates discrete blocks of data with a timestamp, these blocks are * encapsulated in a frame that has any number of channels. A `Frame` must be * constructed from a `Pool` object so that memory can be reused. - * + * * It can be moved around but not copied since the quantity of data involved in * a frame is huge. - * + * * A frame goes through the following stages: * 1) Creation from reused memory in `Pool` * 2) Populate with incoming initial data/changes (from stream) @@ -143,28 +143,28 @@ struct Aggregator { * 4) Create any new data such as new video frames * 5) Flush the data to transmit or save, becomes readonly * 6) Release memory to `Pool` - * + * * A channel stores one particular element of data of a specified type. To write * to a channel the `create` or `set` methods must be used, this will mark the * channel as changed but can only occur before the frame is flushed and * readonly. A `get` method allows const access to the data as long as the * channel exists. - * + * * On change events are triggered when `store` occurs, whereas on flush events * occur after flush. Both of these may occur on destruction if the frame was * not stored or flushed before destruction. - * + * * Some channels may fail `hasChannel` but still be marked as `available`. This * will be due to the data not being transmitted or encoded until requested. - * + * * Each frame is also associated with a `Session` object which stores all * persistent data. Persistent data can then be accessed via any `Frame` with * the same ID since they share a `Session`. - * + * * A `Frame` provides some basic methods, however, it can be cast to other * frame types using the cast method which provides additional wrapper * functions. An example is `ftl::rgbd::Frame`. - * + * * @see https://gitlab.utu.fi/nicolas.pope/ftl/-/wikis/Design/Frames */ class Frame { @@ -330,7 +330,7 @@ class Frame { * channel does not exist or if the template type does not match the content * then it throws an exception. The data can either be within this frame, * or if not in the frame then it checks the persistent store. - * + * * The data may internally still be encoded and will only be decoded on the * first call to `get`. It is therefore strongly advised that any initial * calls to `get` are not concurrent as it will not be thread-safe. @@ -431,7 +431,7 @@ class Frame { /** * Create a change but with encoded data provided. This allows for both * lazy decode and for subsequent data forwarding without encoding. - * + * * Currently unused. */ template <typename T> @@ -441,7 +441,7 @@ class Frame { * Create a channel, mark with the given change type and provided encoded * data. Does not decode the data as it does not know the actually data * type of this channel at this time. - * + * * To be used by `receiver`. * @see ftl::stream::Receiver */ @@ -517,7 +517,7 @@ class Frame { * do generate a change event but do no subsequently generate a flush event * as they are considered completed changes. This prevents loops whilst * ensuring everyone has a copy of the change. - * + * * @see changeType */ inline ftl::Handle onFlush(const std::function<bool(Frame&,ftl::codecs::Channel)> &cb); diff --git a/components/structures/src/new_frame.cpp b/components/structures/src/new_frame.cpp index 1b1700d792d77dac74d106a623700daabb214ad3..09b91e3af8503223e34e834db8d97688c2f397e9 100644 --- a/components/structures/src/new_frame.cpp +++ b/components/structures/src/new_frame.cpp @@ -268,25 +268,29 @@ void Frame::store() { if (!parent_) return; - UNIQUE_LOCK(parent_->mutex(), lk); + { + UNIQUE_LOCK(parent_->mutex(), lk); + for (auto c : changed_) { + if (ftl::data::isPersistent(c.first) && hasOwn(c.first)) { + auto &d = data_[c.first]; + auto &pd = parent_->data_[c.first]; + pd.data = std::move(d.data); + pd.encoded = std::move(d.encoded); + //if (d.status == ChannelStatus::ENCODED) LOG(INFO) << "STORE ENCODED: " << (int)c.first; + pd.status = ChannelStatus::VALID; + //data_.erase(c.first); + d.status = ChannelStatus::INVALID; + } - for (auto c : changed_) { - if (ftl::data::isPersistent(c.first) && hasOwn(c.first)) { - auto &d = data_[c.first]; - auto &pd = parent_->data_[c.first]; - pd.data = std::move(d.data); - pd.encoded = std::move(d.encoded); - //if (d.status == ChannelStatus::ENCODED) LOG(INFO) << "STORE ENCODED: " << (int)c.first; - pd.status = ChannelStatus::VALID; - //data_.erase(c.first); - d.status = ChannelStatus::INVALID; + uint64_t sig = (uint64_t(id()) << 32) + static_cast<unsigned int>(c.first); + const auto &i = parent_->change_channel_.find(sig); + + if (i != parent_->change_channel_.end()) i->second.trigger(*this, c.first); } + } + for (auto c : changed_) { parent_->change_.trigger(*this, c.first); - uint64_t sig = (uint64_t(id()) << 32) + static_cast<unsigned int>(c.first); - const auto &i = parent_->change_channel_.find(sig); - - if (i != parent_->change_channel_.end()) i->second.trigger(*this, c.first); } }