mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 18:44:00 +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),
|
||||
_resetRecentMaxPacketsSoon(true),
|
||||
_swatch(NULL),
|
||||
_pasteMode(false),
|
||||
_scriptEngine(NULL)
|
||||
_pasteMode(false)
|
||||
{
|
||||
_applicationStartupTime = startup_time;
|
||||
_window->setWindowTitle("Interface");
|
||||
|
@ -259,7 +258,7 @@ Application::~Application() {
|
|||
_sharedVoxelSystem.changeTree(new VoxelTree);
|
||||
|
||||
VoxelTreeElement::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown
|
||||
delete Menu::getInstance();
|
||||
Menu::getInstance()->deleteLater();
|
||||
|
||||
delete _settings;
|
||||
delete _followMode;
|
||||
|
@ -4388,12 +4387,6 @@ void Application::packetSentNotification(ssize_t length) {
|
|||
|
||||
void Application::loadScript() {
|
||||
// shut down and stop any existing script
|
||||
if (_scriptEngine) {
|
||||
_scriptEngine->stop();
|
||||
_scriptEngine = NULL;
|
||||
}
|
||||
|
||||
|
||||
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
QString suggestedName = desktopLocation.append("/script.js");
|
||||
|
||||
|
@ -4425,32 +4418,30 @@ void Application::loadScript() {
|
|||
delete[] entireFile;
|
||||
|
||||
// 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
|
||||
// we can use the same ones from the application.
|
||||
_scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender);
|
||||
_scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||
scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender);
|
||||
scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||
|
||||
//_scriptEngine->getVoxelScriptingInterface()->setJurisdictionListener();
|
||||
//_scriptEngine->getParticleScriptingInterface()->setJurisdictionListener();
|
||||
|
||||
QThread* workerThread = new QThread(this);
|
||||
|
||||
// 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
|
||||
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
|
||||
connect(workerThread, SIGNAL(terminated()), _scriptEngine, SLOT(deleteLater()));
|
||||
// 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()), workerThread, SLOT(deleteLater()));
|
||||
|
||||
// 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()
|
||||
workerThread->start();
|
||||
|
|
|
@ -497,8 +497,6 @@ private:
|
|||
|
||||
std::vector<VoxelFade> _voxelFades;
|
||||
std::vector<Avatar*> _avatarFades;
|
||||
|
||||
ScriptEngine* _scriptEngine;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__Application__) */
|
||||
|
|
|
@ -92,6 +92,7 @@ Menu::Menu() :
|
|||
|
||||
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadScript()));
|
||||
_activeScriptsMenu = fileMenu->addMenu("Running Scripts");
|
||||
|
||||
addDisabledActionAndSeparator(fileMenu, "Voxels");
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));
|
||||
|
@ -709,6 +710,13 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
|
|||
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) {
|
||||
return _actionHash.value(menuOption)->isChecked();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <QHash>
|
||||
#include <QKeySequence>
|
||||
|
||||
#include <AbstractMenuInterface.h>
|
||||
|
||||
enum FrustumDrawMode {
|
||||
FRUSTUM_DRAW_MODE_ALL,
|
||||
FRUSTUM_DRAW_MODE_VECTORS,
|
||||
|
@ -37,7 +39,7 @@ class BandwidthDialog;
|
|||
class VoxelStatsDialog;
|
||||
class LodToolsDialog;
|
||||
|
||||
class Menu : public QMenuBar {
|
||||
class Menu : public QMenuBar, public AbstractMenuInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static Menu* getInstance();
|
||||
|
@ -71,6 +73,15 @@ public:
|
|||
// User Tweakable PPS from Voxel Server
|
||||
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:
|
||||
void bandwidthDetails();
|
||||
void voxelStatsDetails();
|
||||
|
@ -110,12 +121,6 @@ private:
|
|||
|
||||
/// helper method to have separators with labels that are also compatible with OS X
|
||||
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,
|
||||
const QString actionName,
|
||||
|
@ -141,6 +146,8 @@ private:
|
|||
int _boundaryLevelAdjust;
|
||||
QAction* _useVoxelShader;
|
||||
int _maxVoxelPacketsPerSecond;
|
||||
|
||||
QMenu* _activeScriptsMenu;
|
||||
};
|
||||
|
||||
namespace MenuOption {
|
||||
|
|
|
@ -416,7 +416,7 @@ void Particle::update() {
|
|||
void Particle::runScript() {
|
||||
if (!_updateScript.isEmpty()) {
|
||||
|
||||
qDebug() << "Script: " << _updateScript << "\n";
|
||||
//qDebug() << "Script: " << _updateScript << "\n";
|
||||
|
||||
QScriptEngine engine;
|
||||
|
||||
|
|
|
@ -21,12 +21,40 @@
|
|||
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
ScriptEngine::ScriptEngine(QString scriptContents) {
|
||||
int ScriptEngine::_scriptNumber = 1;
|
||||
|
||||
ScriptEngine::ScriptEngine(QString scriptContents, bool wantMenuItems,
|
||||
const char* scriptMenuName, AbstractMenuInterface* menu) {
|
||||
_scriptContents = scriptContents;
|
||||
_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() {
|
||||
|
||||
setupMenuItems();
|
||||
|
||||
QScriptEngine engine;
|
||||
|
||||
_voxelScriptingInterface.init();
|
||||
|
@ -68,12 +96,7 @@ void ScriptEngine::run() {
|
|||
|
||||
int thisFrame = 0;
|
||||
|
||||
qDebug() << "before while... thisFrame:" << thisFrame << "\n";
|
||||
|
||||
while (!_isFinished) {
|
||||
|
||||
qDebug() << "while... thisFrame:" << thisFrame << "\n";
|
||||
|
||||
int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow();
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
|
@ -105,7 +128,6 @@ void ScriptEngine::run() {
|
|||
}
|
||||
|
||||
if (willSendVisualDataCallBack) {
|
||||
qDebug() << "willSendVisualDataCallback thisFrame:" << thisFrame << "\n";
|
||||
emit willSendVisualDataCallback();
|
||||
}
|
||||
|
||||
|
@ -115,5 +137,6 @@ void ScriptEngine::run() {
|
|||
qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n";
|
||||
}
|
||||
}
|
||||
cleanMenuItems();
|
||||
emit finished();
|
||||
}
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
#include <VoxelScriptingInterface.h>
|
||||
#include <AbstractMenuInterface.h>
|
||||
#include <ParticleScriptingInterface.h>
|
||||
#include <VoxelScriptingInterface.h>
|
||||
|
||||
class ScriptEngine : public QObject {
|
||||
Q_OBJECT
|
||||
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
|
||||
VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; }
|
||||
|
@ -42,9 +44,17 @@ signals:
|
|||
protected:
|
||||
QString _scriptContents;
|
||||
bool _isFinished;
|
||||
|
||||
void setupMenuItems();
|
||||
void cleanMenuItems();
|
||||
|
||||
private:
|
||||
VoxelScriptingInterface _voxelScriptingInterface;
|
||||
ParticleScriptingInterface _particleScriptingInterface;
|
||||
bool _wantMenuItems;
|
||||
QString _scriptMenuName;
|
||||
AbstractMenuInterface* _menu;
|
||||
static int _scriptNumber;
|
||||
};
|
||||
|
||||
#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