mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:35:08 +02:00
Merge branch 'team-teaching' of https://github.com/highfidelity/hifi into team-teaching-scene-api
This commit is contained in:
commit
007aed7a0a
7 changed files with 101 additions and 12 deletions
|
@ -262,7 +262,6 @@ $(document).ready(function(){
|
|||
$('#' + Settings.FORM_ID).on('click', '#' + Settings.CONNECT_ACCOUNT_BTN_ID, function(e){
|
||||
$(this).blur();
|
||||
prepareAccessTokenPrompt();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
var panelsSource = $('#panels-template').html()
|
||||
|
|
|
@ -114,7 +114,6 @@ void EntityTreeRenderer::init() {
|
|||
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
|
||||
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::addingEntity);
|
||||
connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::entitySciptChanging);
|
||||
connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID);
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::shutdown() {
|
||||
|
@ -855,6 +854,7 @@ void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityS
|
|||
|
||||
connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity);
|
||||
connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity);
|
||||
connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity);
|
||||
}
|
||||
|
||||
QScriptValueList EntityTreeRenderer::createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID) {
|
||||
|
@ -1083,14 +1083,6 @@ void EntityTreeRenderer::checkAndCallUnload(const EntityItemID& entityID) {
|
|||
}
|
||||
|
||||
|
||||
void EntityTreeRenderer::changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID) {
|
||||
if (_entityScripts.contains(oldEntityID)) {
|
||||
EntityScriptDetails details = _entityScripts[oldEntityID];
|
||||
_entityScripts.remove(oldEntityID);
|
||||
_entityScripts[newEntityID] = details;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityTree* entityTree, const EntityItemID& id, const Collision& collision) {
|
||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(id);
|
||||
if (!entity) {
|
||||
|
@ -1169,6 +1161,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
|
|||
playEntityCollisionSound(myNodeID, entityTree, idB, collision);
|
||||
|
||||
// And now the entity scripts
|
||||
emit collisionWithEntity(idA, idB, collision);
|
||||
QScriptValue entityScriptA = loadEntityScript(idA);
|
||||
if (entityScriptA.property("collisionWithEntity").isValid()) {
|
||||
QScriptValueList args;
|
||||
|
@ -1178,6 +1171,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
|
|||
entityScriptA.property("collisionWithEntity").call(entityScriptA, args);
|
||||
}
|
||||
|
||||
emit collisionWithEntity(idB, idA, collision);
|
||||
QScriptValue entityScriptB = loadEntityScript(idB);
|
||||
if (entityScriptB.property("collisionWithEntity").isValid()) {
|
||||
QScriptValueList args;
|
||||
|
|
|
@ -106,11 +106,11 @@ signals:
|
|||
|
||||
void enterEntity(const EntityItemID& entityItemID);
|
||||
void leaveEntity(const EntityItemID& entityItemID);
|
||||
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
||||
public slots:
|
||||
void addingEntity(const EntityItemID& entityID);
|
||||
void deletingEntity(const EntityItemID& entityID);
|
||||
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
|
||||
void entitySciptChanging(const EntityItemID& entityID);
|
||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
||||
|
|
|
@ -121,6 +121,7 @@ public slots:
|
|||
|
||||
signals:
|
||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
||||
void canAdjustLocksChanged(bool canAdjustLocks);
|
||||
void canRezChanged(bool canRez);
|
||||
|
|
|
@ -171,7 +171,6 @@ signals:
|
|||
void deletingEntity(const EntityItemID& entityID);
|
||||
void addingEntity(const EntityItemID& entityID);
|
||||
void entityScriptChanging(const EntityItemID& entityItemID);
|
||||
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
|
||||
void clearingEntities();
|
||||
|
||||
private:
|
||||
|
|
|
@ -389,6 +389,94 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func
|
|||
}
|
||||
}
|
||||
|
||||
// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args
|
||||
void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator) {
|
||||
if (!_registeredHandlers.contains(entityID)) {
|
||||
return;
|
||||
}
|
||||
const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID];
|
||||
if (!handlersOnEntity.contains(eventName)) {
|
||||
return;
|
||||
}
|
||||
QScriptValueList handlersForEvent = handlersOnEntity[eventName];
|
||||
if (!handlersForEvent.isEmpty()) {
|
||||
QScriptValueList args = argGenerator();
|
||||
for (int i = 0; i < handlersForEvent.count(); ++i) {
|
||||
handlersForEvent[i].call(QScriptValue(), args);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Unregister the handlers for this eventName and entityID.
|
||||
void ScriptEngine::removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) {
|
||||
if (!_registeredHandlers.contains(entityID)) {
|
||||
return;
|
||||
}
|
||||
RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID];
|
||||
QScriptValueList& handlersForEvent = handlersOnEntity[eventName];
|
||||
// QScriptValue does not have operator==(), so we can't use QList::removeOne and friends. So iterate.
|
||||
for (int i = 0; i < handlersForEvent.count(); ++i) {
|
||||
if (handlersForEvent[i].equals(handler)) {
|
||||
handlersForEvent.removeAt(i);
|
||||
return; // Design choice: since comparison is relatively expensive, just remove the first matching handler.
|
||||
}
|
||||
}
|
||||
}
|
||||
// Register the handler.
|
||||
void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) {
|
||||
if (_registeredHandlers.count() == 0) { // First time any per-entity handler has been added in this script...
|
||||
// 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.)
|
||||
auto entities = DependencyManager::get<EntityScriptingInterface>();
|
||||
connect(entities.data(), &EntityScriptingInterface::deletingEntity, this,
|
||||
[=](const EntityItemID& entityID) {
|
||||
_registeredHandlers.remove(entityID);
|
||||
});
|
||||
|
||||
// Two common cases of event handler, differing only in argument signature.
|
||||
auto makeSingleEntityHandler = [=](const QString& eventName) -> std::function<void(const EntityItemID&)> {
|
||||
return [=](const EntityItemID& entityItemID) -> void {
|
||||
generalHandler(entityItemID, eventName, [=]() -> QScriptValueList {
|
||||
return QScriptValueList() << entityItemID.toScriptValue(this);
|
||||
});
|
||||
};
|
||||
};
|
||||
auto makeMouseHandler = [=](const QString& eventName) -> std::function<void(const EntityItemID&, const MouseEvent&)> {
|
||||
return [=](const EntityItemID& entityItemID, const MouseEvent& event) -> void {
|
||||
generalHandler(entityItemID, eventName, [=]() -> QScriptValueList {
|
||||
return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this);
|
||||
});
|
||||
};
|
||||
};
|
||||
connect(entities.data(), &EntityScriptingInterface::enterEntity, this, makeSingleEntityHandler("enterEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, makeSingleEntityHandler("leaveEntity"));
|
||||
|
||||
connect(entities.data(), &EntityScriptingInterface::mousePressOnEntity, this, makeMouseHandler("mousePressOnEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, makeMouseHandler("mouseMoveOnEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, makeMouseHandler("mouseReleaseOnEntity"));
|
||||
|
||||
connect(entities.data(), &EntityScriptingInterface::clickDownOnEntity, this, makeMouseHandler("clickDownOnEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::holdingClickOnEntity, this, makeMouseHandler("holdingClickOnEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::clickReleaseOnEntity, this, makeMouseHandler("clickReleaseOnEntity"));
|
||||
|
||||
connect(entities.data(), &EntityScriptingInterface::hoverEnterEntity, this, makeMouseHandler("hoverEnterEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, makeMouseHandler("hoverOverEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, makeMouseHandler("hoverLeaveEntity"));
|
||||
|
||||
connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this,
|
||||
[=](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
||||
generalHandler(idA, "collisionWithEntity", [=]() {
|
||||
return QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision);
|
||||
});
|
||||
});
|
||||
}
|
||||
if (!_registeredHandlers.contains(entityID)) {
|
||||
_registeredHandlers[entityID] = RegisteredEventHandlers();
|
||||
}
|
||||
QScriptValueList& handlersForEvent = _registeredHandlers[entityID][eventName];
|
||||
handlersForEvent << handler; // Note that the same handler can be added many times. See removeEntityEventHandler().
|
||||
}
|
||||
|
||||
|
||||
void ScriptEngine::evaluate() {
|
||||
if (_stoppingAllScripts) {
|
||||
return; // bail early
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <AvatarData.h>
|
||||
#include <AvatarHashMap.h>
|
||||
#include <LimitedNodeList.h>
|
||||
#include <EntityItemID.h>
|
||||
|
||||
#include "AbstractControllerScriptingInterface.h"
|
||||
#include "ArrayBufferClass.h"
|
||||
|
@ -36,6 +37,8 @@ const QString NO_SCRIPT("");
|
|||
|
||||
const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 1000) + 0.5);
|
||||
|
||||
typedef QHash<QString, QScriptValueList> RegisteredEventHandlers;
|
||||
|
||||
class ScriptEngine : public QScriptEngine, public ScriptUser {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -98,6 +101,9 @@ public:
|
|||
virtual void scriptContentsAvailable(const QUrl& url, const QString& scriptContents);
|
||||
virtual void errorInLoadingScript(const QUrl& url);
|
||||
|
||||
Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler);
|
||||
Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler);
|
||||
|
||||
public slots:
|
||||
void loadURL(const QUrl& scriptURL);
|
||||
void stop();
|
||||
|
@ -164,6 +170,8 @@ private:
|
|||
ArrayBufferClass* _arrayBufferClass;
|
||||
|
||||
QHash<QUuid, quint16> _outgoingScriptAudioSequenceNumbers;
|
||||
QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
|
||||
void generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator);
|
||||
|
||||
private:
|
||||
static QSet<ScriptEngine*> _allKnownScriptEngines;
|
||||
|
|
Loading…
Reference in a new issue