mirror of
https://github.com/overte-org/overte.git
synced 2025-06-01 08:31:45 +02:00
Merge branch 'baseball' of github.com:Atlante45/hifi into baseball
This commit is contained in:
commit
779cadd5bd
9 changed files with 103 additions and 193 deletions
|
@ -403,7 +403,7 @@ void Agent::sendPingRequests() {
|
||||||
case NodeType::AvatarMixer:
|
case NodeType::AvatarMixer:
|
||||||
case NodeType::AudioMixer:
|
case NodeType::AudioMixer:
|
||||||
case NodeType::EntityServer:
|
case NodeType::EntityServer:
|
||||||
case NodeType::AssetClient:
|
case NodeType::AssetServer:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -10,11 +10,31 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
var chatter = SoundCache.getSound("atp:d9978e693035d4e2b5c7b546c8cccfb2dde5677834d9eed5206ccb2da55b4732.wav");
|
var chatter = SoundCache.getSound("atp:d9978e693035d4e2b5c7b546c8cccfb2dde5677834d9eed5206ccb2da55b4732.wav");
|
||||||
|
var extras = [
|
||||||
|
SoundCache.getSound("atp:1ee58f4d929fdef7c2989cd8be964952a24cdd653d80f57b6a89a2ae8e3029e1.wav"), // zorba
|
||||||
|
SoundCache.getSound("atp:cefaba2d5f1a378382ee046716bffcf6b6a40676649b23a1e81a996efe22d7d3.wav"), // charge
|
||||||
|
SoundCache.getSound("atp:fb41e37f8f8f7b78e546ac78800df6e39edaa09b2df4bfa0afdd8d749dac38b8.wav"), // take me out to the ball game
|
||||||
|
SoundCache.getSound("atp:44a83a788ccfd2924e35c902c34808b24dbd0309d000299ce01a355f91cf8115.wav") // clapping
|
||||||
|
];
|
||||||
|
|
||||||
function playChatter() {
|
function playChatter() {
|
||||||
if (chatter.downloaded && !chatter.isPlaying) {
|
if (chatter.downloaded && !chatter.isPlaying) {
|
||||||
Audio.playSound(chatter, { position: { x: 0, y: 0, z: 0}, loop: true, volume: 0.5 });
|
Audio.playSound(chatter, { loop: true, volume: 0.5 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chatter.ready.connect(playChatter);
|
chatter.ready.connect(playChatter);
|
||||||
|
|
||||||
|
var currentInjector = null;
|
||||||
|
|
||||||
|
function playRandomExtras() {
|
||||||
|
if ((!currentInjector || !currentInjector.isPlaying) && (Math.random() < (1.0 / 1800.0))) {
|
||||||
|
// play a random extra sound about every 30s
|
||||||
|
currentInjector = Audio.playSound(
|
||||||
|
extras[Math.floor(Math.random() * extras.length)],
|
||||||
|
{ volume: 0.33 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.update.connect(playRandomExtras);
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
//
|
|
||||||
// baseball.js
|
|
||||||
// examples/toys
|
|
||||||
//
|
|
||||||
// Created by Stephen Birarda on 10/20/15.
|
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
var ROBOT_MODEL = "atp:785c81e117206c36205404beec0cc68529644fe377542dbb2d13fae4d665a5de.fbx";
|
|
||||||
var ROBOT_POSITION = { x: -0.81, y: 0.88, z: 2.12 };
|
|
||||||
var ROBOT_DIMENSIONS = { x: 0.95, y: 1.76, z: 0.56 };
|
|
||||||
|
|
||||||
var BAT_MODEL = "atp:07bdd769a57ff15ebe9331ae4e2c2eae8886a6792b4790cce03b4716eb3a81c7.fbx"
|
|
||||||
var BAT_COLLISION_MODEL = "atp:atp:9eafceb7510c41d50661130090de7e0632aa4da236ebda84a0059a4be2130e0c.obj"
|
|
||||||
var BAT_DIMENSIONS = { x: 1.35, y: 0.10, z: 0.10 };
|
|
||||||
var BAT_REGISTRATION_POINT = { x: 0.1, y: 0.5, z: 0.5 };
|
|
||||||
|
|
||||||
// add the fresh robot at home plate
|
|
||||||
var robot = Entities.addEntity({
|
|
||||||
name: 'Robot',
|
|
||||||
type: 'Model',
|
|
||||||
modelURL: ROBOT_MODEL,
|
|
||||||
position: ROBOT_POSITION,
|
|
||||||
// dimensions: ROBOT_DIMENSIONS,a
|
|
||||||
animationIsPlaying: true,
|
|
||||||
animation: {
|
|
||||||
url: ROBOT_MODEL,
|
|
||||||
fps: 30
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add the bat
|
|
||||||
var bat = Entities.addEntity({
|
|
||||||
name: 'Bat',
|
|
||||||
/*/
|
|
||||||
type: 'Box',
|
|
||||||
/*/
|
|
||||||
type: 'Model',
|
|
||||||
modelURL: BAT_COLLISION_MODEL,
|
|
||||||
/**/
|
|
||||||
collisionModelURL: BAT_COLLISION_MODEL,
|
|
||||||
// dimensions: BAT_DIMENSIONS,
|
|
||||||
registrationPoint: BAT_REGISTRATION_POINT,
|
|
||||||
visible: false
|
|
||||||
})
|
|
||||||
|
|
||||||
var lastTriggerValue = 0.0;
|
|
||||||
|
|
||||||
function checkTriggers() {
|
|
||||||
var rightTrigger = Controller.getTriggerValue(1);
|
|
||||||
|
|
||||||
if (rightTrigger == 0) {
|
|
||||||
if (lastTriggerValue > 0) {
|
|
||||||
// the trigger was just released, play out to the last frame of the swing
|
|
||||||
Entities.editEntity(robot, {
|
|
||||||
animation: {
|
|
||||||
running: true,
|
|
||||||
currentFrame: 21,
|
|
||||||
lastFrame: 115
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (lastTriggerValue == 0) {
|
|
||||||
// the trigger was just depressed, start the swing
|
|
||||||
Entities.editEntity(robot, {
|
|
||||||
animation: {
|
|
||||||
running: true,
|
|
||||||
currentFrame: 0,
|
|
||||||
lastFrame: 21
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastTriggerValue = rightTrigger;
|
|
||||||
}
|
|
||||||
|
|
||||||
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
|
|
||||||
var ACTION_LIFETIME = 15; // seconds
|
|
||||||
|
|
||||||
var action = null;
|
|
||||||
var factor = 0.0;
|
|
||||||
var STEP = 0.05;
|
|
||||||
function moveBat() {
|
|
||||||
var JOINT_INDEX = 19;
|
|
||||||
|
|
||||||
var forearmPosition = Entities.getJointPosition(robot, JOINT_INDEX);
|
|
||||||
var forearmRotation = Entities.getJointRotation(robot, JOINT_INDEX);
|
|
||||||
|
|
||||||
/*/
|
|
||||||
var properties = Entities.getEntityProperties(bat, ["position", "rotation"]);
|
|
||||||
var offsetPosition = Vec3.subtract(properties.position, forearmPosition);
|
|
||||||
var offsetRotation = Quat.multiply(Quat.inverse(forearmRotation), properties.rotation);
|
|
||||||
print("offsetPosition = " + JSON.stringify(offsetPosition));
|
|
||||||
print("offsetRotation = " + JSON.stringify(Quat.safeEulerAngles(offsetRotation)));
|
|
||||||
/*/
|
|
||||||
Entities.editEntity(bat, {
|
|
||||||
position: forearmPosition,
|
|
||||||
rotation: forearmRotation,
|
|
||||||
});
|
|
||||||
/**/
|
|
||||||
|
|
||||||
// var actionProperties = {
|
|
||||||
// relativePosition: forearmPosition,
|
|
||||||
// relativeRotation: forearmRotation,
|
|
||||||
//// tag: "bat-to-forearm",
|
|
||||||
//// linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
|
||||||
//// angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
|
||||||
//// lifetime: ACTION_LIFETIME
|
|
||||||
// hand: "left",
|
|
||||||
// timeScale: 0.15
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// if (action === null) {
|
|
||||||
// Entities.addAction("hold", bat, actionProperties);
|
|
||||||
// } else {
|
|
||||||
// Entities.editAction(bat, action, actionProperties);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
// checkTriggers();
|
|
||||||
moveBat();
|
|
||||||
}
|
|
||||||
|
|
||||||
function scriptEnding() {
|
|
||||||
Entities.deleteEntity(robot);
|
|
||||||
Entities.deleteEntity(bat);
|
|
||||||
if (action) {
|
|
||||||
Entities.deleteAction(bat, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// hook the update so we can check controller triggers
|
|
||||||
Script.update.connect(update);
|
|
||||||
Script.scriptEnding.connect(scriptEnding);
|
|
|
@ -564,12 +564,12 @@ CameraTool = function(cameraManager) {
|
||||||
|
|
||||||
var ORIENTATION_OVERLAY_SIZE = 26;
|
var ORIENTATION_OVERLAY_SIZE = 26;
|
||||||
var ORIENTATION_OVERLAY_HALF_SIZE = ORIENTATION_OVERLAY_SIZE / 2;
|
var ORIENTATION_OVERLAY_HALF_SIZE = ORIENTATION_OVERLAY_SIZE / 2;
|
||||||
var ORIENTATION_OVERLAY_CUBE_SIZE = 10.5,
|
var ORIENTATION_OVERLAY_CUBE_SIZE = 10.5;
|
||||||
|
|
||||||
var ORIENTATION_OVERLAY_OFFSET = {
|
var ORIENTATION_OVERLAY_OFFSET = {
|
||||||
x: 30,
|
x: 30,
|
||||||
y: 30,
|
y: 30,
|
||||||
}
|
}
|
||||||
|
|
||||||
var UI_WIDTH = 70;
|
var UI_WIDTH = 70;
|
||||||
var UI_HEIGHT = 70;
|
var UI_HEIGHT = 70;
|
||||||
|
|
|
@ -6,7 +6,7 @@ SoundArray = function(audioOptions, autoUpdateAudioPosition) {
|
||||||
this.audioOptions = audioOptions !== undefined ? audioOptions : {};
|
this.audioOptions = audioOptions !== undefined ? audioOptions : {};
|
||||||
this.autoUpdateAudioPosition = autoUpdateAudioPosition !== undefined ? autoUpdateAudioPosition : false;
|
this.autoUpdateAudioPosition = autoUpdateAudioPosition !== undefined ? autoUpdateAudioPosition : false;
|
||||||
if (this.audioOptions.position === undefined) {
|
if (this.audioOptions.position === undefined) {
|
||||||
this.audioOptions.position = Vec3.sum(MyAvatar.position, { x: 0, y: 1, z: 0}),
|
this.audioOptions.position = Vec3.sum(MyAvatar.position, { x: 0, y: 1, z: 0});
|
||||||
}
|
}
|
||||||
if (this.audioOptions.volume === undefined) {
|
if (this.audioOptions.volume === undefined) {
|
||||||
this.audioOptions.volume = 1.0;
|
this.audioOptions.volume = 1.0;
|
||||||
|
|
|
@ -46,7 +46,7 @@ void AssetResourceRequest::doSend() {
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(_assetRequest, &AssetRequest::progress, this, &AssetResourceRequest::progress);
|
connect(_assetRequest, &AssetRequest::progress, this, &AssetResourceRequest::progress);
|
||||||
connect(_assetRequest, &AssetRequest::finished, [this](AssetRequest* req) {
|
connect(_assetRequest, &AssetRequest::finished, this, [this](AssetRequest* req) {
|
||||||
Q_ASSERT(_state == InProgress);
|
Q_ASSERT(_state == InProgress);
|
||||||
Q_ASSERT(req == _assetRequest);
|
Q_ASSERT(req == _assetRequest);
|
||||||
Q_ASSERT(req->getState() == AssetRequest::Finished);
|
Q_ASSERT(req->getState() == AssetRequest::Finished);
|
||||||
|
|
|
@ -79,7 +79,6 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
|
||||||
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, AbstractInputController* const &in) {
|
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, AbstractInputController* const &in) {
|
||||||
return engine->newQObject(in);
|
return engine->newQObject(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputController* &out) {
|
void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputController* &out) {
|
||||||
out = qobject_cast<AbstractInputController*>(object.toQObject());
|
out = qobject_cast<AbstractInputController*>(object.toQObject());
|
||||||
}
|
}
|
||||||
|
@ -95,9 +94,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
||||||
_wantSignals(wantSignals),
|
_wantSignals(wantSignals),
|
||||||
_controllerScriptingInterface(controllerScriptingInterface),
|
_controllerScriptingInterface(controllerScriptingInterface),
|
||||||
_fileNameString(fileNameString),
|
_fileNameString(fileNameString),
|
||||||
_quatLibrary(),
|
|
||||||
_vec3Library(),
|
|
||||||
_uuidLibrary(),
|
|
||||||
_isUserLoaded(false),
|
_isUserLoaded(false),
|
||||||
_isReloading(false),
|
_isReloading(false),
|
||||||
_arrayBufferClass(new ArrayBufferClass(this))
|
_arrayBufferClass(new ArrayBufferClass(this))
|
||||||
|
@ -513,18 +509,22 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString&
|
||||||
});
|
});
|
||||||
|
|
||||||
// Two common cases of event handler, differing only in argument signature.
|
// Two common cases of event handler, differing only in argument signature.
|
||||||
auto makeSingleEntityHandler = [&](QString eventName) {
|
using SingleEntityHandler = std::function<void(const EntityItemID&)>;
|
||||||
|
auto makeSingleEntityHandler = [this](QString eventName) -> SingleEntityHandler {
|
||||||
return [this, eventName](const EntityItemID& entityItemID) {
|
return [this, eventName](const EntityItemID& entityItemID) {
|
||||||
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this) });
|
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this) });
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
auto makeMouseHandler = [&](QString eventName) {
|
|
||||||
|
using MouseHandler = std::function<void(const EntityItemID&, const MouseEvent&)>;
|
||||||
|
auto makeMouseHandler = [this](QString eventName) -> MouseHandler {
|
||||||
return [this, eventName](const EntityItemID& entityItemID, const MouseEvent& event) {
|
return [this, eventName](const EntityItemID& entityItemID, const MouseEvent& event) {
|
||||||
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) });
|
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) });
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
auto makeCollisionHandler = [&](QString eventName) {
|
using CollisionHandler = std::function<void(const EntityItemID&, const EntityItemID&, const Collision&)>;
|
||||||
|
auto makeCollisionHandler = [this](QString eventName) -> CollisionHandler {
|
||||||
return [this, eventName](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
return [this, eventName](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
||||||
forwardHandlerCall(idA, eventName, { idA.toScriptValue(this), idB.toScriptValue(this),
|
forwardHandlerCall(idA, eventName, { idA.toScriptValue(this), idB.toScriptValue(this),
|
||||||
collisionToScriptValue(this, collision) });
|
collisionToScriptValue(this, collision) });
|
||||||
|
@ -556,7 +556,7 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) {
|
QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fileName, int lineNumber) {
|
||||||
if (_stoppingAllScripts) {
|
if (_stoppingAllScripts) {
|
||||||
return QScriptValue(); // bail early
|
return QScriptValue(); // bail early
|
||||||
}
|
}
|
||||||
|
@ -565,27 +565,30 @@ QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileN
|
||||||
QScriptValue result;
|
QScriptValue result;
|
||||||
#ifdef THREAD_DEBUGGING
|
#ifdef THREAD_DEBUGGING
|
||||||
qDebug() << "*** WARNING *** ScriptEngine::evaluate() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
|
qDebug() << "*** WARNING *** ScriptEngine::evaluate() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
|
||||||
"program:" << program << " fileName:" << fileName << "lineNumber:" << lineNumber;
|
"sourceCode:" << sourceCode << " fileName:" << fileName << "lineNumber:" << lineNumber;
|
||||||
#endif
|
#endif
|
||||||
QMetaObject::invokeMethod(this, "evaluate", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(this, "evaluate", Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(QScriptValue, result),
|
Q_RETURN_ARG(QScriptValue, result),
|
||||||
Q_ARG(const QString&, program),
|
Q_ARG(const QString&, sourceCode),
|
||||||
Q_ARG(const QString&, fileName),
|
Q_ARG(const QString&, fileName),
|
||||||
Q_ARG(int, lineNumber));
|
Q_ARG(int, lineNumber));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check syntax
|
||||||
|
const QScriptProgram program(sourceCode, fileName, lineNumber);
|
||||||
|
if (!checkSyntax(program)) {
|
||||||
|
return QScriptValue();
|
||||||
|
}
|
||||||
|
|
||||||
_evaluatesPending++;
|
++_evaluatesPending;
|
||||||
QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber);
|
const auto result = QScriptEngine::evaluate(program);
|
||||||
if (hasUncaughtException()) {
|
--_evaluatesPending;
|
||||||
int line = uncaughtExceptionLineNumber();
|
|
||||||
qCDebug(scriptengine) << "Uncaught exception at (" << _fileNameString << " : " << fileName << ") line" << line << ": " << result.toString();
|
const auto hadUncaughtException = checkExceptions(*this, program.fileName());
|
||||||
}
|
|
||||||
_evaluatesPending--;
|
|
||||||
if (_wantSignals) {
|
if (_wantSignals) {
|
||||||
emit evaluationFinished(result, hasUncaughtException());
|
emit evaluationFinished(result, hadUncaughtException);
|
||||||
}
|
}
|
||||||
clearExceptions();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,7 +606,7 @@ void ScriptEngine::run() {
|
||||||
emit runningStateChanged();
|
emit runningStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue result = evaluate(_scriptContents);
|
QScriptValue result = evaluate(_scriptContents, _fileNameString);
|
||||||
|
|
||||||
QElapsedTimer startTime;
|
QElapsedTimer startTime;
|
||||||
startTime.start();
|
startTime.start();
|
||||||
|
@ -644,15 +647,6 @@ void ScriptEngine::run() {
|
||||||
qint64 now = usecTimestampNow();
|
qint64 now = usecTimestampNow();
|
||||||
float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND;
|
float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND;
|
||||||
|
|
||||||
if (hasUncaughtException()) {
|
|
||||||
int line = uncaughtExceptionLineNumber();
|
|
||||||
qCDebug(scriptengine) << "Uncaught exception at (" << _fileNameString << ") line" << line << ":" << uncaughtException().toString();
|
|
||||||
if (_wantSignals) {
|
|
||||||
emit errorMessage("Uncaught exception at (" + _fileNameString + ") line" + QString::number(line) + ":" + uncaughtException().toString());
|
|
||||||
}
|
|
||||||
clearExceptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_isFinished) {
|
if (!_isFinished) {
|
||||||
if (_wantSignals) {
|
if (_wantSignals) {
|
||||||
emit update(deltaTime);
|
emit update(deltaTime);
|
||||||
|
@ -660,6 +654,9 @@ void ScriptEngine::run() {
|
||||||
}
|
}
|
||||||
lastUpdate = now;
|
lastUpdate = now;
|
||||||
|
|
||||||
|
if (!checkExceptions(*this, _fileNameString)) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stopAllTimers(); // make sure all our timers are stopped if the script is ending
|
stopAllTimers(); // make sure all our timers are stopped if the script is ending
|
||||||
|
@ -896,6 +893,37 @@ void ScriptEngine::load(const QString& loadFile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScriptEngine::checkSyntax(const QScriptProgram& program) {
|
||||||
|
const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode());
|
||||||
|
if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
|
||||||
|
const auto error = syntaxCheck.errorMessage();
|
||||||
|
const auto line = QString::number(syntaxCheck.errorLineNumber());
|
||||||
|
const auto column = QString::number(syntaxCheck.errorColumnNumber());
|
||||||
|
const auto message = QString("[SyntaxError] %1 in %2:%3(%4)").arg(error, program.fileName(), line, column);
|
||||||
|
qCWarning(scriptengine) << qPrintable(message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScriptEngine::checkExceptions(QScriptEngine& engine, const QString& fileName) {
|
||||||
|
if (engine.hasUncaughtException()) {
|
||||||
|
const auto backtrace = engine.uncaughtExceptionBacktrace();
|
||||||
|
const auto exception = engine.uncaughtException().toString();
|
||||||
|
const auto line = QString::number(engine.uncaughtExceptionLineNumber());
|
||||||
|
engine.clearExceptions();
|
||||||
|
|
||||||
|
auto message = QString("[UncaughtException] %1 in %2:%3").arg(exception, fileName, line);
|
||||||
|
if (!backtrace.empty()) {
|
||||||
|
static const auto lineSeparator = "\n ";
|
||||||
|
message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator));
|
||||||
|
}
|
||||||
|
qCWarning(scriptengine) << qPrintable(message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args
|
// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args
|
||||||
void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs) {
|
void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
|
@ -978,14 +1006,10 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
||||||
|
|
||||||
auto scriptCache = DependencyManager::get<ScriptCache>();
|
auto scriptCache = DependencyManager::get<ScriptCache>();
|
||||||
bool isFileUrl = isURL && scriptOrURL.startsWith("file://");
|
bool isFileUrl = isURL && scriptOrURL.startsWith("file://");
|
||||||
|
auto fileName = QString("(EntityID:%1, %2)").arg(entityID.toString(), isURL ? scriptOrURL : "EmbededEntityScript");
|
||||||
|
|
||||||
// first check the syntax of the script contents
|
QScriptProgram program(contents, fileName);
|
||||||
QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents);
|
if (!checkSyntax(program)) {
|
||||||
if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
|
|
||||||
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
|
|
||||||
qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":"
|
|
||||||
<< syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber();
|
|
||||||
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
|
|
||||||
if (!isFileUrl) {
|
if (!isFileUrl) {
|
||||||
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
||||||
}
|
}
|
||||||
|
@ -997,12 +1021,15 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptEngine sandbox;
|
QScriptEngine sandbox;
|
||||||
QScriptValue testConstructor = sandbox.evaluate(contents);
|
QScriptValue testConstructor = sandbox.evaluate(program);
|
||||||
|
if (!checkExceptions(sandbox, program.fileName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!testConstructor.isFunction()) {
|
if (!testConstructor.isFunction()) {
|
||||||
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
|
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID << "\n"
|
||||||
qCDebug(scriptengine) << " NOT CONSTRUCTOR";
|
" NOT CONSTRUCTOR\n"
|
||||||
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
|
" SCRIPT:" << scriptOrURL;
|
||||||
if (!isFileUrl) {
|
if (!isFileUrl) {
|
||||||
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
scriptCache->addScriptToBadScriptList(scriptOrURL);
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1042,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
||||||
lastModified = (quint64)QFileInfo(file).lastModified().toMSecsSinceEpoch();
|
lastModified = (quint64)QFileInfo(file).lastModified().toMSecsSinceEpoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue entityScriptConstructor = evaluate(contents);
|
QScriptValue entityScriptConstructor = evaluate(contents, fileName);
|
||||||
QScriptValue entityScriptObject = entityScriptConstructor.construct();
|
QScriptValue entityScriptObject = entityScriptConstructor.construct();
|
||||||
EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified };
|
EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified };
|
||||||
_entityScripts[entityID] = newDetails;
|
_entityScripts[entityID] = newDetails;
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
Q_INVOKABLE void registerValue(const QString& valueName, QScriptValue value);
|
Q_INVOKABLE void registerValue(const QString& valueName, QScriptValue value);
|
||||||
|
|
||||||
/// evaluate some code in the context of the ScriptEngine and return the result
|
/// evaluate some code in the context of the ScriptEngine and return the result
|
||||||
Q_INVOKABLE QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1); // this is also used by the script tool widget
|
Q_INVOKABLE QScriptValue evaluate(const QString& program, const QString& fileName, int lineNumber = 1); // this is also used by the script tool widget
|
||||||
|
|
||||||
/// if the script engine is not already running, this will download the URL and start the process of seting it up
|
/// if the script engine is not already running, this will download the URL and start the process of seting it up
|
||||||
/// to run... NOTE - this is used by Application currently to load the url. We don't really want it to be exposed
|
/// to run... NOTE - this is used by Application currently to load the url. We don't really want it to be exposed
|
||||||
|
@ -182,6 +182,9 @@ private:
|
||||||
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
|
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
|
||||||
void stopTimer(QTimer* timer);
|
void stopTimer(QTimer* timer);
|
||||||
|
|
||||||
|
static bool checkSyntax(const QScriptProgram& program);
|
||||||
|
static bool checkExceptions(QScriptEngine& engine, const QString& fileName);
|
||||||
|
|
||||||
AbstractControllerScriptingInterface* _controllerScriptingInterface;
|
AbstractControllerScriptingInterface* _controllerScriptingInterface;
|
||||||
QString _fileNameString;
|
QString _fileNameString;
|
||||||
Quat _quatLibrary;
|
Quat _quatLibrary;
|
||||||
|
|
|
@ -135,7 +135,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
||||||
prefixString.append(QString(" [%1]").arg(_targetName));
|
prefixString.append(QString(" [%1]").arg(_targetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString logMessage = QString("%1 %2").arg(prefixString, message);
|
QString logMessage = QString("%1 %2").arg(prefixString, message.split("\n").join("\n" + prefixString + " "));
|
||||||
fprintf(stdout, "%s\n", qPrintable(logMessage));
|
fprintf(stdout, "%s\n", qPrintable(logMessage));
|
||||||
return logMessage;
|
return logMessage;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue