simple action is working. destructor sequense is still suspicous

This commit is contained in:
Seth Alves 2015-06-03 17:33:55 -07:00
parent 9861e8afcc
commit d634663bb1
15 changed files with 96 additions and 44 deletions

View file

@ -46,6 +46,7 @@ void DeleteEntityOperator::addEntityIDToDeleteList(const EntityItemID& searchEnt
//assert(false);
qCDebug(entities) << "that's UNEXPECTED, we got a _containingElement, but couldn't find the oldEntity!";
} else {
details.entity->clearActions();
details.cube = details.containingElement->getAACube();
_entitiesToDelete << details;
_lookingCount++;

View file

@ -12,6 +12,8 @@
#ifndef hifi_EntityActionInterface_h
#define hifi_EntityActionInterface_h
class EntitySimulation;
enum EntityActionType {
ACTION_TYPE_NONE,
ACTION_TYPE_PULL_TO_POINT
@ -20,8 +22,11 @@ enum EntityActionType {
class EntityActionInterface {
public:
virtual ~EntityActionInterface() {};
EntityActionInterface() { qDebug() << "EntityActionInterface::EntityActionInterface"; }
virtual ~EntityActionInterface() { qDebug() << "EntityActionInterface::~EntityActionInterface"; }
virtual const QUuid& getID() const = 0;
virtual void setSimulation(EntitySimulation* simulation) = 0;
virtual void removeFromSimulation() const = 0;
virtual const EntityItemPointer& getOwnerEntity() const = 0;
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) = 0;
// virtual QByteArray serialize() = 0;

View file

@ -83,9 +83,10 @@ EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemPropert
}
EntityItem::~EntityItem() {
qDebug() << "EntityItem::~EntityItem" << _objectActions.size() << _name;
clearActions();
// these pointers MUST be NULL at delete, else we probably have a dangling backpointer
// to this EntityItem in the corresponding data structure.
clearActions();
assert(!_simulated);
assert(!_element);
assert(!_physicsInfo);
@ -1339,43 +1340,47 @@ void EntityItem::updateSimulatorID(const QUuid& value) {
}
}
void EntityItem::addAction(EntityActionInterface* action) {
bool EntityItem::addAction(EntityActionInterface* action) {
assert(action);
const QUuid& actionID = action->getID();
assert(!_objectActions.contains(actionID) || _objectActions[actionID] == action);
qDebug() << "SETTING" << actionID << "in EntityItem::addAction" << _name;
_objectActions[actionID] = action;
EntityItemPointer thisEntity(this);
assert(action->getOwnerEntity() == nullptr || action->getOwnerEntity() == thisEntity);
action->setOwnerEntity(thisEntity);
const EntityTree* tree = _element->getTree();
if (tree) {
EntitySimulation* simulation = tree->getSimulation();
if (simulation) {
simulation->addAction(action);
}
}
}
void EntityItem::removeAction(const QUuid actionID) {
if (_objectActions.contains(actionID)) {
const EntityActionInterface* action = _objectActions[actionID];
_objectActions.remove(actionID);
assert(action->getOwnerEntity().get() == this);
if (_element) {
const EntityTree* tree = _element->getTree();
if (tree) {
EntitySimulation* simulation = tree->getSimulation();
if (simulation) {
simulation->removeAction(action->getID());
simulation->addAction(action);
return true;
}
}
}
return false;
}
void EntityItem::removeAction(const QUuid actionID) {
if (_objectActions.contains(actionID)) {
EntityActionInterface* action = _objectActions[actionID];
qDebug() << "REMOVING" << actionID << "in EntityItem::removeAction" << _name;
_objectActions.remove(actionID);
action->setOwnerEntity(nullptr);
action->removeFromSimulation();
}
}
void EntityItem::clearActions() {
QHash<QUuid, const EntityActionInterface*>::iterator i;
for (i = _objectActions.begin(); i != _objectActions.end(); ++i) {
removeAction(i.key());
QHash<QUuid, EntityActionInterface*>::iterator i = _objectActions.begin();
while (i != _objectActions.end()) {
const QUuid id = i.key();
EntityActionInterface* action = _objectActions[id];
qDebug() << "ERASING" << id << "in EntityItem::clearActions" << _name;
i = _objectActions.erase(i);
action->setOwnerEntity(nullptr);
action->removeFromSimulation();
}
}

View file

@ -356,10 +356,9 @@ public:
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
void addAction(EntityActionInterface* actionID);
bool addAction(EntityActionInterface* actionID);
void removeAction(const QUuid actionID);
void clearActions();
const QList<QUuid> getActionIDs() const { return _objectActions.keys(); }
protected:
@ -433,7 +432,7 @@ protected:
void* _physicsInfo = nullptr; // set by EntitySimulation
bool _simulated; // set by EntitySimulation
QHash<QUuid, const EntityActionInterface*> _objectActions;
QHash<QUuid, EntityActionInterface*> _objectActions;
};
#endif // hifi_EntityItem_h

View file

@ -450,7 +450,7 @@ bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
});
}
QUuid EntityScriptingInterface::addActionPullToPoint(QUuid entityID, const glm::vec3& target) {
QUuid EntityScriptingInterface::addActionPullToPoint(QUuid entityID, const glm::vec3& target, float speed) {
if (!_entityTree) {
return QUuid();
}
@ -470,6 +470,7 @@ QUuid EntityScriptingInterface::addActionPullToPoint(QUuid entityID, const glm::
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);

View file

@ -124,7 +124,7 @@ public slots:
Q_INVOKABLE void dumpTree() const;
Q_INVOKABLE QUuid addActionPullToPoint(QUuid entityID, const glm::vec3& target);
Q_INVOKABLE QUuid addActionPullToPoint(QUuid entityID, const glm::vec3& target, float velocity);
signals:
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);

View file

@ -24,9 +24,9 @@
typedef QSet<EntityItemPointer> SetOfEntities;
typedef QVector<EntityItemPointer> VectorOfEntities;
// the EntitySimulation needs to know when these things change on an entity,
// the EntitySimulation needs to know when these things change on an entity,
// so it can sort EntityItem or relay its state to the PhysicsEngine.
const int DIRTY_SIMULATION_FLAGS =
const int DIRTY_SIMULATION_FLAGS =
EntityItem::DIRTY_POSITION |
EntityItem::DIRTY_ROTATION |
EntityItem::DIRTY_LINEAR_VELOCITY |
@ -60,7 +60,7 @@ public:
QUuid id,
EntityItemPointer ownerEntity,
QVariantMap arguments) { return nullptr; }
virtual void addAction(EntityActionInterface* action) { _actionsToAdd += action; }
virtual void addAction(EntityActionInterface* action) { action->setSimulation(this); _actionsToAdd += action; }
virtual void removeAction(const QUuid actionID) { _actionsToRemove += actionID; }
virtual void removeActions(QList<QUuid> actionIDsToRemove) { _actionsToRemove += actionIDsToRemove; }
virtual void applyActionChanges() { _actionsToAdd.clear(); _actionsToRemove.clear(); }

View file

@ -279,7 +279,7 @@ void EntityTree::setSimulation(EntitySimulation* simulation) {
if (simulation) {
// assert that the simulation's backpointer has already been properly connected
assert(simulation->getEntityTree() == this);
}
}
if (_simulation && _simulation != simulation) {
// It's important to clearEntities() on the simulation since taht will update each
// EntityItem::_simulationState correctly so as to not confuse the next _simulation.

View file

@ -33,7 +33,7 @@ public:
_totalItems(0),
_movingItems(0)
{ }
QList<EntityItemPointer> _movingEntities;
int _totalElements;
int _totalItems;
@ -42,8 +42,8 @@ public:
class EntityTreeElementExtraEncodeData {
public:
EntityTreeElementExtraEncodeData() :
elementCompleted(false),
EntityTreeElementExtraEncodeData() :
elementCompleted(false),
subtreeCompleted(false),
entities() {
memset(childCompleted, 0, sizeof(childCompleted));
@ -140,7 +140,7 @@ public:
virtual bool canRayIntersect() const { return hasEntities(); }
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
void** intersectedObject, bool precisionPicking, float distanceToElementCube);
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
@ -148,7 +148,7 @@ public:
const EntityItems& getEntities() const { return *_entityItems; }
EntityItems& getEntities() { return *_entityItems; }
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
void setTree(EntityTree* tree) { _myTree = tree; }

View file

@ -154,7 +154,7 @@ void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld, btScala
velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp;
}
_rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection);
}
}
}
}

