mirror of
https://github.com/overte-org/overte.git
synced 2025-06-15 19:39:16 +02:00
shifting classes around and adding static initializers to resolve dependencies on scripting-engine (and drop dependencies from scripting-engine)
This commit is contained in:
parent
1f4f458942
commit
665ea521e8
53 changed files with 455 additions and 402 deletions
|
@ -59,7 +59,7 @@
|
||||||
|
|
||||||
#include "entities/AssignmentParentFinder.h"
|
#include "entities/AssignmentParentFinder.h"
|
||||||
#include "AssignmentDynamicFactory.h"
|
#include "AssignmentDynamicFactory.h"
|
||||||
#include "RecordingScriptingInterface.h"
|
#include <recording/RecordingScriptingInterface.h>
|
||||||
#include "AbstractAudioInterface.h"
|
#include "AbstractAudioInterface.h"
|
||||||
#include "AgentScriptingInterface.h"
|
#include "AgentScriptingInterface.h"
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
#include <plugins/OculusPlatformPlugin.h>
|
#include <plugins/OculusPlatformPlugin.h>
|
||||||
#include <plugins/InputConfiguration.h>
|
#include <plugins/InputConfiguration.h>
|
||||||
#include <Quat.h>
|
#include <Quat.h>
|
||||||
#include <RecordingScriptingInterface.h>
|
#include <recording/RecordingScriptingInterface.h>
|
||||||
#include <render/EngineStats.h>
|
#include <render/EngineStats.h>
|
||||||
#include <SecondaryCamera.h>
|
#include <SecondaryCamera.h>
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include <TextRenderer3D.h>
|
#include <TextRenderer3D.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
#include <recording/Recorder.h>
|
#include <recording/Recorder.h>
|
||||||
#include <RecordingScriptingInterface.h>
|
#include <recording/RecordingScriptingInterface.h>
|
||||||
#include <RenderableModelEntityItem.h>
|
#include <RenderableModelEntityItem.h>
|
||||||
#include <VariantMapToScriptValue.h>
|
#include <VariantMapToScriptValue.h>
|
||||||
#include <NetworkingConstants.h>
|
#include <NetworkingConstants.h>
|
||||||
|
@ -440,7 +440,7 @@ void MyAvatar::enableHandTouchForID(const QUuid& entityID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::registerMetaTypes(ScriptEnginePointer engine) {
|
void MyAvatar::registerMetaTypes(ScriptEnginePointer engine) {
|
||||||
ScriptValuePointer value = engine->newQObject(this, ScriptEngine::QtOwnership, ScriptEngine::ExcludeDeleteLater | ScriptEngine::ExcludeChildObjects);
|
ScriptValuePointer value = engine->newQObject(this, ScriptEngine::QtOwnership);
|
||||||
engine->globalObject()->setProperty("MyAvatar", value);
|
engine->globalObject()->setProperty("MyAvatar", value);
|
||||||
|
|
||||||
ScriptValuePointer driveKeys = engine->newObject();
|
ScriptValuePointer driveKeys = engine->newObject();
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
set(TARGET_NAME animation)
|
set(TARGET_NAME animation)
|
||||||
setup_hifi_library(Network)
|
setup_hifi_library(Network)
|
||||||
link_hifi_libraries(shared graphics model-serializers script-engine)
|
link_hifi_libraries(shared graphics model-serializers script-engine)
|
||||||
include_hifi_library_headers(animation)
|
|
||||||
include_hifi_library_headers(entities)
|
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
include_hifi_library_headers(hfm)
|
include_hifi_library_headers(hfm)
|
||||||
include_hifi_library_headers(image)
|
include_hifi_library_headers(image)
|
||||||
|
|
|
@ -13,10 +13,15 @@
|
||||||
|
|
||||||
#include <ScriptEngine.h>
|
#include <ScriptEngine.h>
|
||||||
#include <ScriptEngineCast.h>
|
#include <ScriptEngineCast.h>
|
||||||
|
#include <ScriptManager.h>
|
||||||
#include <ScriptValue.h>
|
#include <ScriptValue.h>
|
||||||
|
|
||||||
#include "AnimationCache.h"
|
#include "AnimationCache.h"
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager) {
|
||||||
|
registerAnimationTypes(manager->engine().data());
|
||||||
|
});
|
||||||
|
|
||||||
QStringList AnimationObject::getJointNames() const {
|
QStringList AnimationObject::getJointNames() const {
|
||||||
return scriptvalue_cast<AnimationPointer>(thisObject())->getJointNames();
|
return scriptvalue_cast<AnimationPointer>(thisObject())->getJointNames();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1652,14 +1652,35 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
|
||||||
rig->animationStateHandlerResult(identifier, result);
|
rig->animationStateHandlerResult(identifier, result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// invokeMethod makes a copy of the args, and copies of AnimVariantMap do copy the underlying map, so this will correctly capture
|
|
||||||
// the state of _animVars and allow continued changes to _animVars in this thread without conflict.
|
{
|
||||||
QMetaObject::invokeMethod(function->engine()->manager(), "callAnimationStateHandler", Qt::QueuedConnection,
|
// make references to the parameters for the lambda here, but let the lambda be the one to take the copies
|
||||||
Q_ARG(ScriptValuePointer, function),
|
// Copies of AnimVariantMap do copy the underlying map, so this will correctly capture
|
||||||
Q_ARG(AnimVariantMap, _animVars),
|
// the state of _animVars and allow continued changes to _animVars in this thread without conflict.
|
||||||
Q_ARG(QStringList, value.propertyNames),
|
const AnimVariantMap& animVars = _animVars;
|
||||||
Q_ARG(bool, value.useNames),
|
ScriptEnginePointer engine = function->engine();
|
||||||
Q_ARG(AnimVariantResultHandler, handleResult));
|
const QStringList& names = value.propertyNames;
|
||||||
|
bool useNames = value.useNames;
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(
|
||||||
|
engine->manager(),
|
||||||
|
[function, animVars, names, useNames, handleResult, engine] {
|
||||||
|
ScriptValuePointer javascriptParameters = animVars.animVariantMapToScriptValue(engine.get(), names, useNames);
|
||||||
|
ScriptValueList callingArguments;
|
||||||
|
callingArguments << javascriptParameters;
|
||||||
|
ScriptValuePointer result = function->call(ScriptValuePointer(), callingArguments);
|
||||||
|
|
||||||
|
// validate result from callback function.
|
||||||
|
if (result->isValid() && result->isObject()) {
|
||||||
|
handleResult(result);
|
||||||
|
} else {
|
||||||
|
qCWarning(animation) << "Rig::updateAnimationStateHandlers invalid return argument from "
|
||||||
|
"callback, expected an object";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
// It turns out that, for thread-safety reasons, ScriptEngine::callAnimationStateHandler will invoke itself if called from other
|
// It turns out that, for thread-safety reasons, ScriptEngine::callAnimationStateHandler will invoke itself if called from other
|
||||||
// than the script thread. Thus the above _could_ be replaced with an ordinary call, which will then trigger the same
|
// than the script thread. Thus the above _could_ be replaced with an ordinary call, which will then trigger the same
|
||||||
// invokeMethod as is done explicitly above. However, the script-engine library depends on this animation library, not vice versa.
|
// invokeMethod as is done explicitly above. However, the script-engine library depends on this animation library, not vice versa.
|
||||||
|
|
|
@ -12,8 +12,16 @@
|
||||||
|
|
||||||
#include <ScriptContext.h>
|
#include <ScriptContext.h>
|
||||||
#include <ScriptEngine.h>
|
#include <ScriptEngine.h>
|
||||||
|
#include <ScriptManager.h>
|
||||||
#include <ScriptValue.h>
|
#include <ScriptValue.h>
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager) {
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
ScriptValuePointer audioEffectOptionsConstructorValue = scriptEngine->newFunction(AudioEffectOptions::constructor);
|
||||||
|
scriptEngine->globalObject()->setProperty("AudioEffectOptions", audioEffectOptionsConstructorValue);
|
||||||
|
});
|
||||||
|
|
||||||
static const QString BANDWIDTH_HANDLE = "bandwidth";
|
static const QString BANDWIDTH_HANDLE = "bandwidth";
|
||||||
static const QString PRE_DELAY_HANDLE = "preDelay";
|
static const QString PRE_DELAY_HANDLE = "preDelay";
|
||||||
static const QString LATE_DELAY_HANDLE = "lateDelay";
|
static const QString LATE_DELAY_HANDLE = "lateDelay";
|
||||||
|
|
|
@ -16,9 +16,19 @@
|
||||||
#include <shared/QtHelpers.h>
|
#include <shared/QtHelpers.h>
|
||||||
|
|
||||||
#include "ScriptAudioInjector.h"
|
#include "ScriptAudioInjector.h"
|
||||||
#include "ScriptEngine.h"
|
#include <ScriptEngine.h>
|
||||||
#include "ScriptEngineCast.h"
|
#include <ScriptEngineCast.h>
|
||||||
#include "ScriptEngineLogging.h"
|
#include <ScriptEngineLogging.h>
|
||||||
|
#include <ScriptManager.h>
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager){
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
registerAudioMetaTypes(scriptEngine);
|
||||||
|
scriptEngine->registerGlobalObject("Audio", DependencyManager::get<AudioScriptingInterface>().data());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
void registerAudioMetaTypes(ScriptEngine* engine) {
|
void registerAudioMetaTypes(ScriptEngine* engine) {
|
||||||
scriptRegisterMetaType(engine, injectorOptionsToScriptValue, injectorOptionsFromScriptValue);
|
scriptRegisterMetaType(engine, injectorOptionsToScriptValue, injectorOptionsFromScriptValue);
|
|
@ -15,10 +15,10 @@
|
||||||
#ifndef hifi_AudioScriptingInterface_h
|
#ifndef hifi_AudioScriptingInterface_h
|
||||||
#define hifi_AudioScriptingInterface_h
|
#define hifi_AudioScriptingInterface_h
|
||||||
|
|
||||||
#include <AbstractAudioInterface.h>
|
#include "AbstractAudioInterface.h"
|
||||||
#include <AudioInjector.h>
|
#include "AudioInjector.h"
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <Sound.h>
|
#include "Sound.h"
|
||||||
|
|
||||||
class ScriptAudioInjector;
|
class ScriptAudioInjector;
|
||||||
class ScriptEngine;
|
class ScriptEngine;
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptAudioInjector.cpp
|
// ScriptAudioInjector.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/audio/src
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 2015-02-11.
|
// Created by Stephen Birarda on 2015-02-11.
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
@ -11,9 +11,17 @@
|
||||||
|
|
||||||
#include "ScriptAudioInjector.h"
|
#include "ScriptAudioInjector.h"
|
||||||
|
|
||||||
#include "ScriptEngine.h"
|
#include <ScriptEngine.h>
|
||||||
#include "ScriptEngineLogging.h"
|
#include <ScriptEngineCast.h>
|
||||||
#include "ScriptValue.h"
|
#include <ScriptEngineLogging.h>
|
||||||
|
#include <ScriptManager.h>
|
||||||
|
#include <ScriptValue.h>
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager) {
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
scriptRegisterMetaType(scriptEngine, injectorToScriptValue, injectorFromScriptValue);
|
||||||
|
});
|
||||||
|
|
||||||
ScriptValuePointer injectorToScriptValue(ScriptEngine* engine, ScriptAudioInjector* const& in) {
|
ScriptValuePointer injectorToScriptValue(ScriptEngine* engine, ScriptAudioInjector* const& in) {
|
||||||
// The AudioScriptingInterface::playSound method can return null, so we need to account for that.
|
// The AudioScriptingInterface::playSound method can return null, so we need to account for that.
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptAudioInjector.h
|
// ScriptAudioInjector.h
|
||||||
// libraries/script-engine/src
|
// libraries/audio/src
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 2015-02-11.
|
// Created by Stephen Birarda on 2015-02-11.
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
#include <AudioInjectorManager.h>
|
#include "AudioInjectorManager.h"
|
||||||
|
|
||||||
class ScriptEngine;
|
class ScriptEngine;
|
||||||
class ScriptValue;
|
class ScriptValue;
|
|
@ -37,13 +37,14 @@
|
||||||
#include <shared/JSONHelpers.h>
|
#include <shared/JSONHelpers.h>
|
||||||
#include <ScriptEngine.h>
|
#include <ScriptEngine.h>
|
||||||
#include <ScriptEngineCast.h>
|
#include <ScriptEngineCast.h>
|
||||||
|
#include <ScriptManager.h>
|
||||||
#include <ScriptValueIterator.h>
|
#include <ScriptValueIterator.h>
|
||||||
|
#include <ScriptValueUtils.h>
|
||||||
#include <ShapeInfo.h>
|
#include <ShapeInfo.h>
|
||||||
#include <AudioHelpers.h>
|
#include <AudioHelpers.h>
|
||||||
#include <Profile.h>
|
#include <Profile.h>
|
||||||
#include <VariantMapToScriptValue.h>
|
#include <VariantMapToScriptValue.h>
|
||||||
#include <BitVectorHelpers.h>
|
#include <BitVectorHelpers.h>
|
||||||
#include <ScriptValueUtils.h>
|
|
||||||
|
|
||||||
#include "AvatarLogging.h"
|
#include "AvatarLogging.h"
|
||||||
#include "AvatarTraits.h"
|
#include "AvatarTraits.h"
|
||||||
|
@ -67,6 +68,14 @@ static const float DEFAULT_AVATAR_DENSITY = 1000.0f; // density of water
|
||||||
|
|
||||||
#define ASSERT(COND) do { if (!(COND)) { abort(); } } while(0)
|
#define ASSERT(COND) do { if (!(COND)) { abort(); } } while(0)
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager) {
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
registerAvatarTypes(scriptEngine);
|
||||||
|
scriptRegisterMetaType(scriptEngine, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue);
|
||||||
|
scriptRegisterMetaType(scriptEngine, AvatarEntityMapToScriptValue, AvatarEntityMapFromScriptValue);
|
||||||
|
});
|
||||||
|
|
||||||
size_t AvatarDataPacket::maxFaceTrackerInfoSize(size_t numBlendshapeCoefficients) {
|
size_t AvatarDataPacket::maxFaceTrackerInfoSize(size_t numBlendshapeCoefficients) {
|
||||||
return FACE_TRACKER_INFO_SIZE + numBlendshapeCoefficients * sizeof(float);
|
return FACE_TRACKER_INFO_SIZE + numBlendshapeCoefficients * sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,25 @@
|
||||||
|
|
||||||
#include "ScriptAvatarData.h"
|
#include "ScriptAvatarData.h"
|
||||||
|
|
||||||
|
#include <ScriptEngineCast.h>
|
||||||
|
#include <ScriptManager.h>
|
||||||
|
|
||||||
|
ScriptValuePointer avatarDataToScriptValue(ScriptEngine* engine, ScriptAvatarData* const& in) {
|
||||||
|
return engine->newQObject(in, ScriptEngine::ScriptOwnership);
|
||||||
|
}
|
||||||
|
|
||||||
|
void avatarDataFromScriptValue(const ScriptValuePointer& object, ScriptAvatarData*& out) {
|
||||||
|
// This is not implemented because there are no slots/properties that take an AvatarSharedPointer from a script
|
||||||
|
assert(false);
|
||||||
|
out = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager) {
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
scriptRegisterMetaType(scriptEngine, avatarDataToScriptValue, avatarDataFromScriptValue);
|
||||||
|
});
|
||||||
|
|
||||||
ScriptAvatarData::ScriptAvatarData(AvatarSharedPointer avatarData) :
|
ScriptAvatarData::ScriptAvatarData(AvatarSharedPointer avatarData) :
|
||||||
_avatarData(avatarData)
|
_avatarData(avatarData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,27 @@
|
||||||
#include "InputDevice.h"
|
#include "InputDevice.h"
|
||||||
#include "InputRecorder.h"
|
#include "InputRecorder.h"
|
||||||
|
|
||||||
|
#include <ScriptEngine.h>
|
||||||
|
#include <ScriptEngineCast.h>
|
||||||
|
#include <ScriptManager.h>
|
||||||
|
#include <ScriptValue.h>
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(controller::InputController*)
|
||||||
|
//static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
|
||||||
|
|
||||||
|
ScriptValuePointer inputControllerToScriptValue(ScriptEngine* engine, controller::InputController* const& in) {
|
||||||
|
return engine->newQObject(in, ScriptEngine::QtOwnership);
|
||||||
|
}
|
||||||
|
|
||||||
|
void inputControllerFromScriptValue(const ScriptValuePointer& object, controller::InputController*& out) {
|
||||||
|
out = qobject_cast<controller::InputController*>(object->toQObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager) {
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
scriptRegisterMetaType(scriptEngine, inputControllerToScriptValue, inputControllerFromScriptValue);
|
||||||
|
});
|
||||||
|
|
||||||
static QRegularExpression SANITIZE_NAME_EXPRESSION{ "[\\(\\)\\.\\s]" };
|
static QRegularExpression SANITIZE_NAME_EXPRESSION{ "[\\(\\)\\.\\s]" };
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ModelScriptingInterface.cpp
|
// ModelScriptingInterface.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/entities-renderer/src
|
||||||
//
|
//
|
||||||
// Created by Seth Alves on 2017-1-27.
|
// Created by Seth Alves on 2017-1-27.
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
@ -11,12 +11,18 @@
|
||||||
|
|
||||||
#include "ModelScriptingInterface.h"
|
#include "ModelScriptingInterface.h"
|
||||||
#include <model-networking/SimpleMeshProxy.h>
|
#include <model-networking/SimpleMeshProxy.h>
|
||||||
#include "ScriptEngine.h"
|
#include <ScriptEngine.h>
|
||||||
#include "ScriptEngineCast.h"
|
#include <ScriptEngineCast.h>
|
||||||
#include "ScriptEngineLogging.h"
|
#include <ScriptEngineLogging.h>
|
||||||
#include "ScriptManager.h"
|
#include <ScriptManager.h>
|
||||||
#include "ScriptValueUtils.h"
|
#include <ScriptValueUtils.h>
|
||||||
#include "OBJWriter.h"
|
#include <OBJWriter.h>
|
||||||
|
|
||||||
|
STATIC_SCRIPT_INITIALIZER(+[](ScriptManager* manager) {
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
scriptEngine->registerGlobalObject("Model", new ModelScriptingInterface(manager));
|
||||||
|
});
|
||||||
|
|
||||||
ModelScriptingInterface::ModelScriptingInterface(QObject* parent) : QObject(parent) {
|
ModelScriptingInterface::ModelScriptingInterface(QObject* parent) : QObject(parent) {
|
||||||
_modelScriptEngine = qobject_cast<ScriptManager*>(parent)->engine();
|
_modelScriptEngine = qobject_cast<ScriptManager*>(parent)->engine();
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ModelScriptingInterface.h
|
// ModelScriptingInterface.h
|
||||||
// libraries/script-engine/src
|
// libraries/entities-renderer/src
|
||||||
//
|
//
|
||||||
// Created by Seth Alves on 2017-1-27.
|
// Created by Seth Alves on 2017-1-27.
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
|
@ -22,7 +22,7 @@
|
||||||
#include <QtConcurrent/QtConcurrentRun>
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
|
||||||
#include <model-networking/SimpleMeshProxy.h>
|
#include <model-networking/SimpleMeshProxy.h>
|
||||||
#include <ModelScriptingInterface.h>
|
#include "ModelScriptingInterface.h"
|
||||||
#include <EntityEditPacketSender.h>
|
#include <EntityEditPacketSender.h>
|
||||||
#include <PhysicalEntitySimulation.h>
|
#include <PhysicalEntitySimulation.h>
|
||||||
#include <StencilMaskPass.h>
|
#include <StencilMaskPass.h>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
set(TARGET_NAME entities)
|
set(TARGET_NAME entities)
|
||||||
setup_hifi_library(Network)
|
setup_hifi_library(Network)
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE "${OPENSSL_INCLUDE_DIR}")
|
target_include_directories(${TARGET_NAME} PRIVATE "${OPENSSL_INCLUDE_DIR}")
|
||||||
include_hifi_library_headers(animation)
|
|
||||||
include_hifi_library_headers(hfm)
|
include_hifi_library_headers(hfm)
|
||||||
include_hifi_library_headers(model-serializers)
|
include_hifi_library_headers(model-serializers)
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
|
|
|
@ -48,6 +48,36 @@
|
||||||
const QString GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":true}}";
|
const QString GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":true}}";
|
||||||
const QString NOT_GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":false}}";
|
const QString NOT_GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":false}}";
|
||||||
|
|
||||||
|
static void staticScriptInitializer(ScriptManager* manager) {
|
||||||
|
auto scriptEngine = manager->engine().data();
|
||||||
|
|
||||||
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
entityScriptingInterface->init();
|
||||||
|
auto ifacePtr = entityScriptingInterface.data(); // using this when we don't want to leak a reference
|
||||||
|
|
||||||
|
registerMetaTypes(scriptEngine);
|
||||||
|
|
||||||
|
scriptRegisterMetaType(scriptEngine, EntityPropertyFlagsToScriptValue, EntityPropertyFlagsFromScriptValue);
|
||||||
|
scriptRegisterMetaType(scriptEngine, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly);
|
||||||
|
scriptRegisterMetaType(scriptEngine, EntityPropertyInfoToScriptValue, EntityPropertyInfoFromScriptValue);
|
||||||
|
scriptRegisterMetaType(scriptEngine, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
||||||
|
scriptRegisterMetaType(scriptEngine, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
||||||
|
|
||||||
|
scriptEngine->registerGlobalObject("Entities", entityScriptingInterface.data());
|
||||||
|
scriptEngine->registerFunction("Entities", "getMultipleEntityProperties", EntityScriptingInterface::getMultipleEntityProperties);
|
||||||
|
|
||||||
|
// "The return value of QObject::sender() is not valid when the slot is called via a Qt::DirectConnection from a thread
|
||||||
|
// different from this object's thread. Do not use this function in this type of scenario."
|
||||||
|
// so... yay lambdas everywhere to get the sender
|
||||||
|
manager->connect(
|
||||||
|
manager, &ScriptManager::attachDefaultEventHandlers, entityScriptingInterface.data(),
|
||||||
|
[ifacePtr, manager] { ifacePtr->attachDefaultEventHandlers(manager); },
|
||||||
|
Qt::DirectConnection);
|
||||||
|
manager->connect(manager, &ScriptManager::releaseEntityPacketSenderMessages, entityScriptingInterface.data(),
|
||||||
|
&EntityScriptingInterface::releaseEntityPacketSenderMessages, Qt::DirectConnection);
|
||||||
|
}
|
||||||
|
STATIC_SCRIPT_INITIALIZER(staticScriptInitializer);
|
||||||
|
|
||||||
EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership) :
|
EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership) :
|
||||||
_entityTree(nullptr),
|
_entityTree(nullptr),
|
||||||
_bidOnSimulationOwnership(bidOnSimulationOwnership)
|
_bidOnSimulationOwnership(bidOnSimulationOwnership)
|
||||||
|
@ -67,6 +97,146 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
|
||||||
PacketReceiver::makeSourcedListenerReference<EntityScriptingInterface>(this, &EntityScriptingInterface::handleEntityScriptCallMethodPacket));
|
PacketReceiver::makeSourcedListenerReference<EntityScriptingInterface>(this, &EntityScriptingInterface::handleEntityScriptCallMethodPacket));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::releaseEntityPacketSenderMessages(bool wait) {
|
||||||
|
EntityEditPacketSender* entityPacketSender = getEntityPacketSender();
|
||||||
|
if (entityPacketSender->serversExist()) {
|
||||||
|
// release the queue of edit entity messages.
|
||||||
|
entityPacketSender->releaseQueuedMessages();
|
||||||
|
|
||||||
|
// since we're in non-threaded mode, call process so that the packets are sent
|
||||||
|
if (!entityPacketSender->isThreaded()) {
|
||||||
|
if (!wait) {
|
||||||
|
entityPacketSender->process();
|
||||||
|
} else {
|
||||||
|
// wait here till the edit packet sender is completely done sending
|
||||||
|
while (entityPacketSender->hasPacketsToSend()) {
|
||||||
|
entityPacketSender->process();
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// FIXME - do we need to have a similar "wait here" loop for non-threaded packet senders?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EntityScriptingInterface::attachDefaultEventHandlers(ScriptManager* manager) {
|
||||||
|
// Connect up ALL the handlers to the global entities object's signals.
|
||||||
|
// (We could go signal by signal, or even handler by handler, but I don't think the efficiency is worth the complexity.)
|
||||||
|
|
||||||
|
// Bug? These handlers are deleted when entityID is deleted, which is nice.
|
||||||
|
// But if they are created by an entity script on a different entity, should they also be deleted when the entity script unloads?
|
||||||
|
// E.g., suppose a bow has an entity script that causes arrows to be created with a potential lifetime greater than the bow,
|
||||||
|
// and that the entity script adds (e.g., collision) handlers to the arrows. Should those handlers fire if the bow is unloaded?
|
||||||
|
// Also, what about when the entity script is REloaded?
|
||||||
|
// For now, we are leaving them around. Changing that would require some non-trivial digging around to find the
|
||||||
|
// handlers that were added while a given currentEntityIdentifier was in place. I don't think this is dangerous. Just perhaps unexpected. -HRS
|
||||||
|
connect(this, &EntityScriptingInterface::deletingEntity, manager,
|
||||||
|
[manager](const EntityItemID& entityID) { manager->removeAllEventHandlers(entityID); });
|
||||||
|
|
||||||
|
// Two common cases of event handler, differing only in argument signature.
|
||||||
|
|
||||||
|
/*@jsdoc
|
||||||
|
* Called when an entity event occurs on an entity as registered with {@link Script.addEventHandler}.
|
||||||
|
* @callback Script~entityEventCallback
|
||||||
|
* @param {Uuid} entityID - The ID of the entity the event has occured on.
|
||||||
|
*/
|
||||||
|
using SingleEntityHandler = std::function<void(const EntityItemID&)>;
|
||||||
|
auto makeSingleEntityHandler = [manager](QString eventName) -> SingleEntityHandler {
|
||||||
|
return [manager, eventName](const EntityItemID& entityItemID) {
|
||||||
|
manager->forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(manager->engine().data()) });
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@jsdoc
|
||||||
|
* Called when a pointer event occurs on an entity as registered with {@link Script.addEventHandler}.
|
||||||
|
* @callback Script~pointerEventCallback
|
||||||
|
* @param {Uuid} entityID - The ID of the entity the event has occurred on.
|
||||||
|
* @param {PointerEvent} pointerEvent - Details of the event.
|
||||||
|
*/
|
||||||
|
using PointerHandler = std::function<void(const EntityItemID&, const PointerEvent&)>;
|
||||||
|
auto makePointerHandler = [manager](QString eventName) -> PointerHandler {
|
||||||
|
return [manager, eventName](const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||||
|
if (!EntityTree::areEntityClicksCaptured()) {
|
||||||
|
ScriptEngine* engine = manager->engine().data();
|
||||||
|
manager->forwardHandlerCall(entityItemID, eventName,
|
||||||
|
{ entityItemID.toScriptValue(engine), event.toScriptValue(engine) });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@jsdoc
|
||||||
|
* Called when a collision event occurs on an entity as registered with {@link Script.addEventHandler}.
|
||||||
|
* @callback Script~collisionEventCallback
|
||||||
|
* @param {Uuid} entityA - The ID of one entity in the collision.
|
||||||
|
* @param {Uuid} entityB - The ID of the other entity in the collision.
|
||||||
|
* @param {Collision} collisionEvent - Details of the collision.
|
||||||
|
*/
|
||||||
|
using CollisionHandler = std::function<void(const EntityItemID&, const EntityItemID&, const Collision&)>;
|
||||||
|
auto makeCollisionHandler = [manager](QString eventName) -> CollisionHandler {
|
||||||
|
return [manager, eventName](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
||||||
|
ScriptEngine* engine = manager->engine().data();
|
||||||
|
manager->forwardHandlerCall(idA, eventName,
|
||||||
|
{ idA.toScriptValue(engine), idB.toScriptValue(engine),
|
||||||
|
collisionToScriptValue(engine, collision) });
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@jsdoc
|
||||||
|
* <p>The name of an entity event. When the entity event occurs, any function that has been registered for that event
|
||||||
|
* via {@link Script.addEventHandler} is called with parameters per the entity event.</p>
|
||||||
|
* <table>
|
||||||
|
* <thead>
|
||||||
|
* <tr><th>Event Name</th><th>Callback Type</th><th>Entity Event</th></tr>
|
||||||
|
* </thead>
|
||||||
|
* <tbody>
|
||||||
|
* <tr><td><code>"enterEntity"</code></td><td>{@link Script~entityEventCallback|entityEventCallback}</td>
|
||||||
|
* <td>{@link Entities.enterEntity}</td></tr>
|
||||||
|
* <tr><td><code>"leaveEntity"</code></td><td>{@link Script~entityEventCallback|entityEventCallback}</td>
|
||||||
|
* <td>{@link Entities.leaveEntity}</td></tr>
|
||||||
|
* <tr><td><code>"mousePressOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.mousePressOnEntity}</td></tr>
|
||||||
|
* <tr><td><code>"mouseMoveOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.mouseMoveOnEntity}</td></tr>
|
||||||
|
* <tr><td><code>"mouseReleaseOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.mouseReleaseOnEntity}</td></tr>
|
||||||
|
* <tr><td><code>"clickDownOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.clickDownOnEntity}</td></tr>
|
||||||
|
* <tr><td><code>"holdingClickOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.holdingClickOnEntity}</td></tr>
|
||||||
|
* <tr><td><code>"clickReleaseOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.clickReleaseOnEntity}</td></tr>
|
||||||
|
* <tr><td><code>"hoverEnterEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.hoverEnterEntity}</td></tr>
|
||||||
|
* <tr><td><code>"hoverOverEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.hoverOverEntity}</td></tr>
|
||||||
|
* <tr><td><code>"hoverLeaveEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
||||||
|
* <td>{@link Entities.hoverLeaveEntity}</td></tr>
|
||||||
|
* <tr><td><code>"collisionWithEntity"</code><td>{@link Script~collisionEventCallback|collisionEventCallback}</td>
|
||||||
|
* </td><td>{@link Entities.collisionWithEntity}</td></tr>
|
||||||
|
* </tbody>
|
||||||
|
* </table>
|
||||||
|
* @typedef {string} Script.EntityEvent
|
||||||
|
*/
|
||||||
|
connect(this, &EntityScriptingInterface::enterEntity, manager, makeSingleEntityHandler("enterEntity"));
|
||||||
|
connect(this, &EntityScriptingInterface::leaveEntity, manager, makeSingleEntityHandler("leaveEntity"));
|
||||||
|
|
||||||
|
connect(this, &EntityScriptingInterface::mousePressOnEntity, manager, makePointerHandler("mousePressOnEntity"));
|
||||||
|
connect(this, &EntityScriptingInterface::mouseMoveOnEntity, manager, makePointerHandler("mouseMoveOnEntity"));
|
||||||
|
connect(this, &EntityScriptingInterface::mouseReleaseOnEntity, manager, makePointerHandler("mouseReleaseOnEntity"));
|
||||||
|
|
||||||
|
connect(this, &EntityScriptingInterface::clickDownOnEntity, manager, makePointerHandler("clickDownOnEntity"));
|
||||||
|
connect(this, &EntityScriptingInterface::holdingClickOnEntity, manager, makePointerHandler("holdingClickOnEntity"));
|
||||||
|
connect(this, &EntityScriptingInterface::clickReleaseOnEntity, manager, makePointerHandler("clickReleaseOnEntity"));
|
||||||
|
|
||||||
|
connect(this, &EntityScriptingInterface::hoverEnterEntity, manager, makePointerHandler("hoverEnterEntity"));
|
||||||
|
connect(this, &EntityScriptingInterface::hoverOverEntity, manager, makePointerHandler("hoverOverEntity"));
|
||||||
|
connect(this, &EntityScriptingInterface::hoverLeaveEntity, manager, makePointerHandler("hoverLeaveEntity"));
|
||||||
|
|
||||||
|
connect(this, &EntityScriptingInterface::collisionWithEntity, manager, makeCollisionHandler("collisionWithEntity"));
|
||||||
|
}
|
||||||
|
|
||||||
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
||||||
EntityItemID entityID, const EntityItemProperties& properties) {
|
EntityItemID entityID, const EntityItemProperties& properties) {
|
||||||
getEntityPacketSender()->queueEditEntityMessage(packetType, _entityTree, entityID, properties);
|
getEntityPacketSender()->queueEditEntityMessage(packetType, _entityTree, entityID, properties);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <RegisteredMetaTypes.h>
|
#include <RegisteredMetaTypes.h>
|
||||||
#include "PointerEvent.h"
|
#include "PointerEvent.h"
|
||||||
#include <PickFilter.h>
|
#include <PickFilter.h>
|
||||||
#include "ScriptManager.h"
|
#include <ScriptManager.h>
|
||||||
|
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
#include "LineEntityItem.h"
|
#include "LineEntityItem.h"
|
||||||
|
@ -2541,7 +2541,13 @@ protected:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void attachDefaultEventHandlers(ScriptManager* manager); // called on first call to Script.addEventHandler
|
||||||
|
friend void staticScriptInitializer(ScriptManager* manager);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void releaseEntityPacketSenderMessages(bool wait);
|
||||||
|
|
||||||
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
||||||
void onAddingEntity(EntityItem* entity);
|
void onAddingEntity(EntityItem* entity);
|
||||||
void onDeletingEntity(EntityItem* entity);
|
void onDeletingEntity(EntityItem* entity);
|
||||||
|
|
|
@ -323,7 +323,7 @@ namespace scriptable {
|
||||||
if (!object) {
|
if (!object) {
|
||||||
return engine->nullValue();
|
return engine->nullValue();
|
||||||
}
|
}
|
||||||
return engine->newQObject(object, ScriptEngine::QtOwnership, ScriptEngine::ExcludeDeleteLater | ScriptEngine::AutoCreateDynamicProperties);
|
return engine->newQObject(object, ScriptEngine::QtOwnership, ScriptEngine::AutoCreateDynamicProperties);
|
||||||
},
|
},
|
||||||
[](const ScriptValuePointer& value, QPointer<T>& out) {
|
[](const ScriptValuePointer& value, QPointer<T>& out) {
|
||||||
auto obj = value->toQObject();
|
auto obj = value->toQObject();
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "ObjectMotionState.h"
|
#include "ObjectMotionState.h"
|
||||||
#include "BulletUtil.h"
|
#include "BulletUtil.h"
|
||||||
#include "EntityDynamicInterface.h"
|
#include <EntityDynamicInterface.h>
|
||||||
|
|
||||||
|
|
||||||
class ObjectDynamic : public EntityDynamicInterface, public ReadWriteLockable {
|
class ObjectDynamic : public EntityDynamicInterface, public ReadWriteLockable {
|
||||||
|
|
|
@ -4,6 +4,6 @@ set(TARGET_NAME recording)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
|
|
||||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||||
link_hifi_libraries(shared networking)
|
link_hifi_libraries(shared networking script-engine)
|
||||||
|
|
||||||
GroupSources("src/recording")
|
GroupSources("src/recording")
|
||||||
|
|
|
@ -20,16 +20,16 @@
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
#include <Transform.h>
|
#include <Transform.h>
|
||||||
#include <recording/Deck.h>
|
#include "Deck.h"
|
||||||
#include <recording/Recorder.h>
|
#include "Recorder.h"
|
||||||
#include <recording/Clip.h>
|
#include "Clip.h"
|
||||||
#include <recording/Frame.h>
|
#include "Frame.h"
|
||||||
#include <recording/ClipCache.h>
|
#include "ClipCache.h"
|
||||||
|
|
||||||
#include "ScriptEngine.h"
|
#include <ScriptEngine.h>
|
||||||
#include "ScriptEngineLogging.h"
|
#include <ScriptEngineLogging.h>
|
||||||
#include "ScriptManager.h"
|
#include <ScriptManager.h>
|
||||||
#include "ScriptValue.h"
|
#include <ScriptValue.h>
|
||||||
|
|
||||||
using namespace recording;
|
using namespace recording;
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <recording/ClipCache.h>
|
#include "ClipCache.h"
|
||||||
#include <recording/Forward.h>
|
#include "Forward.h"
|
||||||
#include <recording/Frame.h>
|
#include "Frame.h"
|
||||||
|
|
||||||
class ScriptValue;
|
class ScriptValue;
|
||||||
using ScriptValuePointer = QSharedPointer<ScriptValue>;
|
using ScriptValuePointer = QSharedPointer<ScriptValue>;
|
|
@ -1,6 +1,6 @@
|
||||||
set(TARGET_NAME script-engine)
|
set(TARGET_NAME script-engine)
|
||||||
# FIXME Move undo scripting interface to application and remove Widgets
|
# FIXME Move undo scripting interface to application and remove Widgets
|
||||||
setup_hifi_library(Gui Network Script ScriptTools WebSockets)
|
setup_hifi_library(Network Script WebSockets)
|
||||||
|
|
||||||
target_zlib()
|
target_zlib()
|
||||||
if (NOT ANDROID)
|
if (NOT ANDROID)
|
||||||
|
@ -8,21 +8,6 @@ if (NOT ANDROID)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
link_hifi_libraries(shaders)
|
link_hifi_libraries(shaders)
|
||||||
include_hifi_library_headers(animation)
|
|
||||||
include_hifi_library_headers(audio)
|
|
||||||
include_hifi_library_headers(avatars)
|
|
||||||
include_hifi_library_headers(controllers)
|
|
||||||
include_hifi_library_headers(entities)
|
|
||||||
include_hifi_library_headers(gpu)
|
|
||||||
include_hifi_library_headers(hfm)
|
|
||||||
include_hifi_library_headers(image)
|
|
||||||
include_hifi_library_headers(ktx)
|
|
||||||
include_hifi_library_headers(graphics)
|
|
||||||
include_hifi_library_headers(material-networking)
|
|
||||||
include_hifi_library_headers(model-networking)
|
|
||||||
include_hifi_library_headers(model-serializers)
|
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
include_hifi_library_headers(octree)
|
include_hifi_library_headers(octree)
|
||||||
include_hifi_library_headers(procedural)
|
|
||||||
include_hifi_library_headers(recording)
|
|
||||||
include_hifi_library_headers(shared)
|
include_hifi_library_headers(shared)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// EntitiesScriptEngineProvider.h
|
// EntitiesScriptEngineProvider.h
|
||||||
// libraries/entities/src
|
// libraries/script-engine/src
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on Sept. 18, 2015
|
// Created by Brad Hefta-Gaub on Sept. 18, 2015
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// EntityItemID.cpp
|
// EntityItemID.cpp
|
||||||
// libraries/entities/src
|
// libraries/script-engine/src
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on 12/4/13.
|
// Created by Brad Hefta-Gaub on 12/4/13.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
@ -17,9 +17,9 @@
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
#include "RegisteredMetaTypes.h"
|
#include <RegisteredMetaTypes.h>
|
||||||
#include <ScriptValue.h>
|
#include "ScriptValue.h"
|
||||||
#include <ScriptValueUtils.h>
|
#include "ScriptValueUtils.h"
|
||||||
|
|
||||||
int entityItemIDTypeID = qRegisterMetaType<EntityItemID>();
|
int entityItemIDTypeID = qRegisterMetaType<EntityItemID>();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// EntityItemID.h
|
// EntityItemID.h
|
||||||
// libraries/entities/src
|
// libraries/script-engine/src
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on 12/4/13.
|
// Created by Brad Hefta-Gaub on 12/4/13.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// EntityScriptUtils.h
|
// EntityScriptUtils.h
|
||||||
// libraries/networking/src
|
// libraries/script-engine/src
|
||||||
//
|
//
|
||||||
// Created by Ryan Huffman on 2017/01/13
|
// Created by Ryan Huffman on 2017/01/13
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
|
@ -22,6 +22,7 @@
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ResourceCache.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
#include "ScriptEngines.h"
|
#include "ScriptEngines.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#define hifi_ScriptCache_h
|
#define hifi_ScriptCache_h
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <ResourceCache.h>
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
using contentAvailableCallback = std::function<void(const QString& scriptOrURL, const QString& contents, bool isURL, bool contentAvailable, const QString& status)>;
|
using contentAvailableCallback = std::function<void(const QString& scriptOrURL, const QString& contents, bool isURL, bool contentAvailable, const QString& status)>;
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
enum QObjectWrapOption {
|
enum QObjectWrapOption {
|
||||||
ExcludeChildObjects = 0x0001, // The script object will not expose child objects as properties.
|
//ExcludeChildObjects = 0x0001, // The script object will not expose child objects as properties.
|
||||||
ExcludeSuperClassMethods = 0x0002, // The script object will not expose signals and slots inherited from the superclass.
|
ExcludeSuperClassMethods = 0x0002, // The script object will not expose signals and slots inherited from the superclass.
|
||||||
ExcludeSuperClassProperties = 0x0004, // The script object will not expose properties inherited from the superclass.
|
ExcludeSuperClassProperties = 0x0004, // The script object will not expose properties inherited from the superclass.
|
||||||
ExcludeSuperClassContents = 0x0006, // Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties
|
ExcludeSuperClassContents = 0x0006, // Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties
|
||||||
ExcludeDeleteLater = 0x0010, // The script object will not expose the QObject::deleteLater() slot.
|
//ExcludeDeleteLater = 0x0010, // The script object will not expose the QObject::deleteLater() slot.
|
||||||
ExcludeSlots = 0x0020, // The script object will not expose the QObject's slots.
|
ExcludeSlots = 0x0020, // The script object will not expose the QObject's slots.
|
||||||
AutoCreateDynamicProperties = 0x0100, // Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object.
|
AutoCreateDynamicProperties = 0x0100, // Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object.
|
||||||
PreferExistingWrapperObject = 0x0200, // If a wrapper object with the requested configuration already exists, return that object.
|
PreferExistingWrapperObject = 0x0200, // If a wrapper object with the requested configuration already exists, return that object.
|
||||||
|
|
|
@ -24,55 +24,36 @@
|
||||||
#include <QtCore/QFuture>
|
#include <QtCore/QFuture>
|
||||||
#include <QtConcurrent/QtConcurrentRun>
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
|
||||||
#include <QtWidgets/QMainWindow>
|
|
||||||
#include <QtWidgets/QApplication>
|
|
||||||
#include <QtWidgets/QMenuBar>
|
|
||||||
#include <QtWidgets/QMenu>
|
|
||||||
|
|
||||||
#include <QtNetwork/QNetworkRequest>
|
|
||||||
#include <QtNetwork/QNetworkReply>
|
|
||||||
|
|
||||||
#include <shared/LocalFileAccessGate.h>
|
#include <shared/LocalFileAccessGate.h>
|
||||||
#include <shared/QtHelpers.h>
|
|
||||||
#include <shared/AbstractLoggerInterface.h>
|
#include <shared/AbstractLoggerInterface.h>
|
||||||
#include <AudioConstants.h>
|
|
||||||
#include <AudioEffectOptions.h>
|
|
||||||
#include <AvatarData.h>
|
|
||||||
#include <DebugDraw.h>
|
#include <DebugDraw.h>
|
||||||
#include <EntityScriptingInterface.h>
|
|
||||||
#include <MessagesClient.h>
|
#include <MessagesClient.h>
|
||||||
#include <NetworkAccessManager.h>
|
#include <OctreeConstants.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
#include <PortableHighResolutionClock.h>
|
||||||
|
#include <ResourceCache.h>
|
||||||
|
#include <ResourceManager.h>
|
||||||
#include <ResourceScriptingInterface.h>
|
#include <ResourceScriptingInterface.h>
|
||||||
#include <UserActivityLoggerScriptingInterface.h>
|
#include <UserActivityLoggerScriptingInterface.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <ScriptAvatarData.h>
|
|
||||||
#include <udt/PacketHeaders.h>
|
|
||||||
#include <UUID.h>
|
|
||||||
|
|
||||||
#include <controllers/ScriptingInterface.h>
|
|
||||||
#include <AnimationObject.h>
|
|
||||||
|
|
||||||
#include "AudioScriptingInterface.h"
|
|
||||||
#include "AssetScriptingInterface.h"
|
#include "AssetScriptingInterface.h"
|
||||||
#include "BatchLoader.h"
|
#include "BatchLoader.h"
|
||||||
#include "EventTypes.h"
|
#include "EventTypes.h"
|
||||||
#include "FileScriptingInterface.h" // unzip project
|
#include "FileScriptingInterface.h" // unzip project
|
||||||
#include "MenuItemProperties.h"
|
#include "MenuItemProperties.h"
|
||||||
#include "ScriptAudioInjector.h"
|
|
||||||
#include "ScriptAvatarData.h"
|
|
||||||
#include "ScriptCache.h"
|
#include "ScriptCache.h"
|
||||||
#include "ScriptContext.h"
|
#include "ScriptContext.h"
|
||||||
#include "ScriptEngineCast.h"
|
|
||||||
#include "ScriptEngineLogging.h"
|
|
||||||
#include "XMLHttpRequestClass.h"
|
#include "XMLHttpRequestClass.h"
|
||||||
#include "WebSocketClass.h"
|
#include "WebSocketClass.h"
|
||||||
#include "RecordingScriptingInterface.h"
|
#include "ScriptEngine.h"
|
||||||
|
#include "ScriptEngineCast.h"
|
||||||
|
#include "ScriptEngineLogging.h"
|
||||||
#include "ScriptEngines.h"
|
#include "ScriptEngines.h"
|
||||||
#include "StackTestScriptingInterface.h"
|
#include "StackTestScriptingInterface.h"
|
||||||
#include "ModelScriptingInterface.h"
|
|
||||||
#include "ScriptValue.h"
|
#include "ScriptValue.h"
|
||||||
#include "ScriptValueIterator.h"
|
#include "ScriptValueIterator.h"
|
||||||
|
#include "ScriptValueUtils.h"
|
||||||
|
|
||||||
#include <Profile.h>
|
#include <Profile.h>
|
||||||
|
|
||||||
|
@ -94,8 +75,6 @@ const QString ScriptManager::SCRIPT_BACKTRACE_SEP{ "\n " };
|
||||||
static const int MAX_MODULE_ID_LENGTH { 4096 };
|
static const int MAX_MODULE_ID_LENGTH { 4096 };
|
||||||
static const int MAX_DEBUG_VALUE_LENGTH { 80 };
|
static const int MAX_DEBUG_VALUE_LENGTH { 80 };
|
||||||
|
|
||||||
static const ScriptEngine::QObjectWrapOptions DEFAULT_QOBJECT_WRAP_OPTIONS =
|
|
||||||
ScriptEngine::ExcludeDeleteLater | ScriptEngine::ExcludeChildObjects;
|
|
||||||
static const ScriptValue::PropertyFlags READONLY_PROP_FLAGS{ ScriptValue::ReadOnly | ScriptValue::Undeletable };
|
static const ScriptValue::PropertyFlags READONLY_PROP_FLAGS{ ScriptValue::ReadOnly | ScriptValue::Undeletable };
|
||||||
static const ScriptValue::PropertyFlags READONLY_HIDDEN_PROP_FLAGS{ READONLY_PROP_FLAGS | ScriptValue::SkipInEnumeration };
|
static const ScriptValue::PropertyFlags READONLY_HIDDEN_PROP_FLAGS{ READONLY_PROP_FLAGS | ScriptValue::SkipInEnumeration };
|
||||||
|
|
||||||
|
@ -108,6 +87,26 @@ int scriptManagerPointerMetaID = qRegisterMetaType<ScriptManagerPointer>();
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ExternalResource::Bucket);
|
Q_DECLARE_METATYPE(ExternalResource::Bucket);
|
||||||
|
|
||||||
|
// --- Static script initialization registry
|
||||||
|
|
||||||
|
static ScriptManager::StaticInitializerNode* rootInitializer = nullptr;
|
||||||
|
|
||||||
|
void ScriptManager::registerNewStaticInitializer(StaticInitializerNode* dest) {
|
||||||
|
// this function is assumed to be called on LoadLibrary, where we are explicitly operating in single-threaded mode
|
||||||
|
// Therefore there is no mutex or threadsafety here and the structure is assumed not to change after loading
|
||||||
|
dest->prev = rootInitializer;
|
||||||
|
rootInitializer = dest;
|
||||||
|
}
|
||||||
|
static void runStaticInitializers(ScriptManager* manager) {
|
||||||
|
ScriptManager::StaticInitializerNode* here = rootInitializer;
|
||||||
|
while (here != nullptr) {
|
||||||
|
(*here->init)(manager);
|
||||||
|
here = here->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
static ScriptValuePointer debugPrint(ScriptContext* context, ScriptEngine* engine) {
|
static ScriptValuePointer debugPrint(ScriptContext* context, ScriptEngine* engine) {
|
||||||
// assemble the message by concatenating our arguments
|
// assemble the message by concatenating our arguments
|
||||||
QString message = "";
|
QString message = "";
|
||||||
|
@ -172,17 +171,6 @@ static ScriptValuePointer debugPrint(ScriptContext* context, ScriptEngine* engin
|
||||||
return ScriptValuePointer();
|
return ScriptValuePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(controller::InputController*)
|
|
||||||
//static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
|
|
||||||
|
|
||||||
ScriptValuePointer inputControllerToScriptValue(ScriptEngine* engine, controller::InputController* const& in) {
|
|
||||||
return engine->newQObject(in, ScriptEngine::QtOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void inputControllerFromScriptValue(const ScriptValuePointer& object, controller::InputController*& out) {
|
|
||||||
out = qobject_cast<controller::InputController*>(object->toQObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME Come up with a way to properly encode entity IDs in filename
|
// FIXME Come up with a way to properly encode entity IDs in filename
|
||||||
// The purpose of the following two function is to embed entity ids into entity script filenames
|
// The purpose of the following two function is to embed entity ids into entity script filenames
|
||||||
// so that they show up in stacktraces
|
// so that they show up in stacktraces
|
||||||
|
@ -522,28 +510,6 @@ void ScriptManager::clearDebugLogWindow() {
|
||||||
emit clearDebugWindow();
|
emit clearDebugWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of
|
|
||||||
// callAnimationStateHandler requires that the type be registered.
|
|
||||||
// These two are meaningful, if we ever do want to use them...
|
|
||||||
static ScriptValuePointer animVarMapToScriptValue(ScriptEngine* engine, const AnimVariantMap& parameters) {
|
|
||||||
QStringList unused;
|
|
||||||
return parameters.animVariantMapToScriptValue(engine, unused, false);
|
|
||||||
}
|
|
||||||
static void animVarMapFromScriptValue(const ScriptValuePointer& value, AnimVariantMap& parameters) {
|
|
||||||
parameters.animVariantMapFromScriptValue(value);
|
|
||||||
}
|
|
||||||
// ... while these two are not. But none of the four are ever used.
|
|
||||||
static ScriptValuePointer resultHandlerToScriptValue(ScriptEngine* engine,
|
|
||||||
const AnimVariantResultHandler& resultHandler) {
|
|
||||||
qCCritical(scriptengine) << "Attempt to marshall result handler to javascript";
|
|
||||||
assert(false);
|
|
||||||
return ScriptValuePointer();
|
|
||||||
}
|
|
||||||
static void resultHandlerFromScriptValue(const ScriptValuePointer& value, AnimVariantResultHandler& resultHandler) {
|
|
||||||
qCCritical(scriptengine) << "Attempt to marshall result handler from javascript";
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Templated qScriptRegisterMetaType fails to compile with raw pointers
|
// Templated qScriptRegisterMetaType fails to compile with raw pointers
|
||||||
using ScriptableResourceRawPtr = ScriptableResource*;
|
using ScriptableResourceRawPtr = ScriptableResource*;
|
||||||
|
|
||||||
|
@ -562,13 +528,10 @@ static ScriptValuePointer scriptableResourceToScriptValue(ScriptEngine* engine,
|
||||||
auto manager = engine->manager();
|
auto manager = engine->manager();
|
||||||
if (data && manager && !resource->isInScript()) {
|
if (data && manager && !resource->isInScript()) {
|
||||||
resource->setInScript(true);
|
resource->setInScript(true);
|
||||||
QObject::connect(data.data(), SIGNAL(updateSize(qint64)), manager, SLOT(updateMemoryCost(qint64)));
|
QObject::connect(data.data(), &Resource::updateSize, manager, &ScriptManager::updateMemoryCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto object = engine->newQObject(
|
auto object = engine->newQObject(const_cast<ScriptableResourceRawPtr>(resource), ScriptEngine::ScriptOwnership);
|
||||||
const_cast<ScriptableResourceRawPtr>(resource),
|
|
||||||
ScriptEngine::ScriptOwnership,
|
|
||||||
DEFAULT_QOBJECT_WRAP_OPTIONS);
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,22 +565,12 @@ static ScriptValuePointer createScriptableResourcePrototype(ScriptManagerPointer
|
||||||
}
|
}
|
||||||
|
|
||||||
auto prototypeState = engine->newQObject(state, ScriptEngine::QtOwnership,
|
auto prototypeState = engine->newQObject(state, ScriptEngine::QtOwnership,
|
||||||
ScriptEngine::ExcludeDeleteLater | ScriptEngine::ExcludeSlots | ScriptEngine::ExcludeSuperClassMethods);
|
ScriptEngine::ExcludeSlots | ScriptEngine::ExcludeSuperClassMethods);
|
||||||
prototype->setProperty("State", prototypeState);
|
prototype->setProperty("State", prototypeState);
|
||||||
|
|
||||||
return prototype;
|
return prototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptValuePointer avatarDataToScriptValue(ScriptEngine* engine, ScriptAvatarData* const& in) {
|
|
||||||
return engine->newQObject(in, ScriptEngine::ScriptOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void avatarDataFromScriptValue(const ScriptValuePointer& object, ScriptAvatarData*& out) {
|
|
||||||
// This is not implemented because there are no slots/properties that take an AvatarSharedPointer from a script
|
|
||||||
assert(false);
|
|
||||||
out = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScriptValuePointer externalResourceBucketToScriptValue(ScriptEngine* engine, ExternalResource::Bucket const& in) {
|
ScriptValuePointer externalResourceBucketToScriptValue(ScriptEngine* engine, ExternalResource::Bucket const& in) {
|
||||||
return engine->newValue((int)in);
|
return engine->newValue((int)in);
|
||||||
}
|
}
|
||||||
|
@ -666,27 +619,15 @@ void ScriptManager::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
|
runStaticInitializers(this);
|
||||||
|
|
||||||
auto scriptEngine = _engine.data();
|
auto scriptEngine = _engine.data();
|
||||||
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
|
||||||
entityScriptingInterface->init();
|
|
||||||
|
|
||||||
// register various meta-types
|
// register various meta-types
|
||||||
registerMetaTypes(scriptEngine);
|
|
||||||
registerMIDIMetaTypes(scriptEngine);
|
registerMIDIMetaTypes(scriptEngine);
|
||||||
registerEventTypes(scriptEngine);
|
registerEventTypes(scriptEngine);
|
||||||
registerMenuItemProperties(scriptEngine);
|
registerMenuItemProperties(scriptEngine);
|
||||||
registerAnimationTypes(scriptEngine);
|
|
||||||
registerAvatarTypes(scriptEngine);
|
|
||||||
registerAudioMetaTypes(scriptEngine);
|
|
||||||
|
|
||||||
scriptRegisterMetaType(scriptEngine, EntityPropertyFlagsToScriptValue, EntityPropertyFlagsFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly);
|
|
||||||
scriptRegisterMetaType(scriptEngine, EntityPropertyInfoToScriptValue, EntityPropertyInfoFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, AvatarEntityMapToScriptValue, AvatarEntityMapFromScriptValue);
|
|
||||||
scriptRegisterSequenceMetaType<QVector<QUuid>>(scriptEngine);
|
scriptRegisterSequenceMetaType<QVector<QUuid>>(scriptEngine);
|
||||||
scriptRegisterSequenceMetaType<QVector<EntityItemID>>(scriptEngine);
|
scriptRegisterSequenceMetaType<QVector<EntityItemID>>(scriptEngine);
|
||||||
|
|
||||||
|
@ -709,12 +650,6 @@ void ScriptManager::init() {
|
||||||
*/
|
*/
|
||||||
scriptEngine->globalObject()->setProperty("print", scriptEngine->newFunction(debugPrint));
|
scriptEngine->globalObject()->setProperty("print", scriptEngine->newFunction(debugPrint));
|
||||||
|
|
||||||
ScriptValuePointer audioEffectOptionsConstructorValue = scriptEngine->newFunction(AudioEffectOptions::constructor);
|
|
||||||
scriptEngine->globalObject()->setProperty("AudioEffectOptions", audioEffectOptionsConstructorValue);
|
|
||||||
|
|
||||||
scriptRegisterMetaType(scriptEngine, injectorToScriptValue, injectorFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, inputControllerToScriptValue, inputControllerFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, avatarDataToScriptValue, avatarDataFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, animationDetailsToScriptValue, animationDetailsFromScriptValue);
|
scriptRegisterMetaType(scriptEngine, animationDetailsToScriptValue, animationDetailsFromScriptValue);
|
||||||
scriptRegisterMetaType(scriptEngine, webSocketToScriptValue, webSocketFromScriptValue);
|
scriptRegisterMetaType(scriptEngine, webSocketToScriptValue, webSocketFromScriptValue);
|
||||||
scriptRegisterMetaType(scriptEngine, qWSCloseCodeToScriptValue, qWSCloseCodeFromScriptValue);
|
scriptRegisterMetaType(scriptEngine, qWSCloseCodeToScriptValue, qWSCloseCodeFromScriptValue);
|
||||||
|
@ -737,13 +672,8 @@ void ScriptManager::init() {
|
||||||
scriptRegisterMetaType(scriptEngine, externalResourceBucketToScriptValue, externalResourceBucketFromScriptValue);
|
scriptRegisterMetaType(scriptEngine, externalResourceBucketToScriptValue, externalResourceBucketFromScriptValue);
|
||||||
scriptEngine->registerEnum("Script.ExternalPaths", QMetaEnum::fromType<ExternalResource::Bucket>());
|
scriptEngine->registerEnum("Script.ExternalPaths", QMetaEnum::fromType<ExternalResource::Bucket>());
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Audio", DependencyManager::get<AudioScriptingInterface>().data());
|
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Midi", DependencyManager::get<Midi>().data());
|
scriptEngine->registerGlobalObject("Midi", DependencyManager::get<Midi>().data());
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Entities", entityScriptingInterface.data());
|
|
||||||
scriptEngine->registerFunction("Entities", "getMultipleEntityProperties",
|
|
||||||
EntityScriptingInterface::getMultipleEntityProperties);
|
|
||||||
scriptEngine->registerGlobalObject("Quat", &_quatLibrary);
|
scriptEngine->registerGlobalObject("Quat", &_quatLibrary);
|
||||||
scriptEngine->registerGlobalObject("Vec3", &_vec3Library);
|
scriptEngine->registerGlobalObject("Vec3", &_vec3Library);
|
||||||
scriptEngine->registerGlobalObject("Mat4", &_mat4Library);
|
scriptEngine->registerGlobalObject("Mat4", &_mat4Library);
|
||||||
|
@ -762,9 +692,6 @@ void ScriptManager::init() {
|
||||||
scriptEngine->registerFunction("console", "groupCollapsed", ConsoleScriptingInterface::groupCollapsed, 1);
|
scriptEngine->registerFunction("console", "groupCollapsed", ConsoleScriptingInterface::groupCollapsed, 1);
|
||||||
scriptEngine->registerFunction("console", "groupEnd", ConsoleScriptingInterface::groupEnd, 0);
|
scriptEngine->registerFunction("console", "groupEnd", ConsoleScriptingInterface::groupEnd, 0);
|
||||||
|
|
||||||
scriptRegisterMetaType(scriptEngine, animVarMapToScriptValue, animVarMapFromScriptValue);
|
|
||||||
scriptRegisterMetaType(scriptEngine, resultHandlerToScriptValue, resultHandlerFromScriptValue);
|
|
||||||
|
|
||||||
// Scriptable cache access
|
// Scriptable cache access
|
||||||
auto resourcePrototype = createScriptableResourcePrototype(qSharedPointerCast<ScriptManager>(sharedFromThis()));
|
auto resourcePrototype = createScriptableResourcePrototype(qSharedPointerCast<ScriptManager>(sharedFromThis()));
|
||||||
scriptEngine->globalObject()->setProperty("Resource", resourcePrototype);
|
scriptEngine->globalObject()->setProperty("Resource", resourcePrototype);
|
||||||
|
@ -779,7 +706,6 @@ void ScriptManager::init() {
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("DebugDraw", &DebugDraw::getInstance());
|
scriptEngine->registerGlobalObject("DebugDraw", &DebugDraw::getInstance());
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Model", new ModelScriptingInterface(this));
|
|
||||||
scriptRegisterMetaType(scriptEngine, meshToScriptValue, meshFromScriptValue);
|
scriptRegisterMetaType(scriptEngine, meshToScriptValue, meshFromScriptValue);
|
||||||
scriptRegisterMetaType(scriptEngine, meshesToScriptValue, meshesFromScriptValue);
|
scriptRegisterMetaType(scriptEngine, meshesToScriptValue, meshesFromScriptValue);
|
||||||
|
|
||||||
|
@ -825,6 +751,22 @@ void ScriptManager::removeEventHandler(const EntityItemID& entityID, const QStri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unregister all event handlers for the specified entityID (i.e. the entity is being removed)
|
||||||
|
void ScriptManager::removeAllEventHandlers(const EntityItemID& entityID) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
#ifdef THREAD_DEBUGGING
|
||||||
|
qCDebug(scriptengine) << "*** WARNING *** ScriptManager::removeAllEventHandlers() called on wrong thread [" << QThread::currentThread() << ", correct thread is " << thread() << " ], ignoring "
|
||||||
|
"entityID:" << entityID;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_registeredHandlers.contains(entityID)) {
|
||||||
|
_registeredHandlers.remove(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Register the handler.
|
// Register the handler.
|
||||||
void ScriptManager::addEventHandler(const EntityItemID& entityID, const QString& eventName, ScriptValuePointer handler) {
|
void ScriptManager::addEventHandler(const EntityItemID& entityID, const QString& eventName, ScriptValuePointer handler) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
|
@ -843,117 +785,9 @@ void ScriptManager::addEventHandler(const EntityItemID& entityID, const QString&
|
||||||
qCDebug(scriptengine) << "ScriptManager::addEventHandler() called on thread [" << QThread::currentThread() << "] entityID:" << entityID << " eventName : " << eventName;
|
qCDebug(scriptengine) << "ScriptManager::addEventHandler() called on thread [" << QThread::currentThread() << "] entityID:" << entityID << " eventName : " << eventName;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_registeredHandlers.count() == 0) { // First time any per-entity handler has been added in this script...
|
if (_registeredHandlers.count() == 0) {
|
||||||
// Connect up ALL the handlers to the global entities object's signals.
|
// First time any per-entity handler has been added in this script...
|
||||||
// (We could go signal by signal, or even handler by handler, but I don't think the efficiency is worth the complexity.)
|
emit attachDefaultEventHandlers();
|
||||||
auto entities = DependencyManager::get<EntityScriptingInterface>();
|
|
||||||
// Bug? These handlers are deleted when entityID is deleted, which is nice.
|
|
||||||
// But if they are created by an entity script on a different entity, should they also be deleted when the entity script unloads?
|
|
||||||
// E.g., suppose a bow has an entity script that causes arrows to be created with a potential lifetime greater than the bow,
|
|
||||||
// and that the entity script adds (e.g., collision) handlers to the arrows. Should those handlers fire if the bow is unloaded?
|
|
||||||
// Also, what about when the entity script is REloaded?
|
|
||||||
// For now, we are leaving them around. Changing that would require some non-trivial digging around to find the
|
|
||||||
// handlers that were added while a given currentEntityIdentifier was in place. I don't think this is dangerous. Just perhaps unexpected. -HRS
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::deletingEntity, this, [this](const EntityItemID& entityID) {
|
|
||||||
_registeredHandlers.remove(entityID);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Two common cases of event handler, differing only in argument signature.
|
|
||||||
|
|
||||||
/*@jsdoc
|
|
||||||
* Called when an entity event occurs on an entity as registered with {@link Script.addEventHandler}.
|
|
||||||
* @callback Script~entityEventCallback
|
|
||||||
* @param {Uuid} entityID - The ID of the entity the event has occured on.
|
|
||||||
*/
|
|
||||||
using SingleEntityHandler = std::function<void(const EntityItemID&)>;
|
|
||||||
auto makeSingleEntityHandler = [this](QString eventName) -> SingleEntityHandler {
|
|
||||||
return [this, eventName](const EntityItemID& entityItemID) {
|
|
||||||
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(_engine.data()) });
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@jsdoc
|
|
||||||
* Called when a pointer event occurs on an entity as registered with {@link Script.addEventHandler}.
|
|
||||||
* @callback Script~pointerEventCallback
|
|
||||||
* @param {Uuid} entityID - The ID of the entity the event has occurred on.
|
|
||||||
* @param {PointerEvent} pointerEvent - Details of the event.
|
|
||||||
*/
|
|
||||||
using PointerHandler = std::function<void(const EntityItemID&, const PointerEvent&)>;
|
|
||||||
auto makePointerHandler = [this](QString eventName) -> PointerHandler {
|
|
||||||
return [this, eventName](const EntityItemID& entityItemID, const PointerEvent& event) {
|
|
||||||
if (!EntityTree::areEntityClicksCaptured()) {
|
|
||||||
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(_engine.data()), event.toScriptValue(_engine.data()) });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@jsdoc
|
|
||||||
* Called when a collision event occurs on an entity as registered with {@link Script.addEventHandler}.
|
|
||||||
* @callback Script~collisionEventCallback
|
|
||||||
* @param {Uuid} entityA - The ID of one entity in the collision.
|
|
||||||
* @param {Uuid} entityB - The ID of the other entity in the collision.
|
|
||||||
* @param {Collision} collisionEvent - Details of the collision.
|
|
||||||
*/
|
|
||||||
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(_engine.data()), idB.toScriptValue(_engine.data()),
|
|
||||||
collisionToScriptValue(_engine.data(), collision) });
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*@jsdoc
|
|
||||||
* <p>The name of an entity event. When the entity event occurs, any function that has been registered for that event
|
|
||||||
* via {@link Script.addEventHandler} is called with parameters per the entity event.</p>
|
|
||||||
* <table>
|
|
||||||
* <thead>
|
|
||||||
* <tr><th>Event Name</th><th>Callback Type</th><th>Entity Event</th></tr>
|
|
||||||
* </thead>
|
|
||||||
* <tbody>
|
|
||||||
* <tr><td><code>"enterEntity"</code></td><td>{@link Script~entityEventCallback|entityEventCallback}</td>
|
|
||||||
* <td>{@link Entities.enterEntity}</td></tr>
|
|
||||||
* <tr><td><code>"leaveEntity"</code></td><td>{@link Script~entityEventCallback|entityEventCallback}</td>
|
|
||||||
* <td>{@link Entities.leaveEntity}</td></tr>
|
|
||||||
* <tr><td><code>"mousePressOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.mousePressOnEntity}</td></tr>
|
|
||||||
* <tr><td><code>"mouseMoveOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.mouseMoveOnEntity}</td></tr>
|
|
||||||
* <tr><td><code>"mouseReleaseOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.mouseReleaseOnEntity}</td></tr>
|
|
||||||
* <tr><td><code>"clickDownOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.clickDownOnEntity}</td></tr>
|
|
||||||
* <tr><td><code>"holdingClickOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.holdingClickOnEntity}</td></tr>
|
|
||||||
* <tr><td><code>"clickReleaseOnEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.clickReleaseOnEntity}</td></tr>
|
|
||||||
* <tr><td><code>"hoverEnterEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.hoverEnterEntity}</td></tr>
|
|
||||||
* <tr><td><code>"hoverOverEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.hoverOverEntity}</td></tr>
|
|
||||||
* <tr><td><code>"hoverLeaveEntity"</code></td><td>{@link Script~pointerEventCallback|pointerEventCallback}</td>
|
|
||||||
* <td>{@link Entities.hoverLeaveEntity}</td></tr>
|
|
||||||
* <tr><td><code>"collisionWithEntity"</code><td>{@link Script~collisionEventCallback|collisionEventCallback}</td>
|
|
||||||
* </td><td>{@link Entities.collisionWithEntity}</td></tr>
|
|
||||||
* </tbody>
|
|
||||||
* </table>
|
|
||||||
* @typedef {string} Script.EntityEvent
|
|
||||||
*/
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::enterEntity, this, makeSingleEntityHandler("enterEntity"));
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, makeSingleEntityHandler("leaveEntity"));
|
|
||||||
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::mousePressOnEntity, this, makePointerHandler("mousePressOnEntity"));
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, makePointerHandler("mouseMoveOnEntity"));
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, makePointerHandler("mouseReleaseOnEntity"));
|
|
||||||
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::clickDownOnEntity, this, makePointerHandler("clickDownOnEntity"));
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::holdingClickOnEntity, this, makePointerHandler("holdingClickOnEntity"));
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::clickReleaseOnEntity, this, makePointerHandler("clickReleaseOnEntity"));
|
|
||||||
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::hoverEnterEntity, this, makePointerHandler("hoverEnterEntity"));
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, makePointerHandler("hoverOverEntity"));
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, makePointerHandler("hoverLeaveEntity"));
|
|
||||||
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, makeCollisionHandler("collisionWithEntity"));
|
|
||||||
}
|
}
|
||||||
if (!_registeredHandlers.contains(entityID)) {
|
if (!_registeredHandlers.contains(entityID)) {
|
||||||
_registeredHandlers[entityID] = RegisteredEventHandlers();
|
_registeredHandlers[entityID] = RegisteredEventHandlers();
|
||||||
|
@ -1008,9 +842,6 @@ void ScriptManager::run() {
|
||||||
clock::time_point startTime = clock::now();
|
clock::time_point startTime = clock::now();
|
||||||
int thisFrame = 0;
|
int thisFrame = 0;
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
|
||||||
|
|
||||||
_lastUpdate = usecTimestampNow();
|
_lastUpdate = usecTimestampNow();
|
||||||
|
|
||||||
std::chrono::microseconds totalUpdates(0);
|
std::chrono::microseconds totalUpdates(0);
|
||||||
|
@ -1050,7 +881,7 @@ void ScriptManager::run() {
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
QTimer timer;
|
QTimer timer;
|
||||||
timer.setSingleShot(true);
|
timer.setSingleShot(true);
|
||||||
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||||
timer.start(sleepFor.count());
|
timer.start(sleepFor.count());
|
||||||
loop.exec();
|
loop.exec();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1092,14 +923,8 @@ void ScriptManager::run() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_isFinished && entityScriptingInterface->getEntityPacketSender()->serversExist()) {
|
if (!_isFinished) {
|
||||||
// release the queue of edit entity messages.
|
emit releaseEntityPacketSenderMessages(false);
|
||||||
entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages();
|
|
||||||
|
|
||||||
// since we're in non-threaded mode, call process so that the packets are sent
|
|
||||||
if (!entityScriptingInterface->getEntityPacketSender()->isThreaded()) {
|
|
||||||
entityScriptingInterface->getEntityPacketSender()->process();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 now = usecTimestampNow();
|
qint64 now = usecTimestampNow();
|
||||||
|
@ -1133,21 +958,7 @@ void ScriptManager::run() {
|
||||||
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
|
||||||
emit scriptEnding();
|
emit scriptEnding();
|
||||||
|
|
||||||
if (entityScriptingInterface->getEntityPacketSender()->serversExist()) {
|
emit releaseEntityPacketSenderMessages(true);
|
||||||
// release the queue of edit entity messages.
|
|
||||||
entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages();
|
|
||||||
|
|
||||||
// since we're in non-threaded mode, call process so that the packets are sent
|
|
||||||
if (!entityScriptingInterface->getEntityPacketSender()->isThreaded()) {
|
|
||||||
// wait here till the edit packet sender is completely done sending
|
|
||||||
while (entityScriptingInterface->getEntityPacketSender()->hasPacketsToSend()) {
|
|
||||||
entityScriptingInterface->getEntityPacketSender()->process();
|
|
||||||
QCoreApplication::processEvents();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// FIXME - do we need to have a similar "wait here" loop for non-threaded packet senders?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit finished(_fileNameString, qSharedPointerCast<ScriptManager>(sharedFromThis()));
|
emit finished(_fileNameString, qSharedPointerCast<ScriptManager>(sharedFromThis()));
|
||||||
|
|
||||||
|
@ -1203,34 +1014,6 @@ void ScriptManager::stop(bool marshal) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other threads can invoke this through invokeMethod, which causes the callback to be asynchronously executed in this script's thread.
|
|
||||||
void ScriptManager::callAnimationStateHandler(ScriptValuePointer callback, AnimVariantMap parameters, QStringList names, bool useNames, AnimVariantResultHandler resultHandler) {
|
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
#ifdef THREAD_DEBUGGING
|
|
||||||
qCDebug(scriptengine) << "*** WARNING *** ScriptManager::callAnimationStateHandler() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] name:" << name;
|
|
||||||
#endif
|
|
||||||
QMetaObject::invokeMethod(this, "callAnimationStateHandler",
|
|
||||||
Q_ARG(ScriptValuePointer, callback),
|
|
||||||
Q_ARG(AnimVariantMap, parameters),
|
|
||||||
Q_ARG(QStringList, names),
|
|
||||||
Q_ARG(bool, useNames),
|
|
||||||
Q_ARG(AnimVariantResultHandler, resultHandler));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ScriptValuePointer javascriptParameters = parameters.animVariantMapToScriptValue(_engine.get(), names, useNames);
|
|
||||||
ScriptValueList callingArguments;
|
|
||||||
callingArguments << javascriptParameters;
|
|
||||||
assert(currentEntityIdentifier.isInvalidID()); // No animation state handlers from entity scripts.
|
|
||||||
ScriptValuePointer result = callback->call(ScriptValuePointer(), callingArguments);
|
|
||||||
|
|
||||||
// validate result from callback function.
|
|
||||||
if (result->isValid() && result->isObject()) {
|
|
||||||
resultHandler(result);
|
|
||||||
} else {
|
|
||||||
qCWarning(scriptengine) << "ScriptManager::callAnimationStateHandler invalid return argument from callback, expected an object";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptManager::updateMemoryCost(const qint64& deltaSize) {
|
void ScriptManager::updateMemoryCost(const qint64& deltaSize) {
|
||||||
_engine->updateMemoryCost(deltaSize);
|
_engine->updateMemoryCost(deltaSize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <unordered_map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <QtCore/QEnableSharedFromThis>
|
#include <QtCore/QEnableSharedFromThis>
|
||||||
|
@ -29,10 +30,9 @@
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
#include <QtCore/QVariant>
|
#include <QtCore/QVariant>
|
||||||
|
|
||||||
#include <AnimVariant.h>
|
|
||||||
#include "EntityItemID.h"
|
#include "EntityItemID.h"
|
||||||
#include "EntitiesScriptEngineProvider.h"
|
#include "EntitiesScriptEngineProvider.h"
|
||||||
#include <EntityScriptUtils.h>
|
#include "EntityScriptUtils.h"
|
||||||
#include <ExternalResource.h>
|
#include <ExternalResource.h>
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
|
|
||||||
|
@ -44,8 +44,6 @@
|
||||||
#include "ScriptUUID.h"
|
#include "ScriptUUID.h"
|
||||||
#include "Vec3.h"
|
#include "Vec3.h"
|
||||||
|
|
||||||
class QScriptEngineDebugger;
|
|
||||||
|
|
||||||
static const QString NO_SCRIPT("");
|
static const QString NO_SCRIPT("");
|
||||||
|
|
||||||
static const int SCRIPT_FPS = 60;
|
static const int SCRIPT_FPS = 60;
|
||||||
|
@ -104,6 +102,10 @@ public:
|
||||||
QUrl definingSandboxURL { QUrl("about:EntityScript") };
|
QUrl definingSandboxURL { QUrl("about:EntityScript") };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// declare a static script initializer
|
||||||
|
#define STATIC_SCRIPT_INITIALIZER(init) \
|
||||||
|
static ScriptManager::StaticInitializerNode static_script_initializer_(init);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* The <code>Script</code> API provides facilities for working with scripts.
|
* The <code>Script</code> API provides facilities for working with scripts.
|
||||||
*
|
*
|
||||||
|
@ -159,19 +161,27 @@ public:
|
||||||
AGENT,
|
AGENT,
|
||||||
AVATAR
|
AVATAR
|
||||||
};
|
};
|
||||||
Q_ENUM(Type)
|
Q_ENUM(Type);
|
||||||
|
|
||||||
static int processLevelMaxRetries;
|
static int processLevelMaxRetries;
|
||||||
ScriptManager(Context context, const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString("about:ScriptEngine"));
|
ScriptManager(Context context, const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString("about:ScriptEngine"));
|
||||||
~ScriptManager();
|
~ScriptManager();
|
||||||
|
|
||||||
|
// static initialization support
|
||||||
|
typedef void (*ScriptManagerInitializer)(ScriptManager*);
|
||||||
|
class StaticInitializerNode {
|
||||||
|
public:
|
||||||
|
ScriptManagerInitializer init;
|
||||||
|
StaticInitializerNode* prev;
|
||||||
|
inline StaticInitializerNode(ScriptManagerInitializer&& pInit) : init(std::move(pInit)),prev(nullptr) { registerNewStaticInitializer(this); }
|
||||||
|
};
|
||||||
|
static void registerNewStaticInitializer(StaticInitializerNode* dest);
|
||||||
|
|
||||||
/// run the script in a dedicated thread. This will have the side effect of evalulating
|
/// run the script in a dedicated thread. This will have the side effect of evalulating
|
||||||
/// the current script contents and calling run(). Callers will likely want to register the script with external
|
/// the current script contents and calling run(). Callers will likely want to register the script with external
|
||||||
/// services before calling this.
|
/// services before calling this.
|
||||||
void runInThread();
|
void runInThread();
|
||||||
|
|
||||||
void runDebuggable();
|
|
||||||
|
|
||||||
/// run the script in the callers thread, exit when stop() is called.
|
/// run the script in the callers thread, exit when stop() is called.
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
@ -376,7 +386,7 @@ public:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Provides access to methods or objects provided in an external JavaScript or JSON file.
|
* Provides access to methods or objects provided in an external JavaScript or JSON file.
|
||||||
* See {@link https://docs.vircadia.dev/script/js-tips.html} for further details.
|
* See {@link https://docs.overte.org/script/js-tips.html} for further details.
|
||||||
* @function Script.require
|
* @function Script.require
|
||||||
* @param {string} module - The module to use. May be a JavaScript file, a JSON file, or the name of a system module such
|
* @param {string} module - The module to use. May be a JavaScript file, a JSON file, or the name of a system module such
|
||||||
* as <code>"appUi"</code> (i.e., the "appUi.js" system module JavaScript file).
|
* as <code>"appUi"</code> (i.e., the "appUi.js" system module JavaScript file).
|
||||||
|
@ -595,8 +605,6 @@ public:
|
||||||
// this is used by code in ScriptEngines.cpp during the "reload all" operation
|
// this is used by code in ScriptEngines.cpp during the "reload all" operation
|
||||||
bool isStopping() const { return _isStopping; }
|
bool isStopping() const { return _isStopping; }
|
||||||
|
|
||||||
bool isDebuggable() const { return _debuggable; }
|
|
||||||
|
|
||||||
void disconnectNonEssentialSignals();
|
void disconnectNonEssentialSignals();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -621,6 +629,13 @@ public:
|
||||||
|
|
||||||
void setScriptEngines(QSharedPointer<ScriptEngines>& scriptEngines) { _scriptEngines = scriptEngines; }
|
void setScriptEngines(QSharedPointer<ScriptEngines>& scriptEngines) { _scriptEngines = scriptEngines; }
|
||||||
|
|
||||||
|
// call all the registered event handlers on an entity for the specified name.
|
||||||
|
void forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, ScriptValueList eventHanderArgs);
|
||||||
|
|
||||||
|
// remove all event handlers for the specified entityID (i.e. the entity is being removed)
|
||||||
|
void removeAllEventHandlers(const EntityItemID& entityID);
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Gets the URL for an asset in an external resource bucket. (The location where the bucket is hosted may change over time
|
* Gets the URL for an asset in an external resource bucket. (The location where the bucket is hosted may change over time
|
||||||
* but this method will return the asset's current URL.)
|
* but this method will return the asset's current URL.)
|
||||||
|
@ -640,17 +655,6 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
|
||||||
* @function Script.callAnimationStateHandler
|
|
||||||
* @param {function} callback - Callback function.
|
|
||||||
* @param {object} parameters - Parameters.
|
|
||||||
* @param {string[]} names - Names.
|
|
||||||
* @param {boolean} useNames - Use names.
|
|
||||||
* @param {function} resultHandler - Result handler.
|
|
||||||
* @deprecated This function is deprecated and will be removed.
|
|
||||||
*/
|
|
||||||
void callAnimationStateHandler(ScriptValuePointer callback, AnimVariantMap parameters, QStringList names, bool useNames, AnimVariantResultHandler resultHandler);
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Script.updateMemoryCost
|
* @function Script.updateMemoryCost
|
||||||
* @param {number} deltaSize - Delta size.
|
* @param {number} deltaSize - Delta size.
|
||||||
|
@ -851,6 +855,14 @@ signals:
|
||||||
*/
|
*/
|
||||||
void unhandledException(const ScriptValuePointer& exception);
|
void unhandledException(const ScriptValuePointer& exception);
|
||||||
|
|
||||||
|
// Triggered once before the first call to Script.addEventHandler happens on this ScriptManager
|
||||||
|
// connections assumed to use Qt::DirectConnection; not for use by scripts
|
||||||
|
void attachDefaultEventHandlers();
|
||||||
|
|
||||||
|
// Triggered repeatedly in the scripting loop to ensure entity edit messages get processed properly
|
||||||
|
// connections assumed to use Qt::DirectConnection; not for use by scripts
|
||||||
|
void releaseEntityPacketSenderMessages(bool wait);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
@ -886,7 +898,6 @@ protected:
|
||||||
void stopTimer(QTimer* timer);
|
void stopTimer(QTimer* timer);
|
||||||
|
|
||||||
QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
|
QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
|
||||||
void forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, ScriptValueList eventHanderArgs);
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function Script.entityScriptContentAvailable
|
* @function Script.entityScriptContentAvailable
|
||||||
|
@ -921,8 +932,6 @@ protected:
|
||||||
EntityScriptContentAvailableMap _contentAvailableQueue;
|
EntityScriptContentAvailableMap _contentAvailableQueue;
|
||||||
|
|
||||||
bool _isThreaded { false };
|
bool _isThreaded { false };
|
||||||
QScriptEngineDebugger* _debugger { nullptr };
|
|
||||||
bool _debuggable { false };
|
|
||||||
qint64 _lastUpdate;
|
qint64 _lastUpdate;
|
||||||
|
|
||||||
QString _fileNameString;
|
QString _fileNameString;
|
||||||
|
|
|
@ -806,8 +806,7 @@ void animationDetailsFromScriptValue(const ScriptValuePointer& object, Animation
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptValuePointer meshToScriptValue(ScriptEngine* engine, MeshProxy* const& in) {
|
ScriptValuePointer meshToScriptValue(ScriptEngine* engine, MeshProxy* const& in) {
|
||||||
return engine->newQObject(in, ScriptEngine::QtOwnership,
|
return engine->newQObject(in, ScriptEngine::QtOwnership);
|
||||||
ScriptEngine::ExcludeDeleteLater | ScriptEngine::ExcludeChildObjects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void meshFromScriptValue(const ScriptValuePointer& value, MeshProxy*& out) {
|
void meshFromScriptValue(const ScriptValuePointer& value, MeshProxy*& out) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptContextQtAgent.cpp
|
// ScriptContextQtAgent.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 5/22/21.
|
// Created by Heather Anderson on 5/22/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptContextQtAgent.h
|
// ScriptContextQtAgent.h
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 5/22/21.
|
// Created by Heather Anderson on 5/22/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptContextQtWrapper.cpp
|
// ScriptContextQtWrapper.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 5/22/21.
|
// Created by Heather Anderson on 5/22/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptContextQtWrapper.h
|
// ScriptContextQtWrapper.h
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 5/22/21.
|
// Created by Heather Anderson on 5/22/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptEngineQtScript.cpp
|
// ScriptEngineQtScript.cpp
|
||||||
// libraries/script-engine-qtscript/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on 12/14/13.
|
// Created by Brad Hefta-Gaub on 12/14/13.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
@ -869,11 +869,11 @@ ScriptProgramPointer ScriptEngineQtScript::newProgram(const QString& sourceCode,
|
||||||
return ScriptProgramPointer(new ScriptProgramQtWrapper(this, result));
|
return ScriptProgramPointer(new ScriptProgramQtWrapper(this, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptValuePointer ScriptEngineQtScript::newQObject(QObject* obj,
|
ScriptValuePointer ScriptEngineQtScript::newQObject(QObject* object,
|
||||||
ScriptEngine::ValueOwnership ownership,
|
ScriptEngine::ValueOwnership ownership,
|
||||||
const ScriptEngine::QObjectWrapOptions& options) {
|
const ScriptEngine::QObjectWrapOptions& options) {
|
||||||
QScriptValue result = QScriptEngine::newQObject(obj, static_cast<QScriptEngine::ValueOwnership>(ownership),
|
QScriptValue result = QScriptEngine::newQObject(object, static_cast<QScriptEngine::ValueOwnership>(ownership),
|
||||||
(QScriptEngine::QObjectWrapOptions)(int)options);
|
(QScriptEngine::QObjectWrapOptions)((int)options | DEFAULT_QOBJECT_WRAP_OPTIONS));
|
||||||
return ScriptValuePointer(new ScriptValueQtWrapper(this, std::move(result)));
|
return ScriptValuePointer(new ScriptValueQtWrapper(this, std::move(result)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptEngineQtScript.h
|
// ScriptEngineQtScript.h
|
||||||
// libraries/script-engine-qtscript/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Brad Hefta-Gaub on 12/14/13.
|
// Created by Brad Hefta-Gaub on 12/14/13.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptProgramQtWrapper.cpp
|
// ScriptProgramQtWrapper.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 8/24/21.
|
// Created by Heather Anderson on 8/24/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptProgramQtWrapper.h
|
// ScriptProgramQtWrapper.h
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 5/21/21.
|
// Created by Heather Anderson on 5/21/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptValueIteratorQtWrapper.cpp
|
// ScriptValueIteratorQtWrapper.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 8/29/21.
|
// Created by Heather Anderson on 8/29/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptValueIteratorQtWrapper.h
|
// ScriptValueIteratorQtWrapper.h
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 8/29/21.
|
// Created by Heather Anderson on 8/29/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptValueQtWrapper.cpp
|
// ScriptValueQtWrapper.cpp
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 5/16/21.
|
// Created by Heather Anderson on 5/16/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// ScriptValueQtWrapper.h
|
// ScriptValueQtWrapper.h
|
||||||
// libraries/script-engine/src
|
// libraries/script-engine/src/qtscript
|
||||||
//
|
//
|
||||||
// Created by Heather Anderson on 5/16/21.
|
// Created by Heather Anderson on 5/16/21.
|
||||||
// Copyright 2021 Vircadia contributors.
|
// Copyright 2021 Vircadia contributors.
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
set(TARGET_NAME ui)
|
set(TARGET_NAME ui)
|
||||||
setup_hifi_library(OpenGL Multimedia Network Qml Quick WebChannel WebSockets XmlPatterns ${PLATFORM_QT_COMPONENTS})
|
setup_hifi_library(OpenGL Multimedia Network Qml Quick WebChannel WebSockets XmlPatterns ${PLATFORM_QT_COMPONENTS})
|
||||||
link_hifi_libraries(shared networking qml gl audio audio-client plugins pointers script-engine)
|
link_hifi_libraries(shared networking qml gl audio audio-client plugins pointers script-engine)
|
||||||
include_hifi_library_headers(animation)
|
|
||||||
include_hifi_library_headers(entities)
|
|
||||||
include_hifi_library_headers(controllers)
|
include_hifi_library_headers(controllers)
|
||||||
|
|
||||||
# Required for some low level GL interaction in the OffscreenQMLSurface
|
# Required for some low level GL interaction in the OffscreenQMLSurface
|
||||||
|
|
|
@ -36,7 +36,7 @@ ScriptValuePointer wrapperToScriptValue(ScriptEngine* engine, T* const &in) {
|
||||||
if (!in) {
|
if (!in) {
|
||||||
return engine->undefinedValue();
|
return engine->undefinedValue();
|
||||||
}
|
}
|
||||||
return engine->newQObject(in, ScriptEngine::QtOwnership, ScriptEngine::ExcludeDeleteLater | ScriptEngine::ExcludeChildObjects);
|
return engine->newQObject(in, ScriptEngine::QtOwnership);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -20,7 +20,7 @@ ScriptValuePointer toolbarToScriptValue(ScriptEngine* engine, ToolbarProxy* cons
|
||||||
if (!in) {
|
if (!in) {
|
||||||
return engine->undefinedValue();
|
return engine->undefinedValue();
|
||||||
}
|
}
|
||||||
return engine->newQObject(in, ScriptEngine::QtOwnership, ScriptEngine::ExcludeDeleteLater | ScriptEngine::ExcludeChildObjects);
|
return engine->newQObject(in, ScriptEngine::QtOwnership);
|
||||||
}
|
}
|
||||||
|
|
||||||
void toolbarFromScriptValue(const ScriptValuePointer& value, ToolbarProxy* &out) {
|
void toolbarFromScriptValue(const ScriptValuePointer& value, ToolbarProxy* &out) {
|
||||||
|
@ -31,7 +31,7 @@ ScriptValuePointer toolbarButtonToScriptValue(ScriptEngine* engine, ToolbarButto
|
||||||
if (!in) {
|
if (!in) {
|
||||||
return engine->undefinedValue();
|
return engine->undefinedValue();
|
||||||
}
|
}
|
||||||
return engine->newQObject(in, ScriptEngine::QtOwnership, ScriptEngine::ExcludeDeleteLater | ScriptEngine::ExcludeChildObjects);
|
return engine->newQObject(in, ScriptEngine::QtOwnership);
|
||||||
}
|
}
|
||||||
|
|
||||||
void toolbarButtonFromScriptValue(const ScriptValuePointer& value, ToolbarButtonProxy* &out) {
|
void toolbarButtonFromScriptValue(const ScriptValuePointer& value, ToolbarButtonProxy* &out) {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
set(TARGET_NAME JSAPIExample)
|
set(TARGET_NAME JSAPIExample)
|
||||||
setup_hifi_client_server_plugin(scripting)
|
setup_hifi_client_server_plugin(scripting)
|
||||||
link_hifi_libraries(shared plugins script-engine)
|
link_hifi_libraries(shared plugins script-engine)
|
||||||
include_hifi_library_headers(animation)
|
|
||||||
include_hifi_library_headers(entities)
|
|
||||||
include_hifi_library_headers(networking)
|
include_hifi_library_headers(networking)
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace REPLACE_ME_WITH_UNIQUE_NAME {
|
||||||
}
|
}
|
||||||
qCWarning(logger) << "registering w/ScriptInitializerMixin..." << scriptInit.data();
|
qCWarning(logger) << "registering w/ScriptInitializerMixin..." << scriptInit.data();
|
||||||
scriptInit->registerScriptInitializer([this](ScriptEngine* engine) {
|
scriptInit->registerScriptInitializer([this](ScriptEngine* engine) {
|
||||||
auto value = engine->newQObject(this, ScriptEngine::QtOwnership, ScriptEngine::ExcludeDeleteLater);
|
auto value = engine->newQObject(this, ScriptEngine::QtOwnership);
|
||||||
engine->globalObject()->setProperty(objectName(), value);
|
engine->globalObject()->setProperty(objectName(), value);
|
||||||
// qCDebug(logger) << "setGlobalInstance" << objectName() << engine->property("fileName");
|
// qCDebug(logger) << "setGlobalInstance" << objectName() << engine->property("fileName");
|
||||||
});
|
});
|
||||||
|
@ -175,7 +175,7 @@ namespace REPLACE_ME_WITH_UNIQUE_NAME {
|
||||||
raiseScriptingError(context(), "error creating scoped settings instance: " + error);
|
raiseScriptingError(context(), "error creating scoped settings instance: " + error);
|
||||||
return engine->nullValue();
|
return engine->nullValue();
|
||||||
}
|
}
|
||||||
return engine->newQObject(cppValue, ScriptEngine::ScriptOwnership, ScriptEngine::ExcludeDeleteLater);
|
return engine->newQObject(cppValue, ScriptEngine::ScriptOwnership);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue