History

dropping dependencies from networking to script-engine by moving EntityScriptClient and LocationScriptingInterface

Heather Anderson committed 5 years ago

Commit 45ef4581 parent 7964f066 files · +13 −15Browse files

Showing the changes to libraries/script-engine/src/EntityScriptClient.cpp (1 of 6 files). Show all

Unified · Split

libraries/script-engine/src/EntityScriptClient.cpp+210−0
@@ -0,0 +1,210 @@
1#include "EntityScriptClient.h"
2#include <NodeList.h>
3#include <NetworkLogging.h>
4#include "EntityScriptUtils.h"
5
6#include <QThread>
7
8MessageID EntityScriptClient::_currentID = 0;
9
10GetScriptStatusRequest::GetScriptStatusRequest(QUuid entityID) : _entityID(entityID) {
11}
12
13GetScriptStatusRequest::~GetScriptStatusRequest() {
14
15}
16
17void GetScriptStatusRequest::start() {
18 auto client = DependencyManager::get<EntityScriptClient>();
19 client->getEntityServerScriptStatus(_entityID, [this](bool responseReceived, bool isRunning, EntityScriptStatus status, QString errorInfo) {
20 _responseReceived = responseReceived;
21 _isRunning = isRunning;
22 _status = status;
23 _errorInfo = errorInfo;
24
25 emit finished(this);
26 });
27}
28
29EntityScriptClient::EntityScriptClient() {
30 setCustomDeleter([](Dependency* dependency){
31 static_cast<EntityScriptClient*>(dependency)->deleteLater();
32 });
33
34 auto nodeList = DependencyManager::get<NodeList>();
35 auto& packetReceiver = nodeList->getPacketReceiver();
36
37 packetReceiver.registerListener(PacketType::EntityScriptGetStatusReply,
38 PacketReceiver::makeSourcedListenerReference<EntityScriptClient>(this, &EntityScriptClient::handleGetScriptStatusReply));
39
40 connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &EntityScriptClient::handleNodeKilled);
41 connect(nodeList.data(), &LimitedNodeList::clientConnectionToNodeReset,
42 this, &EntityScriptClient::handleNodeClientConnectionReset);
43}
44
45GetScriptStatusRequest* EntityScriptClient::createScriptStatusRequest(QUuid entityID) {
46 auto request = new GetScriptStatusRequest(entityID);
47
48 request->moveToThread(thread());
49
50 return request;
51}
52
53bool EntityScriptClient::reloadServerScript(QUuid entityID) {
54 // Send packet to entity script server
55 auto nodeList = DependencyManager::get<NodeList>();
56 SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
57
58 if (entityScriptServer) {
59 auto id = entityID.toRfc4122();
60 auto payloadSize = id.size();
61 auto packet = NLPacket::create(PacketType::ReloadEntityServerScript, payloadSize, true);
62
63 packet->write(id);
64
65 if (nodeList->sendPacket(std::move(packet), *entityScriptServer) != -1) {
66 return true;
67 }
68 }
69
70 return false;
71}
72
73void EntityScriptClient::callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params) {
74 // Send packet to entity script server
75 auto nodeList = DependencyManager::get<NodeList>();
76 SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
77
78 if (entityScriptServer) {
79 auto packetList = NLPacketList::create(PacketType::EntityScriptCallMethod, QByteArray(), true, true);
80
81 packetList->write(entityID.toRfc4122());
82
83 packetList->writeString(method);
84
85 quint16 paramCount = params.length();
86 packetList->writePrimitive(paramCount);
87
88 foreach(const QString& param, params) {
89 packetList->writeString(param);
90 }
91
92 nodeList->sendPacketList(std::move(packetList), *entityScriptServer);
93 }
94}
95
96void EntityScriptServerServices::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) {
97 // only valid to call this function if you are the entity script server
98 auto nodeList = DependencyManager::get<NodeList>();
99 SharedNodePointer targetClient = nodeList->nodeWithUUID(clientSessionID);
100
101 if (nodeList->getOwnerType() == NodeType::EntityScriptServer && targetClient) {
102 auto packetList = NLPacketList::create(PacketType::EntityScriptCallMethod, QByteArray(), true, true);
103
104 packetList->write(entityID.toRfc4122());
105
106 packetList->writeString(method);
107
108 quint16 paramCount = params.length();
109 packetList->writePrimitive(paramCount);
110
111 foreach(const QString& param, params) {
112 packetList->writeString(param);
113 }
114
115 nodeList->sendPacketList(std::move(packetList), *targetClient);
116 }
117}
118
119MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
120 auto nodeList = DependencyManager::get<NodeList>();
121 SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
122
123 if (entityScriptServer) {
124 auto packetList = NLPacketList::create(PacketType::EntityScriptGetStatus, QByteArray(), true, true);
125
126 auto messageID = ++_currentID;
127 packetList->writePrimitive(messageID);
128
129 packetList->write(entityID.toRfc4122());
130
131 if (nodeList->sendPacketList(std::move(packetList), *entityScriptServer) != -1) {
132 _pendingEntityScriptStatusRequests[entityScriptServer][messageID] = callback;
133
134 return messageID;
135 }
136 }
137
138 callback(false, false, EntityScriptStatus::ERROR_LOADING_SCRIPT, "");
139 return INVALID_MESSAGE_ID;
140}
141
142void EntityScriptClient::handleGetScriptStatusReply(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
143 Q_ASSERT(QThread::currentThread() == thread());
144
145 MessageID messageID;
146 bool isKnown { false };
147 EntityScriptStatus status = EntityScriptStatus::ERROR_LOADING_SCRIPT;
148 QString errorInfo { "" };
149
150 message->readPrimitive(&messageID);
151 message->readPrimitive(&isKnown);
152
153 if (isKnown) {
154 message->readPrimitive(&status);
155 errorInfo = message->readString();
156 }
157
158 // Check if we have any pending requests for this node
159 auto messageMapIt = _pendingEntityScriptStatusRequests.find(senderNode);
160 if (messageMapIt != _pendingEntityScriptStatusRequests.end()) {
161
162 // Found the node, get the MessageID -> Callback map
163 auto& messageCallbackMap = messageMapIt->second;
164
165 // Check if we have this pending request
166 auto requestIt = messageCallbackMap.find(messageID);
167 if (requestIt != messageCallbackMap.end()) {
168 auto callback = requestIt->second;
169 callback(true, isKnown, status, errorInfo);
170 messageCallbackMap.erase(requestIt);
171 }
172
173 // Although the messageCallbackMap may now be empty, we won't delete the node until we have disconnected from
174 // it to avoid constantly creating/deleting the map on subsequent requests.
175 }
176}
177
178void EntityScriptClient::handleNodeKilled(SharedNodePointer node) {
179 Q_ASSERT(QThread::currentThread() == thread());
180
181 if (node->getType() != NodeType::EntityScriptServer) {
182 return;
183 }
184
185 forceFailureOfPendingRequests(node);
186}
187
188void EntityScriptClient::handleNodeClientConnectionReset(SharedNodePointer node) {
189 // a client connection to a Node was reset
190 // if it was an EntityScriptServer we need to cause anything pending to fail so it is re-attempted
191
192 if (node->getType() != NodeType::EntityScriptServer) {
193 return;
194 }
195
196 forceFailureOfPendingRequests(node);
197}
198
199void EntityScriptClient::forceFailureOfPendingRequests(SharedNodePointer node) {
200
201 {
202 auto messageMapIt = _pendingEntityScriptStatusRequests.find(node);
203 if (messageMapIt != _pendingEntityScriptStatusRequests.end()) {
204 for (const auto& value : messageMapIt->second) {
205 value.second(false, false, EntityScriptStatus::ERROR_LOADING_SCRIPT, "");
206 }
207 messageMapIt->second.clear();
208 }
209 }
210}