mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-12 06:29:27 +02:00
Enable script debugging
This commit is contained in:
parent
0de721e8f4
commit
40316498a4
6 changed files with 111 additions and 17 deletions
|
@ -44,7 +44,7 @@ else ()
|
|||
endif ()
|
||||
|
||||
find_package(Qt5 COMPONENTS
|
||||
Gui Multimedia Network OpenGL Qml Quick Script Svg
|
||||
Gui Multimedia Network OpenGL Qml Quick Script ScriptTools Svg
|
||||
WebChannel WebEngine WebEngineWidgets WebKitWidgets WebSockets)
|
||||
|
||||
# grab the ui files in resources/ui
|
||||
|
@ -201,7 +201,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src")
|
|||
target_link_libraries(
|
||||
${TARGET_NAME}
|
||||
Qt5::Gui Qt5::Network Qt5::Multimedia Qt5::OpenGL
|
||||
Qt5::Qml Qt5::Quick Qt5::Script Qt5::Svg
|
||||
Qt5::Qml Qt5::Quick Qt5::Script Qt5::ScriptTools Qt5::Svg
|
||||
Qt5::WebChannel Qt5::WebEngine Qt5::WebEngineWidgets Qt5::WebKitWidgets
|
||||
)
|
||||
|
||||
|
|
|
@ -11,8 +11,11 @@
|
|||
|
||||
#include "MenuScriptingInterface.h"
|
||||
|
||||
#include "Menu.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include <MenuItemProperties.h>
|
||||
#include "Menu.h"
|
||||
|
||||
MenuScriptingInterface* MenuScriptingInterface::getInstance() {
|
||||
static MenuScriptingInterface sharedInstance;
|
||||
|
@ -36,6 +39,9 @@ void MenuScriptingInterface::removeMenu(const QString& menu) {
|
|||
}
|
||||
|
||||
bool MenuScriptingInterface::menuExists(const QString& menu) {
|
||||
if (QThread::currentThread() == qApp->thread()) {
|
||||
return Menu::getInstance()->menuExists(menu);
|
||||
}
|
||||
bool result;
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "menuExists", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, result),
|
||||
|
@ -76,11 +82,14 @@ void MenuScriptingInterface::removeMenuItem(const QString& menu, const QString&
|
|||
};
|
||||
|
||||
bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& menuitem) {
|
||||
if (QThread::currentThread() == qApp->thread()) {
|
||||
return Menu::getInstance()->menuItemExists(menu, menuitem);
|
||||
}
|
||||
bool result;
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "menuItemExists", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, result),
|
||||
Q_ARG(const QString&, menu),
|
||||
Q_ARG(const QString&, menuitem));
|
||||
Q_RETURN_ARG(bool, result),
|
||||
Q_ARG(const QString&, menu),
|
||||
Q_ARG(const QString&, menuitem));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -101,6 +110,9 @@ void MenuScriptingInterface::removeActionGroup(const QString& groupName) {
|
|||
}
|
||||
|
||||
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
|
||||
if (QThread::currentThread() == qApp->thread()) {
|
||||
return Menu::getInstance()->isOptionChecked(menuOption);
|
||||
}
|
||||
bool result;
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "isOptionChecked", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, result),
|
||||
|
@ -109,7 +121,7 @@ bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
|
|||
}
|
||||
|
||||
void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool isChecked) {
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked", Qt::BlockingQueuedConnection,
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "setIsOptionChecked",
|
||||
Q_ARG(const QString&, menuOption),
|
||||
Q_ARG(bool, isChecked));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
set(TARGET_NAME script-engine)
|
||||
setup_hifi_library(Gui Network Script WebSockets Widgets)
|
||||
setup_hifi_library(Gui Network Script ScriptTools WebSockets Widgets)
|
||||
link_hifi_libraries(shared networking octree gpu ui procedural model model-networking recording avatars fbx entities controllers animation audio physics)
|
||||
|
|
|
@ -17,12 +17,18 @@
|
|||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QRegularExpression>
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include <QtScript/QScriptValue>
|
||||
#include <QtScript/QScriptValueIterator>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <QtScriptTools/QScriptEngineDebugger>
|
||||
|
||||
#include <AudioConstants.h>
|
||||
#include <AudioEffectOptions.h>
|
||||
|
@ -34,6 +40,7 @@
|
|||
#include <NodeList.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <UUID.h>
|
||||
#include <ui/Menu.h>
|
||||
|
||||
#include <controllers/ScriptingInterface.h>
|
||||
#include <AnimationObject.h>
|
||||
|
@ -169,6 +176,61 @@ void ScriptEngine::disconnectNonEssentialSignals() {
|
|||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::runDebuggable() {
|
||||
init();
|
||||
_isRunning = true;
|
||||
_debuggable = true;
|
||||
_debugger = new QScriptEngineDebugger(this);
|
||||
_debugger->attachTo(this);
|
||||
static QMenu* scriptDebugMenu = qobject_cast<QMainWindow*>(qApp->activeWindow())->menuBar()->addMenu("Script Debug");
|
||||
scriptDebugMenu->addMenu(_fileNameString)->addMenu(_debugger->createStandardMenu(qApp->activeWindow()));
|
||||
_debugger->action(QScriptEngineDebugger::InterruptAction)->trigger();
|
||||
QScriptValue result = evaluate(_scriptContents, _fileNameString);
|
||||
|
||||
_lastUpdate = usecTimestampNow();
|
||||
QTimer* timer = new QTimer(this);
|
||||
connect(this, &ScriptEngine::finished, [this, timer] {
|
||||
disconnect(timer);
|
||||
});
|
||||
|
||||
connect(timer, &QTimer::timeout, [this, timer] {
|
||||
if (_isFinished) {
|
||||
if (!_isRunning) {
|
||||
return;
|
||||
}
|
||||
stopAllTimers(); // make sure all our timers are stopped if the script is ending
|
||||
if (_wantSignals) {
|
||||
emit scriptEnding();
|
||||
emit finished(_fileNameString, this);
|
||||
}
|
||||
_isRunning = false;
|
||||
if (_wantSignals) {
|
||||
emit runningStateChanged();
|
||||
emit doneRunning();
|
||||
}
|
||||
timer->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
qint64 now = usecTimestampNow();
|
||||
// we check for 'now' in the past in case people set their clock back
|
||||
if (_lastUpdate < now) {
|
||||
float deltaTime = (float)(now - _lastUpdate) / (float)USECS_PER_SECOND;
|
||||
if (!_isFinished) {
|
||||
if (_wantSignals) {
|
||||
emit update(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
_lastUpdate = now;
|
||||
// Debug and clear exceptions
|
||||
hadUncaughtExceptions(*this, _fileNameString);
|
||||
});
|
||||
|
||||
timer->start(10);
|
||||
}
|
||||
|
||||
|
||||
void ScriptEngine::runInThread() {
|
||||
Q_ASSERT_X(!_isThreaded, "ScriptEngine::runInThread()", "runInThread should not be called more than once");
|
||||
|
||||
|
@ -260,6 +322,10 @@ void ScriptEngine::loadURL(const QUrl& scriptURL, bool reload) {
|
|||
// FIXME - switch this to the new model of ScriptCache callbacks
|
||||
void ScriptEngine::scriptContentsAvailable(const QUrl& url, const QString& scriptContents) {
|
||||
_scriptContents = scriptContents;
|
||||
static const QString DEBUG_FLAG("#debug");
|
||||
if (QRegularExpression(DEBUG_FLAG).match(scriptContents).hasMatch()) {
|
||||
_debuggable = true;
|
||||
}
|
||||
if (_wantSignals) {
|
||||
emit scriptLoaded(url.toString());
|
||||
}
|
||||
|
@ -723,7 +789,7 @@ void ScriptEngine::run() {
|
|||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
|
||||
qint64 lastUpdate = usecTimestampNow();
|
||||
_lastUpdate = usecTimestampNow();
|
||||
|
||||
// TODO: Integrate this with signals/slots instead of reimplementing throttling for ScriptEngine
|
||||
while (!_isFinished) {
|
||||
|
@ -771,15 +837,15 @@ void ScriptEngine::run() {
|
|||
qint64 now = usecTimestampNow();
|
||||
|
||||
// we check for 'now' in the past in case people set their clock back
|
||||
if (lastUpdate < now) {
|
||||
float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND;
|
||||
if (_lastUpdate < now) {
|
||||
float deltaTime = (float) (now - _lastUpdate) / (float) USECS_PER_SECOND;
|
||||
if (!_isFinished) {
|
||||
if (_wantSignals) {
|
||||
emit update(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastUpdate = now;
|
||||
_lastUpdate = now;
|
||||
|
||||
// Debug and clear exceptions
|
||||
hadUncaughtExceptions(*this, _fileNameString);
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QWaitCondition>
|
||||
#include <QtScript/QScriptEngine>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include <AnimationCache.h>
|
||||
#include <AnimVariant.h>
|
||||
#include <AvatarData.h>
|
||||
|
@ -39,6 +40,8 @@
|
|||
#include "ScriptUUID.h"
|
||||
#include "Vec3.h"
|
||||
|
||||
class QScriptEngineDebugger;
|
||||
|
||||
static const QString NO_SCRIPT("");
|
||||
|
||||
static const int SCRIPT_FPS = 60;
|
||||
|
@ -75,6 +78,8 @@ public:
|
|||
/// services before calling this.
|
||||
void runInThread();
|
||||
|
||||
void runDebuggable();
|
||||
|
||||
/// run the script in the callers thread, exit when stop() is called.
|
||||
void run();
|
||||
|
||||
|
@ -140,6 +145,8 @@ public:
|
|||
bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget
|
||||
bool isRunning() const { return _isRunning; } // used by ScriptWidget
|
||||
|
||||
bool isDebuggable() const { return _debuggable; }
|
||||
|
||||
void disconnectNonEssentialSignals();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -187,6 +194,9 @@ protected:
|
|||
bool _wantSignals { true };
|
||||
QHash<EntityItemID, EntityScriptDetails> _entityScripts;
|
||||
bool _isThreaded { false };
|
||||
QScriptEngineDebugger* _debugger { nullptr };
|
||||
bool _debuggable { false };
|
||||
qint64 _lastUpdate;
|
||||
|
||||
void init();
|
||||
QString getFilename() const;
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#include "ScriptEngines.h"
|
||||
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
#include <SettingHandle.h>
|
||||
#include <UserActivityLogger.h>
|
||||
|
@ -490,7 +491,12 @@ void ScriptEngines::launchScriptEngine(ScriptEngine* scriptEngine) {
|
|||
for (auto initializer : _scriptInitializers) {
|
||||
initializer(scriptEngine);
|
||||
}
|
||||
scriptEngine->runInThread();
|
||||
|
||||
if (scriptEngine->isDebuggable() || (qApp->queryKeyboardModifiers() & Qt::ShiftModifier)) {
|
||||
scriptEngine->runDebuggable();
|
||||
} else {
|
||||
scriptEngine->runInThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue