mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 23:46:41 +00:00
Add a status entry showing loaded python extensions & debugger status
This commit is contained in:
@@ -453,11 +453,21 @@ rdcarray<ExtensionMetadata> CaptureContext::GetInstalledExtensions()
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdcarray<rdcstr> CaptureContext::GetLoadedExtensions()
|
||||
{
|
||||
return m_ExtensionObjects.keys();
|
||||
}
|
||||
|
||||
bool CaptureContext::IsExtensionLoaded(rdcstr name)
|
||||
{
|
||||
return m_ExtensionObjects.contains(name);
|
||||
}
|
||||
|
||||
bool CaptureContext::IsPythonDebuggerConnected()
|
||||
{
|
||||
return PythonContext::IsDebuggingEnabled() && PythonContext::IsDebuggerConnected();
|
||||
}
|
||||
|
||||
rdcstr CaptureContext::LoadExtension(rdcstr name)
|
||||
{
|
||||
QString ret;
|
||||
|
||||
@@ -76,8 +76,10 @@ public:
|
||||
// IExtensionManager
|
||||
|
||||
rdcarray<ExtensionMetadata> GetInstalledExtensions() override;
|
||||
rdcarray<rdcstr> GetLoadedExtensions() override;
|
||||
bool IsExtensionLoaded(rdcstr name) override;
|
||||
rdcstr LoadExtension(rdcstr name) override;
|
||||
bool IsPythonDebuggerConnected() override;
|
||||
|
||||
void RegisterWindowMenu(WindowMenu base, const rdcarray<rdcstr> &submenus,
|
||||
ExtensionCallback callback) override;
|
||||
|
||||
@@ -1098,6 +1098,13 @@ struct IExtensionManager
|
||||
)");
|
||||
virtual bool IsExtensionLoaded(rdcstr name) = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve a list of loaded extensions.
|
||||
|
||||
:return: The list of installed extension names.
|
||||
:rtype: List[str]
|
||||
)");
|
||||
virtual rdcarray<rdcstr> GetLoadedExtensions() = 0;
|
||||
|
||||
DOCUMENT(R"(Enable an extension by name. If the extension is already enabled, this will reload it.
|
||||
|
||||
:param str name: The qualified name of the extension, e.g. ``foo.bar``
|
||||
@@ -1107,6 +1114,16 @@ struct IExtensionManager
|
||||
)");
|
||||
virtual rdcstr LoadExtension(rdcstr name) = 0;
|
||||
|
||||
DOCUMENT(R"(Check if a python debugger is connected.
|
||||
|
||||
.. note::
|
||||
If python debugging is not supported or failed to load, this will return ``False``.
|
||||
|
||||
:return: If a python debugger is connected.
|
||||
:rtype: bool
|
||||
)");
|
||||
virtual bool IsPythonDebuggerConnected() = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// UI hook/callback registration
|
||||
|
||||
|
||||
@@ -2113,6 +2113,22 @@ PyObject *PythonContext::outstream_trace(PyObject *self, PyObject *args, PyObjec
|
||||
return self;
|
||||
}
|
||||
|
||||
bool PythonContext::IsDebuggerConnected()
|
||||
{
|
||||
if(!m_DebugPy)
|
||||
return false;
|
||||
|
||||
PyGILState_STATE gil = PyGILState_Ensure();
|
||||
|
||||
PyObject *is_connected = PyObject_CallMethod(m_DebugPy, "is_client_connected", NULL);
|
||||
bool ret = (PyBool_Check(is_connected) && is_connected == Py_True);
|
||||
Py_XDECREF(is_connected);
|
||||
|
||||
PyGILState_Release(gil);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PythonContext::PrepareDebuggerWait()
|
||||
{
|
||||
if(!m_DebugPy)
|
||||
|
||||
@@ -70,6 +70,9 @@ public:
|
||||
|
||||
static void PrepareDebugTracing();
|
||||
|
||||
static bool IsDebuggingEnabled() { return m_DebugPy != NULL; }
|
||||
static bool IsDebuggerConnected();
|
||||
|
||||
static void PrepareDebuggerWait();
|
||||
static bool WaitForDebugger();
|
||||
static void LaunchDebugger(QWidget *window, PersistantConfig &config, QString context_location);
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
#include <QToolTip>
|
||||
#include "Code/QRDUtils.h"
|
||||
#include "Code/Resources.h"
|
||||
#include "Code/pyrenderdoc/PythonContext.h"
|
||||
#include "Widgets/Extended/RDLabel.h"
|
||||
#include "Widgets/Extended/RDMenu.h"
|
||||
#include "Widgets/Extended/RDToolButton.h"
|
||||
#include "Widgets/ReplayOptionsSelector.h"
|
||||
#include "Windows/Dialogs/AboutDialog.h"
|
||||
#include "Windows/Dialogs/CaptureDialog.h"
|
||||
@@ -224,6 +226,26 @@ MainWindow::MainWindow(ICaptureContext &ctx) : QMainWindow(NULL), ui(new Ui::Mai
|
||||
QObject::connect(statusIcon, &RDLabel::doubleClicked, this, &MainWindow::statusDoubleClicked);
|
||||
QObject::connect(statusText, &RDLabel::doubleClicked, this, &MainWindow::statusDoubleClicked);
|
||||
|
||||
extensionStatus = new RDToolButton(this);
|
||||
extensionStatus->setAutoRaise(true);
|
||||
extensionStatus->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
ui->statusBar->addWidget(extensionStatus);
|
||||
|
||||
extensionStatus->setIcon(Icons::plugin());
|
||||
extensionStatus->setVisible(false);
|
||||
|
||||
QObject::connect(extensionStatus, &RDToolButton::clicked, this,
|
||||
&MainWindow::on_action_Manage_Extensions_triggered);
|
||||
QObject::connect(PythonContext::GetExtensionContext(), &PythonContext::extensionLoaded, this,
|
||||
&MainWindow::PythonStatusUpdate);
|
||||
|
||||
QTimer *debuggerTimer = new QTimer(this);
|
||||
QObject::connect(debuggerTimer, &QTimer::timeout, this, &MainWindow::PythonStatusUpdate);
|
||||
|
||||
debuggerTimer->setSingleShot(false);
|
||||
debuggerTimer->setInterval(500);
|
||||
debuggerTimer->start();
|
||||
|
||||
QObject::connect(&m_MessageTick, &QTimer::timeout, this, &MainWindow::messageCheck);
|
||||
m_MessageTick.setSingleShot(false);
|
||||
m_MessageTick.setInterval(175);
|
||||
@@ -1316,6 +1338,22 @@ void MainWindow::ClearRecentCaptureSettings()
|
||||
PopulateRecentCaptureSettings();
|
||||
}
|
||||
|
||||
void MainWindow::PythonStatusUpdate()
|
||||
{
|
||||
int num = m_Ctx.Extensions().GetLoadedExtensions().count();
|
||||
|
||||
if(num > 0 || PythonContext::IsDebuggerConnected())
|
||||
{
|
||||
// extensions can't be unloaded so we can just unconditionally show this now
|
||||
extensionStatus->setVisible(true);
|
||||
|
||||
QString text = tr("%n extension(s) active", NULL, num);
|
||||
if(PythonContext::IsDebuggerConnected())
|
||||
text += tr(": Python debugger connected");
|
||||
extensionStatus->setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::networkRequestFailed(QUrl url, QString error)
|
||||
{
|
||||
if(m_NetworkFailCallbacks.contains(url))
|
||||
|
||||
@@ -40,6 +40,7 @@ class MainWindow;
|
||||
}
|
||||
|
||||
class RDLabel;
|
||||
class RDToolButton;
|
||||
class RDMenu;
|
||||
class LambdaThread;
|
||||
class QMimeData;
|
||||
@@ -203,6 +204,8 @@ private slots:
|
||||
void ClearRecentCaptureFiles();
|
||||
void ClearRecentCaptureSettings();
|
||||
|
||||
void PythonStatusUpdate();
|
||||
|
||||
void networkRequestFailed(QUrl url, QString error);
|
||||
void networkRequestCompleted(QUrl url, QByteArray data);
|
||||
|
||||
@@ -248,6 +251,7 @@ private:
|
||||
|
||||
RDLabel *statusIcon;
|
||||
RDLabel *statusText;
|
||||
RDToolButton *extensionStatus;
|
||||
QProgressBar *statusProgress;
|
||||
RDMenu *contextChooserMenu;
|
||||
QToolButton *contextChooser;
|
||||
|
||||
@@ -375,8 +375,10 @@ struct ExtensionInvoker : ObjectForwarder<IExtensionManager>
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
rdcarray<ExtensionMetadata> GetInstalledExtensions() { return m_Obj.GetInstalledExtensions(); }
|
||||
rdcarray<rdcstr> GetLoadedExtensions() { return m_Obj.GetLoadedExtensions(); }
|
||||
bool IsExtensionLoaded(rdcstr name) { return m_Obj.IsExtensionLoaded(name); }
|
||||
rdcstr LoadExtension(rdcstr name) { return m_Obj.LoadExtension(name); }
|
||||
bool IsPythonDebuggerConnected() { return m_Obj.IsPythonDebuggerConnected(); }
|
||||
IMiniQtHelper &GetMiniQtHelper() { return *m_MiniQt; }
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user