From 14026667f51d37b6b886f82aaee87516e1f06dc8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 4 Jun 2015 10:55:32 -0700 Subject: [PATCH] script interface for creating an action now takes an action-type name rather than having a different call for each action --- .../entities/src/EntityActionInterface.cpp | 39 +++++++++++++++++++ .../entities/src/EntityActionInterface.h | 6 +++ libraries/entities/src/EntityItem.cpp | 13 +------ libraries/entities/src/EntityItem.h | 2 +- .../entities/src/EntityScriptingInterface.cpp | 27 ++++++++----- .../entities/src/EntityScriptingInterface.h | 2 +- libraries/entities/src/EntityTree.h | 26 ++++++------- libraries/entities/src/EntityTreeElement.h | 1 - .../physics/src/PhysicalEntitySimulation.cpp | 38 +++++++++++++++--- 9 files changed, 112 insertions(+), 42 deletions(-) create mode 100644 libraries/entities/src/EntityActionInterface.cpp diff --git a/libraries/entities/src/EntityActionInterface.cpp b/libraries/entities/src/EntityActionInterface.cpp new file mode 100644 index 0000000000..8a230f73d6 --- /dev/null +++ b/libraries/entities/src/EntityActionInterface.cpp @@ -0,0 +1,39 @@ +// +// EntityItem.h +// libraries/entities/src +// +// Created by Seth Alves on 2015-6-4 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "EntityItem.h" + +#include "EntityActionInterface.h" + + +EntityActionType EntityActionInterface::actionTypeFromString(QString actionTypeString) { + QString normalizedActionTypeString = actionTypeString.toLower().remove('-').remove('_'); + if (normalizedActionTypeString == "none") { + return ACTION_TYPE_NONE; + } + if (normalizedActionTypeString == "pulltopoint") { + return ACTION_TYPE_PULL_TO_POINT; + } + + qDebug() << "Warning -- EntityActionInterface::actionTypeFromString got unknown action-type name" << actionTypeString; + return ACTION_TYPE_NONE; +} + +QString EntityActionInterface::actionTypeToString(EntityActionType actionType) { + switch(actionType) { + case ACTION_TYPE_NONE: + return "none"; + case ACTION_TYPE_PULL_TO_POINT: + return "pullToPoint"; + } + assert(false); + return "none"; +} diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index dc80282d78..72281fdc1d 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -12,9 +12,12 @@ #ifndef hifi_EntityActionInterface_h #define hifi_EntityActionInterface_h +#include + class EntitySimulation; enum EntityActionType { + // keep these synchronized with actionTypeFromString and actionTypeToString ACTION_TYPE_NONE, ACTION_TYPE_PULL_TO_POINT }; @@ -30,6 +33,9 @@ class EntityActionInterface { virtual void setOwnerEntity(const EntityItemPointer ownerEntity) = 0; // virtual QByteArray serialize() = 0; // static EntityActionInterface* deserialize(EntityItemPointer ownerEntity, QByteArray data); + + static EntityActionType actionTypeFromString(QString actionTypeString); + static QString actionTypeToString(EntityActionType actionType); }; #endif // hifi_EntityActionInterface_h diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 10954cb4f5..1a4c0fff63 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1338,7 +1338,7 @@ void EntityItem::updateSimulatorID(const QUuid& value) { } } -bool EntityItem::addAction(EntityActionInterface* action) { +bool EntityItem::addAction(EntitySimulation* simulation, EntityActionInterface* action) { assert(action); const QUuid& actionID = action->getID(); assert(!_objectActions.contains(actionID) || _objectActions[actionID] == action); @@ -1347,16 +1347,7 @@ bool EntityItem::addAction(EntityActionInterface* action) { assert(action->getOwnerEntity().get() == this); - if (_element) { - const EntityTree* tree = _element->getTree(); - if (tree) { - EntitySimulation* simulation = tree->getSimulation(); - if (simulation) { - simulation->addAction(action); - return true; - } - } - } + simulation->addAction(action); return false; } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index cf8a1fe584..5db3dd3d80 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -354,7 +354,7 @@ public: void getAllTerseUpdateProperties(EntityItemProperties& properties) const; - bool addAction(EntityActionInterface* actionID); + bool addAction(EntitySimulation* simulation, EntityActionInterface* actionID); void removeAction(EntitySimulation* simulation, const QUuid actionID); void clearActions(EntitySimulation* simulation); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f14109ee05..22b35b20b4 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -450,7 +450,7 @@ bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) { }); } -QUuid EntityScriptingInterface::addActionPullToPoint(QUuid entityID, const glm::vec3& target, float speed) { +QUuid EntityScriptingInterface::addAction(QString actionTypeString, QUuid entityID, QVariantMap arguments) { if (!_entityTree) { return QUuid(); } @@ -466,15 +466,24 @@ QUuid EntityScriptingInterface::addActionPullToPoint(QUuid entityID, const glm:: return QUuid(); } - QVariantMap arguments; - QVariantList targetList; - targetList << QVariant(target[0]) << QVariant(target[1]) << QVariant(target[2]); - arguments["target"] = targetList; - arguments["speed"] = QVariant(speed); - EntityActionInterface* action = simulation->actionFactory(ACTION_TYPE_PULL_TO_POINT, actionID, entity, arguments); - entity->addAction(action); + if (!simulation) { + qDebug() << "addAction -- no simulation" << entityID; + _entityTree->unlock(); + return QUuid(); + } + EntityActionType actionType = EntityActionInterface::actionTypeFromString(actionTypeString); + + if (actionType == ACTION_TYPE_NONE) { + _entityTree->unlock(); + return QUuid(); + } + + EntityActionInterface* action = simulation->actionFactory(actionType, actionID, entity, arguments); _entityTree->unlock(); - return actionID; + if (action) { + return actionID; + } + return QUuid(); } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 555cca14de..d5646d8fd0 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -124,7 +124,7 @@ public slots: Q_INVOKABLE void dumpTree() const; - Q_INVOKABLE QUuid addActionPullToPoint(QUuid entityID, const glm::vec3& target, float velocity); + Q_INVOKABLE QUuid addAction(QString actionTypeString, QUuid entityID, QVariantMap arguments); signals: void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index f8c06479ec..54a9193074 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -31,7 +31,7 @@ public: class EntityItemFBXService { public: virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) = 0; - virtual const Model* getModelForEntityItem(EntityItemPointer entityItem) = 0; + virtual const Model* getModelForEntityItem(EntityItemPointer entityItem) = 0; virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) = 0; }; @@ -63,23 +63,23 @@ public: // own definition. Implement these to allow your octree based server to support editing virtual bool getWantSVOfileVersions() const { return true; } virtual PacketType expectedDataPacketType() const { return PacketTypeEntityData; } - virtual bool canProcessVersion(PacketVersion thisVersion) const + virtual bool canProcessVersion(PacketVersion thisVersion) const { return thisVersion >= VERSION_ENTITIES_SUPPORT_SPLIT_MTU; } // we support all versions with split mtu virtual bool handlesEditPacketType(PacketType packetType) const; virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength, const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode); virtual bool rootElementHasData() const { return true; } - + // the root at least needs to store the number of entities in the packet/buffer virtual int minimumRequiredRootDataBytes() const { return sizeof(uint16_t); } virtual bool suppressEmptySubtrees() const { return false; } virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const; virtual bool mustIncludeAllChildData() const { return false; } - virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const + virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const { return thisVersion >= VERSION_ENTITIES_HAS_FILE_BREAKS; } - + virtual void update(); // The newer API... @@ -111,13 +111,13 @@ public: /// \param foundEntities[out] vector of EntityItemPointer /// \remark Side effect: any initial contents in foundEntities will be lost void findEntities(const glm::vec3& center, float radius, QVector& foundEntities); - + /// finds all entities that touch a cube /// \param cube the query cube in world-frame (meters) /// \param foundEntities[out] vector of non-EntityItemPointer /// \remark Side effect: any initial contents in entities will be lost void findEntities(const AACube& cube, QVector& foundEntities); - + /// finds all entities that touch a box /// \param box the query box in world-frame (meters) /// \param foundEntities[out] vector of non-EntityItemPointer @@ -129,13 +129,13 @@ public: bool hasAnyDeletedEntities() const { return _recentlyDeletedEntityItemIDs.size() > 0; } bool hasEntitiesDeletedSince(quint64 sinceTime); - bool encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime, + bool encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime, unsigned char* packetData, size_t maxLength, size_t& outputLength); void forgetEntitiesDeletedBefore(quint64 sinceTime); int processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); int processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); - + EntityItemFBXService* getFBXService() const { return _fbxService; } void setFBXService(EntityItemFBXService* service) { _fbxService = service; } const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) { @@ -144,7 +144,7 @@ public: const Model* getModelForEntityItem(EntityItemPointer entityItem) { return _fbxService ? _fbxService->getModelForEntityItem(entityItem) : NULL; } - + EntityTreeElement* getContainingElement(const EntityItemID& entityItemID) /*const*/; void setContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element); void debugDumpMap(); @@ -165,7 +165,7 @@ public: bool writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues); bool readFromMap(QVariantMap& entityDescription); - + float getContentsLargestDimension(); signals: @@ -178,7 +178,7 @@ signals: private: void processRemovedEntities(const DeleteEntityOperator& theOperator); - bool updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& properties, + bool updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& properties, EntityTreeElement* containingElement, const SharedNodePointer& senderNode = SharedNodePointer(nullptr)); static bool findNearPointOperation(OctreeElement* element, void* extraData); @@ -199,7 +199,7 @@ private: QHash _entityToElementMap; EntitySimulation* _simulation; - + bool _wantEditLogging = false; void maybeNotifyNewCollisionSoundURL(const QString& oldCollisionSoundURL, const QString& newCollisionSoundURL); }; diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index 589bf4033f..2504f947bd 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -152,7 +152,6 @@ public: bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; } void setTree(EntityTree* tree) { _myTree = tree; } - const EntityTree* getTree() const { return _myTree; } bool updateEntity(const EntityItem& entity); void addEntityItem(EntityItemPointer entity); diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 0d04c103de..5ad68ee7ab 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -238,19 +238,45 @@ EntityActionInterface* PhysicalEntitySimulation::actionFactory(EntityActionType QUuid id, EntityItemPointer ownerEntity, QVariantMap arguments) { + EntityActionInterface* action = nullptr; switch (type) { case ACTION_TYPE_NONE: - assert(false); return nullptr; case ACTION_TYPE_PULL_TO_POINT: - QVariantList target = arguments["target"].toList(); - glm::vec3 glmTarget(target[0].toFloat(), target[1].toFloat(), target[2].toFloat()); + if (!arguments.contains("target")) { + qDebug() << "PullToPoint action requires a `target' argument"; + return nullptr; + } + QVariant targetV = arguments["target"]; + if (targetV.type() != (QVariant::Type) QMetaType::QVariantMap) { + qDebug() << "PullToPoint argument `target' must be a map"; + return nullptr; + } + QVariantMap targetVM = targetV.toMap(); + if (!targetVM.contains("x") || !targetVM.contains("y") || !targetVM.contains("z")) { + qDebug() << "PullToPoint argument `target' must be a map with keys of x, y, z"; + return nullptr; + } + QVariant xV = targetVM["x"]; + QVariant yV = targetVM["y"]; + QVariant zV = targetVM["z"]; + bool xOk = true; + bool yOk = true; + bool zOk = true; + float x = xV.toFloat(&xOk); + float y = yV.toFloat(&yOk); + float z = zV.toFloat(&zOk); + if (!xOk || !yOk || !zOk) { + qDebug() << "PullToPoint argument `target' must be a map with keys of x, y, z and values of type float."; + } + glm::vec3 glmTarget(x, y, z); float speed = arguments["speed"].toFloat(); - return (EntityActionInterface*) new ObjectActionPullToPoint(id, ownerEntity, glmTarget, speed); + action = (EntityActionInterface*) new ObjectActionPullToPoint(id, ownerEntity, glmTarget, speed); } - assert(false); - return nullptr; + assert(action); + ownerEntity->addAction(this, action); + return action; } void PhysicalEntitySimulation::applyActionChanges() {