View file

@ -9,15 +9,19 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "EntitySimulation.h"
#include "ObjectAction.h"
ObjectAction::ObjectAction(QUuid id, EntityItemPointer ownerEntity) :
btActionInterface(),
_id(id),
_ownerEntity(ownerEntity) {
qDebug() << "ObjectAction::ObjectAction";
}
ObjectAction::~ObjectAction() {
qDebug() << "ObjectAction::~ObjectAction";
}
void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
@ -26,3 +30,9 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta
void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) {
}
void ObjectAction::removeFromSimulation() const {
if (_simulation) {
_simulation->removeAction(_id);
}
}

View file

@ -25,6 +25,8 @@ public:
virtual ~ObjectAction();
const QUuid& getID() const { return _id; }
virtual void setSimulation(EntitySimulation* simulation) { _simulation = simulation; }
virtual void removeFromSimulation() const;
virtual const EntityItemPointer& getOwnerEntity() const { return _ownerEntity; }
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; }
@ -34,7 +36,10 @@ public:
private:
QUuid _id;
protected:
EntityItemPointer _ownerEntity;
EntitySimulation* _simulation;
};
#endif // hifi_ObjectAction_h

View file

@ -9,16 +9,40 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ObjectMotionState.h"
#include "BulletUtil.h"
#include "ObjectActionPullToPoint.h"
ObjectActionPullToPoint::ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity, glm::vec3 target) :
ObjectActionPullToPoint::ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity, glm::vec3 target, float speed) :
ObjectAction(id, ownerEntity),
_target(target) {
_target(target),
_speed(speed) {
qDebug() << "ObjectActionPullToPoint::ObjectActionPullToPoint";
}
ObjectActionPullToPoint::~ObjectActionPullToPoint() {
qDebug() << "ObjectActionPullToPoint::~ObjectActionPullToPoint";
}
void ObjectActionPullToPoint::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
qDebug() << "ObjectActionPullToPoint::updateAction called";
glm::vec3 offset = _target - _ownerEntity->getPosition();
if (glm::length(offset) < IGNORE_POSITION_DELTA) {
offset = glm::vec3(0.0f, 0.0f, 0.0f);
}
glm::vec3 newVelocity = glm::normalize(offset) * _speed;
void* physicsInfo = _ownerEntity->getPhysicsInfo();
if (physicsInfo) {
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* rigidBody = motionState->getRigidBody();
if (rigidBody) {
rigidBody->setLinearVelocity(glmToBullet(newVelocity));
return;
}
}
_ownerEntity->updateVelocity(newVelocity);
}

View file

@ -19,13 +19,14 @@
class ObjectActionPullToPoint : public ObjectAction {
public:
ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity, glm::vec3 target);
ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity, glm::vec3 target, float speed);
virtual ~ObjectActionPullToPoint();
void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
private:
glm::vec3 _target;
float _speed;
};
#endif // hifi_ObjectActionPullToPoint_h

View file

@ -245,7 +245,8 @@ EntityActionInterface* PhysicalEntitySimulation::actionFactory(EntityActionType
case ACTION_TYPE_PULL_TO_POINT:
QVariantList target = arguments["target"].toList();
glm::vec3 glmTarget(target[0].toFloat(), target[1].toFloat(), target[2].toFloat());
return (EntityActionInterface*) new ObjectActionPullToPoint(id, ownerEntity, glmTarget);
float speed = arguments["speed"].toFloat();
return (EntityActionInterface*) new ObjectActionPullToPoint(id, ownerEntity, glmTarget, speed);
}
assert(false);