X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fsession.cpp;h=70637437e08b5ad1ea867e58ae4573956cc30bb9;hp=7bb9de8da443fccb6a19d523572d9472b7ef87a9;hb=3917ba77254318c3518555f164983d4d92183fba;hpb=f3d66e52ed6b454ea7a0662d5e6367e230116a2b diff --git a/pv/session.cpp b/pv/session.cpp index 7bb9de8d..70637437 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -45,7 +45,7 @@ #include -#include +#include using boost::shared_lock; using boost::shared_mutex; @@ -60,6 +60,7 @@ using std::mutex; using std::set; using std::shared_ptr; using std::string; +using std::unordered_set; using std::vector; using sigrok::Analog; @@ -123,9 +124,12 @@ void Session::set_device(shared_ptr device) stop_capture(); // Are we setting a session device? - auto session_device = dynamic_pointer_cast(device); + const auto session_device = + dynamic_pointer_cast(device); + // Did we have a session device selected previously? - auto prev_session_device = dynamic_pointer_cast(device_); + const auto prev_session_device = + dynamic_pointer_cast(device_); if (device_) { session_->remove_datafeed_callbacks(); @@ -159,6 +163,7 @@ void Session::set_device(shared_ptr device) (shared_ptr device, shared_ptr packet) { data_feed_in(device, packet); }); + device_manager_.update_display_name(device); update_signals(device); } else device_ = nullptr; @@ -166,18 +171,11 @@ void Session::set_device(shared_ptr device) device_selected(); } -void Session::set_file(const string &name) +void Session::set_session_file(const string &name) { - session_ = device_manager_.context()->load_session(name); - device_ = session_->devices()[0]; - decode_traces_.clear(); - session_->add_datafeed_callback([=] - (shared_ptr device, shared_ptr packet) { - data_feed_in(device, packet); - }); - device_manager_.update_display_name(device_); - update_signals(device_); - device_selected(); + const shared_ptr session = + device_manager_.context()->load_session(name); + set_device(session->devices()[0]); } void Session::set_default_device() @@ -260,7 +258,7 @@ boost::shared_mutex& Session::signals_mutex() const return signals_mutex_; } -const vector< shared_ptr >& Session::signals() const +const unordered_set< shared_ptr >& Session::signals() const { return signals_; } @@ -354,9 +352,6 @@ void Session::update_signals(shared_ptr device) assert(device); assert(capture_state_ == Stopped); - // Clear the decode traces - decode_traces_.clear(); - // Detect what data types we will receive auto channels = device->channels(); unsigned int logic_channel_count = std::count_if( @@ -368,8 +363,10 @@ void Session::update_signals(shared_ptr device) { lock_guard data_lock(data_mutex_); - logic_data_.reset(); - if (logic_channel_count != 0) { + if (logic_channel_count == 0) { + logic_data_.reset(); + } else if (!logic_data_ || + logic_data_->num_channels() != logic_channel_count) { logic_data_.reset(new data::Logic( logic_channel_count)); assert(logic_data_); @@ -380,37 +377,55 @@ void Session::update_signals(shared_ptr device) { unique_lock lock(signals_mutex_); + unordered_set< shared_ptr > prev_sigs(signals_); signals_.clear(); for (auto channel : device->channels()) { shared_ptr signal; - switch(channel->type()->id()) { - case SR_CHANNEL_LOGIC: - signal = shared_ptr( - new view::LogicSignal(*this, device, - channel, logic_data_)); - break; - - case SR_CHANNEL_ANALOG: - { - shared_ptr data( - new data::Analog()); - signal = shared_ptr( - new view::AnalogSignal( - *this, channel, data)); - break; - } - - default: - assert(0); - break; + // Find the channel in the old signals + const auto iter = std::find_if( + prev_sigs.cbegin(), prev_sigs.cend(), + [&](const shared_ptr &s) { + return s->channel() == channel; + }); + if (iter != prev_sigs.end()) { + // Copy the signal from the old set to the new + signal = *iter; + auto logic_signal = dynamic_pointer_cast< + view::LogicSignal>(signal); + if (logic_signal) + logic_signal->set_logic_data( + logic_data_); + } else { + // Create a new signal + switch(channel->type()->id()) { + case SR_CHANNEL_LOGIC: + signal = shared_ptr( + new view::LogicSignal(*this, + device, channel, + logic_data_)); + break; + + case SR_CHANNEL_ANALOG: + { + shared_ptr data( + new data::Analog()); + signal = shared_ptr( + new view::AnalogSignal( + *this, channel, data)); + break; + } + + default: + assert(0); + break; + } } assert(signal); - signals_.push_back(signal); + signals_.insert(signal); } - } signals_changed();