mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 23:36:44 +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 "EntityScriptServer.h"
|
||||||
|
|
||||||
|
#include <AudioConstants.h>
|
||||||
#include <AudioInjectorManager.h>
|
#include <AudioInjectorManager.h>
|
||||||
#include <EntityScriptingInterface.h>
|
#include <EntityScriptingInterface.h>
|
||||||
#include <MessagesClient.h>
|
#include <MessagesClient.h>
|
||||||
|
@ -20,15 +21,13 @@
|
||||||
#include <ScriptCache.h>
|
#include <ScriptCache.h>
|
||||||
#include <ScriptEngines.h>
|
#include <ScriptEngines.h>
|
||||||
#include <SoundCache.h>
|
#include <SoundCache.h>
|
||||||
|
#include <WebSocketServerClass.h>
|
||||||
|
|
||||||
#include "../entities/AssignmentParentFinder.h"
|
#include "../entities/AssignmentParentFinder.h"
|
||||||
|
|
||||||
static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 10;
|
int EntityScriptServer::_entitiesScriptEngineCount = 0;
|
||||||
|
|
||||||
EntityScriptServer::EntityScriptServer(ReceivedMessage& message) :
|
EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssignment(message) {
|
||||||
ThreadedAssignment(message),
|
|
||||||
_receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES, RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES)
|
|
||||||
{
|
|
||||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||||
|
|
||||||
ResourceManager::init();
|
ResourceManager::init();
|
||||||
|
@ -44,14 +43,15 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) :
|
||||||
|
|
||||||
|
|
||||||
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
||||||
|
|
||||||
packetReceiver.registerListenerForTypes({ PacketType::MixedAudio, PacketType::SilentAudioFrame },
|
|
||||||
this, "handleAudioPacket");
|
|
||||||
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
|
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
|
||||||
this, "handleOctreePacket");
|
this, "handleOctreePacket");
|
||||||
packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket");
|
packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket");
|
||||||
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
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";
|
static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server";
|
||||||
|
@ -77,6 +77,27 @@ void EntityScriptServer::run() {
|
||||||
nodeList->addSetOfNodeTypesToNodeInterestSet({
|
nodeList->addSetOfNodeTypesToNodeInterestSet({
|
||||||
NodeType::AudioMixer, NodeType::AvatarMixer, NodeType::EntityServer, NodeType::MessagesMixer, NodeType::AssetServer
|
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) {
|
void EntityScriptServer::nodeActivated(SharedNodePointer activatedNode) {
|
||||||
|
@ -121,13 +142,11 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
||||||
_encoder = nullptr;
|
_encoder = nullptr;
|
||||||
_codec = nullptr;
|
_codec = nullptr;
|
||||||
}
|
}
|
||||||
_receivedAudioStream.cleanupCodec();
|
|
||||||
|
|
||||||
auto codecPlugins = PluginManager::getInstance()->getCodecPlugins();
|
auto codecPlugins = PluginManager::getInstance()->getCodecPlugins();
|
||||||
for (auto& plugin : codecPlugins) {
|
for (auto& plugin : codecPlugins) {
|
||||||
if (_selectedCodecName == plugin->getName()) {
|
if (_selectedCodecName == plugin->getName()) {
|
||||||
_codec = plugin;
|
_codec = plugin;
|
||||||
_receivedAudioStream.setupCodec(plugin, _selectedCodecName, AudioConstants::STEREO);
|
|
||||||
_encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
_encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
||||||
qDebug() << "Selected Codec Plugin:" << _codec.get();
|
qDebug() << "Selected Codec Plugin:" << _codec.get();
|
||||||
break;
|
break;
|
||||||
|
@ -135,11 +154,91 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityScriptServer::handleAudioPacket(QSharedPointer<ReceivedMessage> message) {
|
void EntityScriptServer::resetEntitiesScriptEngine() {
|
||||||
_receivedAudioStream.parseData(*message);
|
auto engineName = QString("Entities %1").arg(++_entitiesScriptEngineCount);
|
||||||
|
auto newEngine = QSharedPointer<ScriptEngine>(new ScriptEngine(NO_SCRIPT, engineName));
|
||||||
|
|
||||||
_lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness();
|
newEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
||||||
_receivedAudioStream.clearBuffer();
|
|
||||||
|
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) {
|
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
|
||||||
|
@ -151,11 +250,43 @@ void EntityScriptServer::sendStatsPacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityScriptServer::handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
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) {
|
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() {
|
void EntityScriptServer::aboutToFinish() {
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include <EntityEditPacketSender.h>
|
#include <EntityEditPacketSender.h>
|
||||||
|
#include <EntityTreeHeadlessViewer.h>
|
||||||
#include <plugins/CodecPlugin.h>
|
#include <plugins/CodecPlugin.h>
|
||||||
|
#include <ScriptEngine.h>
|
||||||
#include <ThreadedAssignment.h>
|
#include <ThreadedAssignment.h>
|
||||||
|
|
||||||
#include "MixedAudioStream.h"
|
|
||||||
|
|
||||||
class EntityScriptServer : public ThreadedAssignment {
|
class EntityScriptServer : public ThreadedAssignment {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -38,19 +38,29 @@ private slots:
|
||||||
void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||||
void handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
void handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||||
void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
|
void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
|
||||||
void handleAudioPacket(QSharedPointer<ReceivedMessage> message);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void negotiateAudioFormat();
|
void negotiateAudioFormat();
|
||||||
void selectAudioFormat(const QString& selectedCodecName);
|
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;
|
EntityEditPacketSender _entityEditSender;
|
||||||
|
EntityTreeHeadlessViewer _entityViewer;
|
||||||
|
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
Encoder* _encoder { nullptr };
|
Encoder* _encoder { nullptr };
|
||||||
MixedAudioStream _receivedAudioStream;
|
|
||||||
float _lastReceivedAudioLoudness;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityScriptServer_h
|
#endif // hifi_EntityScriptServer_h
|
||||||
|
|
|
@ -45,9 +45,7 @@
|
||||||
|
|
||||||
EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
||||||
AbstractScriptingServicesInterface* scriptingServices) :
|
AbstractScriptingServicesInterface* scriptingServices) :
|
||||||
OctreeRenderer(),
|
|
||||||
_wantScripts(wantScripts),
|
_wantScripts(wantScripts),
|
||||||
_entitiesScriptEngine(NULL),
|
|
||||||
_lastPointerEventValid(false),
|
_lastPointerEventValid(false),
|
||||||
_viewState(viewState),
|
_viewState(viewState),
|
||||||
_scriptingServices(scriptingServices),
|
_scriptingServices(scriptingServices),
|
||||||
|
@ -106,6 +104,35 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
|
||||||
auto newEngine = new ScriptEngine(NO_SCRIPT, QString("Entities %1").arg(++_entitiesScriptEngineCount));
|
auto newEngine = new ScriptEngine(NO_SCRIPT, QString("Entities %1").arg(++_entitiesScriptEngineCount));
|
||||||
_entitiesScriptEngine = QSharedPointer<ScriptEngine>(newEngine, entitiesScriptEngineDeleter);
|
_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());
|
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine.data());
|
||||||
_entitiesScriptEngine->runInThread();
|
_entitiesScriptEngine->runInThread();
|
||||||
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(_entitiesScriptEngine.data());
|
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
|
// and we want to simulate this message here as well as in mouse move
|
||||||
if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) {
|
if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) {
|
||||||
emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent);
|
emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent);
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -302,9 +328,6 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||||
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
||||||
if (!entitiesContainingAvatar.contains(entityID)) {
|
if (!entitiesContainingAvatar.contains(entityID)) {
|
||||||
emit leaveEntity(entityID);
|
emit leaveEntity(entityID);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,9 +335,6 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||||
foreach(const EntityItemID& entityID, entitiesContainingAvatar) {
|
foreach(const EntityItemID& entityID, entitiesContainingAvatar) {
|
||||||
if (!_currentEntitiesInside.contains(entityID)) {
|
if (!_currentEntitiesInside.contains(entityID)) {
|
||||||
emit enterEntity(entityID);
|
emit enterEntity(entityID);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_currentEntitiesInside = entitiesContainingAvatar;
|
_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
|
// for all of our previous containing entities, if they are no longer containing then send them a leave event
|
||||||
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
||||||
emit leaveEntity(entityID);
|
emit leaveEntity(entityID);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_currentEntitiesInside.clear();
|
_currentEntitiesInside.clear();
|
||||||
forceRecheckEntities();
|
forceRecheckEntities();
|
||||||
|
@ -719,15 +736,8 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
|
||||||
|
|
||||||
emit mousePressOnEntity(rayPickResult.entityID, pointerEvent);
|
emit mousePressOnEntity(rayPickResult.entityID, pointerEvent);
|
||||||
|
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", pointerEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentClickingOnEntityID = rayPickResult.entityID;
|
_currentClickingOnEntityID = rayPickResult.entityID;
|
||||||
emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent);
|
emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", pointerEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastPointerEvent = pointerEvent;
|
_lastPointerEvent = pointerEvent;
|
||||||
_lastPointerEventValid = true;
|
_lastPointerEventValid = true;
|
||||||
|
@ -758,9 +768,6 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
toPointerButton(*event), toPointerButtons(*event));
|
toPointerButton(*event), toPointerButtons(*event));
|
||||||
|
|
||||||
emit mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent);
|
emit mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", pointerEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastPointerEvent = pointerEvent;
|
_lastPointerEvent = pointerEvent;
|
||||||
_lastPointerEventValid = true;
|
_lastPointerEventValid = true;
|
||||||
|
@ -778,9 +785,6 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
toPointerButton(*event), toPointerButtons(*event));
|
toPointerButton(*event), toPointerButtons(*event));
|
||||||
|
|
||||||
emit clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent);
|
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
|
// 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);
|
emit mouseMoveOnEntity(rayPickResult.entityID, pointerEvent);
|
||||||
|
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", pointerEvent);
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveOnEntity", pointerEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle the hover logic...
|
// handle the hover logic...
|
||||||
|
|
||||||
// if we were previously hovering over an entity, and this new entity is not the same as our previous entity
|
// 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));
|
toPointerButton(*event), toPointerButtons(*event));
|
||||||
|
|
||||||
emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
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
|
// 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
|
// this is true if the _currentHoverOverEntityID is known or unknown
|
||||||
if (rayPickResult.entityID != _currentHoverOverEntityID) {
|
if (rayPickResult.entityID != _currentHoverOverEntityID) {
|
||||||
emit hoverEnterEntity(rayPickResult.entityID, pointerEvent);
|
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
|
// 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
|
// we should send our hover over event
|
||||||
emit hoverOverEntity(rayPickResult.entityID, pointerEvent);
|
emit hoverOverEntity(rayPickResult.entityID, pointerEvent);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", pointerEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember what we're hovering over
|
// remember what we're hovering over
|
||||||
_currentHoverOverEntityID = rayPickResult.entityID;
|
_currentHoverOverEntityID = rayPickResult.entityID;
|
||||||
|
@ -869,9 +859,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
||||||
toPointerButton(*event), toPointerButtons(*event));
|
toPointerButton(*event), toPointerButtons(*event));
|
||||||
|
|
||||||
emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent);
|
|
||||||
}
|
|
||||||
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID
|
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -888,9 +875,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
||||||
toPointerButton(*event), toPointerButtons(*event));
|
toPointerButton(*event), toPointerButtons(*event));
|
||||||
|
|
||||||
emit holdingClickOnEntity(_currentClickingOnEntityID, pointerEvent);
|
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
|
// And now the entity scripts
|
||||||
if (isCollisionOwner(myNodeID, entityTree, idA, collision)) {
|
if (isCollisionOwner(myNodeID, entityTree, idA, collision)) {
|
||||||
emit collisionWithEntity(idA, idB, collision);
|
emit collisionWithEntity(idA, idB, collision);
|
||||||
if (_entitiesScriptEngine) {
|
|
||||||
_entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCollisionOwner(myNodeID, entityTree, idA, collision)) {
|
if (isCollisionOwner(myNodeID, entityTree, idA, collision)) {
|
||||||
emit collisionWithEntity(idB, 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 PhysicalEntitySimulationPointer = std::shared_ptr<PhysicalEntitySimulation>;
|
||||||
using SetOfEntityMotionStates = QSet<EntityMotionState*>;
|
using SetOfEntityMotionStates = QSet<EntityMotionState*>;
|
||||||
|
|
||||||
class PhysicalEntitySimulation :public EntitySimulation {
|
class PhysicalEntitySimulation : public EntitySimulation {
|
||||||
public:
|
public:
|
||||||
PhysicalEntitySimulation();
|
PhysicalEntitySimulation();
|
||||||
~PhysicalEntitySimulation();
|
~PhysicalEntitySimulation();
|
||||||
|
|
|
@ -90,7 +90,6 @@ public slots:
|
||||||
protected slots:
|
protected slots:
|
||||||
void onScriptFinished(const QString& fileNameString, ScriptEngine* engine);
|
void onScriptFinished(const QString& fileNameString, ScriptEngine* engine);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class ScriptEngine;
|
friend class ScriptEngine;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue