Merge branch 'baseball' of github.com:Atlante45/hifi into baseball

This commit is contained in:
Ryan Huffman 2015-10-27 15:14:30 -07:00
commit 779cadd5bd
9 changed files with 103 additions and 193 deletions

View file

@ -403,7 +403,7 @@ void Agent::sendPingRequests() {
case NodeType::AvatarMixer:
case NodeType::AudioMixer:
case NodeType::EntityServer:
case NodeType::AssetClient:
case NodeType::AssetServer:
return true;
default:
return false;

View file

@ -10,11 +10,31 @@
//
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() {
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);
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);

View file

@ -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);

View file

@ -564,7 +564,7 @@ CameraTool = function(cameraManager) {
var ORIENTATION_OVERLAY_SIZE = 26;
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 = {
x: 30,

View file

@ -6,7 +6,7 @@ SoundArray = function(audioOptions, autoUpdateAudioPosition) {
this.audioOptions = audioOptions !== undefined ? audioOptions : {};
this.autoUpdateAudioPosition = autoUpdateAudioPosition !== undefined ? autoUpdateAudioPosition : false;
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) {
this.audioOptions.volume = 1.0;

View file

@ -46,7 +46,7 @@ void AssetResourceRequest::doSend() {
}
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(req == _assetRequest);
Q_ASSERT(req->getState() == AssetRequest::Finished);

View file

@ -79,7 +79,6 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, AbstractInputController* const &in) {
return engine->newQObject(in);
}
void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputController* &out) {
out = qobject_cast<AbstractInputController*>(object.toQObject());
}
@ -95,9 +94,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
_wantSignals(wantSignals),
_controllerScriptingInterface(controllerScriptingInterface),
_fileNameString(fileNameString),
_quatLibrary(),
_vec3Library(),
_uuidLibrary(),
_isUserLoaded(false),
_isReloading(false),
_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.
auto makeSingleEntityHandler = [&](QString eventName) {
using SingleEntityHandler = std::function<void(const EntityItemID&)>;
auto makeSingleEntityHandler = [this](QString eventName) -> SingleEntityHandler {
return [this, eventName](const EntityItemID& entityItemID) {
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) {
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) {
forwardHandlerCall(idA, eventName, { idA.toScriptValue(this), idB.toScriptValue(this),
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) {
return QScriptValue(); // bail early
}
@ -565,27 +565,30 @@ QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileN
QScriptValue result;
#ifdef THREAD_DEBUGGING
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
QMetaObject::invokeMethod(this, "evaluate", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QScriptValue, result),
Q_ARG(const QString&, program),
Q_ARG(const QString&, sourceCode),
Q_ARG(const QString&, fileName),
Q_ARG(int, lineNumber));
return result;
}
_evaluatesPending++;
QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber);
if (hasUncaughtException()) {
int line = uncaughtExceptionLineNumber();
qCDebug(scriptengine) << "Uncaught exception at (" << _fileNameString << " : " << fileName << ") line" << line << ": " << result.toString();
// Check syntax
const QScriptProgram program(sourceCode, fileName, lineNumber);
if (!checkSyntax(program)) {
return QScriptValue();
}
_evaluatesPending--;
++_evaluatesPending;
const auto result = QScriptEngine::evaluate(program);
--_evaluatesPending;
const auto hadUncaughtException = checkExceptions(*this, program.fileName());
if (_wantSignals) {
emit evaluationFinished(result, hasUncaughtException());
emit evaluationFinished(result, hadUncaughtException);
}
clearExceptions();
return result;
}
@ -603,7 +606,7 @@ void ScriptEngine::run() {
emit runningStateChanged();
}
QScriptValue result = evaluate(_scriptContents);
QScriptValue result = evaluate(_scriptContents, _fileNameString);
QElapsedTimer startTime;
startTime.start();
@ -644,15 +647,6 @@ void ScriptEngine::run() {
qint64 now = usecTimestampNow();
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 (_wantSignals) {
emit update(deltaTime);
@ -660,6 +654,9 @@ void ScriptEngine::run() {
}
lastUpdate = now;
if (!checkExceptions(*this, _fileNameString)) {
stop();
}
}
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
void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs) {
if (QThread::currentThread() != thread()) {
@ -978,14 +1006,10 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
auto scriptCache = DependencyManager::get<ScriptCache>();
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
QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents);
if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":"
<< syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber();
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
QScriptProgram program(contents, fileName);
if (!checkSyntax(program)) {
if (!isFileUrl) {
scriptCache->addScriptToBadScriptList(scriptOrURL);
}
@ -997,12 +1021,15 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
}
QScriptEngine sandbox;
QScriptValue testConstructor = sandbox.evaluate(contents);
QScriptValue testConstructor = sandbox.evaluate(program);
if (!checkExceptions(sandbox, program.fileName())) {
return;
}
if (!testConstructor.isFunction()) {
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
qCDebug(scriptengine) << " NOT CONSTRUCTOR";
qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID << "\n"
" NOT CONSTRUCTOR\n"
" SCRIPT:" << scriptOrURL;
if (!isFileUrl) {
scriptCache->addScriptToBadScriptList(scriptOrURL);
}
@ -1015,7 +1042,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
lastModified = (quint64)QFileInfo(file).lastModified().toMSecsSinceEpoch();
}
QScriptValue entityScriptConstructor = evaluate(contents);
QScriptValue entityScriptConstructor = evaluate(contents, fileName);
QScriptValue entityScriptObject = entityScriptConstructor.construct();
EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject, lastModified };
_entityScripts[entityID] = newDetails;

View file

@ -88,7 +88,7 @@ public:
Q_INVOKABLE void registerValue(const QString& valueName, QScriptValue value);
/// 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
/// 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);
void stopTimer(QTimer* timer);
static bool checkSyntax(const QScriptProgram& program);
static bool checkExceptions(QScriptEngine& engine, const QString& fileName);
AbstractControllerScriptingInterface* _controllerScriptingInterface;
QString _fileNameString;
Quat _quatLibrary;

View file

@ -135,7 +135,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
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));
return logMessage;
}