mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-07 03:30:44 +00:00
Move function definitions out of XmlReplayEvent and XmlReplayLock class declarations.
This commit is contained in:
parent
d5cb629069
commit
c9ebc0d175
@ -211,74 +211,25 @@ public:
|
|||||||
static XmlReplayEvent* createInstance(const QString & tag);
|
static XmlReplayEvent* createInstance(const QString & tag);
|
||||||
|
|
||||||
//! \brief Add the given key/value to the event. This will be written as an XML attribute in the order it added.
|
//! \brief Add the given key/value to the event. This will be written as an XML attribute in the order it added.
|
||||||
void set(const QString & name, const QString & value)
|
void set(const QString & name, const QString & value);
|
||||||
{
|
|
||||||
if (!m_values.contains(name)) {
|
|
||||||
m_keys.append(name);
|
|
||||||
}
|
|
||||||
m_values[name] = value;
|
|
||||||
}
|
|
||||||
//! \brief Add the given key/integer to the event. This will be written as an XML attribute in the order it added.
|
//! \brief Add the given key/integer to the event. This will be written as an XML attribute in the order it added.
|
||||||
void set(const QString & name, qint64 value)
|
void set(const QString & name, qint64 value);
|
||||||
{
|
|
||||||
set(name, QString::number(value));
|
|
||||||
}
|
|
||||||
//! \brief Add the raw data to the event. This will be written in hexadecimal as content of the event's XML tag.
|
//! \brief Add the raw data to the event. This will be written in hexadecimal as content of the event's XML tag.
|
||||||
void setData(const char* data, qint64 length)
|
void setData(const char* data, qint64 length);
|
||||||
{
|
|
||||||
Q_ASSERT(usesData() == true);
|
|
||||||
QByteArray bytes = QByteArray::fromRawData(data, length);
|
|
||||||
m_data = bytes.toHex(' ').toUpper();
|
|
||||||
}
|
|
||||||
//! \brief Get the value for the given key.
|
//! \brief Get the value for the given key.
|
||||||
inline QString get(const QString & name) const
|
QString get(const QString & name) const;
|
||||||
{
|
|
||||||
if (!m_values.contains(name)) {
|
|
||||||
qWarning().noquote() << *this << "missing attribute:" << name;
|
|
||||||
}
|
|
||||||
return m_values[name];
|
|
||||||
}
|
|
||||||
//! \brief Get the raw data for this event.
|
//! \brief Get the raw data for this event.
|
||||||
QByteArray getData() const
|
QByteArray getData() const;
|
||||||
{
|
|
||||||
Q_ASSERT(usesData() == true);
|
|
||||||
if (m_data.isEmpty()) {
|
|
||||||
qWarning().noquote() << "replaying event with missing data" << *this;
|
|
||||||
QByteArray empty;
|
|
||||||
return empty; // toUtf8() below crashes with an empty string.
|
|
||||||
}
|
|
||||||
return QByteArray::fromHex(m_data.toUtf8());
|
|
||||||
}
|
|
||||||
//! \brief True if there are no errors in this event, or false if the "error" attribute is set.
|
//! \brief True if there are no errors in this event, or false if the "error" attribute is set.
|
||||||
inline bool ok() const { return m_values.contains("error") == false; }
|
inline bool ok() const { return m_values.contains("error") == false; }
|
||||||
//! \brief Return a string of this event as an XML tag.
|
//! \brief Return a string of this event as an XML tag.
|
||||||
operator QString() const
|
operator QString() const;
|
||||||
{
|
|
||||||
QString out;
|
|
||||||
QXmlStreamWriter xml(&out);
|
|
||||||
xml << *this;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \brief Copy the result from the retrieved replay event (if any) into the current event.
|
//! \brief Copy the result from the retrieved replay event (if any) into the current event.
|
||||||
void copyIf(const XmlReplayEvent* other)
|
void copyIf(const XmlReplayEvent* other);
|
||||||
{
|
|
||||||
// Leave the proposed event alone if there was no replay event.
|
|
||||||
if (other == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Do not copy timestamp.
|
|
||||||
m_values = other->m_values;
|
|
||||||
m_keys = other->m_keys;
|
|
||||||
m_data = other->m_data;
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Copy the timestamp as well as the results. This is necessary for replaying substreams that use the timestamp as part of their ID.
|
//! \brief Copy the timestamp as well as the results. This is necessary for replaying substreams that use the timestamp as part of their ID.
|
||||||
void copy(const XmlReplayEvent & other)
|
void copy(const XmlReplayEvent & other);
|
||||||
{
|
|
||||||
copyIf(&other);
|
|
||||||
m_time = other.m_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static QHash<QString,FactoryMethod> s_factories; // registered subclass factory methods, arranged by XML tag
|
static QHash<QString,FactoryMethod> s_factories; // registered subclass factory methods, arranged by XML tag
|
||||||
@ -290,12 +241,7 @@ protected:
|
|||||||
inline bool isSignal() const { return m_signal != nullptr; }
|
inline bool isSignal() const { return m_signal != nullptr; }
|
||||||
|
|
||||||
//! \brief Send a signal to the target object. Subclasses may override this to send signal arguments.
|
//! \brief Send a signal to the target object. Subclasses may override this to send signal arguments.
|
||||||
virtual void signal(QObject* target)
|
virtual void signal(QObject* target);
|
||||||
{
|
|
||||||
// Queue the signal so that it won't be processed before the current event returns to its caller.
|
|
||||||
// (See XmlReplayLock below.)
|
|
||||||
QMetaObject::invokeMethod(target, m_signal, Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<QString,QString> m_values; // hash of key/value pairs for this event, written as attributes of the XML tag
|
QHash<QString,QString> m_values; // hash of key/value pairs for this event, written as attributes of the XML tag
|
||||||
QList<QString> m_keys; // list of keys so that attributes will be written in the order they were set
|
QList<QString> m_keys; // list of keys so that attributes will be written in the order they were set
|
||||||
@ -305,7 +251,88 @@ protected:
|
|||||||
virtual bool usesData() const { return false; }
|
virtual bool usesData() const { return false; }
|
||||||
|
|
||||||
//! \brief Write any attributes or content needed specific to event. Subclasses may override this to support complex data types.
|
//! \brief Write any attributes or content needed specific to event. Subclasses may override this to support complex data types.
|
||||||
virtual void write(QXmlStreamWriter & xml) const
|
virtual void write(QXmlStreamWriter & xml) const;
|
||||||
|
//! \brief Read any attributes or content specific to this event. Subclasses may override this to support complex data types.
|
||||||
|
virtual void read(QXmlStreamReader & xml);
|
||||||
|
|
||||||
|
friend class XmlReplay;
|
||||||
|
};
|
||||||
|
QHash<QString,XmlReplayEvent::FactoryMethod> XmlReplayEvent::s_factories;
|
||||||
|
|
||||||
|
void XmlReplayEvent::set(const QString & name, const QString & value)
|
||||||
|
{
|
||||||
|
if (!m_values.contains(name)) {
|
||||||
|
m_keys.append(name);
|
||||||
|
}
|
||||||
|
m_values[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlReplayEvent::set(const QString & name, qint64 value)
|
||||||
|
{
|
||||||
|
set(name, QString::number(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlReplayEvent::setData(const char* data, qint64 length)
|
||||||
|
{
|
||||||
|
Q_ASSERT(usesData() == true);
|
||||||
|
QByteArray bytes = QByteArray::fromRawData(data, length);
|
||||||
|
m_data = bytes.toHex(' ').toUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XmlReplayEvent::get(const QString & name) const
|
||||||
|
{
|
||||||
|
if (!m_values.contains(name)) {
|
||||||
|
qWarning().noquote() << *this << "missing attribute:" << name;
|
||||||
|
}
|
||||||
|
return m_values[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray XmlReplayEvent::getData() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(usesData() == true);
|
||||||
|
if (m_data.isEmpty()) {
|
||||||
|
qWarning().noquote() << "replaying event with missing data" << *this;
|
||||||
|
QByteArray empty;
|
||||||
|
return empty; // toUtf8() below crashes with an empty string.
|
||||||
|
}
|
||||||
|
return QByteArray::fromHex(m_data.toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlReplayEvent::operator QString() const
|
||||||
|
{
|
||||||
|
QString out;
|
||||||
|
QXmlStreamWriter xml(&out);
|
||||||
|
xml << *this;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlReplayEvent::copyIf(const XmlReplayEvent* other)
|
||||||
|
{
|
||||||
|
// Leave the proposed event alone if there was no replay event.
|
||||||
|
if (other == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Do not copy timestamp.
|
||||||
|
m_values = other->m_values;
|
||||||
|
m_keys = other->m_keys;
|
||||||
|
m_data = other->m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlReplayEvent::copy(const XmlReplayEvent & other)
|
||||||
|
{
|
||||||
|
copyIf(&other);
|
||||||
|
// Copy the timestamp, as it is necessary for replaying substreams that use the timestamp as part of their ID.
|
||||||
|
m_time = other.m_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlReplayEvent::signal(QObject* target)
|
||||||
|
{
|
||||||
|
// Queue the signal so that it won't be processed before the current event returns to its caller.
|
||||||
|
// (See XmlReplayLock below.)
|
||||||
|
QMetaObject::invokeMethod(target, m_signal, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlReplayEvent::write(QXmlStreamWriter & xml) const
|
||||||
{
|
{
|
||||||
// Write key/value pairs as attributes in the order they were set.
|
// Write key/value pairs as attributes in the order they were set.
|
||||||
for (auto key : m_keys) {
|
for (auto key : m_keys) {
|
||||||
@ -316,8 +343,8 @@ protected:
|
|||||||
xml.writeCharacters(m_data);
|
xml.writeCharacters(m_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//! \brief Read any attributes or content specific to this event. Subclasses may override this to support complex data types.
|
|
||||||
virtual void read(QXmlStreamReader & xml)
|
void XmlReplayEvent::read(QXmlStreamReader & xml)
|
||||||
{
|
{
|
||||||
QXmlStreamAttributes attribs = xml.attributes();
|
QXmlStreamAttributes attribs = xml.attributes();
|
||||||
for (auto & attrib : attribs) {
|
for (auto & attrib : attribs) {
|
||||||
@ -332,9 +359,6 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class XmlReplay;
|
|
||||||
};
|
|
||||||
QHash<QString,XmlReplayEvent::FactoryMethod> XmlReplayEvent::s_factories;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XML replay lock class
|
* XML replay lock class
|
||||||
@ -349,7 +373,15 @@ class XmlReplayLock
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! \brief Temporarily lock the XML replay (if any) until exiting scope, at which point any pending signals will be sent to the specified object.
|
//! \brief Temporarily lock the XML replay (if any) until exiting scope, at which point any pending signals will be sent to the specified object.
|
||||||
XmlReplayLock(const QObject* obj, XmlReplay* replay)
|
XmlReplayLock(const QObject* obj, XmlReplay* replay);
|
||||||
|
~XmlReplayLock();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const QObject* m_target; // target object to receive any pending signals
|
||||||
|
XmlReplay* m_replay; // replay instance, or nullptr if not replaying
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlReplayLock::XmlReplayLock(const QObject* obj, XmlReplay* replay)
|
||||||
: m_target(obj), m_replay(replay)
|
: m_target(obj), m_replay(replay)
|
||||||
{
|
{
|
||||||
if (m_replay) {
|
if (m_replay) {
|
||||||
@ -357,7 +389,8 @@ public:
|
|||||||
m_replay->lock();
|
m_replay->lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~XmlReplayLock()
|
|
||||||
|
XmlReplayLock::~XmlReplayLock()
|
||||||
{
|
{
|
||||||
if (m_replay) {
|
if (m_replay) {
|
||||||
m_replay->processPendingSignals(m_target);
|
m_replay->processPendingSignals(m_target);
|
||||||
@ -365,10 +398,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
const QObject* m_target; // target object to receive any pending signals
|
|
||||||
XmlReplay* m_replay; // replay instance, or nullptr if not replaying
|
|
||||||
};
|
|
||||||
|
|
||||||
// Derive the filepath for the given substream ID relative to the parent stream.
|
// Derive the filepath for the given substream ID relative to the parent stream.
|
||||||
static QString substreamFilepath(QFile* parent, const QString & id)
|
static QString substreamFilepath(QFile* parent, const QString & id)
|
||||||
@ -837,20 +866,6 @@ public:
|
|||||||
DeviceReplay(QXmlStreamReader & xml) : XmlReplay(xml, DeviceRecorder::TAG) {}
|
DeviceReplay(QXmlStreamReader & xml) : XmlReplay(xml, DeviceRecorder::TAG) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Return singleton instance of DeviceConnectionManager, creating it if necessary.
|
|
||||||
inline DeviceConnectionManager & DeviceConnectionManager::getInstance()
|
|
||||||
{
|
|
||||||
static DeviceConnectionManager instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protected constructor
|
|
||||||
DeviceConnectionManager::DeviceConnectionManager()
|
|
||||||
: m_record(nullptr), m_replay(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeviceConnectionManager::record(QFile* stream)
|
void DeviceConnectionManager::record(QFile* stream)
|
||||||
{
|
{
|
||||||
if (m_record) {
|
if (m_record) {
|
||||||
@ -896,6 +911,20 @@ void DeviceConnectionManager::replay(QFile* file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return singleton instance of DeviceConnectionManager, creating it if necessary.
|
||||||
|
inline DeviceConnectionManager & DeviceConnectionManager::getInstance()
|
||||||
|
{
|
||||||
|
static DeviceConnectionManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protected constructor
|
||||||
|
DeviceConnectionManager::DeviceConnectionManager()
|
||||||
|
: m_record(nullptr), m_replay(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
DeviceConnection* DeviceConnectionManager::openConnection(const QString & type, const QString & name)
|
DeviceConnection* DeviceConnectionManager::openConnection(const QString & type, const QString & name)
|
||||||
{
|
{
|
||||||
if (!s_factories.contains(type)) {
|
if (!s_factories.contains(type)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user