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 @@ ...@@ -27,12 +27,9 @@
#include <debugger/debugger_global.h> #include <debugger/debugger_global.h>
#include <projectexplorer/runnables.h>
#include <ssh/sshconnection.h> #include <ssh/sshconnection.h>
#include <utils/port.h> #include <utils/port.h>
#include <QMetaType>
namespace Debugger { namespace Debugger {
class DEBUGGER_EXPORT AnalyzerConnection class DEBUGGER_EXPORT AnalyzerConnection
...@@ -44,6 +41,4 @@ public: ...@@ -44,6 +41,4 @@ public:
Utils::Port analyzerPort; Utils::Port analyzerPort;
}; };
DEBUGGER_EXPORT bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2);
} // namespace Debugger } // namespace Debugger
...@@ -3633,14 +3633,6 @@ AnalyzerRunControl *createAnalyzerRunControl(RunConfiguration *runConfiguration, ...@@ -3633,14 +3633,6 @@ AnalyzerRunControl *createAnalyzerRunControl(RunConfiguration *runConfiguration,
return 0; 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 { namespace Internal {
static bool s_testRun = false; static bool s_testRun = false;
......
...@@ -668,7 +668,7 @@ bool RunControl::canReUseOutputPane(const RunControl *other) const ...@@ -668,7 +668,7 @@ bool RunControl::canReUseOutputPane(const RunControl *other) const
if (other->isRunning()) if (other->isRunning())
return false; return false;
return d->runnable == other->d->runnable; return d->runnable.canReUseOutputPane(other->d->runnable);
} }
ProcessHandle RunControl::applicationProcessHandle() const ProcessHandle RunControl::applicationProcessHandle() const
...@@ -771,9 +771,9 @@ void RunControl::appendMessage(const QString &msg, Utils::OutputFormat format) ...@@ -771,9 +771,9 @@ void RunControl::appendMessage(const QString &msg, Utils::OutputFormat format)
emit appendMessage(this, msg, 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 } // namespace ProjectExplorer
...@@ -154,75 +154,77 @@ private: ...@@ -154,75 +154,77 @@ private:
RunConfigWidgetCreator m_runConfigWidgetCreator; RunConfigWidgetCreator m_runConfigWidgetCreator;
}; };
class PROJECTEXPLORER_EXPORT ClonableConcept class PROJECTEXPLORER_EXPORT Runnable
{
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
{ {
public: struct Concept
ClonableModel(const T &data) : m_data(data) { } {
~ClonableModel() Q_DECL_NOEXCEPT { } // gcc 4.7.3 virtual ~Concept() {}
ClonableConcept *clone() const override { return new ClonableModel(*this); } 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()); Model(const T &data) : m_data(data) {}
return that && m_data == that->m_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: public:
Runnable() = default; Runnable() = default;
Runnable(const Runnable &other) : d(other.d->clone()) { } Runnable(const Runnable &other) : d(other.d->clone()) { }
Runnable(Runnable &&other) /* MSVC 2013 doesn't want = default */ : d(std::move(other.d)) {} Runnable(Runnable &&other) : d(std::move(other.d)) {}
template <class T> Runnable(const T &data) : d(new ClonableModel<T>(data)) {} template <class T> Runnable(const T &data) : d(new Model<T>(data)) {}
void operator=(Runnable other) { d = std::move(other.d); } void operator=(Runnable other) { d = std::move(other.d); }
template <class T> bool is() const { template <class T> bool is() const { return dynamic_cast<Model<T> *>(d.get()) != 0; }
return dynamic_cast<ClonableModel<T> *>(d.get()) != 0; template <class T> const T &as() const { return static_cast<Model<T> *>(d.get())->m_data; }
}
template <class T> const T &as() const {
return static_cast<ClonableModel<T> *>(d.get())->m_data;
}
bool operator==(const Runnable &other) const; bool canReUseOutputPane(const Runnable &other) const;
private: private:
std::unique_ptr<ClonableConcept> d; std::unique_ptr<Concept> d;
}; };
class PROJECTEXPLORER_EXPORT Connection 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: public:
Connection() = default; Connection() = default;
Connection(const Connection &other) : d(other.d->clone()) { } Connection(const Connection &other) : d(other.d->clone()) { }
Connection(Connection &&other) /* MSVC 2013 doesn't want = default */ : d(std::move(other.d)) {} 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); } void operator=(Connection other) { d = std::move(other.d); }
template <class T> bool is() const { template <class T> bool is() const { return dynamic_cast<Model<T> *>(d.get()) != 0; }
return dynamic_cast<ClonableModel<T> *>(d.get()) != 0; template <class T> const T &as() const { return static_cast<Model<T> *>(d.get())->m_data; }
}
template <class T> const T &as() const {
return static_cast<ClonableModel<T> *>(d.get())->m_data;
}
private: private:
std::unique_ptr<ClonableConcept> d; std::unique_ptr<Concept> d;
}; };
// Documentation inside. // 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