implement support for Entities.callEntityServerMethod()

This commit is contained in:
ZappoMan 2017-10-21 20:27:35 -07:00
parent e85494b958
commit 934c9479af
7 changed files with 95 additions and 7 deletions

View file

@ -85,6 +85,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
auto timer = new QTimer(this);
@ -231,6 +232,33 @@ 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));
quint16 methodLength;
receivedMessage->readPrimitive(&methodLength);
auto methodData = receivedMessage->read(methodLength);
auto method = QString::fromUtf8(methodData);
quint16 paramCount;
receivedMessage->readPrimitive(&paramCount);
QStringList params;
for (int param = 0; param < paramCount; param++) {
quint16 paramLength;
receivedMessage->readPrimitive(&paramLength);
auto paramData = receivedMessage->read(paramLength);
auto paramString = QString::fromUtf8(paramData);
params << paramString;
}
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params);
}
}
void EntityScriptServer::run() {
// make sure we request our script once the agent connects to the domain
auto nodeList = DependencyManager::get<NodeList>();

View file

@ -54,6 +54,9 @@ private slots:
void pushLogs();
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
private:
void negotiateAudioFormat();
void selectAudioFormat(const QString& selectedCodecName);

View file

@ -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 {
PROFILE_RANGE(script_entities, __FUNCTION__);

View file

@ -188,11 +188,11 @@ public slots:
*/
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
* 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
* 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());
/// 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
* 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;

View file

@ -69,6 +69,36 @@ bool EntityScriptClient::reloadServerScript(QUuid entityID) {
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());
auto methodUtf8 = method.toUtf8();
quint16 methodLength = methodUtf8.length();
packetList->writePrimitive(methodLength);
packetList->write(methodUtf8);
quint16 paramCount = params.length();
packetList->writePrimitive(paramCount);
foreach(const QString& param, params) {
auto paramUtf8 = param.toUtf8();
quint16 paramLength = paramUtf8.length();
packetList->writePrimitive(paramLength);
packetList->write(paramUtf8);
}
nodeList->sendPacketList(std::move(packetList), *entityScriptServer);
}
}
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
auto nodeList = DependencyManager::get<NodeList>();
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);

View file

@ -58,6 +58,8 @@ public:
bool reloadServerScript(QUuid entityID);
MessageID getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback);
void callEntityServerMethod(QUuid id, const QString& method, const QStringList& params);
private slots:
void handleNodeKilled(SharedNodePointer node);

View file

@ -123,6 +123,7 @@ public:
ReplicatedBulkAvatarData,
OctreeFileReplacementFromUrl,
ChallengeOwnership,
EntityScriptCallMethod,
NUM_PACKET_TYPE
};