Debugger: Avoid multiple inheritance in ThreadHandler

Using it implies dynamic_cast in treeitems, and we want to avoid that
across library boundaries.

Change-Id: Id2e624b770cd559ef9e8b25366734f2dd92658c0
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2016-04-29 09:39:44 +02:00
parent 8e058ee338
commit d69bec2dcd

View File

@@ -60,13 +60,13 @@ static const QIcon &emptyIcon()
return icon; return icon;
} }
class ThreadItem : public TreeItem, public ThreadData class ThreadItem : public TreeItem
{ {
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::ThreadsHandler) Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::ThreadsHandler)
public: public:
ThreadItem(const ThreadsHandler *handler, const ThreadData &data = ThreadData()) ThreadItem(const ThreadsHandler *handler, const ThreadData &data = ThreadData())
: ThreadData(data), handler(handler) : threadData(data), handler(handler)
{} {}
QVariant data(int column, int role) const QVariant data(int column, int role) const
@@ -79,10 +79,10 @@ public:
case Qt::DecorationRole: case Qt::DecorationRole:
// Return icon that indicates whether this is the active stack frame. // Return icon that indicates whether this is the active stack frame.
if (column == 0) if (column == 0)
return id == handler->currentThread() ? positionIcon() : emptyIcon(); return threadData.id == handler->currentThread() ? positionIcon() : emptyIcon();
break; break;
case ThreadData::IdRole: case ThreadData::IdRole:
return id.raw(); return threadData.id.raw();
default: default:
break; break;
} }
@@ -91,7 +91,7 @@ public:
Qt::ItemFlags flags(int column) const Qt::ItemFlags flags(int column) const
{ {
return stopped ? TreeItem::flags(column) : Qt::ItemFlags(0); return threadData.stopped ? TreeItem::flags(column) : Qt::ItemFlags(0);
} }
QString threadToolTip() const QString threadToolTip() const
@@ -103,29 +103,29 @@ public:
QTextStream str(&rc); QTextStream str(&rc);
str << "<html><head/><body><table>" str << "<html><head/><body><table>"
<< start << ThreadsHandler::tr("Thread&nbsp;id:") << start << ThreadsHandler::tr("Thread&nbsp;id:")
<< sep << id.raw() << end; << sep << threadData.id.raw() << end;
if (!targetId.isEmpty()) if (!threadData.targetId.isEmpty())
str << start << ThreadsHandler::tr("Target&nbsp;id:") str << start << ThreadsHandler::tr("Target&nbsp;id:")
<< sep << targetId << end; << sep << threadData.targetId << end;
if (!groupId.isEmpty()) if (!threadData.groupId.isEmpty())
str << start << ThreadsHandler::tr("Group&nbsp;id:") str << start << ThreadsHandler::tr("Group&nbsp;id:")
<< sep << groupId << end; << sep << threadData.groupId << end;
if (!name.isEmpty()) if (!threadData.name.isEmpty())
str << start << ThreadsHandler::tr("Name:") str << start << ThreadsHandler::tr("Name:")
<< sep << name << end; << sep << threadData.name << end;
if (!state.isEmpty()) if (!threadData.state.isEmpty())
str << start << ThreadsHandler::tr("State:") str << start << ThreadsHandler::tr("State:")
<< sep << state << end; << sep << threadData.state << end;
if (!core.isEmpty()) if (!threadData.core.isEmpty())
str << start << ThreadsHandler::tr("Core:") str << start << ThreadsHandler::tr("Core:")
<< sep << core << end; << sep << threadData.core << end;
if (address) { if (threadData.address) {
str << start << ThreadsHandler::tr("Stopped&nbsp;at:") << sep; str << start << ThreadsHandler::tr("Stopped&nbsp;at:") << sep;
if (!function.isEmpty()) if (!threadData.function.isEmpty())
str << function << "<br>"; str << threadData.function << "<br>";
if (!fileName.isEmpty()) if (!threadData.fileName.isEmpty())
str << fileName << ':' << lineNumber << "<br>"; str << threadData.fileName << ':' << threadData.lineNumber << "<br>";
str << formatToolTipAddress(address); str << formatToolTipAddress(threadData.address);
} }
str << "</table></body></html>"; str << "</table></body></html>";
return rc; return rc;
@@ -135,83 +135,84 @@ public:
{ {
switch (column) { switch (column) {
case ThreadData::IdColumn: case ThreadData::IdColumn:
return id.raw(); return threadData.id.raw();
case ThreadData::FunctionColumn: case ThreadData::FunctionColumn:
return function; return threadData.function;
case ThreadData::FileColumn: case ThreadData::FileColumn:
return fileName.isEmpty() ? module : fileName; return threadData.fileName.isEmpty() ? threadData.module : threadData.fileName;
case ThreadData::LineColumn: case ThreadData::LineColumn:
return lineNumber >= 0 return threadData.lineNumber >= 0
? QString::number(lineNumber) : QString(); ? QString::number(threadData.lineNumber) : QString();
case ThreadData::AddressColumn: case ThreadData::AddressColumn:
return address > 0 return threadData.address > 0
? QLatin1String("0x") + QString::number(address, 16) ? QLatin1String("0x") + QString::number(threadData.address, 16)
: QString(); : QString();
case ThreadData::CoreColumn: case ThreadData::CoreColumn:
return core; return threadData.core;
case ThreadData::StateColumn: case ThreadData::StateColumn:
return state; return threadData.state;
case ThreadData::TargetIdColumn: case ThreadData::TargetIdColumn:
if (targetId.startsWith(QLatin1String("Thread "))) if (threadData.targetId.startsWith(QLatin1String("Thread ")))
return targetId.mid(7); return threadData.targetId.mid(7);
return targetId; return threadData.targetId;
case ThreadData::NameColumn: case ThreadData::NameColumn:
return name; return threadData.name;
case ThreadData::DetailsColumn: case ThreadData::DetailsColumn:
return details; return threadData.details;
case ThreadData::ComboNameColumn: case ThreadData::ComboNameColumn:
return QString::fromLatin1("#%1 %2").arg(id.raw()).arg(name); return QString::fromLatin1("#%1 %2").arg(threadData.id.raw()).arg(threadData.name);
} }
return QVariant(); return QVariant();
} }
void notifyRunning() // Clear state information. void notifyRunning() // Clear state information.
{ {
address = 0; threadData.address = 0;
function.clear(); threadData.function.clear();
fileName.clear(); threadData.fileName.clear();
frameLevel = -1; threadData.frameLevel = -1;
state.clear(); threadData.state.clear();
lineNumber = -1; threadData.lineNumber = -1;
stopped = false; threadData.stopped = false;
update(); update();
} }
void notifyStopped() void notifyStopped()
{ {
stopped = true; threadData.stopped = true;
update(); update();
} }
void mergeThreadData(const ThreadData &other) void mergeThreadData(const ThreadData &other)
{ {
if (!other.core.isEmpty()) if (!other.core.isEmpty())
core = other.core; threadData.core = other.core;
if (!other.fileName.isEmpty()) if (!other.fileName.isEmpty())
fileName = other.fileName; threadData.fileName = other.fileName;
if (!other.targetId.isEmpty()) if (!other.targetId.isEmpty())
targetId = other.targetId; threadData.targetId = other.targetId;
if (!other.name.isEmpty()) if (!other.name.isEmpty())
name = other.name; threadData.name = other.name;
if (other.frameLevel != -1) if (other.frameLevel != -1)
frameLevel = other.frameLevel; threadData.frameLevel = other.frameLevel;
if (!other.function.isEmpty()) if (!other.function.isEmpty())
function = other.function; threadData.function = other.function;
if (other.address) if (other.address)
address = other.address; threadData.address = other.address;
if (!other.module.isEmpty()) if (!other.module.isEmpty())
module = other.module; threadData.module = other.module;
if (!other.details.isEmpty()) if (!other.details.isEmpty())
details = other.details; threadData.details = other.details;
if (!other.state.isEmpty()) if (!other.state.isEmpty())
state = other.state; threadData.state = other.state;
if (other.lineNumber != -1) if (other.lineNumber != -1)
lineNumber = other.lineNumber; threadData.lineNumber = other.lineNumber;
update(); update();
} }
public: public:
ThreadData threadData;
const ThreadsHandler * const handler; const ThreadsHandler * const handler;
}; };
@@ -249,7 +250,7 @@ ThreadsHandler::ThreadsHandler()
static ThreadItem *itemForThreadId(const ThreadsHandler *handler, ThreadId threadId) static ThreadItem *itemForThreadId(const ThreadsHandler *handler, ThreadId threadId)
{ {
const auto matcher = [threadId](ThreadItem *item) { return item->id == threadId; }; const auto matcher = [threadId](ThreadItem *item) { return item->threadData.id == threadId; };
return handler->findItemAtLevel<ThreadItem *>(1, matcher); return handler->findItemAtLevel<ThreadItem *>(1, matcher);
} }
@@ -286,7 +287,7 @@ ThreadId ThreadsHandler::currentThread() const
ThreadId ThreadsHandler::threadAt(int index) const ThreadId ThreadsHandler::threadAt(int index) const
{ {
QTC_ASSERT(index >= 0 && index < rootItem()->childCount(), return ThreadId()); QTC_ASSERT(index >= 0 && index < rootItem()->childCount(), return ThreadId());
return static_cast<ThreadItem *>(rootItem()->childAt(index))->id; return static_cast<ThreadItem *>(rootItem()->childAt(index))->threadData.id;
} }
void ThreadsHandler::setCurrentThread(ThreadId id) void ThreadsHandler::setCurrentThread(ThreadId id)
@@ -350,14 +351,14 @@ void ThreadsHandler::updateThreadBox()
QStringList list; QStringList list;
auto items = itemsAtLevel<ThreadItem *>(1); auto items = itemsAtLevel<ThreadItem *>(1);
foreach (ThreadItem *item, items) foreach (ThreadItem *item, items)
list.append(QString::fromLatin1("#%1 %2").arg(item->id.raw()).arg(item->name)); list.append(QString::fromLatin1("#%1 %2").arg(item->threadData.id.raw()).arg(item->threadData.name));
Internal::setThreadBoxContents(list, indexForThreadId(this, m_currentId)); Internal::setThreadBoxContents(list, indexForThreadId(this, m_currentId));
} }
ThreadData ThreadsHandler::thread(ThreadId id) const ThreadData ThreadsHandler::thread(ThreadId id) const
{ {
if (ThreadItem *item = itemForThreadId(this, id)) if (ThreadItem *item = itemForThreadId(this, id))
return *item; return item->threadData;
return ThreadData(); return ThreadData();
} }
@@ -371,7 +372,7 @@ bool ThreadsHandler::notifyGroupExited(const QByteArray &groupId)
QList<ThreadItem *> list; QList<ThreadItem *> list;
auto items = itemsAtLevel<ThreadItem *>(1); auto items = itemsAtLevel<ThreadItem *>(1);
foreach (ThreadItem *item, items) foreach (ThreadItem *item, items)
if (item->groupId == groupId) if (item->threadData.groupId == groupId)
list.append(item); list.append(item);
foreach (ThreadItem *item, list) foreach (ThreadItem *item, list)
delete takeItem(item); delete takeItem(item);