X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=pv%2Fsession.cpp;h=5f2bc8ea0544de070b62ff33fd9b5f2d66d06c30;hb=1dccc4ad96fd764c30b64502e3de570ff6cc04ba;hp=751afb30bd746abb7fe95fa20a35dcce9a232149;hpb=339e9524a80da7521796648bab4aa4a0ce6c7049;p=pulseview.git diff --git a/pv/session.cpp b/pv/session.cpp index 751afb3..5f2bc8e 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -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; @@ -122,30 +123,26 @@ void Session::set_device(shared_ptr device) // Ensure we are not capturing before setting the device stop_capture(); - // Are we setting a session device? - const auto session_device = - dynamic_pointer_cast(device); - - // Did we have a session device selected previously? - const auto prev_session_device = - dynamic_pointer_cast(device_); - if (device_) { session_->remove_datafeed_callbacks(); - if (!prev_session_device) { + + // Did we have a hardware device selected previously? + if (!dynamic_pointer_cast(device_)) { device_->close(); session_->remove_devices(); } } - if (session_device) - session_ = session_device->parent(); - decode_traces_.clear(); if (device) { - if (!session_device) - { + // Are we setting a session device? + const auto session_device = + dynamic_pointer_cast(device); + + if (session_device) + session_ = session_device->parent(); + else { session_ = device_manager_.context()->create_session(); try { @@ -257,7 +254,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_; } @@ -351,9 +348,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( @@ -365,8 +359,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_); @@ -377,37 +373,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();