mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-28 22:49:54 +02:00
Handle all the signals.
This commit is contained in:
parent
1dd2b7275e
commit
b884d3cf90
4 changed files with 69 additions and 65 deletions
|
@ -47,6 +47,7 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) {
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
disconnect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
disconnect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
||||||
disconnect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
disconnect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
||||||
|
disconnect(_entityTree, &EntityTree::changingEntityID, this, &EntityScriptingInterface::changingEntityID);
|
||||||
disconnect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
disconnect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) {
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
connect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
connect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
||||||
connect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
connect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
||||||
|
connect(_entityTree, &EntityTree::changingEntityID, this, &EntityScriptingInterface::changingEntityID);
|
||||||
connect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
connect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,7 @@ signals:
|
||||||
|
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
void deletingEntity(const EntityItemID& entityID);
|
||||||
void addingEntity(const EntityItemID& entityID);
|
void addingEntity(const EntityItemID& entityID);
|
||||||
|
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
|
||||||
void clearingEntities();
|
void clearingEntities();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -389,82 +389,84 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Answer the previously registered handler for the given entityID/eventName, else an invalid QScriptValue.
|
// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args
|
||||||
QScriptValue ScriptEngine::getEntityEventHandler(const EntityItemID& entityID, const QString& eventName) {
|
void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator) {
|
||||||
if (!_registeredHandlers.contains(entityID)) return _illegal;
|
if (!_registeredHandlers.contains(entityID)) return;
|
||||||
const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID];
|
const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID];
|
||||||
if (!handlersOnEntity.contains(eventName)) return _illegal;
|
if (!handlersOnEntity.contains(eventName)) return;
|
||||||
// FIXME: Need one more level of indirection. We need to allow multiple handlers per event, registered by different scripts.
|
// FIXME: Need one more level of indirection. We need to allow multiple handlers per event, registered by different scripts.
|
||||||
return handlersOnEntity[eventName];
|
QScriptValue handlerForEvent = handlersOnEntity[eventName];
|
||||||
|
if (handlerForEvent.isValid()) {
|
||||||
|
QScriptValueList args = argGenerator();
|
||||||
|
handlerForEvent.call(QScriptValue(), args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Unregister the handler for this eventName and entityID.
|
||||||
void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) {
|
void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) {
|
||||||
// FIXME
|
if (!_registeredHandlers.contains(entityID)) return;
|
||||||
|
RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID];
|
||||||
|
if (!handlersOnEntity.contains(eventName)) return;
|
||||||
|
handlersOnEntity.remove(eventName);
|
||||||
}
|
}
|
||||||
// FIXME: deletingEntity, changingEntityID
|
// FIXME: deletingEntity, changingEntityID
|
||||||
|
// Register the handler.
|
||||||
void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) {
|
void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) {
|
||||||
if (!_registeredHandlers.contains(entityID)) {
|
if (_registeredHandlers.count() == 0) { // First time any per-entity handler has been added in this script...
|
||||||
_registeredHandlers[entityID] = RegisteredEventHandlers();
|
// 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.)
|
||||||
_registeredHandlers[entityID][eventName] = handler;
|
auto entities = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
connect(entities.data(), &EntityScriptingInterface::deletingEntity, this,
|
||||||
// The rest connects the Entities signal to the handler here.
|
[=](const EntityItemID& entityID) {
|
||||||
auto entities = DependencyManager::get<EntityScriptingInterface>();
|
_registeredHandlers.remove(entityID);
|
||||||
|
});
|
||||||
// Given thunk that generates the arglist, evaluate that thunk only if needed, and call the handler.
|
connect(entities.data(), &EntityScriptingInterface::changingEntityID, this,
|
||||||
auto generalHandler = [=](std::function<QScriptValueList()> argGenerator) {
|
[=](const EntityItemID& oldEntityID, const EntityItemID& newEntityID) {
|
||||||
QScriptValue handlerForEvent = getEntityEventHandler(entityID, eventName);
|
if (!_registeredHandlers.contains(oldEntityID)) return;
|
||||||
if (handlerForEvent.isValid()) {
|
_registeredHandlers[newEntityID] = _registeredHandlers[oldEntityID];
|
||||||
QScriptValueList args = argGenerator();
|
_registeredHandlers.remove(oldEntityID);
|
||||||
handlerForEvent.call(QScriptValue(), args);
|
});
|
||||||
}
|
|
||||||
};
|
// Two common cases of event handler, differing only in argument signature.
|
||||||
// Two common cases of event handler, differing only in argument signature.
|
auto makeSingleEntityHandler = [=](const QString& eventName) {
|
||||||
auto singleEntityHandler = [=](const EntityItemID& entityItemID) {
|
return [=](const EntityItemID& entityItemID) {
|
||||||
generalHandler([=]() {
|
generalHandler(entityItemID, eventName, [=]() {
|
||||||
return QScriptValueList() << entityItemID.toScriptValue(this);
|
return QScriptValueList() << entityItemID.toScriptValue(this);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
auto mouseHandler = [=](const EntityItemID& entityItemID, const MouseEvent& event) {
|
};
|
||||||
generalHandler([=]() {
|
auto makeMouseHandler = [=](const QString& eventName) {
|
||||||
return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this);
|
return [=](const EntityItemID& entityItemID, const MouseEvent& event) {
|
||||||
});
|
generalHandler(entityItemID, eventName, [=]() {
|
||||||
};
|
return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this);
|
||||||
// This string comparison maze only happens when adding a handler, which isn't often, rather than during events.
|
});
|
||||||
// Nonetheless, I wish it were more DRY. Variadic signals from strings? "I know reflection. I've worked with reflection. QT is no reflection."
|
};
|
||||||
if (eventName == "enterEntity") {
|
};
|
||||||
connect(entities.data(), &EntityScriptingInterface::enterEntity, this, singleEntityHandler);
|
connect(entities.data(), &EntityScriptingInterface::enterEntity, this, makeSingleEntityHandler("enterEntity"));
|
||||||
} else if (eventName == "leaveEntity") {
|
connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, makeSingleEntityHandler("leaveEntity"));
|
||||||
connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, singleEntityHandler);
|
|
||||||
|
connect(entities.data(), &EntityScriptingInterface::mousePressOnEntity, this, makeMouseHandler("mousePressOnEntity"));
|
||||||
} else if (eventName == "mousePressOnEntity") {
|
connect(entities.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, makeMouseHandler("mouseMoveOnEntity"));
|
||||||
connect(entities.data(), &EntityScriptingInterface::mousePressOnEntity, this, mouseHandler);
|
connect(entities.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, makeMouseHandler("mouseReleaseOnEntity"));
|
||||||
} else if (eventName == "mouseMoveOnEntity") {
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, mouseHandler);
|
connect(entities.data(), &EntityScriptingInterface::clickDownOnEntity, this, makeMouseHandler("clickDownOnEntity"));
|
||||||
} else if (eventName == "mouseReleaseOnEntity") {
|
connect(entities.data(), &EntityScriptingInterface::holdingClickOnEntity, this, makeMouseHandler("holdingClickOnEntity"));
|
||||||
connect(entities.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, mouseHandler);
|
connect(entities.data(), &EntityScriptingInterface::clickReleaseOnEntity, this, makeMouseHandler("clickReleaseOnEntity"));
|
||||||
|
|
||||||
} else if (eventName == "clickDownOnEntity") {
|
connect(entities.data(), &EntityScriptingInterface::hoverEnterEntity, this, makeMouseHandler("hoverEnterEntity"));
|
||||||
connect(entities.data(), &EntityScriptingInterface::clickDownOnEntity, this, mouseHandler);
|
connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, makeMouseHandler("hoverOverEntity"));
|
||||||
} else if (eventName == "holdingClickOnEntity") {
|
connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, makeMouseHandler("hoverLeaveEntity"));
|
||||||
connect(entities.data(), &EntityScriptingInterface::holdingClickOnEntity, this, mouseHandler);
|
|
||||||
} else if (eventName == "clickReleaseOnEntity") {
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::clickReleaseOnEntity, this, mouseHandler);
|
|
||||||
|
|
||||||
} else if (eventName == "hoverEnterEntity") {
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::hoverEnterEntity, this, mouseHandler);
|
|
||||||
} else if (eventName == "hoverOverEntity") {
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, mouseHandler);
|
|
||||||
} else if (eventName == "hoverLeaveEntity") {
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, mouseHandler);
|
|
||||||
|
|
||||||
} else if (eventName == "collisionWithEntity") {
|
|
||||||
connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this,
|
connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this,
|
||||||
[=](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
[=](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
||||||
generalHandler([=]() {
|
generalHandler(idA, "collisionWithEntity", [=]() {
|
||||||
return QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision);
|
return QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (!_registeredHandlers.contains(entityID)) {
|
||||||
|
_registeredHandlers[entityID] = RegisteredEventHandlers();
|
||||||
|
}
|
||||||
|
_registeredHandlers[entityID][eventName] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -171,8 +171,7 @@ private:
|
||||||
|
|
||||||
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
||||||
QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
|
QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
|
||||||
QScriptValue _illegal;
|
void generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator);
|
||||||
QScriptValue getEntityEventHandler(const EntityItemID& entityID, const QString& eventName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QSet<ScriptEngine*> _allKnownScriptEngines;
|
static QSet<ScriptEngine*> _allKnownScriptEngines;
|
||||||
|
|
Loading…
Reference in a new issue