connection.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "connection.h"
  9. #include "native/connection/connectionworker.h"
  10. #include "native/utilities/ByteArrayStream.h"
  11. #include <QSettings>
  12. Connection::Connection(qintptr socketDescriptor, QObject* parent)
  13. : Connection(false, socketDescriptor, parent)
  14. {
  15. }
  16. Connection::Connection(bool isUserCreatedConnection, qintptr socketDescriptor, QObject* parent)
  17. : QObject(parent)
  18. , m_userCreatedConnection(isUserCreatedConnection)
  19. {
  20. m_runElapsed = true;
  21. //metrics
  22. m_numOpenRequests = 0;
  23. m_numCloseRequests = 0;
  24. m_numOpened = 0;
  25. m_numClosed = 0;
  26. m_numReadRequests = 0;
  27. m_numWriteRequests = 0;
  28. m_numTellRequests = 0;
  29. m_numSeekRequests = 0;
  30. m_numEofRequests = 0;
  31. m_numIsReadOnlyRequests = 0;
  32. m_numIsDirectoryRequests = 0;
  33. m_numSizeRequests = 0;
  34. m_numModificationTimeRequests = 0;
  35. m_numExistsRequests = 0;
  36. m_numFlushRequests = 0;
  37. m_numCreatePathRequests = 0;
  38. m_numDestroyPathRequests = 0;
  39. m_numRemoveRequests = 0;
  40. m_numCopyRequests = 0;
  41. m_numRenameRequests = 0;
  42. m_numFindFileNamesRequests = 0;
  43. m_bytesRead = 0;
  44. m_bytesWritten = 0;
  45. m_bytesSent = 0;
  46. m_bytesReceived = 0;
  47. m_numOpenFiles = 0;
  48. //connection
  49. m_identifier = "";//empty
  50. m_ipAddress = "127.0.0.1";// default is loopback address
  51. m_port = 22229;//default port number
  52. m_status = Disconnected;//default status
  53. m_autoConnect = false;//default status
  54. m_connectionId = 0; //default
  55. m_connectionWorker = new AssetProcessor::ConnectionWorker(socketDescriptor);
  56. m_connectionWorker->moveToThread(&m_connectionWorkerThread);
  57. m_connectionWorker->GetSocket().moveToThread(&m_connectionWorkerThread);
  58. connect(this, &Connection::TerminateConnection, m_connectionWorker, &AssetProcessor::ConnectionWorker::RequestTerminate, Qt::DirectConnection);
  59. connect(this, &Connection::NormalConnectionRequested, m_connectionWorker, &AssetProcessor::ConnectionWorker::ConnectToEngine);
  60. connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::Identifier, this, [this](QString identifier) {
  61. // For user created connections, the id is user generated (either because they've manually entered some text
  62. // this session, or because the id was loaded from a session previously saved where the user entered it).
  63. // As such, when the connection worker reports a new id from after the connection occurs,
  64. // we only pay attention to it when it is not a user created connection.
  65. if (!m_userCreatedConnection)
  66. {
  67. SetIdentifier(identifier);
  68. }
  69. });
  70. connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::AssetPlatformsString, this, &Connection::SetAssetPlatformsString);
  71. connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::ConnectionDisconnected, this, &Connection::OnConnectionDisconnect, Qt::QueuedConnection);
  72. // the blocking queued connection is here because the worker calls OnConnectionEstablished and then immediately starts emitting messages about
  73. // data coming in. We want to immediately establish connectivity this way and we don't want it to proceed with message delivery until then.
  74. connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::ConnectionEstablished, this, &Connection::OnConnectionEstablished, Qt::BlockingQueuedConnection);
  75. connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::ErrorMessage, this, &Connection::ErrorMessage);
  76. connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::IsAddressInAllowedList, this, &Connection::IsAddressInAllowedList);
  77. connect(this, &Connection::AddressIsInAllowedList, m_connectionWorker, &AssetProcessor::ConnectionWorker::AddressIsInAllowedList);
  78. }
  79. void Connection::Activate(qintptr socketDescriptor)
  80. {
  81. m_connectionWorkerThread.setObjectName("Connection Worker Thread");
  82. m_connectionWorkerThread.start();
  83. //if socketDescriptor is positive it means that it is an incoming connection
  84. if (socketDescriptor >= 0)
  85. {
  86. SetStatus(Connecting);
  87. // by invoking the ConnectSocket, we cause it to occur in the worker's thread
  88. QMetaObject::invokeMethod(m_connectionWorker, "ConnectSocket", Q_ARG(qintptr, socketDescriptor));
  89. }
  90. }
  91. Connection::~Connection()
  92. {
  93. Q_ASSERT(!m_connectionWorkerThread.isRunning());
  94. Q_EMIT ConnectionDestroyed(m_connectionId);
  95. }
  96. QString Connection::Identifier() const
  97. {
  98. return m_identifier;
  99. }
  100. void Connection::SetIdentifier(QString identifier)
  101. {
  102. if (m_identifier == identifier)
  103. {
  104. return;
  105. }
  106. m_identifier = identifier;
  107. Q_EMIT IdentifierChanged();
  108. Q_EMIT DisplayNameChanged(); // regardless of whether the identifier is empty or not, this always affects the display name.
  109. }
  110. QString Connection::IpAddress() const
  111. {
  112. return m_ipAddress;
  113. }
  114. QStringList Connection::AssetPlatforms() const
  115. {
  116. return m_assetPlatforms;
  117. }
  118. QString Connection::AssetPlatformsString() const
  119. {
  120. return m_assetPlatforms.join(',');
  121. }
  122. void Connection::SetAssetPlatforms(QStringList assetPlatforms)
  123. {
  124. if (m_assetPlatforms == assetPlatforms)
  125. {
  126. return;
  127. }
  128. m_assetPlatforms = assetPlatforms;
  129. Q_EMIT AssetPlatformChanged();
  130. }
  131. QString Connection::DisplayName() const
  132. {
  133. if (m_identifier.isEmpty())
  134. {
  135. return m_ipAddress;
  136. }
  137. return m_identifier;
  138. }
  139. QString Connection::Elapsed() const
  140. {
  141. return m_elapsedDisplay;
  142. }
  143. void Connection::SetIpAddress(QString ipAddress)
  144. {
  145. if (Status() == Connected)
  146. {
  147. AZ_Warning(AssetProcessor::ConsoleChannel, Status() == Connected, "You are not allowed to change the ip address of a connected connection.\n");
  148. return;
  149. }
  150. if (ipAddress == m_ipAddress)
  151. {
  152. return;
  153. }
  154. m_ipAddress = ipAddress;
  155. Q_EMIT IpAddressChanged();
  156. if (m_identifier.isEmpty()) // if the identifier is empty, then the display name is the ip address
  157. {
  158. Q_EMIT DisplayNameChanged();
  159. }
  160. }
  161. int Connection::Port() const
  162. {
  163. return m_port;
  164. }
  165. void Connection::SetPort(int port)
  166. {
  167. if (Status() == Connected)
  168. {
  169. AZ_Warning(AssetProcessor::ConsoleChannel, Status() == Connected, "You are not allowed to change the port of a connected connection.\n");
  170. return;
  171. }
  172. if (port == m_port)
  173. {
  174. return;
  175. }
  176. m_port = aznumeric_cast<quint16>(port);
  177. Q_EMIT PortChanged();
  178. }
  179. Connection::ConnectionStatus Connection::Status() const
  180. {
  181. return m_status;
  182. }
  183. void Connection::SaveConnection(QSettings& qSettings)
  184. {
  185. qSettings.setValue("identifier", Identifier());
  186. qSettings.setValue("ipAddress", IpAddress());
  187. qSettings.setValue("port", Port());
  188. qSettings.setValue("assetplatform", AssetPlatforms());
  189. qSettings.setValue("autoConnect", AutoConnect());
  190. qSettings.setValue("userConnection", m_userCreatedConnection);
  191. }
  192. void Connection::LoadConnection(QSettings& qSettings)
  193. {
  194. SetIdentifier(qSettings.value("identifier").toString());
  195. SetIpAddress(qSettings.value("ipAddress").toString());
  196. SetPort(qSettings.value("port").toInt());
  197. SetAssetPlatformsString(qSettings.value("assetplatform").toString());
  198. SetAutoConnect(qSettings.value("autoConnect").toBool());
  199. SetStatus(Disconnected);
  200. m_userCreatedConnection = qSettings.value("userConnection", false).toBool();
  201. }
  202. void Connection::SetStatus(Connection::ConnectionStatus status)
  203. {
  204. if (status == m_status)
  205. {
  206. return;
  207. }
  208. m_status = status;
  209. Q_EMIT StatusChanged(m_connectionId);
  210. if (status == Connection::Connected)
  211. {
  212. AssetProcessor::ConnectionBus::Handler::BusConnect(m_connectionId);
  213. }
  214. else if (status == Connection::Disconnected)
  215. {
  216. AssetProcessor::ConnectionBus::Handler::BusDisconnect();
  217. }
  218. }
  219. bool Connection::AutoConnect() const
  220. {
  221. return m_autoConnect;
  222. }
  223. void Connection::Connect()
  224. {
  225. m_queuedReconnect = false;
  226. if (!m_connectionWorker)
  227. {
  228. // this can happen if you queued a connect but in the interim, we were deleteLater'd due to removal.
  229. return;
  230. }
  231. m_connectionWorker->Reset();
  232. Q_EMIT NormalConnectionRequested(m_ipAddress, m_port);
  233. }
  234. void Connection::Disconnect()
  235. {
  236. Q_EMIT DisconnectConnection(m_connectionId);
  237. }
  238. void Connection::Terminate()
  239. {
  240. Q_EMIT TerminateConnection();
  241. if (m_connectionWorkerThread.isRunning())
  242. {
  243. m_connectionWorkerThread.quit();
  244. m_connectionWorkerThread.wait();
  245. }
  246. deleteLater();
  247. }
  248. void Connection::SetAutoConnect(bool autoConnect)
  249. {
  250. if (autoConnect == m_autoConnect)
  251. {
  252. return;
  253. }
  254. m_autoConnect = autoConnect;
  255. if (m_autoConnect)
  256. {
  257. SetStatus(Connecting);
  258. Connect();
  259. }
  260. else
  261. {
  262. SetStatus(Disconnected);
  263. Disconnect();
  264. }
  265. Q_EMIT AutoConnectChanged();
  266. }
  267. void Connection::OnConnectionDisconnect()
  268. {
  269. if (m_connectionWorker)
  270. {
  271. disconnect(this, &Connection::SendMessage, m_connectionWorker, &AssetProcessor::ConnectionWorker::SendMessage);
  272. disconnect(m_connectionWorker, &AssetProcessor::ConnectionWorker::ReceiveMessage, this, &Connection::ReceiveMessage);
  273. }
  274. // For user created connections, the id is user generated (either because they've manually entered some text
  275. // this session, or because the id was loaded from a session previously saved where the user entered it).
  276. // As such, when a connection disconnects, we only want to clear the id when the connection was triggered
  277. // from something other than the user (i.e. like when an automatic connection from Editor or a job worker
  278. // disconnects).
  279. if (!m_userCreatedConnection)
  280. {
  281. SetIdentifier(QString());
  282. }
  283. SetAssetPlatforms(QStringList());
  284. if (m_autoConnect)
  285. {
  286. if (!m_queuedReconnect)
  287. {
  288. m_queuedReconnect = true;
  289. SetStatus(Connecting);
  290. QTimer::singleShot(500, this, SLOT(Connect()));
  291. }
  292. }
  293. else
  294. {
  295. Disconnect();
  296. SetStatus(Disconnected);
  297. SetAssetPlatforms(QStringList());
  298. // if we did not initiate the connection, we should erase it when it disappears.
  299. if (!InitiatedConnection())
  300. {
  301. Terminate();
  302. }
  303. }
  304. }
  305. void Connection::OnConnectionEstablished(QString ipAddress, quint16 port)
  306. {
  307. connect(this, &Connection::SendMessage, m_connectionWorker, &AssetProcessor::ConnectionWorker::SendMessage, Qt::UniqueConnection);
  308. connect(m_connectionWorker, &AssetProcessor::ConnectionWorker::ReceiveMessage, this, &Connection::ReceiveMessage, Qt::UniqueConnection);
  309. m_elapsed = 0;
  310. m_elapsedTimer.start();
  311. m_runElapsed = true;
  312. UpdateElapsed();
  313. SetIpAddress(ipAddress);
  314. SetPort(port);
  315. SetStatus(Connected);
  316. Q_EMIT ConnectionReady(ConnectionId(), AssetPlatforms());
  317. }
  318. void Connection::ReceiveMessage(unsigned int type, unsigned int serial, QByteArray payload)
  319. {
  320. Q_EMIT DeliverMessage(m_connectionId, type, serial, payload);
  321. }
  322. void Connection::ErrorMessage(QString errorString)
  323. {
  324. Q_EMIT Error(m_connectionId, errorString);
  325. }
  326. void Connection::UpdateElapsed()
  327. {
  328. if (m_runElapsed)
  329. {
  330. m_elapsed += m_elapsedTimer.restart();
  331. int seconds = aznumeric_cast<int>(m_elapsed / 1000);
  332. int hours = seconds / (60 * 60);
  333. seconds -= hours * (60 * 60);
  334. int minutes = seconds / 60;
  335. seconds -= minutes * 60;
  336. m_elapsedDisplay.clear();
  337. if (hours < 10)
  338. {
  339. m_elapsedDisplay = "0";
  340. }
  341. m_elapsedDisplay += QString::number(hours) + ":";
  342. if (minutes < 10)
  343. {
  344. m_elapsedDisplay += "0";
  345. }
  346. m_elapsedDisplay += QString::number(minutes) + ":";
  347. if (seconds < 10)
  348. {
  349. m_elapsedDisplay += "0";
  350. }
  351. m_elapsedDisplay += QString::number(seconds);
  352. Q_EMIT ElapsedChanged();
  353. QTimer::singleShot(1000, this, SLOT(UpdateElapsed()));
  354. }
  355. }
  356. unsigned int Connection::ConnectionId() const
  357. {
  358. return m_connectionId;
  359. }
  360. void Connection::SetConnectionId(unsigned int connectionId)
  361. {
  362. m_connectionId = connectionId;
  363. }
  364. void Connection::SendMessageToWorker(unsigned int type, unsigned int serial, QByteArray payload)
  365. {
  366. Q_EMIT SendMessage(type, serial, payload);
  367. }
  368. void Connection::AddBytesReceived(qint64 add, bool update)
  369. {
  370. m_bytesReceived += add;
  371. if (update)
  372. {
  373. Q_EMIT BytesReceivedChanged();
  374. }
  375. }
  376. void Connection::AddBytesSent(qint64 add, bool update)
  377. {
  378. m_bytesSent += add;
  379. if (update)
  380. {
  381. Q_EMIT BytesSentChanged();
  382. }
  383. }
  384. void Connection::AddBytesRead(qint64 add, bool update)
  385. {
  386. m_bytesRead += add;
  387. if (update)
  388. {
  389. Q_EMIT BytesReadChanged();
  390. }
  391. }
  392. void Connection::AddBytesWritten(qint64 add, bool update)
  393. {
  394. m_bytesWritten += add;
  395. if (update)
  396. {
  397. Q_EMIT BytesWrittenChanged();
  398. }
  399. }
  400. void Connection::AddOpenRequest(bool update)
  401. {
  402. m_numOpenRequests++;
  403. if (update)
  404. {
  405. Q_EMIT NumOpenRequestsChanged();
  406. }
  407. }
  408. void Connection::AddCloseRequest(bool update)
  409. {
  410. m_numCloseRequests++;
  411. if (update)
  412. {
  413. Q_EMIT NumCloseRequestsChanged();
  414. }
  415. }
  416. void Connection::AddOpened(bool update)
  417. {
  418. m_numOpened++;
  419. m_numOpenFiles = m_numOpened - m_numClosed;
  420. if (update)
  421. {
  422. Q_EMIT NumOpenedChanged();
  423. Q_EMIT NumOpenFilesChanged();
  424. }
  425. }
  426. void Connection::AddClosed(bool update)
  427. {
  428. m_numClosed++;
  429. m_numOpenFiles = m_numOpened - m_numClosed;
  430. if (update)
  431. {
  432. Q_EMIT NumClosedChanged();
  433. Q_EMIT NumOpenFilesChanged();
  434. }
  435. }
  436. void Connection::AddReadRequest(bool update)
  437. {
  438. m_numReadRequests++;
  439. if (update)
  440. {
  441. Q_EMIT NumReadRequestsChanged();
  442. }
  443. }
  444. void Connection::AddWriteRequest(bool update)
  445. {
  446. m_numWriteRequests++;
  447. if (update)
  448. {
  449. Q_EMIT NumWriteRequestsChanged();
  450. }
  451. }
  452. void Connection::AddTellRequest(bool update)
  453. {
  454. m_numTellRequests++;
  455. if (update)
  456. {
  457. Q_EMIT NumTellRequestsChanged();
  458. }
  459. }
  460. void Connection::AddSeekRequest(bool update)
  461. {
  462. m_numSeekRequests++;
  463. if (update)
  464. {
  465. Q_EMIT NumSeekRequestsChanged();
  466. }
  467. }
  468. void Connection::AddEofRequest(bool update)
  469. {
  470. m_numEofRequests++;
  471. if (update)
  472. {
  473. Q_EMIT NumEofRequestsChanged();
  474. }
  475. }
  476. void Connection::AddIsReadOnlyRequest(bool update)
  477. {
  478. m_numIsReadOnlyRequests++;
  479. if (update)
  480. {
  481. Q_EMIT NumIsReadOnlyRequestsChanged();
  482. }
  483. }
  484. void Connection::AddIsDirectoryRequest(bool update)
  485. {
  486. m_numIsDirectoryRequests++;
  487. if (update)
  488. {
  489. Q_EMIT NumIsDirectoryRequestsChanged();
  490. }
  491. }
  492. void Connection::AddSizeRequest(bool update)
  493. {
  494. m_numSizeRequests++;
  495. if (update)
  496. {
  497. Q_EMIT NumSizeRequestsChanged();
  498. }
  499. }
  500. void Connection::AddModificationTimeRequest(bool update)
  501. {
  502. m_numModificationTimeRequests++;
  503. if (update)
  504. {
  505. Q_EMIT NumModificationTimeRequestsChanged();
  506. }
  507. }
  508. void Connection::AddExistsRequest(bool update)
  509. {
  510. m_numExistsRequests++;
  511. if (update)
  512. {
  513. Q_EMIT NumExistsRequestsChanged();
  514. }
  515. }
  516. void Connection::AddFlushRequest(bool update)
  517. {
  518. m_numFlushRequests++;
  519. if (update)
  520. {
  521. Q_EMIT NumFlushRequestsChanged();
  522. }
  523. }
  524. void Connection::AddCreatePathRequest(bool update)
  525. {
  526. m_numCreatePathRequests++;
  527. if (update)
  528. {
  529. Q_EMIT NumCreatePathRequestsChanged();
  530. }
  531. }
  532. void Connection::AddDestroyPathRequest(bool update)
  533. {
  534. m_numDestroyPathRequests++;
  535. if (update)
  536. {
  537. Q_EMIT NumDestroyPathRequestsChanged();
  538. }
  539. }
  540. void Connection::AddRemoveRequest(bool update)
  541. {
  542. m_numRemoveRequests++;
  543. if (update)
  544. {
  545. Q_EMIT NumRemoveRequestsChanged();
  546. }
  547. }
  548. void Connection::AddCopyRequest(bool update)
  549. {
  550. m_numCopyRequests++;
  551. if (update)
  552. {
  553. Q_EMIT NumCopyRequestsChanged();
  554. }
  555. }
  556. void Connection::AddRenameRequest(bool update)
  557. {
  558. m_numRenameRequests++;
  559. if (update)
  560. {
  561. Q_EMIT NumRenameRequestsChanged();
  562. }
  563. }
  564. void Connection::AddFindFileNamesRequest(bool update)
  565. {
  566. m_numFindFileNamesRequests++;
  567. if (update)
  568. {
  569. Q_EMIT NumFindFileNamesRequestsChanged();
  570. }
  571. }
  572. void Connection::UpdateBytesReceived()
  573. {
  574. Q_EMIT BytesReceivedChanged();
  575. }
  576. void Connection::UpdateBytesSent()
  577. {
  578. Q_EMIT BytesSentChanged();
  579. }
  580. void Connection::UpdateBytesRead()
  581. {
  582. Q_EMIT BytesReadChanged();
  583. }
  584. void Connection::UpdateBytesWritten()
  585. {
  586. Q_EMIT BytesWrittenChanged();
  587. }
  588. void Connection::UpdateOpenRequest()
  589. {
  590. Q_EMIT NumOpenRequestsChanged();
  591. }
  592. void Connection::UpdateCloseRequest()
  593. {
  594. Q_EMIT NumCloseRequestsChanged();
  595. }
  596. void Connection::UpdateOpened()
  597. {
  598. Q_EMIT NumOpenedChanged();
  599. }
  600. void Connection::UpdateClosed()
  601. {
  602. Q_EMIT NumClosedChanged();
  603. }
  604. void Connection::UpdateReadRequest()
  605. {
  606. Q_EMIT NumReadRequestsChanged();
  607. }
  608. void Connection::UpdateWriteRequest()
  609. {
  610. Q_EMIT NumWriteRequestsChanged();
  611. }
  612. void Connection::UpdateTellRequest()
  613. {
  614. Q_EMIT NumTellRequestsChanged();
  615. }
  616. void Connection::UpdateSeekRequest()
  617. {
  618. Q_EMIT NumSeekRequestsChanged();
  619. }
  620. void Connection::UpdateEofRequest()
  621. {
  622. Q_EMIT NumEofRequestsChanged();
  623. }
  624. void Connection::UpdateIsReadOnlyRequest()
  625. {
  626. Q_EMIT NumIsReadOnlyRequestsChanged();
  627. }
  628. void Connection::UpdateIsDirectoryRequest()
  629. {
  630. Q_EMIT NumIsDirectoryRequestsChanged();
  631. }
  632. void Connection::UpdateSizeRequest()
  633. {
  634. Q_EMIT NumSizeRequestsChanged();
  635. }
  636. void Connection::UpdateModificationTimeRequest()
  637. {
  638. Q_EMIT NumModificationTimeRequestsChanged();
  639. }
  640. void Connection::UpdateExistsRequest()
  641. {
  642. Q_EMIT NumExistsRequestsChanged();
  643. }
  644. void Connection::UpdateFlushRequest()
  645. {
  646. Q_EMIT NumFlushRequestsChanged();
  647. }
  648. void Connection::UpdateCreatePathRequest()
  649. {
  650. Q_EMIT NumCreatePathRequestsChanged();
  651. }
  652. void Connection::UpdateDestroyPathRequest()
  653. {
  654. Q_EMIT NumDestroyPathRequestsChanged();
  655. }
  656. void Connection::UpdateRemoveRequest()
  657. {
  658. Q_EMIT NumRemoveRequestsChanged();
  659. }
  660. void Connection::UpdateCopyRequest()
  661. {
  662. Q_EMIT NumCopyRequestsChanged();
  663. }
  664. void Connection::UpdateRenameRequest()
  665. {
  666. Q_EMIT NumRenameRequestsChanged();
  667. }
  668. void Connection::UpdateFindFileNamesRequest()
  669. {
  670. Q_EMIT NumFindFileNamesRequestsChanged();
  671. }
  672. void Connection::UpdateMetrics()
  673. {
  674. UpdateBytesReceived();
  675. UpdateBytesSent();
  676. UpdateBytesRead();
  677. UpdateBytesWritten();
  678. UpdateOpenRequest();
  679. UpdateCloseRequest();
  680. UpdateOpened();
  681. UpdateClosed();
  682. UpdateReadRequest();
  683. UpdateWriteRequest();
  684. UpdateTellRequest();
  685. UpdateSeekRequest();
  686. UpdateEofRequest();
  687. UpdateIsReadOnlyRequest();
  688. UpdateIsDirectoryRequest();
  689. UpdateSizeRequest();
  690. UpdateModificationTimeRequest();
  691. UpdateExistsRequest();
  692. UpdateFlushRequest();
  693. UpdateCreatePathRequest();
  694. UpdateDestroyPathRequest();
  695. UpdateRemoveRequest();
  696. UpdateCopyRequest();
  697. UpdateRenameRequest();
  698. UpdateFindFileNamesRequest();
  699. }
  700. size_t Connection::Send(unsigned int serial, const AzFramework::AssetSystem::BaseAssetProcessorMessage& message)
  701. {
  702. QByteArray buffer;
  703. bool wroteToStream = AssetProcessor::PackMessage(message, buffer);
  704. AZ_Assert(wroteToStream, "Connection::Send: Could not serialize to stream (type=%u)", message.GetMessageType());
  705. if (wroteToStream)
  706. {
  707. return SendRaw(message.GetMessageType(), serial, buffer);
  708. }
  709. return 0;
  710. }
  711. size_t Connection::SendRaw(unsigned int type, unsigned int serial, const QByteArray& data)
  712. {
  713. SendMessageToWorker(type, serial, data);
  714. return data.size();
  715. }
  716. size_t Connection::SendPerPlatform(unsigned int serial, const AzFramework::AssetSystem::BaseAssetProcessorMessage& message, const QString& platform)
  717. {
  718. if (m_assetPlatforms.contains(platform, Qt::CaseInsensitive))
  719. {
  720. return Send(serial, message);
  721. }
  722. return 0;
  723. }
  724. size_t Connection::SendRawPerPlatform(unsigned int type, unsigned int serial, const QByteArray& data, const QString& platform)
  725. {
  726. if (m_assetPlatforms.contains(platform, Qt::CaseInsensitive))
  727. {
  728. return SendRaw(type, serial, data);
  729. }
  730. return 0;
  731. }
  732. AZ::u32 Connection::GetNextSerial()
  733. {
  734. static AZStd::atomic_uint serial(AzFramework::AssetSystem::DEFAULT_SERIAL);
  735. AZ::u32 nextSerial = ++serial;
  736. // Avoid special-case serials
  737. return (nextSerial & AzFramework::AssetSystem::RESPONSE_SERIAL_FLAG
  738. || nextSerial == AzFramework::AssetSystem::DEFAULT_SERIAL
  739. || nextSerial == AzFramework::AssetSystem::NEGOTIATION_SERIAL)
  740. ? GetNextSerial() // re-roll, we picked a special serial
  741. : nextSerial;
  742. }
  743. unsigned int Connection::SendRequest(const AzFramework::AssetSystem::BaseAssetProcessorMessage& message, const AssetProcessor::ConnectionBusTraits::ResponseCallback& callback)
  744. {
  745. AZ::u32 serial = GetNextSerial();
  746. {
  747. AZStd::lock_guard<AZStd::mutex> lock(m_responseHandlerMutex);
  748. m_responseHandlerMap.insert({ serial, callback });
  749. }
  750. Send(serial, message);
  751. return serial;
  752. }
  753. size_t Connection::SendResponse(unsigned int serial, const AzFramework::AssetSystem::BaseAssetProcessorMessage& message)
  754. {
  755. serial |= AzFramework::AssetSystem::RESPONSE_SERIAL_FLAG; // Set top bit to indicate this is a response
  756. return Send(serial, message);
  757. }
  758. void Connection::InvokeResponseHandler(AZ::u32 serial, AZ::u32 type, QByteArray data)
  759. {
  760. AZStd::lock_guard<AZStd::mutex> lock(m_responseHandlerMutex);
  761. auto itr = m_responseHandlerMap.find(serial);
  762. if (itr != m_responseHandlerMap.end())
  763. {
  764. itr->second(type, data);
  765. m_responseHandlerMap.erase(itr);
  766. }
  767. }
  768. void Connection::RemoveResponseHandler(unsigned int serial)
  769. {
  770. AZStd::lock_guard<AZStd::mutex> lock(m_responseHandlerMutex);
  771. m_responseHandlerMap.erase(serial);
  772. }
  773. bool Connection::InitiatedConnection() const
  774. {
  775. if (m_connectionWorker)
  776. {
  777. return m_connectionWorker->InitiatedConnection();
  778. }
  779. return false;
  780. }
  781. bool Connection::UserCreatedConnection() const
  782. {
  783. return m_userCreatedConnection;
  784. }
  785. void Connection::SetAssetPlatformsString(QString assetPlatforms)
  786. {
  787. SetAssetPlatforms(assetPlatforms.split(',', Qt::SkipEmptyParts));
  788. }