From 8ce0e732cfe912e022eb96d06aaaa40390efcd6b Mon Sep 17 00:00:00 2001 From: Soeren Apel Date: Thu, 5 Apr 2018 09:07:36 +0200 Subject: [PATCH 1/1] Apply option changes immediately, not on decode stack rebuild --- pv/data/decode/decoder.cpp | 38 ++++++++++++++++++++++++++++++-------- pv/data/decode/decoder.hpp | 4 +++- pv/data/decodesignal.cpp | 12 +++++++++--- pv/data/decodesignal.hpp | 2 +- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/pv/data/decode/decoder.cpp b/pv/data/decode/decoder.cpp index 1c941074..c6995bcf 100644 --- a/pv/data/decode/decoder.cpp +++ b/pv/data/decode/decoder.cpp @@ -19,6 +19,8 @@ #include +#include + #include #include @@ -37,7 +39,8 @@ namespace decode { Decoder::Decoder(const srd_decoder *const dec) : decoder_(dec), - shown_(true) + shown_(true), + decoder_inst_(nullptr) { } @@ -82,6 +85,18 @@ void Decoder::set_option(const char *id, GVariant *value) assert(value); g_variant_ref(value); options_[id] = value; + + // If we have a decoder instance, apply option value immediately + if (decoder_inst_) { + GHashTable *const opt_hash = g_hash_table_new_full(g_str_hash, + g_str_equal, g_free, (GDestroyNotify)g_variant_unref); + + g_variant_ref(value); + g_hash_table_insert(opt_hash, (void*)g_strdup(id), value); + + srd_inst_option_set(decoder_inst_, opt_hash); + g_hash_table_destroy(opt_hash); + } } bool Decoder::have_required_channels() const @@ -93,7 +108,7 @@ bool Decoder::have_required_channels() const return true; } -srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session) const +srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session) { GHashTable *const opt_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); @@ -105,11 +120,13 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session) const option.first.c_str()), value); } - srd_decoder_inst *const decoder_inst = srd_inst_new( - session, decoder_->id, opt_hash); + if (decoder_inst_) + qDebug() << "WARNING: previous decoder instance" << decoder_inst_ << "exists"; + + decoder_inst_ = srd_inst_new(session, decoder_->id, opt_hash); g_hash_table_destroy(opt_hash); - if (!decoder_inst) + if (!decoder_inst_) return nullptr; // Setup the channels @@ -133,12 +150,17 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session) const g_hash_table_insert(channels, ch->pdch_->id, gvar); } - srd_inst_channel_set_all(decoder_inst, channels); + srd_inst_channel_set_all(decoder_inst_, channels); - srd_inst_initial_pins_set_all(decoder_inst, init_pin_states); + srd_inst_initial_pins_set_all(decoder_inst_, init_pin_states); g_array_free(init_pin_states, true); - return decoder_inst; + return decoder_inst_; +} + +void Decoder::invalidate_decoder_inst() +{ + decoder_inst_ = nullptr; } } // namespace decode diff --git a/pv/data/decode/decoder.hpp b/pv/data/decode/decoder.hpp index 1ef3a28a..02f3f04b 100644 --- a/pv/data/decode/decoder.hpp +++ b/pv/data/decode/decoder.hpp @@ -67,7 +67,8 @@ public: bool have_required_channels() const; - srd_decoder_inst* create_decoder_inst(srd_session *session) const; + srd_decoder_inst* create_decoder_inst(srd_session *session); + void invalidate_decoder_inst(); private: const srd_decoder *const decoder_; @@ -76,6 +77,7 @@ private: vector channels_; map options_; + srd_decoder_inst *decoder_inst_; }; } // namespace decode diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index f5dc0001..1e005391 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -65,7 +65,7 @@ DecodeSignal::DecodeSignal(pv::Session &session) : DecodeSignal::~DecodeSignal() { - reset_decode(); + reset_decode(true); } const vector< shared_ptr >& DecodeSignal::decoder_stack() const @@ -130,9 +130,9 @@ bool DecodeSignal::toggle_decoder_visibility(int index) return state; } -void DecodeSignal::reset_decode() +void DecodeSignal::reset_decode(bool shutting_down) { - if (stack_config_changed_) + if (stack_config_changed_ || shutting_down) stop_srd_session(); else terminate_srd_session(); @@ -1003,6 +1003,8 @@ void DecodeSignal::start_srd_session() { uint64_t samplerate; + // If there were stack changes, the session has been destroyed by now, so if + // it hasn't been destroyed, we can just reset and re-use it if (srd_session_) { // When a decoder stack was created before, re-use it // for the next stream of input data, after terminating @@ -1075,6 +1077,10 @@ void DecodeSignal::stop_srd_session() // Destroy the session srd_session_destroy(srd_session_); srd_session_ = nullptr; + + // Mark the decoder instances as non-existant since they were deleted + for (const shared_ptr &dec : stack_) + dec->invalidate_decoder_inst(); } } diff --git a/pv/data/decodesignal.hpp b/pv/data/decodesignal.hpp index 807f0e70..2d41e500 100644 --- a/pv/data/decodesignal.hpp +++ b/pv/data/decodesignal.hpp @@ -99,7 +99,7 @@ public: void remove_decoder(int index); bool toggle_decoder_visibility(int index); - void reset_decode(); + void reset_decode(bool shutting_down = false); void begin_decode(); QString error_message() const; -- 2.30.2