X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fsession.cpp;h=0077ccfd00d0d36d6de0a401d8f71347e24a4d08;hp=2e98c8f73f40c08a70f451c60716824a1b348bbb;hb=00f6bae935837b38b0d03a5928ba8175d460413f;hpb=efdec55aec1a137460fa362a381ed1904182bfed diff --git a/pv/session.cpp b/pv/session.cpp index 2e98c8f7..0077ccfd 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -76,6 +76,7 @@ using std::pair; using std::recursive_mutex; using std::set; using std::shared_ptr; +using std::make_shared; using std::string; using std::unordered_set; using std::vector; @@ -105,7 +106,8 @@ Session::Session(DeviceManager &device_manager, QString name) : default_name_(name), name_(name), capture_state_(Stopped), - cur_samplerate_(0) + cur_samplerate_(0), + data_saved_(true) { } @@ -172,6 +174,11 @@ shared_ptr Session::main_bar() const return main_bar_; } +bool Session::data_saved() const +{ + return data_saved_; +} + void Session::save_settings(QSettings &settings) const { map dev_info; @@ -186,11 +193,11 @@ void Session::save_settings(QSettings &settings) const settings.setValue("device_type", "hardware"); settings.beginGroup("device"); - key_list.push_back("vendor"); - key_list.push_back("model"); - key_list.push_back("version"); - key_list.push_back("serial_num"); - key_list.push_back("connection_id"); + key_list.emplace_back("vendor"); + key_list.emplace_back("model"); + key_list.emplace_back("version"); + key_list.emplace_back("serial_num"); + key_list.emplace_back("connection_id"); dev_info = device_manager_.get_device_info(device_); @@ -270,11 +277,11 @@ void Session::restore_settings(QSettings &settings) // Re-select last used device if possible but only if it's not demo settings.beginGroup("device"); - key_list.push_back("vendor"); - key_list.push_back("model"); - key_list.push_back("version"); - key_list.push_back("serial_num"); - key_list.push_back("connection_id"); + key_list.emplace_back("vendor"); + key_list.emplace_back("model"); + key_list.emplace_back("version"); + key_list.emplace_back("serial_num"); + key_list.emplace_back("connection_id"); for (string key : key_list) { const QString k = QString::fromStdString(key); @@ -301,7 +308,7 @@ void Session::restore_settings(QSettings &settings) settings.endGroup(); if (QFileInfo(filename).isReadable()) { - device = std::make_shared(device_manager_.context(), + device = make_shared(device_manager_.context(), filename.toStdString()); set_device(device); @@ -377,7 +384,7 @@ void Session::set_device(shared_ptr device) device_.reset(); - // Revert name back to default name (e.g. "Untitled-1") as the data is gone + // Revert name back to default name (e.g. "Session 1") as the data is gone name_ = default_name_; name_changed(); @@ -409,16 +416,17 @@ void Session::set_device(shared_ptr device) device_->open(); } catch (const QString &e) { device_.reset(); - device_changed(); - throw; } - device_->session()->add_datafeed_callback([=] - (shared_ptr device, shared_ptr packet) { - data_feed_in(device, packet); - }); + if (device_) { + device_->session()->add_datafeed_callback([=] + (shared_ptr device, shared_ptr packet) { + data_feed_in(device, packet); + }); + + update_signals(); + } - update_signals(); device_changed(); } @@ -526,9 +534,15 @@ void Session::start_capture(function error_handler) for (const shared_ptr d : all_signal_data_) d->clear(); - // Revert name back to default name (e.g. "Untitled-1") as the data is gone - name_ = default_name_; - name_changed(); + // Revert name back to default name (e.g. "Session 1") for real devices + // as the (possibly saved) data is gone. File devices keep their name. + shared_ptr hw_device = + dynamic_pointer_cast< devices::HardwareDevice >(device_); + + if (hw_device) { + name_ = default_name_; + name_changed(); + } // Begin the session sampling_thread_ = std::thread( @@ -610,8 +624,7 @@ bool Session::add_decoder(srd_decoder *const dec) try { // Create the decoder - decoder_stack = shared_ptr( - new data::DecoderStack(*this, dec)); + decoder_stack = make_shared(*this, dec); // Make a list of all the channels std::vector all_channels; @@ -637,7 +650,7 @@ bool Session::add_decoder(srd_decoder *const dec) // Create the decode signal shared_ptr signalbase = - shared_ptr(new data::SignalBase(nullptr)); + make_shared(nullptr); signalbase->set_decoder_stack(decoder_stack); signalbases_.insert(signalbase); @@ -765,8 +778,7 @@ void Session::update_signals() switch(channel->type()->id()) { case SR_CHANNEL_LOGIC: if (!signalbase) { - signalbase = shared_ptr( - new data::SignalBase(channel)); + signalbase = make_shared(channel); signalbases_.insert(signalbase); all_signal_data_.insert(logic_data_); @@ -782,8 +794,7 @@ void Session::update_signals() case SR_CHANNEL_ANALOG: { if (!signalbase) { - signalbase = shared_ptr( - new data::SignalBase(channel)); + signalbase = make_shared(channel); signalbases_.insert(signalbase); shared_ptr data(new data::Analog()); @@ -851,10 +862,31 @@ void Session::sample_thread_proc(function error_handler) assert(0); } + // Optimize memory usage + free_unused_memory(); + + // We now have unsaved data unless we just "captured" from a file + shared_ptr file_device = + dynamic_pointer_cast(device_); + + if (!file_device) + data_saved_ = false; + if (out_of_memory_) error_handler(tr("Out of memory, acquisition stopped.")); } +void Session::free_unused_memory() +{ + for (shared_ptr data : all_signal_data_) { + const vector< shared_ptr > segments = data->segments(); + + for (shared_ptr segment : segments) { + segment->free_unused_memory(); + } + } +} + void Session::feed_in_header() { cur_samplerate_ = device_->read_config(ConfigKey::SAMPLERATE); @@ -914,8 +946,6 @@ void Session::feed_in_logic(shared_ptr logic) { lock_guard lock(data_mutex_); - const size_t sample_count = logic->data_length() / logic->unit_size(); - if (!logic_data_) { // The only reason logic_data_ would not have been created is // if it was not possible to determine the signals when the @@ -928,9 +958,8 @@ void Session::feed_in_logic(shared_ptr logic) set_capture_state(Running); // Create a new data segment - cur_logic_segment_ = shared_ptr( - new data::LogicSegment( - logic, cur_samplerate_, sample_count)); + cur_logic_segment_ = make_shared( + *logic_data_, logic, cur_samplerate_); logic_data_->push_segment(cur_logic_segment_); // @todo Putting this here means that only listeners querying @@ -973,12 +1002,6 @@ void Session::feed_in_analog(shared_ptr analog) // in the sweep containing this segment. sweep_beginning = true; - // Create a segment, keep it in the maps of channels - segment = shared_ptr( - new data::AnalogSegment( - cur_samplerate_, sample_count)); - cur_analog_segments_[channel] = segment; - // Find the analog data associated with the channel shared_ptr base = signalbase_from_channel(channel); assert(base); @@ -986,6 +1009,11 @@ void Session::feed_in_analog(shared_ptr analog) shared_ptr data(base->analog_data()); assert(data); + // Create a segment, keep it in the maps of channels + segment = make_shared( + *data, cur_samplerate_); + cur_analog_segments_[channel] = segment; + // Push the segment into the analog data. data->push_segment(segment); } @@ -1008,6 +1036,8 @@ void Session::feed_in_analog(shared_ptr analog) void Session::data_feed_in(shared_ptr device, shared_ptr packet) { + static bool frame_began=false; + (void)device; assert(device); @@ -1029,6 +1059,7 @@ void Session::data_feed_in(shared_ptr device, case SR_DF_FRAME_BEGIN: feed_in_frame_begin(); + frame_began = true; break; case SR_DF_LOGIC: @@ -1049,6 +1080,7 @@ void Session::data_feed_in(shared_ptr device, } break; + case SR_DF_FRAME_END: case SR_DF_END: { { @@ -1056,7 +1088,10 @@ void Session::data_feed_in(shared_ptr device, cur_logic_segment_.reset(); cur_analog_segments_.clear(); } - frame_ended(); + if (frame_began) { + frame_began = false; + frame_ended(); + } break; } default: @@ -1064,4 +1099,9 @@ void Session::data_feed_in(shared_ptr device, } } +void Session::on_data_saved() +{ + data_saved_ = true; +} + } // namespace pv