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+
8+MessageID EntityScriptClient::_currentID = 0;
9+
10+GetScriptStatusRequest::GetScriptStatusRequest(QUuid entityID) : _entityID(entityID) {
11+}
12+
13+GetScriptStatusRequest::~GetScriptStatusRequest() {
14+
15+}
16+
17+void 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+
29+EntityScriptClient::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+
45+GetScriptStatusRequest* EntityScriptClient::createScriptStatusRequest(QUuid entityID) {
46+ auto request = new GetScriptStatusRequest(entityID);
47+
48+ request->moveToThread(thread());
49+
50+ return request;
51+}
52+
53+bool 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+
73+void 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+
96+void 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+
119+MessageID 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+
142+void 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+
178+void 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+
188+void 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+
199+void 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+}