RESTJobsAsync.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. /*===============================================================================
  2. Copyright (C) 2022 Immersal - Part of Hexagon. All Rights Reserved.
  3. This file is part of the Immersal SDK.
  4. The Immersal SDK cannot be copied, distributed, or made available to
  5. third-parties for commercial purposes without written permission of Immersal Ltd.
  6. Contact sdk@immersal.com for licensing requests.
  7. ===============================================================================*/
  8. using System;
  9. using System.Runtime.InteropServices;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. using System.Net.Http;
  13. using System.IO;
  14. using System.Text;
  15. using UnityEngine;
  16. namespace Immersal.REST
  17. {
  18. public class ImmersalHttp
  19. {
  20. public static readonly string URL_FORMAT = "{0}/{1}";
  21. public static async Task<U> Request<T, U>(T request, IProgress<float> progress)
  22. {
  23. U result = default(U);
  24. string jsonString = JsonUtility.ToJson(request);
  25. HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Post, string.Format(URL_FORMAT, ImmersalSDK.Instance.localizationServer, (string)typeof(T).GetField("endpoint").GetValue(null)));
  26. r.Content = new StringContent(jsonString);
  27. try
  28. {
  29. using (MemoryStream stream = new MemoryStream())
  30. {
  31. using (var response = await ImmersalSDK.client.DownloadAsync(r, stream, progress, CancellationToken.None))
  32. {
  33. string responseBody = Encoding.ASCII.GetString(stream.GetBuffer());
  34. //Debug.Log(responseBody);
  35. result = JsonUtility.FromJson<U>(responseBody);
  36. if (!response.IsSuccessStatusCode)
  37. {
  38. Debug.Log(string.Format("ImmersalHttp error: {0} ({1}), {2}\nrequest JSON: {3}\nresponse JSON: {4}", (int)response.StatusCode, response.ReasonPhrase, response.RequestMessage, jsonString, responseBody));
  39. }
  40. }
  41. }
  42. }
  43. catch (Exception e)
  44. {
  45. Debug.LogError("ImmersalHttp connection error: " + e);
  46. }
  47. return result;
  48. }
  49. public static async Task<byte[]> RequestGet(string uri, IProgress<float> progress)
  50. {
  51. byte[] result = null;
  52. HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Get, uri);
  53. try
  54. {
  55. using (MemoryStream stream = new MemoryStream())
  56. {
  57. using (var response = await ImmersalSDK.client.DownloadAsync(r, stream, progress, CancellationToken.None))
  58. {
  59. result = stream.GetBuffer();
  60. if (!response.IsSuccessStatusCode)
  61. {
  62. Debug.Log(string.Format("ImmersalHttp error: {0} ({1}), {2}", (int)response.StatusCode, response.ReasonPhrase, response.RequestMessage));
  63. }
  64. }
  65. }
  66. }
  67. catch (Exception e)
  68. {
  69. Debug.LogError("ImmersalHttp connection error: " + e);
  70. }
  71. return result;
  72. }
  73. public static async Task<U> RequestUpload<T, U>(T request, byte[] data, IProgress<float> progress)
  74. {
  75. U result = default(U);
  76. string jsonString = JsonUtility.ToJson(request);
  77. byte[] jsonBytes = Encoding.ASCII.GetBytes(jsonString);
  78. byte[] body = new byte[jsonBytes.Length + 1 + data.Length];
  79. Array.Copy(jsonBytes, 0, body, 0, jsonBytes.Length);
  80. body[jsonBytes.Length] = 0;
  81. Array.Copy(data, 0, body, jsonBytes.Length + 1, data.Length);
  82. HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Post, string.Format(URL_FORMAT, ImmersalSDK.Instance.localizationServer, (string)typeof(T).GetField("endpoint").GetValue(null)));
  83. var byteStream = new ProgressMemoryStream(body, progress);
  84. r.Content = new StreamContent(byteStream);
  85. try
  86. {
  87. using (MemoryStream stream = new MemoryStream())
  88. {
  89. using (var response = await ImmersalSDK.client.DownloadAsync(r, stream, null, CancellationToken.None))
  90. {
  91. string responseBody = Encoding.ASCII.GetString(stream.GetBuffer());
  92. //Debug.Log(responseBody);
  93. result = JsonUtility.FromJson<U>(responseBody);
  94. if (!response.IsSuccessStatusCode)
  95. {
  96. Debug.Log(string.Format("ImmersalHttp error: {0} ({1}), {2}", (int)response.StatusCode, response.ReasonPhrase, response.RequestMessage));
  97. }
  98. }
  99. }
  100. }
  101. catch (Exception e)
  102. {
  103. Debug.LogError("ImmersalHttp connection error: " + e);
  104. }
  105. return result;
  106. }
  107. }
  108. public static class HttpClientExtensions
  109. {
  110. public static async Task<HttpResponseMessage> DownloadAsync(this HttpClient client, HttpRequestMessage request, Stream destination, IProgress<float> progress = null, CancellationToken cancellationToken = default) {
  111. using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
  112. {
  113. request.Dispose();
  114. var contentLength = response.Content.Headers.ContentLength;
  115. using (var download = await response.Content.ReadAsStreamAsync())
  116. {
  117. if (progress == null || !contentLength.HasValue)
  118. {
  119. await download.CopyToAsync(destination);
  120. return response;
  121. }
  122. var relativeProgress = new Progress<long>(totalBytes => progress.Report((float)totalBytes / contentLength.Value));
  123. await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken);
  124. }
  125. return response;
  126. }
  127. }
  128. }
  129. public class ProgressMemoryStream : MemoryStream
  130. {
  131. IProgress<float> progress;
  132. private int length;
  133. public ProgressMemoryStream(byte[] buffer, IProgress<float> progress = null)
  134. : base(buffer, true) {
  135. this.length = buffer.Length;
  136. this.progress = progress;
  137. }
  138. public override int Read([In, Out] byte[] buffer, int offset, int count) {
  139. int n = base.Read(buffer, offset, count);
  140. progress?.Report((float)this.Position / this.length);
  141. return n;
  142. }
  143. }
  144. public static class StreamExtensions
  145. {
  146. public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default) {
  147. if (source == null)
  148. throw new ArgumentNullException(nameof(source));
  149. if (!source.CanRead)
  150. throw new ArgumentException("Has to be readable", nameof(source));
  151. if (destination == null)
  152. throw new ArgumentNullException(nameof(destination));
  153. if (!destination.CanWrite)
  154. throw new ArgumentException("Has to be writable", nameof(destination));
  155. if (bufferSize < 0)
  156. throw new ArgumentOutOfRangeException(nameof(bufferSize));
  157. var buffer = new byte[bufferSize];
  158. long totalBytesRead = 0;
  159. int bytesRead;
  160. while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) {
  161. await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
  162. totalBytesRead += bytesRead;
  163. progress?.Report(totalBytesRead);
  164. }
  165. }
  166. }
  167. public class JobAsync
  168. {
  169. public string token = ImmersalSDK.Instance.developerToken;
  170. public Action OnStart;
  171. public Action<string> OnError;
  172. public Progress<float> Progress = new Progress<float>();
  173. public virtual async Task RunJobAsync()
  174. {
  175. await Task.Yield();
  176. }
  177. protected void HandleError(string e)
  178. {
  179. OnError?.Invoke(e ?? "conn");
  180. }
  181. }
  182. public class JobSetMapAccessTokenAsync : JobAsync
  183. {
  184. public int id;
  185. public Action<SDKMapAccessTokenResult> OnResult;
  186. public override async Task RunJobAsync()
  187. {
  188. Debug.Log("*************************** JobSetMapAccessTokenAsync ***************************");
  189. this.OnStart?.Invoke();
  190. SDKSetMapAccessTokenRequest r = new SDKSetMapAccessTokenRequest();
  191. r.token = this.token;
  192. r.id = this.id;
  193. SDKMapAccessTokenResult result = await ImmersalHttp.Request<SDKSetMapAccessTokenRequest, SDKMapAccessTokenResult>(r, this.Progress);
  194. if (result.error == "none")
  195. {
  196. this.OnResult?.Invoke(result);
  197. }
  198. else
  199. {
  200. HandleError(result.error);
  201. }
  202. }
  203. }
  204. public class JobClearMapAccessTokenAsync : JobAsync
  205. {
  206. public int id;
  207. public Action<SDKMapAccessTokenResult> OnResult;
  208. public override async Task RunJobAsync()
  209. {
  210. Debug.Log("*************************** JobSetMapAccessTokenAsync ***************************");
  211. this.OnStart?.Invoke();
  212. SDKClearMapAccessTokenRequest r = new SDKClearMapAccessTokenRequest();
  213. r.token = this.token;
  214. r.id = this.id;
  215. SDKMapAccessTokenResult result = await ImmersalHttp.Request<SDKClearMapAccessTokenRequest, SDKMapAccessTokenResult>(r, this.Progress);
  216. if (result.error == "none")
  217. {
  218. this.OnResult?.Invoke(result);
  219. }
  220. else
  221. {
  222. HandleError(result.error);
  223. }
  224. }
  225. }
  226. public class JobClearAsync : JobAsync
  227. {
  228. public bool anchor;
  229. public Action<SDKClearResult> OnResult;
  230. public override async Task RunJobAsync()
  231. {
  232. this.OnStart?.Invoke();
  233. SDKClearRequest r = new SDKClearRequest();
  234. r.token = this.token;
  235. r.anchor = this.anchor;
  236. SDKClearResult result = await ImmersalHttp.Request<SDKClearRequest, SDKClearResult>(r, this.Progress);
  237. if (result.error == "none")
  238. {
  239. this.OnResult?.Invoke(result);
  240. }
  241. else
  242. {
  243. HandleError(result.error);
  244. }
  245. }
  246. }
  247. public class JobConstructAsync : JobAsync
  248. {
  249. public string name;
  250. public int featureCount = 1024;
  251. public int featureType = 2;
  252. public int windowSize = 0;
  253. public bool preservePoses = false;
  254. public Action<SDKConstructResult> OnResult;
  255. public override async Task RunJobAsync()
  256. {
  257. this.OnStart?.Invoke();
  258. SDKConstructRequest r = new SDKConstructRequest();
  259. r.token = this.token;
  260. r.name = this.name;
  261. r.featureCount = this.featureCount;
  262. r.featureType = this.featureType;
  263. r.windowSize = this.windowSize;
  264. r.preservePoses = this.preservePoses;
  265. SDKConstructResult result = await ImmersalHttp.Request<SDKConstructRequest, SDKConstructResult>(r, this.Progress);
  266. if (result.error == "none")
  267. {
  268. this.OnResult?.Invoke(result);
  269. }
  270. else
  271. {
  272. HandleError(result.error);
  273. }
  274. }
  275. }
  276. public class JobRestoreMapImagesAsync : JobAsync
  277. {
  278. public int id;
  279. public bool clear;
  280. public Action<SDKRestoreMapImagesResult> OnResult;
  281. public override async Task RunJobAsync()
  282. {
  283. this.OnStart?.Invoke();
  284. SDKRestoreMapImagesRequest r = new SDKRestoreMapImagesRequest();
  285. r.token = this.token;
  286. r.id = this.id;
  287. r.clear = this.clear;
  288. SDKRestoreMapImagesResult result = await ImmersalHttp.Request<SDKRestoreMapImagesRequest, SDKRestoreMapImagesResult>(r, this.Progress);
  289. if (result.error == "none")
  290. {
  291. this.OnResult?.Invoke(result);
  292. }
  293. else
  294. {
  295. HandleError(result.error);
  296. }
  297. }
  298. }
  299. public class JobDeleteMapAsync : JobAsync
  300. {
  301. public int id;
  302. public Action<SDKDeleteMapResult> OnResult;
  303. public override async Task RunJobAsync()
  304. {
  305. this.OnStart?.Invoke();
  306. SDKDeleteMapRequest r = new SDKDeleteMapRequest();
  307. r.token = this.token;
  308. r.id = this.id;
  309. SDKDeleteMapResult result = await ImmersalHttp.Request<SDKDeleteMapRequest, SDKDeleteMapResult>(r, this.Progress);
  310. if (result.error == "none")
  311. {
  312. this.OnResult?.Invoke(result);
  313. }
  314. else
  315. {
  316. HandleError(result.error);
  317. }
  318. }
  319. }
  320. public class JobStatusAsync : JobAsync
  321. {
  322. public Action<SDKStatusResult> OnResult;
  323. public override async Task RunJobAsync()
  324. {
  325. this.OnStart?.Invoke();
  326. SDKStatusRequest r = new SDKStatusRequest();
  327. r.token = this.token;
  328. SDKStatusResult result = await ImmersalHttp.Request<SDKStatusRequest, SDKStatusResult>(r, this.Progress);
  329. if (result.error == "none")
  330. {
  331. this.OnResult?.Invoke(result);
  332. }
  333. else
  334. {
  335. HandleError(result.error);
  336. }
  337. }
  338. }
  339. public class JobCaptureAsync : JobAsync
  340. {
  341. public int run;
  342. public int index;
  343. public bool anchor;
  344. public Vector4 intrinsics;
  345. public Matrix4x4 rotation;
  346. public Vector3 position;
  347. public double latitude;
  348. public double longitude;
  349. public double altitude;
  350. public string encodedImage;
  351. public string imagePath;
  352. public Action<SDKImageResult> OnResult;
  353. public override async Task RunJobAsync()
  354. {
  355. this.OnStart?.Invoke();
  356. SDKImageRequest r = new SDKImageRequest();
  357. r.token = this.token;
  358. r.run = this.run;
  359. r.index = this.index;
  360. r.anchor = this.anchor;
  361. r.px = position.x;
  362. r.py = position.y;
  363. r.pz = position.z;
  364. r.r00 = rotation.m00;
  365. r.r01 = rotation.m01;
  366. r.r02 = rotation.m02;
  367. r.r10 = rotation.m10;
  368. r.r11 = rotation.m11;
  369. r.r12 = rotation.m12;
  370. r.r20 = rotation.m20;
  371. r.r21 = rotation.m21;
  372. r.r22 = rotation.m22;
  373. r.fx = intrinsics.x;
  374. r.fy = intrinsics.y;
  375. r.ox = intrinsics.z;
  376. r.oy = intrinsics.w;
  377. r.latitude = latitude;
  378. r.longitude = longitude;
  379. r.altitude = altitude;
  380. byte[] image = File.ReadAllBytes(imagePath);
  381. SDKImageResult result = await ImmersalHttp.RequestUpload<SDKImageRequest, SDKImageResult>(r, image, this.Progress);
  382. if (result.error == "none")
  383. {
  384. this.OnResult?.Invoke(result);
  385. }
  386. else
  387. {
  388. HandleError(result.error);
  389. }
  390. }
  391. }
  392. public class JobLocalizeServerAsync : JobAsync
  393. {
  394. public Vector3 position;
  395. public Quaternion rotation;
  396. public Vector4 intrinsics;
  397. public int param1 = 0;
  398. public int param2 = 12;
  399. public float param3 = 0.0f;
  400. public float param4 = 2.0f;
  401. public double latitude = 0.0;
  402. public double longitude = 0.0;
  403. public double radius = 0.0;
  404. public bool useGPS = false;
  405. public SDKMapId[] mapIds;
  406. public byte[] image;
  407. public Action<SDKLocalizeResult> OnResult;
  408. public override async Task RunJobAsync()
  409. {
  410. this.OnStart?.Invoke();
  411. SDKLocalizeResult result = default;
  412. if (this.useGPS)
  413. {
  414. SDKGeoLocalizeRequest r = new SDKGeoLocalizeRequest();
  415. r.token = this.token;
  416. r.fx = intrinsics.x;
  417. r.fy = intrinsics.y;
  418. r.ox = intrinsics.z;
  419. r.oy = intrinsics.w;
  420. r.param1 = param1;
  421. r.param2 = param2;
  422. r.param3 = param3;
  423. r.param4 = param4;
  424. r.latitude = this.latitude;
  425. r.longitude = this.longitude;
  426. r.radius = this.radius;
  427. result = await ImmersalHttp.RequestUpload<SDKGeoLocalizeRequest, SDKLocalizeResult>(r, this.image, this.Progress);
  428. }
  429. else
  430. {
  431. SDKLocalizeRequest r = new SDKLocalizeRequest();
  432. r.token = this.token;
  433. r.fx = intrinsics.x;
  434. r.fy = intrinsics.y;
  435. r.ox = intrinsics.z;
  436. r.oy = intrinsics.w;
  437. r.param1 = param1;
  438. r.param2 = param2;
  439. r.param3 = param3;
  440. r.param4 = param4;
  441. r.mapIds = this.mapIds;
  442. result = await ImmersalHttp.RequestUpload<SDKLocalizeRequest, SDKLocalizeResult>(r, this.image, this.Progress);
  443. }
  444. if (result.error == "none")
  445. {
  446. this.OnResult?.Invoke(result);
  447. }
  448. else
  449. {
  450. HandleError(result.error);
  451. }
  452. }
  453. }
  454. public class JobGeoPoseAsync : JobAsync
  455. {
  456. public Vector3 position;
  457. public Quaternion rotation;
  458. public Vector4 intrinsics;
  459. public int param1 = 0;
  460. public int param2 = 12;
  461. public float param3 = 0.0f;
  462. public float param4 = 2.0f;
  463. public SDKMapId[] mapIds;
  464. public byte[] image;
  465. public Action<SDKGeoPoseResult> OnResult;
  466. public override async Task RunJobAsync()
  467. {
  468. this.OnStart?.Invoke();
  469. SDKGeoPoseRequest r = new SDKGeoPoseRequest();
  470. r.token = this.token;
  471. r.fx = intrinsics.x;
  472. r.fy = intrinsics.y;
  473. r.ox = intrinsics.z;
  474. r.oy = intrinsics.w;
  475. r.param1 = param1;
  476. r.param2 = param2;
  477. r.param3 = param3;
  478. r.param4 = param4;
  479. r.mapIds = this.mapIds;
  480. SDKGeoPoseResult result = await ImmersalHttp.RequestUpload<SDKGeoPoseRequest, SDKGeoPoseResult>(r, this.image, this.Progress);
  481. if (result.error == "none")
  482. {
  483. this.OnResult?.Invoke(result);
  484. }
  485. else
  486. {
  487. HandleError(result.error);
  488. }
  489. }
  490. }
  491. public class JobEcefAsync : JobAsync
  492. {
  493. public int id;
  494. public bool useToken = true;
  495. public Action<SDKEcefResult> OnResult;
  496. public override async Task RunJobAsync()
  497. {
  498. this.OnStart?.Invoke();
  499. SDKEcefRequest r = new SDKEcefRequest();
  500. r.token = useToken ? this.token : "";
  501. r.id = this.id;
  502. SDKEcefResult result = await ImmersalHttp.Request<SDKEcefRequest, SDKEcefResult>(r, this.Progress);
  503. if (result.error == "none")
  504. {
  505. this.OnResult?.Invoke(result);
  506. }
  507. else
  508. {
  509. HandleError(result.error);
  510. }
  511. }
  512. }
  513. public class JobListJobsAsync : JobAsync
  514. {
  515. public double latitude = 0.0;
  516. public double longitude = 0.0;
  517. public double radius = 0.0;
  518. public bool useGPS = false;
  519. public bool useToken = true;
  520. public Action<SDKJobsResult> OnResult;
  521. public override async Task RunJobAsync()
  522. {
  523. this.OnStart?.Invoke();
  524. SDKJobsResult result = default;
  525. if (this.useGPS)
  526. {
  527. SDKGeoJobsRequest r = new SDKGeoJobsRequest();
  528. r.token = this.useToken ? this.token : "";
  529. r.latitude = this.latitude;
  530. r.longitude = this.longitude;
  531. r.radius = this.radius;
  532. result = await ImmersalHttp.Request<SDKGeoJobsRequest, SDKJobsResult>(r, this.Progress);
  533. }
  534. else
  535. {
  536. SDKJobsRequest r = new SDKJobsRequest();
  537. r.token = this.useToken ? this.token : "";
  538. result = await ImmersalHttp.Request<SDKJobsRequest, SDKJobsResult>(r, this.Progress);
  539. }
  540. if (result.error == "none")
  541. {
  542. this.OnResult?.Invoke(result);
  543. }
  544. else
  545. {
  546. HandleError(result.error);
  547. }
  548. }
  549. }
  550. public class JobLoadMapBinaryAsync : JobAsync
  551. {
  552. public int id;
  553. public bool useToken = true;
  554. public string sha256_al;
  555. public Action<SDKMapResult> OnResult;
  556. public override async Task RunJobAsync()
  557. {
  558. this.OnStart?.Invoke();
  559. SDKMapBinaryRequest r = new SDKMapBinaryRequest();
  560. r.token = this.useToken ? this.token : "";
  561. r.id = this.id;
  562. string uri = string.Format(ImmersalHttp.URL_FORMAT, ImmersalSDK.Instance.localizationServer, SDKMapBinaryRequest.endpoint);
  563. uri += (r.token != "") ? string.Format("?token={0}&id={1}", r.token, r.id) : string.Format("?id={0}", r.id);
  564. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
  565. SDKMapResult result = default;
  566. byte[] data = await ImmersalHttp.RequestGet(uri, this.Progress);
  567. if (data == null || data.Length == 0)
  568. {
  569. result.error = "no data";
  570. }
  571. else if (data.Length == 256) // error
  572. {
  573. var str = Encoding.Default.GetString(data);
  574. result = JsonUtility.FromJson<SDKMapResult>(str);
  575. }
  576. else
  577. {
  578. result.error = "none";
  579. result.sha256_al = this.sha256_al;
  580. result.mapData = data;
  581. }
  582. if (result.error == "none")
  583. {
  584. JobMapMetadataGetAsync j = new JobMapMetadataGetAsync();
  585. j.id = this.id;
  586. j.token = r.token;
  587. j.OnError += (e) =>
  588. {
  589. this.OnResult?.Invoke(result);
  590. };
  591. j.OnResult += (SDKMapMetadataGetResult metadata) =>
  592. {
  593. if (metadata.error == "none")
  594. {
  595. result.metadata = metadata;
  596. this.OnResult?.Invoke(result);
  597. }
  598. else
  599. {
  600. HandleError(metadata.error);
  601. }
  602. };
  603. await j.RunJobAsync();
  604. }
  605. else
  606. {
  607. HandleError(result.error);
  608. }
  609. }
  610. }
  611. public class JobLoadMapAsync : JobAsync
  612. {
  613. public int id;
  614. public bool useToken = true;
  615. public Action<SDKMapResult> OnResult;
  616. public override async Task RunJobAsync()
  617. {
  618. this.OnStart?.Invoke();
  619. SDKMapRequest r = new SDKMapRequest();
  620. r.token = this.useToken ? this.token : "";
  621. r.id = this.id;
  622. SDKMapResult result = await ImmersalHttp.Request<SDKMapRequest, SDKMapResult>(r, this.Progress);
  623. if (result.error == "none")
  624. {
  625. JobMapMetadataGetAsync j = new JobMapMetadataGetAsync();
  626. j.id = this.id;
  627. j.token = r.token;
  628. j.OnError += (e) =>
  629. {
  630. this.OnResult?.Invoke(result);
  631. };
  632. j.OnResult += (SDKMapMetadataGetResult metadata) =>
  633. {
  634. if (metadata.error == "none")
  635. {
  636. result.metadata = metadata;
  637. this.OnResult?.Invoke(result);
  638. }
  639. else
  640. {
  641. HandleError(metadata.error);
  642. }
  643. };
  644. await j.RunJobAsync();
  645. }
  646. else
  647. {
  648. HandleError(result.error);
  649. }
  650. }
  651. }
  652. public class JobSetPrivacyAsync : JobAsync
  653. {
  654. public int id;
  655. public int privacy;
  656. public Action<SDKMapPrivacyResult> OnResult;
  657. public override async Task RunJobAsync()
  658. {
  659. this.OnStart?.Invoke();
  660. SDKMapPrivacyRequest r = new SDKMapPrivacyRequest();
  661. r.token = this.token;
  662. r.id = this.id;
  663. r.privacy = this.privacy;
  664. SDKMapPrivacyResult result = await ImmersalHttp.Request<SDKMapPrivacyRequest, SDKMapPrivacyResult>(r, this.Progress);
  665. if (result.error == "none")
  666. {
  667. this.OnResult?.Invoke(result);
  668. }
  669. else
  670. {
  671. HandleError(result.error);
  672. }
  673. }
  674. }
  675. public class JobLoginAsync : JobAsync
  676. {
  677. public string username;
  678. public string password;
  679. public Action<SDKLoginResult> OnResult;
  680. public override async Task RunJobAsync()
  681. {
  682. this.OnStart?.Invoke();
  683. SDKLoginRequest r = new SDKLoginRequest();
  684. r.login = this.username;
  685. r.password = this.password;
  686. SDKLoginResult result = await ImmersalHttp.Request<SDKLoginRequest, SDKLoginResult>(r, this.Progress);
  687. if (result.error == "none")
  688. {
  689. this.OnResult?.Invoke(result);
  690. }
  691. else
  692. {
  693. HandleError(result.error);
  694. }
  695. }
  696. }
  697. public class JobMapDownloadAsync : JobAsync
  698. {
  699. public int id;
  700. public Action<SDKMapDownloadResult> OnResult;
  701. public override async Task RunJobAsync()
  702. {
  703. this.OnStart?.Invoke();
  704. SDKMapDownloadRequest r = new SDKMapDownloadRequest();
  705. r.token = this.token;
  706. r.id = this.id;
  707. SDKMapDownloadResult result = await ImmersalHttp.Request<SDKMapDownloadRequest, SDKMapDownloadResult>(r, this.Progress);
  708. if (result.error == "none")
  709. {
  710. this.OnResult?.Invoke(result);
  711. }
  712. else
  713. {
  714. HandleError(result.error);
  715. }
  716. }
  717. }
  718. public class JobMapMetadataGetAsync : JobAsync
  719. {
  720. public int id;
  721. public Action<SDKMapMetadataGetResult> OnResult;
  722. public override async Task RunJobAsync()
  723. {
  724. this.OnStart?.Invoke();
  725. SDKMapMetadataGetRequest r = new SDKMapMetadataGetRequest();
  726. r.token = this.token;
  727. r.id = this.id;
  728. SDKMapMetadataGetResult result = await ImmersalHttp.Request<SDKMapMetadataGetRequest, SDKMapMetadataGetResult>(r, this.Progress);
  729. if (result.error == "none")
  730. {
  731. this.OnResult?.Invoke(result);
  732. }
  733. else
  734. {
  735. HandleError(result.error);
  736. }
  737. }
  738. }
  739. public class JobMapAlignmentSetAsync : JobAsync
  740. {
  741. public int id;
  742. public double tx;
  743. public double ty;
  744. public double tz;
  745. public double qw;
  746. public double qx;
  747. public double qy;
  748. public double qz;
  749. public double scale;
  750. public Action<SDKMapAlignmentSetResult> OnResult;
  751. public override async Task RunJobAsync()
  752. {
  753. this.OnStart?.Invoke();
  754. SDKMapAlignmentSetRequest r = new SDKMapAlignmentSetRequest();
  755. r.token = this.token;
  756. r.id = this.id;
  757. r.tx = this.tx;
  758. r.ty = this.ty;
  759. r.tz = this.tz;
  760. r.qw = this.qw;
  761. r.qx = this.qx;
  762. r.qy = this.qy;
  763. r.qz = this.qz;
  764. r.scale = this.scale;
  765. SDKMapAlignmentSetResult result = await ImmersalHttp.Request<SDKMapAlignmentSetRequest, SDKMapAlignmentSetResult>(r, this.Progress);
  766. if (result.error == "none")
  767. {
  768. this.OnResult?.Invoke(result);
  769. }
  770. else
  771. {
  772. HandleError(result.error);
  773. }
  774. }
  775. }
  776. }