Commit 4320aeea authored by hjk's avatar hjk

ProjectExplorer: Move Runnable/Connection model into class

Somewhat better encapsulation.

Removes the "false" sharing of Concept implementations, and takes
the opportunity to change the operator==() into a 'canReUseOutputPane'
function to be explicit about its only use.

This doesn't solve the change in output pane reuse behavior yet,
but provides the base to put the required logic into canReUseOutputPane,
as opposed to abusing the general equality concept.

Change-Id: Id9e4e6b8601c5fcf40a252fb423c2c4c2b74ddb6
Reviewed-by: Christian Stenger's avatarChristian Stenger <christian.stenger@qt.io>
parent 9b1e2cb4
......@@ -27,12 +27,9 @@
#include <debugger/debugger_global.h>
#include <projectexplorer/runnables.h>
#include <ssh/sshconnection.h>
#include <utils/port.h>
#include <QMetaType>
namespace Debugger {
class DEBUGGER_EXPORT AnalyzerConnection
......@@ -44,6 +41,4 @@ public:
Utils::Port analyzerPort;
};
DEBUGGER_EXPORT bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2);
} // namespace Debugger
......@@ -3633,14 +3633,6 @@ AnalyzerRunControl *createAnalyzerRunControl(RunConfiguration *runConfiguration,
return 0;
}
bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2)
{
return c1.connParams == c2.connParams
&& c1.analyzerHost == c2.analyzerHost
&& c1.analyzerSocket == c2.analyzerSocket
&& c1.analyzerPort == c2.analyzerPort;
}
namespace Internal {
static bool s_testRun = false;
......
......@@ -668,7 +668,7 @@ bool RunControl::canReUseOutputPane(const RunControl *other) const
if (other->isRunning())
return false;
return d->runnable == other->d->runnable;
return d->runnable.canReUseOutputPane(other->d->runnable);
}
ProcessHandle RunControl::applicationProcessHandle() const
......@@ -771,9 +771,9 @@ void RunControl::appendMessage(const QString &msg, Utils::OutputFormat format)
emit appendMessage(this, msg, format);
}
bool Runnable::operator==(const Runnable &other) const
bool Runnable::canReUseOutputPane(const Runnable &other) const
{
return d ? d->equals(other.d) : (other.d.get() == 0);
return d ? d->canReUseOutputPane(other.d) : (other.d.get() == 0);
}
} // namespace ProjectExplorer
......@@ -154,75 +154,77 @@ private:
RunConfigWidgetCreator m_runConfigWidgetCreator;
};
class PROJECTEXPLORER_EXPORT ClonableConcept
{
public:
virtual ~ClonableConcept() = default;
virtual ClonableConcept *clone() const = 0;
virtual bool equals(const std::unique_ptr<ClonableConcept> &other) const = 0;
};
template <class T>
class ClonableModel : public ClonableConcept
class PROJECTEXPLORER_EXPORT Runnable
{
public:
ClonableModel(const T &data) : m_data(data) { }
~ClonableModel() Q_DECL_NOEXCEPT { } // gcc 4.7.3
ClonableConcept *clone() const override { return new ClonableModel(*this); }
struct Concept
{
virtual ~Concept() {}
virtual Concept *clone() const = 0;
virtual bool canReUseOutputPane(const std::unique_ptr<Concept> &other) const = 0;
};
bool equals(const std::unique_ptr<ClonableConcept> &other) const override
template <class T>
struct Model : public Concept
{
auto that = dynamic_cast<const ClonableModel<T> *>(other.get());
return that && m_data == that->m_data;
}
Model(const T &data) : m_data(data) {}
T m_data;
};
Concept *clone() const override { return new Model(*this); }
bool canReUseOutputPane(const std::unique_ptr<Concept> &other) const override
{
auto that = dynamic_cast<const Model<T> *>(other.get());
return that && m_data == that->m_data;
}
T m_data;
};
class PROJECTEXPLORER_EXPORT Runnable
{
public:
Runnable() = default;
Runnable(const Runnable &other) : d(other.d->clone()) { }
Runnable(Runnable &&other) /* MSVC 2013 doesn't want = default */ : d(std::move(other.d)) {}
template <class T> Runnable(const T &data) : d(new ClonableModel<T>(data)) {}
Runnable(Runnable &&other) : d(std::move(other.d)) {}
template <class T> Runnable(const T &data) : d(new Model<T>(data)) {}
void operator=(Runnable other) { d = std::move(other.d); }
template <class T> bool is() const {
return dynamic_cast<ClonableModel<T> *>(d.get()) != 0;
}
template <class T> const T &as() const {
return static_cast<ClonableModel<T> *>(d.get())->m_data;
}
template <class T> bool is() const { return dynamic_cast<Model<T> *>(d.get()) != 0; }
template <class T> const T &as() const { return static_cast<Model<T> *>(d.get())->m_data; }
bool operator==(const Runnable &other) const;
bool canReUseOutputPane(const Runnable &other) const;
private:
std::unique_ptr<ClonableConcept> d;
std::unique_ptr<Concept> d;
};
class PROJECTEXPLORER_EXPORT Connection
{
struct Concept
{
virtual ~Concept() {}
virtual Concept *clone() const = 0;
};
template <class T>
struct Model : public Concept
{
Model(const T &data) : m_data(data) { }
Concept *clone() const override { return new Model(*this); }
T m_data;
};
public:
Connection() = default;
Connection(const Connection &other) : d(other.d->clone()) { }
Connection(Connection &&other) /* MSVC 2013 doesn't want = default */ : d(std::move(other.d)) {}
template <class T> Connection(const T &data) : d(new ClonableModel<T>(data)) {}
template <class T> Connection(const T &data) : d(new Model<T>(data)) {}
void operator=(Connection other) { d = std::move(other.d); }
template <class T> bool is() const {
return dynamic_cast<ClonableModel<T> *>(d.get()) != 0;
}
template <class T> const T &as() const {
return static_cast<ClonableModel<T> *>(d.get())->m_data;
}
template <class T> bool is() const { return dynamic_cast<Model<T> *>(d.get()) != 0; }
template <class T> const T &as() const { return static_cast<Model<T> *>(d.get())->m_data; }
private:
std::unique_ptr<ClonableConcept> d;
std::unique_ptr<Concept> d;
};
// Documentation inside.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment