Showing the changes to assignment-client/src/scripts/EntityScriptServer.cpp (1 of 9 files). Show all
Unified · Split
| @@ -11,7 +11,166 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #include "EntityScriptServer.h" |
| 13 | 13 | |
| 14 | −EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssignment(message) { | |
| 14 | +#include <AudioInjectorManager.h> | |
| 15 | +#include <EntityScriptingInterface.h> | |
| 16 | +#include <MessagesClient.h> | |
| 17 | +#include <plugins/CodecPlugin.h> | |
| 18 | +#include <plugins/PluginManager.h> | |
| 19 | +#include <ResourceManager.h> | |
| 20 | +#include <ScriptCache.h> | |
| 21 | +#include <ScriptEngines.h> | |
| 22 | +#include <SoundCache.h> | |
| 15 | 23 | |
| 24 | +#include "../entities/AssignmentParentFinder.h" | |
| 16 | 25 | |
| 26 | +static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 10; | |
| 27 | + | |
| 28 | +EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : | |
| 29 | + ThreadedAssignment(message), | |
| 30 | + _receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES, RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES) | |
| 31 | +{ | |
| 32 | + DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender); | |
| 33 | + | |
| 34 | + ResourceManager::init(); | |
| 35 | + | |
| 36 | + DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>(); | |
| 37 | + | |
| 38 | + DependencyManager::set<ResourceCacheSharedItems>(); | |
| 39 | + DependencyManager::set<SoundCache>(); | |
| 40 | + DependencyManager::set<AudioInjectorManager>(); | |
| 41 | + | |
| 42 | + DependencyManager::set<ScriptCache>(); | |
| 43 | + DependencyManager::set<ScriptEngines>(); | |
| 44 | + | |
| 45 | + | |
| 46 | + auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); | |
| 47 | + | |
| 48 | + packetReceiver.registerListenerForTypes({ PacketType::MixedAudio, PacketType::SilentAudioFrame }, | |
| 49 | + this, "handleAudioPacket"); | |
| 50 | + packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, | |
| 51 | + this, "handleOctreePacket"); | |
| 52 | + packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket"); | |
| 53 | + packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat"); | |
| 54 | + | |
| 55 | +} | |
| 56 | + | |
| 57 | +static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server"; | |
| 58 | + | |
| 59 | +void EntityScriptServer::run() { | |
| 60 | + // make sure we request our script once the agent connects to the domain | |
| 61 | + auto nodeList = DependencyManager::get<NodeList>(); | |
| 62 | + | |
| 63 | + ThreadedAssignment::commonInit(ENTITY_SCRIPT_SERVER_LOGGING_NAME, NodeType::EntityScriptServer); | |
| 64 | + | |
| 65 | + // Setup MessagesClient | |
| 66 | + auto messagesClient = DependencyManager::set<MessagesClient>(); | |
| 67 | + QThread* messagesThread = new QThread; | |
| 68 | + messagesThread->setObjectName("Messages Client Thread"); | |
| 69 | + messagesClient->moveToThread(messagesThread); | |
| 70 | + connect(messagesThread, &QThread::started, messagesClient.data(), &MessagesClient::init); | |
| 71 | + messagesThread->start(); | |
| 72 | + | |
| 73 | + // make sure we hear about connected nodes so we can grab an ATP script if a request is pending | |
| 74 | + connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &EntityScriptServer::nodeActivated); | |
| 75 | + connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &EntityScriptServer::nodeKilled); | |
| 76 | + | |
| 77 | + nodeList->addSetOfNodeTypesToNodeInterestSet({ | |
| 78 | + NodeType::AudioMixer, NodeType::AvatarMixer, NodeType::EntityServer, NodeType::MessagesMixer, NodeType::AssetServer | |
| 79 | + }); | |
| 80 | +} | |
| 81 | + | |
| 82 | +void EntityScriptServer::nodeActivated(SharedNodePointer activatedNode) { | |
| 83 | + if (activatedNode->getType() == NodeType::AudioMixer) { | |
| 84 | + negotiateAudioFormat(); | |
| 85 | + } | |
| 86 | +} | |
| 87 | + | |
| 88 | +void EntityScriptServer::negotiateAudioFormat() { | |
| 89 | + auto nodeList = DependencyManager::get<NodeList>(); | |
| 90 | + auto negotiateFormatPacket = NLPacket::create(PacketType::NegotiateAudioFormat); | |
| 91 | + auto codecPlugins = PluginManager::getInstance()->getCodecPlugins(); | |
| 92 | + quint8 numberOfCodecs = (quint8)codecPlugins.size(); | |
| 93 | + negotiateFormatPacket->writePrimitive(numberOfCodecs); | |
| 94 | + for (auto& plugin : codecPlugins) { | |
| 95 | + auto codecName = plugin->getName(); | |
| 96 | + negotiateFormatPacket->writeString(codecName); | |
| 97 | + } | |
| 98 | + | |
| 99 | + // grab our audio mixer from the NodeList, if it exists | |
| 100 | + SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer); | |
| 101 | + | |
| 102 | + if (audioMixer) { | |
| 103 | + // send off this mute packet | |
| 104 | + nodeList->sendPacket(std::move(negotiateFormatPacket), *audioMixer); | |
| 105 | + } | |
| 106 | +} | |
| 107 | + | |
| 108 | +void EntityScriptServer::handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message) { | |
| 109 | + QString selectedCodecName = message->readString(); | |
| 110 | + selectAudioFormat(selectedCodecName); | |
| 111 | +} | |
| 112 | + | |
| 113 | +void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) { | |
| 114 | + _selectedCodecName = selectedCodecName; | |
| 115 | + | |
| 116 | + qDebug() << "Selected Codec:" << _selectedCodecName; | |
| 117 | + | |
| 118 | + // release any old codec encoder/decoder first... | |
| 119 | + if (_codec && _encoder) { | |
| 120 | + _codec->releaseEncoder(_encoder); | |
| 121 | + _encoder = nullptr; | |
| 122 | + _codec = nullptr; | |
| 123 | + } | |
| 124 | + _receivedAudioStream.cleanupCodec(); | |
| 125 | + | |
| 126 | + auto codecPlugins = PluginManager::getInstance()->getCodecPlugins(); | |
| 127 | + for (auto& plugin : codecPlugins) { | |
| 128 | + if (_selectedCodecName == plugin->getName()) { | |
| 129 | + _codec = plugin; | |
| 130 | + _receivedAudioStream.setupCodec(plugin, _selectedCodecName, AudioConstants::STEREO); | |
| 131 | + _encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO); | |
| 132 | + qDebug() << "Selected Codec Plugin:" << _codec.get(); | |
| 133 | + break; | |
| 134 | + } | |
| 135 | + } | |
| 136 | +} | |
| 137 | + | |
| 138 | +void EntityScriptServer::handleAudioPacket(QSharedPointer<ReceivedMessage> message) { | |
| 139 | + _receivedAudioStream.parseData(*message); | |
| 140 | + | |
| 141 | + _lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness(); | |
| 142 | + _receivedAudioStream.clearBuffer(); | |
| 143 | +} | |
| 144 | + | |
| 145 | +void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) { | |
| 146 | + | |
| 147 | +} | |
| 148 | + | |
| 149 | +void EntityScriptServer::sendStatsPacket() { | |
| 150 | + | |
| 151 | +} | |
| 152 | + | |
| 153 | +void EntityScriptServer::handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) { | |
| 154 | + | |
| 155 | +} | |
| 156 | + | |
| 157 | +void EntityScriptServer::handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) { | |
| 158 | + | |
| 159 | +} | |
| 160 | + | |
| 161 | +void EntityScriptServer::aboutToFinish() { | |
| 162 | + // our entity tree is going to go away so tell that to the EntityScriptingInterface | |
| 163 | + DependencyManager::get<EntityScriptingInterface>()->setEntityTree(nullptr); | |
| 164 | + | |
| 165 | + ResourceManager::cleanup(); | |
| 166 | + | |
| 167 | + // cleanup the AudioInjectorManager (and any still running injectors) | |
| 168 | + DependencyManager::destroy<AudioInjectorManager>(); | |
| 169 | + DependencyManager::destroy<ScriptEngines>(); | |
| 170 | + | |
| 171 | + // cleanup codec & encoder | |
| 172 | + if (_codec && _encoder) { | |
| 173 | + _codec->releaseEncoder(_encoder); | |
| 174 | + _encoder = nullptr; | |
| 175 | + } | |
| 17 | 176 | } |