mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-10 05:09:51 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into blue
This commit is contained in:
commit
ccdda798c0
15 changed files with 233 additions and 142 deletions
|
@ -85,6 +85,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
||||||
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
||||||
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
||||||
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
||||||
|
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
|
||||||
|
|
||||||
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
|
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
|
||||||
auto timer = new QTimer(this);
|
auto timer = new QTimer(this);
|
||||||
|
@ -231,6 +232,27 @@ void EntityScriptServer::pushLogs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptServer::handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode) {
|
||||||
|
|
||||||
|
if (_entitiesScriptEngine && _entityViewer.getTree() && !_shuttingDown) {
|
||||||
|
auto entityID = QUuid::fromRfc4122(receivedMessage->read(NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
|
auto method = receivedMessage->readString();
|
||||||
|
|
||||||
|
quint16 paramCount;
|
||||||
|
receivedMessage->readPrimitive(¶mCount);
|
||||||
|
|
||||||
|
QStringList params;
|
||||||
|
for (int param = 0; param < paramCount; param++) {
|
||||||
|
auto paramString = receivedMessage->readString();
|
||||||
|
params << paramString;
|
||||||
|
}
|
||||||
|
|
||||||
|
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void EntityScriptServer::run() {
|
void EntityScriptServer::run() {
|
||||||
// make sure we request our script once the agent connects to the domain
|
// make sure we request our script once the agent connects to the domain
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
|
@ -54,6 +54,9 @@ private slots:
|
||||||
|
|
||||||
void pushLogs();
|
void pushLogs();
|
||||||
|
|
||||||
|
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void negotiateAudioFormat();
|
void negotiateAudioFormat();
|
||||||
void selectAudioFormat(const QString& selectedCodecName);
|
void selectAudioFormat(const QString& selectedCodecName);
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
import Hifi 1.0
|
import Hifi 1.0
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
import "toolbars"
|
import "toolbars"
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
|
|
||||||
|
@ -243,9 +245,15 @@ Item {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
acceptedButtons: Qt.LeftButton;
|
acceptedButtons: Qt.LeftButton;
|
||||||
onClicked: goFunction("hifi://" + hifiUrl);
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
|
goFunction("hifi://" + hifiUrl);
|
||||||
|
}
|
||||||
hoverEnabled: true;
|
hoverEnabled: true;
|
||||||
onEntered: hoverThunk();
|
onEntered: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
|
hoverThunk();
|
||||||
|
}
|
||||||
onExited: unhoverThunk();
|
onExited: unhoverThunk();
|
||||||
}
|
}
|
||||||
StateImage {
|
StateImage {
|
||||||
|
@ -261,6 +269,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function go() {
|
function go() {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
goFunction(drillDownToPlace ? ("/places/" + placeName) : ("/user_stories/" + storyId));
|
goFunction(drillDownToPlace ? ("/places/" + placeName) : ("/user_stories/" + storyId));
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// skyboxchanger.qml
|
// SkyboxChanger.qml
|
||||||
//
|
// qml/hifi
|
||||||
//
|
//
|
||||||
// Created by Cain Kilgore on 9th August 2017
|
// Created by Cain Kilgore on 9th August 2017
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
@ -9,33 +9,73 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick 2.5
|
||||||
|
import "../styles-uit"
|
||||||
|
import "../controls-uit" as HifiControls
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: root;
|
id: root;
|
||||||
|
HifiConstants { id: hifi; }
|
||||||
color: hifi.colors.baseGray;
|
|
||||||
|
property var defaultThumbnails: [];
|
||||||
|
property var defaultFulls: [];
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: skyboxModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSkyboxes() {
|
||||||
|
var xmlhttp = new XMLHttpRequest();
|
||||||
|
var url = "http://mpassets.highfidelity.com/5fbdbeef-1cf8-4954-811d-3d4acbba4dc9-v1/skyboxes.json";
|
||||||
|
xmlhttp.onreadystatechange = function() {
|
||||||
|
if (xmlhttp.readyState === XMLHttpRequest.DONE && xmlhttp.status === 200) {
|
||||||
|
sortSkyboxes(xmlhttp.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlhttp.open("GET", url, true);
|
||||||
|
xmlhttp.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortSkyboxes(response) {
|
||||||
|
var arr = JSON.parse(response);
|
||||||
|
var arrLength = arr.length;
|
||||||
|
for (var i = 0; i < arrLength; i++) {
|
||||||
|
defaultThumbnails.push(arr[i].thumb);
|
||||||
|
defaultFulls.push(arr[i].full);
|
||||||
|
skyboxModel.append({});
|
||||||
|
}
|
||||||
|
setSkyboxes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSkyboxes() {
|
||||||
|
for (var i = 0; i < skyboxModel.count; i++) {
|
||||||
|
skyboxModel.setProperty(i, "thumbnailPath", defaultThumbnails[i]);
|
||||||
|
skyboxModel.setProperty(i, "fullSkyboxPath", defaultFulls[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
getSkyboxes();
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: titleBarContainer;
|
id: titleBarContainer;
|
||||||
// Size
|
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
height: 50;
|
height: childrenRect.height;
|
||||||
// Anchors
|
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
RalewaySemiBold {
|
anchors.topMargin: 20;
|
||||||
|
RalewayBold {
|
||||||
id: titleBarText;
|
id: titleBarText;
|
||||||
text: "Skybox Changer";
|
text: "Skybox Changer";
|
||||||
// Text size
|
|
||||||
size: hifi.fontSizes.overlayTitle;
|
size: hifi.fontSizes.overlayTitle;
|
||||||
// Anchors
|
anchors.top: parent.top;
|
||||||
anchors.fill: parent;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 16;
|
anchors.leftMargin: 40
|
||||||
// Style
|
height: paintedHeight;
|
||||||
color: hifi.colors.lightGrayText;
|
color: hifi.colors.lightGrayText;
|
||||||
// Alignment
|
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
}
|
}
|
||||||
|
@ -43,131 +83,61 @@ Rectangle {
|
||||||
id: titleBarDesc;
|
id: titleBarDesc;
|
||||||
text: "Click an image to choose a new Skybox.";
|
text: "Click an image to choose a new Skybox.";
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
// Text size
|
|
||||||
size: 14;
|
size: 14;
|
||||||
// Anchors
|
anchors.top: titleBarText.bottom;
|
||||||
anchors.fill: parent;
|
anchors.left: parent.left;
|
||||||
anchors.top: titleBarText.bottom
|
anchors.leftMargin: 40
|
||||||
anchors.leftMargin: 16;
|
height: paintedHeight;
|
||||||
anchors.rightMargin: 16;
|
|
||||||
// Style
|
|
||||||
color: hifi.colors.lightGrayText;
|
color: hifi.colors.lightGrayText;
|
||||||
// Alignment
|
|
||||||
horizontalAlignment: Text.AlignHCenter;
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
verticalAlignment: Text.AlignVCenter;
|
verticalAlignment: Text.AlignVCenter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This RowLayout could be a GridLayout instead for further expandability.
|
GridView {
|
||||||
// As this SkyboxChanger task only required 6 images, implementing GridLayout wasn't necessary.
|
id: gridView
|
||||||
// In the future if this is to be expanded to add more Skyboxes, it might be worth changing this.
|
interactive: true
|
||||||
RowLayout {
|
clip: true
|
||||||
id: row1
|
|
||||||
anchors.top: titleBarContainer.bottom
|
anchors.top: titleBarContainer.bottom
|
||||||
anchors.left: parent.left
|
anchors.topMargin: 20
|
||||||
anchors.leftMargin: 30
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
Layout.fillWidth: true
|
width: 400
|
||||||
anchors.topMargin: 30
|
anchors.bottom: parent.bottom
|
||||||
spacing: 10
|
currentIndex: -1
|
||||||
Image {
|
cellWidth: 200
|
||||||
width: 200; height: 200
|
cellHeight: 200
|
||||||
fillMode: Image.Stretch
|
model: skyboxModel
|
||||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_1.jpg"
|
delegate: Item {
|
||||||
clip: true
|
width: gridView.cellWidth
|
||||||
id: preview1
|
height: gridView.cellHeight
|
||||||
MouseArea {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
Image {
|
||||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/1.jpg'});
|
source: thumbnailPath
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
fillMode: Image.Stretch
|
||||||
|
sourceSize.width: parent.width
|
||||||
|
sourceSize.height: parent.height
|
||||||
|
mipmap: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Image {
|
|
||||||
width: 200; height: 200
|
|
||||||
fillMode: Image.Stretch
|
|
||||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_2.jpg"
|
|
||||||
clip: true
|
|
||||||
id: preview2
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/2.png'});
|
sendToScript({method: 'changeSkybox', url: fullSkyboxPath});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
ScrollBar.vertical: ScrollBar {
|
||||||
RowLayout {
|
parent: gridView.parent
|
||||||
id: row2
|
anchors.top: gridView.top
|
||||||
anchors.top: row1.bottom
|
anchors.left: gridView.right
|
||||||
anchors.topMargin: 10
|
anchors.bottom: gridView.bottom
|
||||||
anchors.left: parent.left
|
anchors.leftMargin: 10
|
||||||
Layout.fillWidth: true
|
width: 19
|
||||||
anchors.leftMargin: 30
|
|
||||||
spacing: 10
|
|
||||||
Image {
|
|
||||||
width: 200; height: 200
|
|
||||||
fillMode: Image.Stretch
|
|
||||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_3.jpg"
|
|
||||||
clip: true
|
|
||||||
id: preview3
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/3.jpg'});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Image {
|
|
||||||
width: 200; height: 200
|
|
||||||
fillMode: Image.Stretch
|
|
||||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_4.jpg"
|
|
||||||
clip: true
|
|
||||||
id: preview4
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/4.jpg'});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
id: row3
|
|
||||||
anchors.top: row2.bottom
|
|
||||||
anchors.topMargin: 10
|
|
||||||
anchors.left: parent.left
|
|
||||||
Layout.fillWidth: true
|
|
||||||
anchors.leftMargin: 30
|
|
||||||
spacing: 10
|
|
||||||
Image {
|
|
||||||
width: 200; height: 200
|
|
||||||
fillMode: Image.Stretch
|
|
||||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_5.jpg"
|
|
||||||
clip: true
|
|
||||||
id: preview5
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/5.png'});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Image {
|
|
||||||
width: 200; height: 200
|
|
||||||
fillMode: Image.Stretch
|
|
||||||
source: "http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/thumbnails/thumb_6.jpg"
|
|
||||||
clip: true
|
|
||||||
id: preview6
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
sendToScript({method: 'changeSkybox', url: 'http://mpassets.highfidelity.com/05904016-8f7d-4dfc-88e1-2bf9ba3fac20-v1/skyboxes/6.jpg'});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
|
}
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: newEntityButton
|
id: newEntityButton
|
||||||
|
@ -122,9 +123,11 @@ Item {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
enabled: true
|
enabled: true
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonClick);
|
||||||
newEntityButton.clicked();
|
newEntityButton.clicked();
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
|
tabletInterface.playSound(TabletEnums.ButtonHover);
|
||||||
newEntityButton.state = "hover state";
|
newEntityButton.state = "hover state";
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
|
|
|
@ -5090,6 +5090,7 @@ void Application::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this->updateCamera(appRenderArgs._renderArgs);
|
this->updateCamera(appRenderArgs._renderArgs);
|
||||||
|
appRenderArgs._eyeToWorld = _myCamera.getTransform();
|
||||||
appRenderArgs._isStereo = false;
|
appRenderArgs._isStereo = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,6 +96,7 @@ void Line3DOverlay::setEnd(const glm::vec3& end) {
|
||||||
} else {
|
} else {
|
||||||
_direction = glm::vec3(0.0f);
|
_direction = glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
notifyRenderTransformChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Line3DOverlay::setLocalEnd(const glm::vec3& localEnd) {
|
void Line3DOverlay::setLocalEnd(const glm::vec3& localEnd) {
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
|
|
||||||
class EntitiesScriptEngineProvider {
|
class EntitiesScriptEngineProvider {
|
||||||
public:
|
public:
|
||||||
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params = QStringList()) = 0;
|
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
||||||
|
const QStringList& params = QStringList(), const QUuid& remoteCallerID = QUuid()) = 0;
|
||||||
virtual QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) = 0;
|
virtual QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -566,6 +566,11 @@ void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::callEntityServerMethod(QUuid id, const QString& method, const QStringList& params) {
|
||||||
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
DependencyManager::get<EntityScriptClient>()->callEntityServerMethod(id, method, params);
|
||||||
|
}
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
|
|
|
@ -188,11 +188,11 @@ public slots:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||||
|
|
||||||
/// Allows a script to call a method on an entity's script. The method will execute in the entity script
|
|
||||||
/// engine. If the entity does not have an entity script or the method does not exist, this call will have
|
|
||||||
/// no effect.
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Call a method on an entity. If it is running an entity script (specified by the `script` property)
|
* Call a method on an entity. Allows a script to call a method on an entity's script.
|
||||||
|
* The method will execute in the entity script engine. If the entity does not have an
|
||||||
|
* entity script or the method does not exist, this call will have no effect.
|
||||||
|
* If it is running an entity script (specified by the `script` property)
|
||||||
* and it exposes a property with the specified name `method`, it will be called
|
* and it exposes a property with the specified name `method`, it will be called
|
||||||
* using `params` as the list of arguments.
|
* using `params` as the list of arguments.
|
||||||
*
|
*
|
||||||
|
@ -203,10 +203,29 @@ public slots:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||||
|
|
||||||
/// finds the closest model to the center point, within the radius
|
|
||||||
/// will return a EntityItemID.isKnownID = false if no models are in the radius
|
|
||||||
/// this function will not find any models in script engine contexts which don't have access to models
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* Call a server method on an entity. Allows a client entity script to call a method on an
|
||||||
|
* entity's server script. The method will execute in the entity server script engine. If
|
||||||
|
* the entity does not have an entity server script or the method does not exist, this call will
|
||||||
|
* have no effect. If the entity is running an entity script (specified by the `serverScripts` property)
|
||||||
|
* and it exposes a property with the specified name `method`, it will be called using `params` as
|
||||||
|
* the list of arguments.
|
||||||
|
*
|
||||||
|
* @function Entities.callEntityServerMethod
|
||||||
|
* @param {EntityID} entityID The ID of the entity to call the method on.
|
||||||
|
* @param {string} method The name of the method to call.
|
||||||
|
* @param {string[]} params The list of parameters to call the specified method with.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* finds the closest model to the center point, within the radius
|
||||||
|
* will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||||
|
* this function will not find any models in script engine contexts which don't have access to models
|
||||||
|
* @function Entities.findClosestEntity
|
||||||
|
* @param {vec3} center point
|
||||||
|
* @param {float} radius to search
|
||||||
|
* @return {EntityID} The EntityID of the entity that is closest and in the radius.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QUuid findClosestEntity(const glm::vec3& center, float radius) const;
|
Q_INVOKABLE QUuid findClosestEntity(const glm::vec3& center, float radius) const;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,30 @@ bool EntityScriptClient::reloadServerScript(QUuid entityID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptClient::callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params) {
|
||||||
|
// Send packet to entity script server
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
||||||
|
|
||||||
|
if (entityScriptServer) {
|
||||||
|
auto packetList = NLPacketList::create(PacketType::EntityScriptCallMethod, QByteArray(), true, true);
|
||||||
|
|
||||||
|
packetList->write(entityID.toRfc4122());
|
||||||
|
|
||||||
|
packetList->writeString(method);
|
||||||
|
|
||||||
|
quint16 paramCount = params.length();
|
||||||
|
packetList->writePrimitive(paramCount);
|
||||||
|
|
||||||
|
foreach(const QString& param, params) {
|
||||||
|
packetList->writeString(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeList->sendPacketList(std::move(packetList), *entityScriptServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
|
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
||||||
|
|
|
@ -58,6 +58,8 @@ public:
|
||||||
|
|
||||||
bool reloadServerScript(QUuid entityID);
|
bool reloadServerScript(QUuid entityID);
|
||||||
MessageID getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback);
|
MessageID getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback);
|
||||||
|
void callEntityServerMethod(QUuid id, const QString& method, const QStringList& params);
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleNodeKilled(SharedNodePointer node);
|
void handleNodeKilled(SharedNodePointer node);
|
||||||
|
|
|
@ -123,6 +123,7 @@ public:
|
||||||
ReplicatedBulkAvatarData,
|
ReplicatedBulkAvatarData,
|
||||||
OctreeFileReplacementFromUrl,
|
OctreeFileReplacementFromUrl,
|
||||||
ChallengeOwnership,
|
ChallengeOwnership,
|
||||||
|
EntityScriptCallMethod,
|
||||||
NUM_PACKET_TYPE
|
NUM_PACKET_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2476,7 +2476,7 @@ void ScriptEngine::callWithEnvironment(const EntityItemID& entityID, const QUrl&
|
||||||
doWithEnvironment(entityID, sandboxURL, operation);
|
doWithEnvironment(entityID, sandboxURL, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params) {
|
void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params, const QUuid& remoteCallerID) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
#ifdef THREAD_DEBUGGING
|
#ifdef THREAD_DEBUGGING
|
||||||
qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
|
qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
|
||||||
|
@ -2486,7 +2486,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
QMetaObject::invokeMethod(this, "callEntityScriptMethod",
|
QMetaObject::invokeMethod(this, "callEntityScriptMethod",
|
||||||
Q_ARG(const EntityItemID&, entityID),
|
Q_ARG(const EntityItemID&, entityID),
|
||||||
Q_ARG(const QString&, methodName),
|
Q_ARG(const QString&, methodName),
|
||||||
Q_ARG(const QStringList&, params));
|
Q_ARG(const QStringList&, params),
|
||||||
|
Q_ARG(const QUuid&, remoteCallerID));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef THREAD_DEBUGGING
|
#ifdef THREAD_DEBUGGING
|
||||||
|
@ -2500,13 +2501,41 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
if (isEntityScriptRunning(entityID)) {
|
if (isEntityScriptRunning(entityID)) {
|
||||||
EntityScriptDetails details = _entityScripts[entityID];
|
EntityScriptDetails details = _entityScripts[entityID];
|
||||||
QScriptValue entityScript = details.scriptObject; // previously loaded
|
QScriptValue entityScript = details.scriptObject; // previously loaded
|
||||||
if (entityScript.property(methodName).isFunction()) {
|
|
||||||
|
// If this is a remote call, we need to check to see if the function is remotely callable
|
||||||
|
// we do this by checking for the existance of the 'remotelyCallable' property on the
|
||||||
|
// entityScript. And we confirm that the method name is included. If this fails, the
|
||||||
|
// function will not be called.
|
||||||
|
bool callAllowed = false;
|
||||||
|
if (remoteCallerID == QUuid()) {
|
||||||
|
callAllowed = true;
|
||||||
|
} else {
|
||||||
|
if (entityScript.property("remotelyCallable").isArray()) {
|
||||||
|
auto callables = entityScript.property("remotelyCallable");
|
||||||
|
auto callableCount = callables.property("length").toInteger();
|
||||||
|
for (int i = 0; i < callableCount; i++) {
|
||||||
|
auto callable = callables.property(i).toString();
|
||||||
|
if (callable == methodName) {
|
||||||
|
callAllowed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!callAllowed) {
|
||||||
|
qDebug() << "Method [" << methodName << "] not remotely callable.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callAllowed && entityScript.property(methodName).isFunction()) {
|
||||||
QScriptValueList args;
|
QScriptValueList args;
|
||||||
args << entityID.toScriptValue(this);
|
args << entityID.toScriptValue(this);
|
||||||
args << qScriptValueFromSequence(this, params);
|
args << qScriptValueFromSequence(this, params);
|
||||||
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
QScriptValue oldData = this->globalObject().property("Script").property("remoteCallerID");
|
||||||
|
this->globalObject().property("Script").setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global.
|
||||||
|
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
||||||
|
this->globalObject().property("Script").setProperty("remoteCallerID", oldData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,8 @@ public:
|
||||||
Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method
|
Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method
|
||||||
Q_INVOKABLE void unloadAllEntityScripts();
|
Q_INVOKABLE void unloadAllEntityScripts();
|
||||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
||||||
const QStringList& params = QStringList()) override;
|
const QStringList& params = QStringList(),
|
||||||
|
const QUuid& remoteCallerID = QUuid()) override;
|
||||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event);
|
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event);
|
||||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision);
|
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue