#include <cassert>
+#include <QDebug>
+
#include <libsigrokcxx/libsigrokcxx.hpp>
#include <libsigrokdecode/libsigrokdecode.h>
Decoder::Decoder(const srd_decoder *const dec) :
decoder_(dec),
- shown_(true)
+ shown_(true),
+ decoder_inst_(nullptr)
{
}
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
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);
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
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
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_;
vector<data::DecodeChannel*> channels_;
map<string, GVariant*> options_;
+ srd_decoder_inst *decoder_inst_;
};
} // namespace decode
DecodeSignal::~DecodeSignal()
{
- reset_decode();
+ reset_decode(true);
}
const vector< shared_ptr<Decoder> >& DecodeSignal::decoder_stack() const
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();
{
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
// 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<decode::Decoder> &dec : stack_)
+ dec->invalidate_decoder_inst();
}
}