mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 00:52:27 +02:00
More entity script server work
This commit is contained in:
parent
529286b2ea
commit
5db37fff95
5 changed files with 190 additions and 72 deletions
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "EntityScriptServer.h"
|
||||
|
||||
#include <AudioConstants.h>
|
||||
#include <AudioInjectorManager.h>
|
||||
#include <EntityScriptingInterface.h>
|
||||
#include <MessagesClient.h>
|
||||
|
@ -20,15 +21,13 @@
|
|||
#include <ScriptCache.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <SoundCache.h>
|
||||
#include <WebSocketServerClass.h>
|
||||
|
||||
#include "../entities/AssignmentParentFinder.h"
|
||||
|
||||
static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 10;
|
||||
int EntityScriptServer::_entitiesScriptEngineCount = 0;
|
||||
|
||||
EntityScriptServer::EntityScriptServer(ReceivedMessage& message) :
|
||||
ThreadedAssignment(message),
|
||||
_receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES, RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES)
|
||||
{
|
||||
EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssignment(message) {
|
||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||
|
||||
ResourceManager::init();
|
||||
|
@ -44,14 +43,15 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) :
|
|||
|
||||
|
||||
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
||||
|
||||
packetReceiver.registerListenerForTypes({ PacketType::MixedAudio, PacketType::SilentAudioFrame },
|
||||
this, "handleAudioPacket");
|
||||
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
|
||||
this, "handleOctreePacket");
|
||||
packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket");
|
||||
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
||||
|
||||
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
||||
packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
|
||||
packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
|
||||
packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
|
||||
}
|
||||
|
||||
static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server";
|
||||
|
@ -77,6 +77,27 @@ void EntityScriptServer::run() {
|
|||
nodeList->addSetOfNodeTypesToNodeInterestSet({
|
||||
NodeType::AudioMixer, NodeType::AvatarMixer, NodeType::EntityServer, NodeType::MessagesMixer, NodeType::AssetServer
|
||||
});
|
||||
|
||||
// Setup Script Engine
|
||||
resetEntitiesScriptEngine();
|
||||
|
||||
// we need to make sure that init has been called for our EntityScriptingInterface
|
||||
// so that it actually has a jurisdiction listener when we ask it for it next
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->init();
|
||||
_entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener());
|
||||
|
||||
_entityViewer.init();
|
||||
|
||||
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
||||
|
||||
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
||||
|
||||
|
||||
auto tree = _entityViewer.getTree().get();
|
||||
connect(tree, &EntityTree::deletingEntity, this, &EntityScriptServer::deletingEntity, Qt::QueuedConnection);
|
||||
connect(tree, &EntityTree::addingEntity, this, &EntityScriptServer::addingEntity, Qt::QueuedConnection);
|
||||
connect(tree, &EntityTree::entityScriptChanging, this, &EntityScriptServer::entitySciptChanging, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void EntityScriptServer::nodeActivated(SharedNodePointer activatedNode) {
|
||||
|
@ -121,13 +142,11 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
|||
_encoder = nullptr;
|
||||
_codec = nullptr;
|
||||
}
|
||||
_receivedAudioStream.cleanupCodec();
|
||||
|
||||
auto codecPlugins = PluginManager::getInstance()->getCodecPlugins();
|
||||
for (auto& plugin : codecPlugins) {
|
||||
if (_selectedCodecName == plugin->getName()) {
|
||||
_codec = plugin;
|
||||
_receivedAudioStream.setupCodec(plugin, _selectedCodecName, AudioConstants::STEREO);
|
||||
_encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
||||
qDebug() << "Selected Codec Plugin:" << _codec.get();
|
||||
break;
|
||||
|
@ -135,11 +154,91 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::handleAudioPacket(QSharedPointer<ReceivedMessage> message) {
|
||||
_receivedAudioStream.parseData(*message);
|
||||
void EntityScriptServer::resetEntitiesScriptEngine() {
|
||||
auto engineName = QString("Entities %1").arg(++_entitiesScriptEngineCount);
|
||||
auto newEngine = QSharedPointer<ScriptEngine>(new ScriptEngine(NO_SCRIPT, engineName));
|
||||
|
||||
_lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness();
|
||||
_receivedAudioStream.clearBuffer();
|
||||
newEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
||||
|
||||
auto webSocketServerConstructorValue = newEngine->newFunction(WebSocketServerClass::constructor);
|
||||
newEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
||||
|
||||
|
||||
// newEngine->setEmitScriptUpdatesFunction([this]() {
|
||||
// SharedNodePointer entityServerNode = DependencyManager::get<NodeList>()->soloNodeOfType(NodeType::EntityServer);
|
||||
// return !entityServerNode || isPhysicsEnabled();
|
||||
// });
|
||||
|
||||
newEngine->registerGlobalObject("AvatarList", DependencyManager::get<AvatarHashMap>().data());
|
||||
newEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
|
||||
|
||||
// connect this script engines printedMessage signal to the global ScriptEngines these various messages
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
||||
connect(newEngine.data(), &ScriptEngine::printedMessage, scriptEngines, &ScriptEngines::onPrintedMessage);
|
||||
connect(newEngine.data(), &ScriptEngine::errorMessage, scriptEngines, &ScriptEngines::onErrorMessage);
|
||||
connect(newEngine.data(), &ScriptEngine::warningMessage, scriptEngines, &ScriptEngines::onWarningMessage);
|
||||
connect(newEngine.data(), &ScriptEngine::infoMessage, scriptEngines, &ScriptEngines::onInfoMessage);
|
||||
|
||||
|
||||
newEngine->runInThread();
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngine.data());
|
||||
|
||||
_entitiesScriptEngine.swap(newEngine);
|
||||
}
|
||||
|
||||
|
||||
void EntityScriptServer::clear() {
|
||||
// unload and stop the engine
|
||||
if (_entitiesScriptEngine) {
|
||||
// do this here (instead of in deleter) to avoid marshalling unload signals back to this thread
|
||||
_entitiesScriptEngine->unloadAllEntityScripts();
|
||||
_entitiesScriptEngine->stop();
|
||||
}
|
||||
|
||||
// reset the engine
|
||||
if (!_shuttingDown) {
|
||||
resetEntitiesScriptEngine();
|
||||
}
|
||||
|
||||
_entityViewer.clear();
|
||||
}
|
||||
|
||||
void EntityScriptServer::shutdown() {
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential
|
||||
}
|
||||
_shuttingDown = true;
|
||||
|
||||
clear(); // always clear() on shutdown
|
||||
}
|
||||
|
||||
void EntityScriptServer::addingEntity(const EntityItemID& entityID) {
|
||||
checkAndCallPreload(entityID);
|
||||
}
|
||||
|
||||
void EntityScriptServer::deletingEntity(const EntityItemID& entityID) {
|
||||
if (_entityViewer.getTree() && !_shuttingDown && _entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->unloadEntityScript(entityID);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::entitySciptChanging(const EntityItemID& entityID, const bool reload) {
|
||||
if (_entityViewer.getTree() && !_shuttingDown) {
|
||||
_entitiesScriptEngine->unloadEntityScript(entityID);
|
||||
checkAndCallPreload(entityID, reload);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::checkAndCallPreload(const EntityItemID& entityID, const bool reload) {
|
||||
if (_entityViewer.getTree() && !_shuttingDown) {
|
||||
EntityItemPointer entity = _entityViewer.getTree()->findEntityByEntityItemID(entityID);
|
||||
if (entity && entity->shouldPreloadScript() && _entitiesScriptEngine) {
|
||||
QString scriptUrl = entity->getScript();
|
||||
scriptUrl = ResourceManager::normalizeURL(scriptUrl);
|
||||
ScriptEngine::loadEntityScript(_entitiesScriptEngine, entityID, scriptUrl, reload);
|
||||
entity->scriptHasPreloaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
|
||||
|
@ -151,11 +250,43 @@ void EntityScriptServer::sendStatsPacket() {
|
|||
}
|
||||
|
||||
void EntityScriptServer::handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
auto packetType = message->getType();
|
||||
|
||||
if (packetType == PacketType::OctreeStats) {
|
||||
|
||||
int statsMessageLength = OctreeHeadlessViewer::parseOctreeStats(message, senderNode);
|
||||
if (message->getSize() > statsMessageLength) {
|
||||
// pull out the piggybacked packet and create a new QSharedPointer<NLPacket> for it
|
||||
int piggyBackedSizeWithHeader = message->getSize() - statsMessageLength;
|
||||
|
||||
auto buffer = std::unique_ptr<char[]>(new char[piggyBackedSizeWithHeader]);
|
||||
memcpy(buffer.get(), message->getRawMessage() + statsMessageLength, piggyBackedSizeWithHeader);
|
||||
|
||||
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggyBackedSizeWithHeader, message->getSenderSockAddr());
|
||||
message = QSharedPointer<ReceivedMessage>::create(*newPacket);
|
||||
} else {
|
||||
return; // bail since no piggyback data
|
||||
}
|
||||
|
||||
packetType = message->getType();
|
||||
} // fall through to piggyback message
|
||||
|
||||
if (packetType == PacketType::EntityData) {
|
||||
_entityViewer.processDatagram(*message, senderNode);
|
||||
} else if (packetType == PacketType::EntityErase) {
|
||||
_entityViewer.processEraseMessage(*message, senderNode);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
NodeType_t nodeType;
|
||||
message->peekPrimitive(&nodeType);
|
||||
|
||||
// PacketType_JURISDICTION, first byte is the node type...
|
||||
if (nodeType == NodeType::EntityServer) {
|
||||
DependencyManager::get<EntityScriptingInterface>()->getJurisdictionListener()->
|
||||
queueReceivedPacket(message, senderNode);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::aboutToFinish() {
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
#include <QtCore/QObject>
|
||||
|
||||
#include <EntityEditPacketSender.h>
|
||||
#include <EntityTreeHeadlessViewer.h>
|
||||
#include <plugins/CodecPlugin.h>
|
||||
#include <ScriptEngine.h>
|
||||
#include <ThreadedAssignment.h>
|
||||
|
||||
#include "MixedAudioStream.h"
|
||||
|
||||
class EntityScriptServer : public ThreadedAssignment {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -38,19 +38,29 @@ private slots:
|
|||
void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
|
||||
void handleAudioPacket(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
private:
|
||||
void negotiateAudioFormat();
|
||||
void selectAudioFormat(const QString& selectedCodecName);
|
||||
|
||||
void resetEntitiesScriptEngine();
|
||||
void clear();
|
||||
void shutdown();
|
||||
void addingEntity(const EntityItemID& entityID);
|
||||
void deletingEntity(const EntityItemID& entityID);
|
||||
void entitySciptChanging(const EntityItemID& entityID, const bool reload);
|
||||
void checkAndCallPreload(const EntityItemID& entityID, const bool reload = false);
|
||||
|
||||
bool _shuttingDown { false };
|
||||
|
||||
static int _entitiesScriptEngineCount;
|
||||
QSharedPointer<ScriptEngine> _entitiesScriptEngine;
|
||||
EntityEditPacketSender _entityEditSender;
|
||||
EntityTreeHeadlessViewer _entityViewer;
|
||||
|
||||
QString _selectedCodecName;
|
||||
CodecPluginPointer _codec;
|
||||
Encoder* _encoder { nullptr };
|
||||
MixedAudioStream _receivedAudioStream;
|
||||
float _lastReceivedAudioLoudness;
|
||||
};
|
||||
|
||||
#endif // hifi_EntityScriptServer_h
|
||||
|
|
|
@ -45,9 +45,7 @@
|
|||
|
||||
EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
||||
AbstractScriptingServicesInterface* scriptingServices) :
|
||||
OctreeRenderer(),
|
||||
_wantScripts(wantScripts),
|
||||
_entitiesScriptEngine(NULL),
|
||||
_lastPointerEventValid(false),
|
||||
_viewState(viewState),
|
||||
_scriptingServices(scriptingServices),
|
||||
|
@ -106,6 +104,35 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
|
|||
auto newEngine = new ScriptEngine(NO_SCRIPT, QString("Entities %1").arg(++_entitiesScriptEngineCount));
|
||||
_entitiesScriptEngine = QSharedPointer<ScriptEngine>(newEngine, entitiesScriptEngineDeleter);
|
||||
|
||||
auto makeSlotForSignal = [&](QString name) {
|
||||
return [newEngine, name](const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||
newEngine->callEntityScriptMethod(entityItemID, name, event);
|
||||
};
|
||||
};
|
||||
|
||||
auto makeSlotForSignalNoEvent = [&](QString name) {
|
||||
return [newEngine, name](const EntityItemID& entityItemID) {
|
||||
newEngine->callEntityScriptMethod(entityItemID, name);
|
||||
};
|
||||
};
|
||||
|
||||
connect(this, &EntityTreeRenderer::mousePressOnEntity, newEngine, makeSlotForSignal("mousePressOnEntity"));
|
||||
connect(this, &EntityTreeRenderer::mouseMoveOnEntity, newEngine, makeSlotForSignal("mouseMoveOnEntity"));
|
||||
connect(this, &EntityTreeRenderer::mouseMoveOnEntity, newEngine, makeSlotForSignal("mouseMoveEvent"));
|
||||
connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, newEngine, makeSlotForSignal("mouseReleaseOnEntity"));
|
||||
|
||||
connect(this, &EntityTreeRenderer::clickDownOnEntity, newEngine, makeSlotForSignal("clickDownOnEntity"));
|
||||
connect(this, &EntityTreeRenderer::holdingClickOnEntity, newEngine, makeSlotForSignal("holdingClickOnEntity"));
|
||||
connect(this, &EntityTreeRenderer::clickReleaseOnEntity, newEngine, makeSlotForSignal("clickReleaseOnEntity"));
|
||||
|
||||
connect(this, &EntityTreeRenderer::hoverEnterEntity, newEngine, makeSlotForSignal("hoverEnterEntity"));
|
||||
connect(this, &EntityTreeRenderer::hoverOverEntity, newEngine, makeSlotForSignal("hoverOverEntity"));
|
||||
connect(this, &EntityTreeRenderer::hoverLeaveEntity, newEngine, makeSlotForSignal("hoverLeaveEntity"));
|
||||
|
||||
connect(this, &EntityTreeRenderer::enterEntity, newEngine, makeSlotForSignalNoEvent("enterEntity"));
|
||||
connect(this, &EntityTreeRenderer::leaveEntity, newEngine, makeSlotForSignalNoEvent("leaveEntity"));
|
||||
|
||||
|
||||
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine.data());
|
||||
_entitiesScriptEngine->runInThread();
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(_entitiesScriptEngine.data());
|
||||
|
@ -208,7 +235,6 @@ void EntityTreeRenderer::update() {
|
|||
// and we want to simulate this message here as well as in mouse move
|
||||
if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) {
|
||||
emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent);
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -302,9 +328,6 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
|
|||
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
||||
if (!entitiesContainingAvatar.contains(entityID)) {
|
||||
emit leaveEntity(entityID);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,9 +335,6 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
|
|||
foreach(const EntityItemID& entityID, entitiesContainingAvatar) {
|
||||
if (!_currentEntitiesInside.contains(entityID)) {
|
||||
emit enterEntity(entityID);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity");
|
||||
}
|
||||
}
|
||||
}
|
||||
_currentEntitiesInside = entitiesContainingAvatar;
|
||||
|
@ -329,9 +349,6 @@ void EntityTreeRenderer::leaveAllEntities() {
|
|||
// for all of our previous containing entities, if they are no longer containing then send them a leave event
|
||||
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
||||
emit leaveEntity(entityID);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
|
||||
}
|
||||
}
|
||||
_currentEntitiesInside.clear();
|
||||
forceRecheckEntities();
|
||||
|
@ -719,15 +736,8 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
|
|||
|
||||
emit mousePressOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", pointerEvent);
|
||||
}
|
||||
|
||||
_currentClickingOnEntityID = rayPickResult.entityID;
|
||||
emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", pointerEvent);
|
||||
}
|
||||
|
||||
_lastPointerEvent = pointerEvent;
|
||||
_lastPointerEventValid = true;
|
||||
|
@ -758,9 +768,6 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event));
|
||||
|
||||
emit mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", pointerEvent);
|
||||
}
|
||||
|
||||
_lastPointerEvent = pointerEvent;
|
||||
_lastPointerEventValid = true;
|
||||
|
@ -778,9 +785,6 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event));
|
||||
|
||||
emit clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "clickReleaseOnEntity", pointerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// makes it the unknown ID, we just released so we can't be clicking on anything
|
||||
|
@ -809,11 +813,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
|
||||
emit mouseMoveOnEntity(rayPickResult.entityID, pointerEvent);
|
||||
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", pointerEvent);
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveOnEntity", pointerEvent);
|
||||
}
|
||||
|
||||
// handle the hover logic...
|
||||
|
||||
// if we were previously hovering over an entity, and this new entity is not the same as our previous entity
|
||||
|
@ -828,26 +827,17 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event));
|
||||
|
||||
emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// If the new hover entity does not match the previous hover entity then we are entering the new one
|
||||
// this is true if the _currentHoverOverEntityID is known or unknown
|
||||
if (rayPickResult.entityID != _currentHoverOverEntityID) {
|
||||
emit hoverEnterEntity(rayPickResult.entityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverEnterEntity", pointerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// and finally, no matter what, if we're intersecting an entity then we're definitely hovering over it, and
|
||||
// we should send our hover over event
|
||||
emit hoverOverEntity(rayPickResult.entityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", pointerEvent);
|
||||
}
|
||||
|
||||
// remember what we're hovering over
|
||||
_currentHoverOverEntityID = rayPickResult.entityID;
|
||||
|
@ -869,9 +859,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event));
|
||||
|
||||
emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent);
|
||||
}
|
||||
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID
|
||||
}
|
||||
}
|
||||
|
@ -888,9 +875,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
toPointerButton(*event), toPointerButtons(*event));
|
||||
|
||||
emit holdingClickOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", pointerEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1058,16 +1042,10 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
|
|||
// And now the entity scripts
|
||||
if (isCollisionOwner(myNodeID, entityTree, idA, collision)) {
|
||||
emit collisionWithEntity(idA, idB, collision);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision);
|
||||
}
|
||||
}
|
||||
|
||||
if (isCollisionOwner(myNodeID, entityTree, idA, collision)) {
|
||||
emit collisionWithEntity(idB, idA, collision);
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, collision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ class PhysicalEntitySimulation;
|
|||
using PhysicalEntitySimulationPointer = std::shared_ptr<PhysicalEntitySimulation>;
|
||||
using SetOfEntityMotionStates = QSet<EntityMotionState*>;
|
||||
|
||||
class PhysicalEntitySimulation :public EntitySimulation {
|
||||
class PhysicalEntitySimulation : public EntitySimulation {
|
||||
public:
|
||||
PhysicalEntitySimulation();
|
||||
~PhysicalEntitySimulation();
|
||||
|
|
|
@ -90,7 +90,6 @@ public slots:
|
|||
protected slots:
|
||||
void onScriptFinished(const QString& fileNameString, ScriptEngine* engine);
|
||||
|
||||
|
||||
protected:
|
||||
friend class ScriptEngine;
|
||||
|
||||
|
|
Loading…
Reference in a new issue