mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 04:37:23 +02:00
Merge branch 'master' of ssh://github.com/highfidelity/hifi into cleanup
Conflicts: interface/src/Application.cpp
This commit is contained in:
commit
cb186b10db
8 changed files with 199 additions and 93 deletions
8
examples/timer.js
Normal file
8
examples/timer.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
var one_timer = Script.setTimeout(function() { print("One time timer fired!"); }, 10000);
|
||||||
|
var multiple_timer = Script.setInterval(function() { print("Repeating timer fired!"); }, 1000);
|
||||||
|
|
||||||
|
// this would stop a scheduled single shot timer
|
||||||
|
Script.clearTimeout(one_timer);
|
||||||
|
|
||||||
|
// this stops the repeating timer
|
||||||
|
Script.clearInterval(multiple_timer);
|
|
@ -17,6 +17,7 @@ class AbstractLoggerInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
AbstractLoggerInterface(QObject* parent = NULL) : QObject(parent) {};
|
||||||
inline bool extraDebugging() { return _extraDebugging; };
|
inline bool extraDebugging() { return _extraDebugging; };
|
||||||
inline void setExtraDebugging(bool debugging) { _extraDebugging = debugging; };
|
inline void setExtraDebugging(bool debugging) { _extraDebugging = debugging; };
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
_resetRecentMaxPacketsSoon(true),
|
_resetRecentMaxPacketsSoon(true),
|
||||||
_swatch(NULL),
|
_swatch(NULL),
|
||||||
_pasteMode(false),
|
_pasteMode(false),
|
||||||
_logger(new FileLogger()),
|
_logger(new FileLogger(this)),
|
||||||
_persistThread(NULL)
|
_persistThread(NULL)
|
||||||
{
|
{
|
||||||
_myAvatar = _avatarManager.getMyAvatar();
|
_myAvatar = _avatarManager.getMyAvatar();
|
||||||
|
@ -329,8 +329,6 @@ Application::~Application() {
|
||||||
|
|
||||||
_myAvatar = NULL;
|
_myAvatar = NULL;
|
||||||
|
|
||||||
delete _logger;
|
|
||||||
delete _settings;
|
|
||||||
delete _glWidget;
|
delete _glWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4038,33 +4036,33 @@ void Application::packetSent(quint64 length) {
|
||||||
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(length);
|
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::loadScripts(){
|
void Application::loadScripts() {
|
||||||
// loads all saved scripts
|
// loads all saved scripts
|
||||||
QSettings* settings = new QSettings(this);
|
QSettings* settings = new QSettings(this);
|
||||||
int size = settings->beginReadArray("Settings");
|
int size = settings->beginReadArray("Settings");
|
||||||
for(int i=0; i<size; ++i){
|
|
||||||
|
for (int i = 0; i < size; ++i){
|
||||||
settings->setArrayIndex(i);
|
settings->setArrayIndex(i);
|
||||||
QString string = settings->value("script").toString();
|
QString string = settings->value("script").toString();
|
||||||
loadScript(string);
|
loadScript(string);
|
||||||
}
|
}
|
||||||
settings->endArray();
|
|
||||||
|
|
||||||
|
settings->endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::saveScripts(){
|
void Application::saveScripts() {
|
||||||
// saves all current running scripts
|
// saves all current running scripts
|
||||||
QSettings* settings = new QSettings(this);
|
QSettings* settings = new QSettings(this);
|
||||||
settings->beginWriteArray("Settings");
|
settings->beginWriteArray("Settings");
|
||||||
for(int i=0; i<_activeScripts.size(); ++i){
|
for (int i = 0; i < _activeScripts.size(); ++i){
|
||||||
settings->setArrayIndex(i);
|
settings->setArrayIndex(i);
|
||||||
settings->setValue("script", _activeScripts.at(i));
|
settings->setValue("script", _activeScripts.at(i));
|
||||||
}
|
}
|
||||||
settings->endArray();
|
|
||||||
|
|
||||||
|
settings->endArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::removeScriptName(const QString& fileNameString)
|
void Application::removeScriptName(const QString& fileNameString) {
|
||||||
{
|
|
||||||
_activeScripts.removeOne(fileNameString);
|
_activeScripts.removeOne(fileNameString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4096,7 +4094,8 @@ void Application::loadScript(const QString& fileNameString) {
|
||||||
// start the script on a new thread...
|
// start the script on a new thread...
|
||||||
bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself
|
bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself
|
||||||
|
|
||||||
ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance(), &_controllerScriptingInterface);
|
ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance(),
|
||||||
|
&_controllerScriptingInterface);
|
||||||
scriptEngine->setupMenuItems();
|
scriptEngine->setupMenuItems();
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -18,7 +18,10 @@ const QString FILENAME_FORMAT = "hifi-log_%1_%2.txt";
|
||||||
const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss";
|
const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss";
|
||||||
const QString LOGS_DIRECTORY = "Logs";
|
const QString LOGS_DIRECTORY = "Logs";
|
||||||
|
|
||||||
FileLogger::FileLogger() : _logData(NULL) {
|
FileLogger::FileLogger(QObject* parent) :
|
||||||
|
AbstractLoggerInterface(parent),
|
||||||
|
_logData(NULL)
|
||||||
|
{
|
||||||
setExtraDebugging(false);
|
setExtraDebugging(false);
|
||||||
|
|
||||||
_fileName = FileUtils::standardPath(LOGS_DIRECTORY);
|
_fileName = FileUtils::standardPath(LOGS_DIRECTORY);
|
||||||
|
|
|
@ -16,7 +16,7 @@ class FileLogger : public AbstractLoggerInterface {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FileLogger();
|
FileLogger(QObject* parent = NULL);
|
||||||
|
|
||||||
virtual void addMessage(QString);
|
virtual void addMessage(QString);
|
||||||
virtual QStringList getLogData() { return _logData; };
|
virtual QStringList getLogData() { return _logData; };
|
||||||
|
|
|
@ -738,6 +738,22 @@ ExtractedMesh extractMesh(const FBXNode& object) {
|
||||||
return data.extracted;
|
return data.extracted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FBXBlendshape extractBlendshape(const FBXNode& object) {
|
||||||
|
FBXBlendshape blendshape;
|
||||||
|
foreach (const FBXNode& data, object.children) {
|
||||||
|
if (data.name == "Indexes") {
|
||||||
|
blendshape.indices = getIntVector(data.properties, 0);
|
||||||
|
|
||||||
|
} else if (data.name == "Vertices") {
|
||||||
|
blendshape.vertices = createVec3Vector(getDoubleVector(data.properties, 0));
|
||||||
|
|
||||||
|
} else if (data.name == "Normals") {
|
||||||
|
blendshape.normals = createVec3Vector(getDoubleVector(data.properties, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blendshape;
|
||||||
|
}
|
||||||
|
|
||||||
void setTangents(FBXMesh& mesh, int firstIndex, int secondIndex) {
|
void setTangents(FBXMesh& mesh, int firstIndex, int secondIndex) {
|
||||||
glm::vec3 normal = glm::normalize(mesh.normals.at(firstIndex));
|
glm::vec3 normal = glm::normalize(mesh.normals.at(firstIndex));
|
||||||
glm::vec3 bitangent = glm::cross(normal, mesh.vertices.at(secondIndex) - mesh.vertices.at(firstIndex));
|
glm::vec3 bitangent = glm::cross(normal, mesh.vertices.at(secondIndex) - mesh.vertices.at(firstIndex));
|
||||||
|
@ -760,6 +776,49 @@ QVector<int> getIndices(const QVector<QString> ids, QVector<QString> modelIDs) {
|
||||||
return indices;
|
return indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef QPair<int, float> WeightedIndex;
|
||||||
|
|
||||||
|
void addBlendshapes(const ExtractedBlendshape& extracted, const QList<WeightedIndex>& indices, ExtractedMesh& extractedMesh) {
|
||||||
|
foreach (const WeightedIndex& index, indices) {
|
||||||
|
extractedMesh.mesh.blendshapes.resize(max(extractedMesh.mesh.blendshapes.size(), index.first + 1));
|
||||||
|
extractedMesh.blendshapeIndexMaps.resize(extractedMesh.mesh.blendshapes.size());
|
||||||
|
FBXBlendshape& blendshape = extractedMesh.mesh.blendshapes[index.first];
|
||||||
|
QHash<int, int>& blendshapeIndexMap = extractedMesh.blendshapeIndexMaps[index.first];
|
||||||
|
for (int i = 0; i < extracted.blendshape.indices.size(); i++) {
|
||||||
|
int oldIndex = extracted.blendshape.indices.at(i);
|
||||||
|
for (QMultiHash<int, int>::const_iterator it = extractedMesh.newIndices.constFind(oldIndex);
|
||||||
|
it != extractedMesh.newIndices.constEnd() && it.key() == oldIndex; it++) {
|
||||||
|
QHash<int, int>::iterator blendshapeIndex = blendshapeIndexMap.find(it.value());
|
||||||
|
if (blendshapeIndex == blendshapeIndexMap.end()) {
|
||||||
|
blendshapeIndexMap.insert(it.value(), blendshape.indices.size());
|
||||||
|
blendshape.indices.append(it.value());
|
||||||
|
blendshape.vertices.append(extracted.blendshape.vertices.at(i) * index.second);
|
||||||
|
blendshape.normals.append(extracted.blendshape.normals.at(i) * index.second);
|
||||||
|
} else {
|
||||||
|
blendshape.vertices[*blendshapeIndex] += extracted.blendshape.vertices.at(i) * index.second;
|
||||||
|
blendshape.normals[*blendshapeIndex] += extracted.blendshape.normals.at(i) * index.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getTopModelID(const QMultiHash<QString, QString>& parentMap,
|
||||||
|
const QHash<QString, FBXModel>& models, const QString& modelID) {
|
||||||
|
QString topID = modelID;
|
||||||
|
forever {
|
||||||
|
foreach (const QString& parentID, parentMap.values(topID)) {
|
||||||
|
if (models.contains(parentID)) {
|
||||||
|
topID = parentID;
|
||||||
|
goto outerContinue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return topID;
|
||||||
|
|
||||||
|
outerContinue: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
||||||
QHash<QString, ExtractedMesh> meshes;
|
QHash<QString, ExtractedMesh> meshes;
|
||||||
QVector<ExtractedBlendshape> blendshapes;
|
QVector<ExtractedBlendshape> blendshapes;
|
||||||
|
@ -799,7 +858,6 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
QVector<QString> jointRightFingertipIDs(jointRightFingertipNames.size());
|
QVector<QString> jointRightFingertipIDs(jointRightFingertipNames.size());
|
||||||
|
|
||||||
QVariantHash blendshapeMappings = mapping.value("bs").toHash();
|
QVariantHash blendshapeMappings = mapping.value("bs").toHash();
|
||||||
typedef QPair<int, float> WeightedIndex;
|
|
||||||
QMultiHash<QByteArray, WeightedIndex> blendshapeIndices;
|
QMultiHash<QByteArray, WeightedIndex> blendshapeIndices;
|
||||||
for (int i = 0;; i++) {
|
for (int i = 0;; i++) {
|
||||||
QByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i];
|
QByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i];
|
||||||
|
@ -827,22 +885,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
meshes.insert(getID(object.properties), extractMesh(object));
|
meshes.insert(getID(object.properties), extractMesh(object));
|
||||||
|
|
||||||
} else { // object.properties.at(2) == "Shape"
|
} else { // object.properties.at(2) == "Shape"
|
||||||
ExtractedBlendshape extracted = { getID(object.properties) };
|
ExtractedBlendshape extracted = { getID(object.properties), extractBlendshape(object) };
|
||||||
|
|
||||||
foreach (const FBXNode& data, object.children) {
|
|
||||||
if (data.name == "Indexes") {
|
|
||||||
extracted.blendshape.indices = getIntVector(data.properties, 0);
|
|
||||||
|
|
||||||
} else if (data.name == "Vertices") {
|
|
||||||
extracted.blendshape.vertices = createVec3Vector(
|
|
||||||
getDoubleVector(data.properties, 0));
|
|
||||||
|
|
||||||
} else if (data.name == "Normals") {
|
|
||||||
extracted.blendshape.normals = createVec3Vector(
|
|
||||||
getDoubleVector(data.properties, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blendshapes.append(extracted);
|
blendshapes.append(extracted);
|
||||||
}
|
}
|
||||||
} else if (object.name == "Model") {
|
} else if (object.name == "Model") {
|
||||||
|
@ -900,6 +943,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
bool rotationMaxX = false, rotationMaxY = false, rotationMaxZ = false;
|
bool rotationMaxX = false, rotationMaxY = false, rotationMaxZ = false;
|
||||||
glm::vec3 rotationMin, rotationMax;
|
glm::vec3 rotationMin, rotationMax;
|
||||||
FBXModel model = { name, -1 };
|
FBXModel model = { name, -1 };
|
||||||
|
ExtractedMesh* mesh = NULL;
|
||||||
|
QVector<ExtractedBlendshape> blendshapes;
|
||||||
foreach (const FBXNode& subobject, object.children) {
|
foreach (const FBXNode& subobject, object.children) {
|
||||||
bool properties = false;
|
bool properties = false;
|
||||||
QByteArray propertyName;
|
QByteArray propertyName;
|
||||||
|
@ -969,9 +1014,23 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
}
|
}
|
||||||
} else if (subobject.name == "Vertices") {
|
} else if (subobject.name == "Vertices") {
|
||||||
// it's a mesh as well as a model
|
// it's a mesh as well as a model
|
||||||
meshes.insert(getID(object.properties), extractMesh(object));
|
mesh = &meshes[getID(object.properties)];
|
||||||
|
*mesh = extractMesh(object);
|
||||||
|
|
||||||
|
} else if (subobject.name == "Shape") {
|
||||||
|
ExtractedBlendshape blendshape = { subobject.properties.at(0).toString(),
|
||||||
|
extractBlendshape(subobject) };
|
||||||
|
blendshapes.append(blendshape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the blendshapes included in the model, if any
|
||||||
|
if (mesh) {
|
||||||
|
foreach (const ExtractedBlendshape& extracted, blendshapes) {
|
||||||
|
addBlendshapes(extracted, blendshapeIndices.values(extracted.id.toLatin1()), *mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html
|
// see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html
|
||||||
model.translation = translation;
|
model.translation = translation;
|
||||||
model.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot);
|
model.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot);
|
||||||
|
@ -1084,29 +1143,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
QString blendshapeChannelID = parentMap.value(extracted.id);
|
QString blendshapeChannelID = parentMap.value(extracted.id);
|
||||||
QString blendshapeID = parentMap.value(blendshapeChannelID);
|
QString blendshapeID = parentMap.value(blendshapeChannelID);
|
||||||
QString meshID = parentMap.value(blendshapeID);
|
QString meshID = parentMap.value(blendshapeID);
|
||||||
ExtractedMesh& extractedMesh = meshes[meshID];
|
addBlendshapes(extracted, blendshapeChannelIndices.values(blendshapeChannelID), meshes[meshID]);
|
||||||
foreach (const WeightedIndex& index, blendshapeChannelIndices.values(blendshapeChannelID)) {
|
|
||||||
extractedMesh.mesh.blendshapes.resize(max(extractedMesh.mesh.blendshapes.size(), index.first + 1));
|
|
||||||
extractedMesh.blendshapeIndexMaps.resize(extractedMesh.mesh.blendshapes.size());
|
|
||||||
FBXBlendshape& blendshape = extractedMesh.mesh.blendshapes[index.first];
|
|
||||||
QHash<int, int>& blendshapeIndexMap = extractedMesh.blendshapeIndexMaps[index.first];
|
|
||||||
for (int i = 0; i < extracted.blendshape.indices.size(); i++) {
|
|
||||||
int oldIndex = extracted.blendshape.indices.at(i);
|
|
||||||
for (QMultiHash<int, int>::const_iterator it = extractedMesh.newIndices.constFind(oldIndex);
|
|
||||||
it != extractedMesh.newIndices.constEnd() && it.key() == oldIndex; it++) {
|
|
||||||
QHash<int, int>::iterator blendshapeIndex = blendshapeIndexMap.find(it.value());
|
|
||||||
if (blendshapeIndex == blendshapeIndexMap.end()) {
|
|
||||||
blendshapeIndexMap.insert(it.value(), blendshape.indices.size());
|
|
||||||
blendshape.indices.append(it.value());
|
|
||||||
blendshape.vertices.append(extracted.blendshape.vertices.at(i) * index.second);
|
|
||||||
blendshape.normals.append(extracted.blendshape.normals.at(i) * index.second);
|
|
||||||
} else {
|
|
||||||
blendshape.vertices[*blendshapeIndex] += extracted.blendshape.vertices.at(i) * index.second;
|
|
||||||
blendshape.normals[*blendshapeIndex] += extracted.blendshape.normals.at(i) * index.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get offset transform from mapping
|
// get offset transform from mapping
|
||||||
|
@ -1121,6 +1158,20 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
QVector<QString> modelIDs;
|
QVector<QString> modelIDs;
|
||||||
QSet<QString> remainingModels;
|
QSet<QString> remainingModels;
|
||||||
for (QHash<QString, FBXModel>::const_iterator model = models.constBegin(); model != models.constEnd(); model++) {
|
for (QHash<QString, FBXModel>::const_iterator model = models.constBegin(); model != models.constEnd(); model++) {
|
||||||
|
// models with clusters must be parented to the cluster top
|
||||||
|
foreach (const QString& deformerID, childMap.values(model.key())) {
|
||||||
|
foreach (const QString& clusterID, childMap.values(deformerID)) {
|
||||||
|
if (!clusters.contains(clusterID)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QString topID = getTopModelID(parentMap, models, childMap.value(clusterID));
|
||||||
|
childMap.remove(parentMap.take(model.key()), model.key());
|
||||||
|
parentMap.insert(model.key(), topID);
|
||||||
|
goto outerBreak;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outerBreak:
|
||||||
|
|
||||||
// make sure the parent is in the child map
|
// make sure the parent is in the child map
|
||||||
QString parent = parentMap.value(model.key());
|
QString parent = parentMap.value(model.key());
|
||||||
if (!childMap.contains(parent, model.key())) {
|
if (!childMap.contains(parent, model.key())) {
|
||||||
|
@ -1129,20 +1180,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
remainingModels.insert(model.key());
|
remainingModels.insert(model.key());
|
||||||
}
|
}
|
||||||
while (!remainingModels.isEmpty()) {
|
while (!remainingModels.isEmpty()) {
|
||||||
QString top = *remainingModels.constBegin();
|
QString topID = getTopModelID(parentMap, models, *remainingModels.constBegin());
|
||||||
forever {
|
appendModelIDs(parentMap.value(topID), childMap, models, remainingModels, modelIDs);
|
||||||
foreach (const QString& name, parentMap.values(top)) {
|
|
||||||
if (models.contains(name)) {
|
|
||||||
top = name;
|
|
||||||
goto outerContinue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
top = parentMap.value(top);
|
|
||||||
break;
|
|
||||||
|
|
||||||
outerContinue: ;
|
|
||||||
}
|
|
||||||
appendModelIDs(top, childMap, models, remainingModels, modelIDs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the models to joints
|
// convert the models to joints
|
||||||
|
|
|
@ -40,7 +40,8 @@ static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* eng
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, const QString& fileNameString, AbstractMenuInterface* menu,
|
ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, const QString& fileNameString,
|
||||||
|
AbstractMenuInterface* menu,
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface) :
|
AbstractControllerScriptingInterface* controllerScriptingInterface) :
|
||||||
_isAvatar(false),
|
_isAvatar(false),
|
||||||
_dataServerScriptingInterface(),
|
_dataServerScriptingInterface(),
|
||||||
|
@ -104,8 +105,6 @@ bool ScriptEngine::setScriptContents(const QString& scriptContents) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_SCRIPT_DECLARE_QMETAOBJECT(AudioInjectorOptions, QObject*)
|
|
||||||
|
|
||||||
void ScriptEngine::init() {
|
void ScriptEngine::init() {
|
||||||
if (_isInitialized) {
|
if (_isInitialized) {
|
||||||
return; // only initialize once
|
return; // only initialize once
|
||||||
|
@ -297,4 +296,51 @@ void ScriptEngine::stop() {
|
||||||
_isFinished = true;
|
_isFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::timerFired() {
|
||||||
|
QTimer* callingTimer = reinterpret_cast<QTimer*>(sender());
|
||||||
|
|
||||||
|
// call the associated JS function, if it exists
|
||||||
|
QScriptValue timerFunction = _timerFunctionMap.value(callingTimer);
|
||||||
|
if (timerFunction.isValid()) {
|
||||||
|
timerFunction.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!callingTimer->isActive()) {
|
||||||
|
// this timer is done, we can kill it
|
||||||
|
qDebug() << "Deleting a single shot timer";
|
||||||
|
delete callingTimer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot) {
|
||||||
|
// create the timer, add it to the map, and start it
|
||||||
|
QTimer* newTimer = new QTimer(this);
|
||||||
|
newTimer->setSingleShot(isSingleShot);
|
||||||
|
|
||||||
|
connect(newTimer, &QTimer::timeout, this, &ScriptEngine::timerFired);
|
||||||
|
|
||||||
|
// make sure the timer stops when the script does
|
||||||
|
connect(this, &ScriptEngine::scriptEnding, newTimer, &QTimer::stop);
|
||||||
|
|
||||||
|
_timerFunctionMap.insert(newTimer, function);
|
||||||
|
|
||||||
|
newTimer->start(intervalMS);
|
||||||
|
return newTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) {
|
||||||
|
return setupTimerWithInterval(function, intervalMS, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) {
|
||||||
|
return setupTimerWithInterval(function, timeoutMS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::stopTimer(QTimer *timer) {
|
||||||
|
if (_timerFunctionMap.contains(timer)) {
|
||||||
|
timer->stop();
|
||||||
|
_timerFunctionMap.remove(timer);
|
||||||
|
delete timer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,19 @@ public:
|
||||||
|
|
||||||
void setAvatarData(AvatarData* avatarData, const QString& objectName);
|
void setAvatarData(AvatarData* avatarData, const QString& objectName);
|
||||||
|
|
||||||
|
void timerFired();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void init();
|
void init();
|
||||||
void run(); /// runs continuously until Agent.stop() is called
|
void run(); /// runs continuously until Agent.stop() is called
|
||||||
void stop();
|
void stop();
|
||||||
void evaluate(); /// initializes the engine, and evaluates the script, but then returns control to caller
|
void evaluate(); /// initializes the engine, and evaluates the script, but then returns control to caller
|
||||||
|
|
||||||
|
QObject* setInterval(const QScriptValue& function, int intervalMS);
|
||||||
|
QObject* setTimeout(const QScriptValue& function, int timeoutMS);
|
||||||
|
void clearInterval(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
|
||||||
|
void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void willSendAudioDataCallback();
|
void willSendAudioDataCallback();
|
||||||
void willSendVisualDataCallback();
|
void willSendVisualDataCallback();
|
||||||
|
@ -73,15 +80,18 @@ signals:
|
||||||
void finished(const QString& fileNameString);
|
void finished(const QString& fileNameString);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QString _scriptContents;
|
QString _scriptContents;
|
||||||
bool _isFinished;
|
bool _isFinished;
|
||||||
bool _isRunning;
|
bool _isRunning;
|
||||||
bool _isInitialized;
|
bool _isInitialized;
|
||||||
QScriptEngine _engine;
|
QScriptEngine _engine;
|
||||||
bool _isAvatar;
|
bool _isAvatar;
|
||||||
|
QHash<QTimer*, QScriptValue> _timerFunctionMap;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
|
||||||
|
void stopTimer(QTimer* timer);
|
||||||
|
|
||||||
static VoxelsScriptingInterface _voxelsScriptingInterface;
|
static VoxelsScriptingInterface _voxelsScriptingInterface;
|
||||||
static ParticlesScriptingInterface _particlesScriptingInterface;
|
static ParticlesScriptingInterface _particlesScriptingInterface;
|
||||||
AbstractControllerScriptingInterface* _controllerScriptingInterface;
|
AbstractControllerScriptingInterface* _controllerScriptingInterface;
|
||||||
|
|
Loading…
Reference in a new issue