mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 14:29:03 +02:00
multiple scripts running at same time, menu interface for scripts
This commit is contained in:
parent
a220804fb0
commit
524a41468c
8 changed files with 106 additions and 40 deletions
|
@ -139,8 +139,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
_recentMaxPackets(0),
|
_recentMaxPackets(0),
|
||||||
_resetRecentMaxPacketsSoon(true),
|
_resetRecentMaxPacketsSoon(true),
|
||||||
_swatch(NULL),
|
_swatch(NULL),
|
||||||
_pasteMode(false),
|
_pasteMode(false)
|
||||||
_scriptEngine(NULL)
|
|
||||||
{
|
{
|
||||||
_applicationStartupTime = startup_time;
|
_applicationStartupTime = startup_time;
|
||||||
_window->setWindowTitle("Interface");
|
_window->setWindowTitle("Interface");
|
||||||
|
@ -259,7 +258,7 @@ Application::~Application() {
|
||||||
_sharedVoxelSystem.changeTree(new VoxelTree);
|
_sharedVoxelSystem.changeTree(new VoxelTree);
|
||||||
|
|
||||||
VoxelTreeElement::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown
|
VoxelTreeElement::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown
|
||||||
delete Menu::getInstance();
|
Menu::getInstance()->deleteLater();
|
||||||
|
|
||||||
delete _settings;
|
delete _settings;
|
||||||
delete _followMode;
|
delete _followMode;
|
||||||
|
@ -4388,12 +4387,6 @@ void Application::packetSentNotification(ssize_t length) {
|
||||||
|
|
||||||
void Application::loadScript() {
|
void Application::loadScript() {
|
||||||
// shut down and stop any existing script
|
// shut down and stop any existing script
|
||||||
if (_scriptEngine) {
|
|
||||||
_scriptEngine->stop();
|
|
||||||
_scriptEngine = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||||
QString suggestedName = desktopLocation.append("/script.js");
|
QString suggestedName = desktopLocation.append("/script.js");
|
||||||
|
|
||||||
|
@ -4425,32 +4418,30 @@ void Application::loadScript() {
|
||||||
delete[] entireFile;
|
delete[] entireFile;
|
||||||
|
|
||||||
// start the script on a new thread...
|
// start the script on a new thread...
|
||||||
_scriptEngine = new ScriptEngine(script);
|
bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself
|
||||||
|
ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance());
|
||||||
|
|
||||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||||
// we can use the same ones from the application.
|
// we can use the same ones from the application.
|
||||||
_scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender);
|
scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender);
|
||||||
_scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender);
|
scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||||
|
|
||||||
//_scriptEngine->getVoxelScriptingInterface()->setJurisdictionListener();
|
|
||||||
//_scriptEngine->getParticleScriptingInterface()->setJurisdictionListener();
|
|
||||||
|
|
||||||
QThread* workerThread = new QThread(this);
|
QThread* workerThread = new QThread(this);
|
||||||
|
|
||||||
// when the worker thread is started, call our engine's run..
|
// when the worker thread is started, call our engine's run..
|
||||||
connect(workerThread, SIGNAL(started()), _scriptEngine, SLOT(run()));
|
connect(workerThread, SIGNAL(started()), scriptEngine, SLOT(run()));
|
||||||
|
|
||||||
// when the engine emits finished, call our threads quit
|
// when the engine emits finished, call our threads quit
|
||||||
connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit()));
|
connect(scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit()));
|
||||||
|
|
||||||
// when the thread is terminated, add both _scriptEngine and thread to the deleteLater queue
|
// when the thread is terminated, add both scriptEngine and thread to the deleteLater queue
|
||||||
connect(workerThread, SIGNAL(terminated()), _scriptEngine, SLOT(deleteLater()));
|
connect(workerThread, SIGNAL(terminated()), scriptEngine, SLOT(deleteLater()));
|
||||||
connect(workerThread, SIGNAL(terminated()), workerThread, SLOT(deleteLater()));
|
connect(workerThread, SIGNAL(terminated()), workerThread, SLOT(deleteLater()));
|
||||||
|
|
||||||
// when the application is about to quit, stop our script engine so it unwinds properly
|
// when the application is about to quit, stop our script engine so it unwinds properly
|
||||||
connect(this, SIGNAL(aboutToQuit()), _scriptEngine, SLOT(stop()));
|
connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop()));
|
||||||
|
|
||||||
_scriptEngine->moveToThread(workerThread);
|
scriptEngine->moveToThread(workerThread);
|
||||||
|
|
||||||
// Starts an event loop, and emits workerThread->started()
|
// Starts an event loop, and emits workerThread->started()
|
||||||
workerThread->start();
|
workerThread->start();
|
||||||
|
|
|
@ -497,8 +497,6 @@ private:
|
||||||
|
|
||||||
std::vector<VoxelFade> _voxelFades;
|
std::vector<VoxelFade> _voxelFades;
|
||||||
std::vector<Avatar*> _avatarFades;
|
std::vector<Avatar*> _avatarFades;
|
||||||
|
|
||||||
ScriptEngine* _scriptEngine;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__Application__) */
|
#endif /* defined(__interface__Application__) */
|
||||||
|
|
|
@ -92,6 +92,7 @@ Menu::Menu() :
|
||||||
|
|
||||||
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
||||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadScript()));
|
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadScript()));
|
||||||
|
_activeScriptsMenu = fileMenu->addMenu("Running Scripts");
|
||||||
|
|
||||||
addDisabledActionAndSeparator(fileMenu, "Voxels");
|
addDisabledActionAndSeparator(fileMenu, "Voxels");
|
||||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));
|
addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));
|
||||||
|
@ -709,6 +710,13 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::removeAction(QMenu* menu, const QString& actionName) {
|
||||||
|
qDebug() << "removeAction() menu=" << menu << " actionName=" << actionName << "\n";
|
||||||
|
|
||||||
|
menu->removeAction(_actionHash.value(actionName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Menu::isOptionChecked(const QString& menuOption) {
|
bool Menu::isOptionChecked(const QString& menuOption) {
|
||||||
return _actionHash.value(menuOption)->isChecked();
|
return _actionHash.value(menuOption)->isChecked();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
|
|
||||||
|
#include <AbstractMenuInterface.h>
|
||||||
|
|
||||||
enum FrustumDrawMode {
|
enum FrustumDrawMode {
|
||||||
FRUSTUM_DRAW_MODE_ALL,
|
FRUSTUM_DRAW_MODE_ALL,
|
||||||
FRUSTUM_DRAW_MODE_VECTORS,
|
FRUSTUM_DRAW_MODE_VECTORS,
|
||||||
|
@ -37,7 +39,7 @@ class BandwidthDialog;
|
||||||
class VoxelStatsDialog;
|
class VoxelStatsDialog;
|
||||||
class LodToolsDialog;
|
class LodToolsDialog;
|
||||||
|
|
||||||
class Menu : public QMenuBar {
|
class Menu : public QMenuBar, public AbstractMenuInterface {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static Menu* getInstance();
|
static Menu* getInstance();
|
||||||
|
@ -71,6 +73,15 @@ public:
|
||||||
// User Tweakable PPS from Voxel Server
|
// User Tweakable PPS from Voxel Server
|
||||||
int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; }
|
int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; }
|
||||||
|
|
||||||
|
virtual QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;}
|
||||||
|
virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||||
|
const QString actionName,
|
||||||
|
const QKeySequence& shortcut = 0,
|
||||||
|
const QObject* receiver = NULL,
|
||||||
|
const char* member = NULL,
|
||||||
|
QAction::MenuRole role = QAction::NoRole);
|
||||||
|
virtual void removeAction(QMenu* menu, const QString& actionName);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void bandwidthDetails();
|
void bandwidthDetails();
|
||||||
void voxelStatsDetails();
|
void voxelStatsDetails();
|
||||||
|
@ -110,12 +121,6 @@ private:
|
||||||
|
|
||||||
/// helper method to have separators with labels that are also compatible with OS X
|
/// helper method to have separators with labels that are also compatible with OS X
|
||||||
void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName);
|
void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName);
|
||||||
QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
|
||||||
const QString actionName,
|
|
||||||
const QKeySequence& shortcut = 0,
|
|
||||||
const QObject* receiver = NULL,
|
|
||||||
const char* member = NULL,
|
|
||||||
QAction::MenuRole role = QAction::NoRole);
|
|
||||||
|
|
||||||
QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
|
QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||||
const QString actionName,
|
const QString actionName,
|
||||||
|
@ -141,6 +146,8 @@ private:
|
||||||
int _boundaryLevelAdjust;
|
int _boundaryLevelAdjust;
|
||||||
QAction* _useVoxelShader;
|
QAction* _useVoxelShader;
|
||||||
int _maxVoxelPacketsPerSecond;
|
int _maxVoxelPacketsPerSecond;
|
||||||
|
|
||||||
|
QMenu* _activeScriptsMenu;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MenuOption {
|
namespace MenuOption {
|
||||||
|
|
|
@ -416,7 +416,7 @@ void Particle::update() {
|
||||||
void Particle::runScript() {
|
void Particle::runScript() {
|
||||||
if (!_updateScript.isEmpty()) {
|
if (!_updateScript.isEmpty()) {
|
||||||
|
|
||||||
qDebug() << "Script: " << _updateScript << "\n";
|
//qDebug() << "Script: " << _updateScript << "\n";
|
||||||
|
|
||||||
QScriptEngine engine;
|
QScriptEngine engine;
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,40 @@
|
||||||
|
|
||||||
#include "ScriptEngine.h"
|
#include "ScriptEngine.h"
|
||||||
|
|
||||||
ScriptEngine::ScriptEngine(QString scriptContents) {
|
int ScriptEngine::_scriptNumber = 1;
|
||||||
|
|
||||||
|
ScriptEngine::ScriptEngine(QString scriptContents, bool wantMenuItems,
|
||||||
|
const char* scriptMenuName, AbstractMenuInterface* menu) {
|
||||||
_scriptContents = scriptContents;
|
_scriptContents = scriptContents;
|
||||||
_isFinished = false;
|
_isFinished = false;
|
||||||
|
_wantMenuItems = wantMenuItems;
|
||||||
|
if (scriptMenuName) {
|
||||||
|
_scriptMenuName = "Stop ";
|
||||||
|
_scriptMenuName.append(scriptMenuName);
|
||||||
|
} else {
|
||||||
|
_scriptMenuName = "Stop Script ";
|
||||||
|
_scriptNumber++;
|
||||||
|
_scriptMenuName.append(_scriptNumber);
|
||||||
|
}
|
||||||
|
_menu = menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::setupMenuItems() {
|
||||||
|
if (_menu && _wantMenuItems) {
|
||||||
|
_menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::cleanMenuItems() {
|
||||||
|
if (_menu && _wantMenuItems) {
|
||||||
|
_menu->removeAction(_menu->getActiveScriptsMenu(), _scriptMenuName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::run() {
|
void ScriptEngine::run() {
|
||||||
|
|
||||||
|
setupMenuItems();
|
||||||
|
|
||||||
QScriptEngine engine;
|
QScriptEngine engine;
|
||||||
|
|
||||||
_voxelScriptingInterface.init();
|
_voxelScriptingInterface.init();
|
||||||
|
@ -68,12 +96,7 @@ void ScriptEngine::run() {
|
||||||
|
|
||||||
int thisFrame = 0;
|
int thisFrame = 0;
|
||||||
|
|
||||||
qDebug() << "before while... thisFrame:" << thisFrame << "\n";
|
|
||||||
|
|
||||||
while (!_isFinished) {
|
while (!_isFinished) {
|
||||||
|
|
||||||
qDebug() << "while... thisFrame:" << thisFrame << "\n";
|
|
||||||
|
|
||||||
int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow();
|
int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow();
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep > 0) {
|
||||||
usleep(usecToSleep);
|
usleep(usecToSleep);
|
||||||
|
@ -105,7 +128,6 @@ void ScriptEngine::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (willSendVisualDataCallBack) {
|
if (willSendVisualDataCallBack) {
|
||||||
qDebug() << "willSendVisualDataCallback thisFrame:" << thisFrame << "\n";
|
|
||||||
emit willSendVisualDataCallback();
|
emit willSendVisualDataCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,5 +137,6 @@ void ScriptEngine::run() {
|
||||||
qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n";
|
qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cleanMenuItems();
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,15 @@
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
|
|
||||||
#include <VoxelScriptingInterface.h>
|
#include <AbstractMenuInterface.h>
|
||||||
#include <ParticleScriptingInterface.h>
|
#include <ParticleScriptingInterface.h>
|
||||||
|
#include <VoxelScriptingInterface.h>
|
||||||
|
|
||||||
class ScriptEngine : public QObject {
|
class ScriptEngine : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ScriptEngine(QString scriptContents);
|
ScriptEngine(QString scriptContents, bool wantMenuItems = false,
|
||||||
|
const char* scriptMenuName = NULL, AbstractMenuInterface* menu = NULL);
|
||||||
|
|
||||||
/// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
/// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
||||||
VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; }
|
VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; }
|
||||||
|
@ -42,9 +44,17 @@ signals:
|
||||||
protected:
|
protected:
|
||||||
QString _scriptContents;
|
QString _scriptContents;
|
||||||
bool _isFinished;
|
bool _isFinished;
|
||||||
|
|
||||||
|
void setupMenuItems();
|
||||||
|
void cleanMenuItems();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VoxelScriptingInterface _voxelScriptingInterface;
|
VoxelScriptingInterface _voxelScriptingInterface;
|
||||||
ParticleScriptingInterface _particleScriptingInterface;
|
ParticleScriptingInterface _particleScriptingInterface;
|
||||||
|
bool _wantMenuItems;
|
||||||
|
QString _scriptMenuName;
|
||||||
|
AbstractMenuInterface* _menu;
|
||||||
|
static int _scriptNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__ScriptEngine__) */
|
#endif /* defined(__hifi__ScriptEngine__) */
|
||||||
|
|
29
libraries/shared/src/AbstractMenuInterface.h
Normal file
29
libraries/shared/src/AbstractMenuInterface.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// AbstractMenuInterface.h
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 12/16/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __hifi__AbstractMenuInterface__
|
||||||
|
#define __hifi__AbstractMenuInterface__
|
||||||
|
|
||||||
|
#include <QMenuBar>
|
||||||
|
//#include <QHash>
|
||||||
|
//#include <QKeySequence>
|
||||||
|
|
||||||
|
class AbstractMenuInterface {
|
||||||
|
public:
|
||||||
|
virtual QMenu* getActiveScriptsMenu() = 0;
|
||||||
|
virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||||
|
const QString actionName,
|
||||||
|
const QKeySequence& shortcut = 0,
|
||||||
|
const QObject* receiver = NULL,
|
||||||
|
const char* member = NULL,
|
||||||
|
QAction::MenuRole role = QAction::NoRole) = 0;
|
||||||
|
virtual void removeAction(QMenu* menu, const QString& actionName) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__hifi__AbstractMenuInterface__) */
|
Loading…
Reference in a new issue