X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fsession.cpp;h=9ec8bd07264036e85c052c05695749f4bccf797b;hp=6b879cf91dcdd4e4b6127cb99a780366042d09a1;hb=554af71bf515d2763ca13c3829dbeb2064cc4c83;hpb=7697cd83435e88689936b14c952b8a34d5258b69 diff --git a/pv/session.cpp b/pv/session.cpp index 6b879cf9..9ec8bd07 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -105,6 +105,7 @@ using Gst::ElementFactory; using Gst::Pipeline; #endif +using pv::data::SignalGroup; using pv::util::Timestamp; using pv::views::trace::Signal; using pv::views::trace::AnalogSignal; @@ -115,6 +116,7 @@ namespace pv { shared_ptr Session::sr_context; Session::Session(DeviceManager &device_manager, QString name) : + shutting_down_(false), device_manager_(device_manager), default_name_(name), name_(name), @@ -126,8 +128,15 @@ Session::Session(DeviceManager &device_manager, QString name) : Session::~Session() { + shutting_down_ = true; + // Stop and join to the thread stop_capture(); + + for (SignalGroup* group : signal_groups_) { + group->clear(); + delete group; + } } DeviceManager& Session::device_manager() @@ -500,14 +509,22 @@ void Session::set_device(shared_ptr device) // Remove all stored data and reset all views for (shared_ptr view : views_) { - view->clear_signals(); + view->clear_signalbases(); #ifdef ENABLE_DECODE view->clear_decode_signals(); #endif view->reset_view_state(); } + + for (SignalGroup* group : signal_groups_) { + group->clear(); + delete group; + } + signal_groups_.clear(); + for (const shared_ptr& d : all_signal_data_) d->clear(); + all_signal_data_.clear(); signalbases_.clear(); cur_logic_segment_.reset(); @@ -857,15 +874,29 @@ const vector< shared_ptr > Session::signalbases() const return signalbases_; } -bool Session::all_segments_complete(uint32_t segment_id) const +void Session::add_generated_signal(shared_ptr signal) { - bool all_complete = true; + signalbases_.push_back(signal); - for (const shared_ptr& base : signalbases_) - if (!base->segment_is_complete(segment_id)) - all_complete = false; + for (shared_ptr& view : views_) + view->add_signalbase(signal); - return all_complete; + update_signals(); +} + +void Session::remove_generated_signal(shared_ptr signal) +{ + if (shutting_down_) + return; + + signalbases_.erase(std::remove_if(signalbases_.begin(), signalbases_.end(), + [&](shared_ptr s) { return s == signal; }), + signalbases_.end()); + + for (shared_ptr& view : views_) + view->remove_signalbase(signal); + + update_signals(); } #ifdef ENABLE_DECODE @@ -894,6 +925,9 @@ shared_ptr Session::add_decode_signal() void Session::remove_decode_signal(shared_ptr signal) { + if (shutting_down_) + return; + signalbases_.erase(std::remove_if(signalbases_.begin(), signalbases_.end(), [&](shared_ptr s) { return s == signal; }), signalbases_.end()); @@ -905,6 +939,22 @@ void Session::remove_decode_signal(shared_ptr signal) } #endif +bool Session::all_segments_complete(uint32_t segment_id) const +{ + bool all_complete = true; + + for (const shared_ptr& base : signalbases_) + if (!base->segment_is_complete(segment_id)) + all_complete = false; + + return all_complete; +} + +MetadataObjManager* Session::metadata_obj_manager() +{ + return &metadata_obj_manager_; +} + void Session::set_capture_state(capture_state state) { bool changed; @@ -930,7 +980,7 @@ void Session::update_signals() signalbases_.clear(); logic_data_.reset(); for (shared_ptr& view : views_) { - view->clear_signals(); + view->clear_signalbases(); #ifdef ENABLE_DECODE view->clear_decode_signals(); #endif @@ -945,7 +995,7 @@ void Session::update_signals() signalbases_.clear(); logic_data_.reset(); for (shared_ptr& view : views_) { - view->clear_signals(); + view->clear_signalbases(); #ifdef ENABLE_DECODE view->clear_decode_signals(); #endif @@ -960,7 +1010,7 @@ void Session::update_signals() [] (shared_ptr channel) { return channel->type() == sigrok::ChannelType::LOGIC; }); - // Create data containers for the logic data segments + // Create a common data container for the logic signalbases { lock_guard data_lock(data_mutex_); @@ -968,97 +1018,96 @@ void Session::update_signals() logic_data_.reset(); } else if (!logic_data_ || logic_data_->num_channels() != logic_channel_count) { - logic_data_.reset(new data::Logic( - logic_channel_count)); + logic_data_.reset(new data::Logic(logic_channel_count)); assert(logic_data_); } } - // Make the signals list - for (shared_ptr& viewbase : views_) { - views::trace::View *trace_view = - qobject_cast(viewbase.get()); - - if (trace_view) { - vector< shared_ptr > prev_sigs(trace_view->signals()); - trace_view->clear_signals(); - - for (auto channel : sr_dev->channels()) { - shared_ptr signalbase; - shared_ptr signal; - - // Find the channel in the old signals - const auto iter = find_if( - prev_sigs.cbegin(), prev_sigs.cend(), - [&](const shared_ptr &s) { - return s->base()->channel() == channel; - }); - if (iter != prev_sigs.end()) { - // Copy the signal from the old set to the new - signal = *iter; - trace_view->add_signal(signal); - } else { - // Find the signalbase for this channel if possible - signalbase.reset(); - for (const shared_ptr& b : signalbases_) - if (b->channel() == channel) - signalbase = b; - - shared_ptr signal; - - switch(channel->type()->id()) { - case SR_CHANNEL_LOGIC: - if (!signalbase) { - signalbase = make_shared(channel, - data::SignalBase::LogicChannel); - signalbases_.push_back(signalbase); - - all_signal_data_.insert(logic_data_); - signalbase->set_data(logic_data_); - - connect(this, SIGNAL(capture_state_changed(int)), - signalbase.get(), SLOT(on_capture_state_changed(int))); - } - - signal = shared_ptr(new LogicSignal(*this, device_, signalbase)); - break; + // Create signalbases if necessary + for (auto channel : sr_dev->channels()) { - case SR_CHANNEL_ANALOG: - { - if (!signalbase) { - signalbase = make_shared(channel, - data::SignalBase::AnalogChannel); - signalbases_.push_back(signalbase); + // Try to find the channel in the list of existing signalbases + const auto iter = find_if(signalbases_.cbegin(), signalbases_.cend(), + [&](const shared_ptr &sb) { return sb->channel() == channel; }); - shared_ptr data(new data::Analog()); - all_signal_data_.insert(data); - signalbase->set_data(data); + // Not found, let's make a signalbase for it + if (iter == signalbases_.cend()) { + shared_ptr signalbase; + switch(channel->type()->id()) { + case SR_CHANNEL_LOGIC: + signalbase = make_shared(channel, data::SignalBase::LogicChannel); + signalbases_.push_back(signalbase); - connect(this, SIGNAL(capture_state_changed(int)), - signalbase.get(), SLOT(on_capture_state_changed(int))); - } + all_signal_data_.insert(logic_data_); + signalbase->set_data(logic_data_); - signal = shared_ptr(new AnalogSignal(*this, signalbase)); - break; - } + connect(this, SIGNAL(capture_state_changed(int)), + signalbase.get(), SLOT(on_capture_state_changed(int))); + break; - default: - assert(false); - break; - } + case SR_CHANNEL_ANALOG: + signalbase = make_shared(channel, data::SignalBase::AnalogChannel); + signalbases_.push_back(signalbase); - // New views take their signal settings from the main view - if (!viewbase->is_main_view()) { - shared_ptr main_tv = - dynamic_pointer_cast(main_view_); - shared_ptr main_signal = - main_tv->get_signal_by_signalbase(signalbase); - signal->restore_settings(main_signal->save_settings()); - } + shared_ptr data(new data::Analog()); + all_signal_data_.insert(data); + signalbase->set_data(data); + + connect(this, SIGNAL(capture_state_changed(int)), + signalbase.get(), SLOT(on_capture_state_changed(int))); + break; + } + } + } - trace_view->add_signal(signal); + // Create and assign default signal groups if needed + if (signal_groups_.empty()) { + for (auto& entry : sr_dev->channel_groups()) { + const shared_ptr& group = entry.second; + + if (group->channels().size() <= 1) + continue; + + SignalGroup* sg = new SignalGroup(QString::fromStdString(entry.first)); + for (const shared_ptr& channel : group->channels()) { + for (shared_ptr s : signalbases_) { + if (s->channel() == channel) { + sg->append_signal(s); + break; + } } } + signal_groups_.emplace_back(sg); + } + } + + // Update all views + for (shared_ptr& viewbase : views_) { + vector< shared_ptr > view_signalbases = + viewbase->signalbases(); + + // Add all non-decode signalbases that don't yet exist in the view + for (shared_ptr& session_sb : signalbases_) { + if (session_sb->type() == SignalBase::DecodeChannel) + continue; + + const auto iter = find_if(view_signalbases.cbegin(), view_signalbases.cend(), + [&](const shared_ptr &sb) { return sb == session_sb; }); + + if (iter == view_signalbases.cend()) + viewbase->add_signalbase(session_sb); + } + + // Remove all non-decode signalbases that no longer exist + for (shared_ptr& view_sb : view_signalbases) { + if (view_sb->type() == SignalBase::DecodeChannel) + continue; + + const auto iter = find_if(signalbases_.cbegin(), signalbases_.cend(), + [&](const shared_ptr &sb) { return sb == view_sb; }); + + if (iter == signalbases_.cend()) + viewbase->remove_signalbase(view_sb); } } @@ -1124,6 +1173,8 @@ void Session::sample_thread_proc(function error_handler) lock_guard lock(data_mutex_); cur_logic_segment_.reset(); cur_analog_segments_.clear(); + for (shared_ptr sb : signalbases_) + sb->clear_sample_data(); } highest_segment_id_ = -1; frame_began_ = false; @@ -1366,7 +1417,7 @@ void Session::feed_in_frame_end() signal_segment_completed(); } -void Session::feed_in_logic(shared_ptr logic) +void Session::feed_in_logic(shared_ptr logic) { if (logic->data_length() == 0) { qDebug() << "WARNING: Received logic packet with 0 samples."; @@ -1410,7 +1461,7 @@ void Session::feed_in_logic(shared_ptr logic) data_received(); } -void Session::feed_in_analog(shared_ptr analog) +void Session::feed_in_analog(shared_ptr analog) { if (analog->num_samples() == 0) { qDebug() << "WARNING: Received analog packet with 0 samples.";