diff --git a/Editor/Scripts/WorldAnalysisInfoEditor.cs b/Editor/Scripts/WorldAnalysisInfoEditor.cs new file mode 100644 index 0000000000000000000000000000000000000000..70a489e197ac199bf1b5d640c030887df5254532 --- /dev/null +++ b/Editor/Scripts/WorldAnalysisInfoEditor.cs @@ -0,0 +1,39 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: August 2024 +// + +using UnityEditor; + +[CustomEditor(typeof(WorldAnalysisInfo))] +public class WorldAnalysisInfoEditor : Editor +{ + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + EditorGUILayout.Space(); + WorldAnalysisInfo srv = (WorldAnalysisInfo)target; + + string state = "";// srv.GetServerState(); + EditorGUILayout.LabelField("Server State", state); + + string api = "";// srv.GetAPIVersion(); + EditorGUILayout.LabelField("OpenAPI Version", api); + } +} diff --git a/Editor/Scripts/WorldAnalysisInfoEditor.cs.meta b/Editor/Scripts/WorldAnalysisInfoEditor.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..0642c98c929f8cb55c470c3ee423dafb38e19feb --- /dev/null +++ b/Editor/Scripts/WorldAnalysisInfoEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b890e537ebae974b862e97bfefa51ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Scripts/WorldAnalysisServerEditor.cs b/Editor/Scripts/WorldAnalysisServerEditor.cs new file mode 100644 index 0000000000000000000000000000000000000000..4fe96c9164fa2618950d512348af3c6689c2552b --- /dev/null +++ b/Editor/Scripts/WorldAnalysisServerEditor.cs @@ -0,0 +1,174 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2024 +// + +using System.Collections; +using UnityEngine; +using UnityEditor; + +using ETSI.ARF.OpenAPI; +using ETSI.ARF.OpenAPI.WorldAnalysis; +using ETSI.ARF.WorldAnalysis; +using ETSI.ARF.WorldAnalysis.REST; + +[CustomEditor(typeof(WorldAnalysisServer))] +public class WorldStorageServerEditor : Editor +{ + WorldAnalysisServer server; + + private string state = ""; + private string version = ""; + + private string test = ""; + + private Queue handleResponseQueue = new Queue(); + + private ResponseObject<string> pendingTest = null; + private ResponseObject<string> pendingState = null; + private ResponseObject<string> pendingVersion = null; + + public void OnEnable() + { + server = (WorldAnalysisServer)target; + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + DrawDefaultInspector(); + EditorGUILayout.Space(); + + if (GUILayout.Button("Test server")) + { + TestPing(); + } + EditorGUILayout.LabelField("Test Response", test); + + EditorGUILayout.Space(); + + if (GUILayout.Button("Query server")) + { + QueryServer(); + } + + EditorGUILayout.LabelField("Server State", state); + EditorGUILayout.LabelField("OpenAPI Version", version); + + if (handleResponseQueue.Count > 0) + { + object o = handleResponseQueue.Dequeue(); + if (o.Equals(pendingTest)) + { + ResponseObject<string> response = o as ResponseObject<string>; + Debug.Log($"Get '{response.result}' from server"); + + test = response.result; + pendingTest = null; + EditorUtility.SetDirty(target); + } + else if (o.Equals(pendingState)) + { + ResponseObject<string> response = o as ResponseObject<string>; + Debug.Log($"Get '{response.result}' from server"); + + state = response.result; + pendingState = null; + EditorUtility.SetDirty(target); + } + else if (o.Equals(pendingVersion)) + { + ResponseObject<string> response = o as ResponseObject<string>; + Debug.Log($"Get '{response.result}' from server"); + + version = response.result; + pendingVersion = null; + EditorUtility.SetDirty(target); + } + else + { + Debug.Log("Unsupported response!"); + } + } + } + + public override bool RequiresConstantRepaint() + { + return handleResponseQueue.Count > 0; + } + + void OnSceneGUI() + { + Debug.Log("OnSceneGUI"); + } + + private void TestPing() + { + test = ""; + EditorUtility.SetDirty(target); + + if (server == null) + { + Debug.LogError("No server defined!"); + return; + } + + //string response = AdminRequest.PingSync(server); + //EditorUtility.DisplayDialog("Test Server", $"Get '{response}' from server", "OK"); + + if (pendingTest != null) + { + pendingTest.Cancel(); + } + + pendingTest = AdminRequest.PingAsync(server, (response) => + { + handleResponseQueue.Enqueue(response); + Debug.Log($"Request Time: { response.requestTime.ToLongTimeString() } / Total Time: { response.DeltaTime.TotalMilliseconds }ms\n\n<b>Content:</b>\n{ response.result }"); + }); + + Debug.Log("Starting request @ time: " + pendingTest.requestTime.ToLongTimeString() + "..."); + } + + private void QueryServer() + { + version = ""; + state = ""; + + if (pendingState != null) + { + pendingState.Cancel(); + } + + pendingState = AdminRequest.AdminAsync(server, (response) => + { + handleResponseQueue.Enqueue(response); + }); + + if (pendingVersion != null) + { + pendingVersion.Cancel(); + } + + pendingVersion = AdminRequest.VersionAsync(server, (response) => + { + handleResponseQueue.Enqueue(response); + }); + } +} \ No newline at end of file diff --git a/Editor/Scripts/WorldAnalysisServerEditor.cs.meta b/Editor/Scripts/WorldAnalysisServerEditor.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..b6c4ebcebcfe89fdf3913ab820a589eda451a592 --- /dev/null +++ b/Editor/Scripts/WorldAnalysisServerEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9899978f4c750de4b98f81a9c6937a94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Scripts/WorldAnalysisUserEditor.cs b/Editor/Scripts/WorldAnalysisUserEditor.cs new file mode 100644 index 0000000000000000000000000000000000000000..043379e03f8193e15c2564926cecb02d3f798529 --- /dev/null +++ b/Editor/Scripts/WorldAnalysisUserEditor.cs @@ -0,0 +1,51 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: June 2022 +// + +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +using ETSI.ARF.WorldAnalysis; + +[CustomEditor(typeof(WorldAnalysisUser))] +public class WorldStorageUserEditor : Editor +{ + WorldAnalysisUser user; + + public void OnEnable() + { + user = (WorldAnalysisUser)target; + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + DrawDefaultInspector(); + EditorGUILayout.Space(); + + if (GUILayout.Button("Generate New Creator UUID")) + { + user.UUID = System.Guid.NewGuid().ToString(); + EditorUtility.SetDirty(target); + } + } +} diff --git a/Editor/Scripts/WorldAnalysisUserEditor.cs.meta b/Editor/Scripts/WorldAnalysisUserEditor.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..74303ebefd651ab1b982263b3fd940c1e17bfc37 --- /dev/null +++ b/Editor/Scripts/WorldAnalysisUserEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0d1b5ae7e5771b4496dfd778bfa031b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scriptables.meta b/Runtime/Scriptables.meta new file mode 100644 index 0000000000000000000000000000000000000000..058c09b1bab8ec6575fc872230f1b2dda37dd350 --- /dev/null +++ b/Runtime/Scriptables.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 24a8b3224329f984c9b1737d44f11163 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scriptables/WorldAnalysisServer.cs b/Runtime/Scriptables/WorldAnalysisServer.cs new file mode 100644 index 0000000000000000000000000000000000000000..fb21b57acd4b6a498532a676e53cd0b7307a2ed2 --- /dev/null +++ b/Runtime/Scriptables/WorldAnalysisServer.cs @@ -0,0 +1,39 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: August 2024 +// + +using UnityEngine; + +namespace ETSI.ARF.WorldAnalysis +{ + [System.Serializable] + [CreateAssetMenu(fileName = "ARFWorldAnalysisServer", menuName = "ARF World Analysis/Create Server", order = 1)] + public class WorldAnalysisServer : ScriptableObject + { + [SerializeField] public string serverName = "myServerName"; + [SerializeField] public string company = ""; + [SerializeField] public string basePath = "https://"; + [SerializeField] public int port = 8080; + + [Space(8)] + [SerializeField] public WorldAnalysisUser currentUser = null; + + public string URI => port == 0 ? basePath : basePath + ":" + port.ToString(); + } +} \ No newline at end of file diff --git a/Runtime/Scriptables/WorldAnalysisServer.cs.meta b/Runtime/Scriptables/WorldAnalysisServer.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..7abd0fffb9fcc28b63065f9585c2337006da5444 --- /dev/null +++ b/Runtime/Scriptables/WorldAnalysisServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4571d019d0609224aa4a14ed18de30cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scriptables/WorldAnalysisUser.cs b/Runtime/Scriptables/WorldAnalysisUser.cs new file mode 100644 index 0000000000000000000000000000000000000000..85faade5a0a7b138d81e0a8e6210c09f18cfa10d --- /dev/null +++ b/Runtime/Scriptables/WorldAnalysisUser.cs @@ -0,0 +1,33 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: August 2024 +// + +using UnityEngine; + +namespace ETSI.ARF.WorldAnalysis +{ + [System.Serializable] + [CreateAssetMenu(fileName = "ARFWorldAnalysisUser", menuName = "ARF World Analysis/Create User", order = 1)] + public class WorldAnalysisUser : ScriptableObject + { + [SerializeField] public string userName = "myName"; + [SerializeField] public string company = ""; + [SerializeField] public string UUID = System.Guid.Empty.ToString(); + } +} \ No newline at end of file diff --git a/Runtime/Scriptables/WorldAnalysisUser.cs.meta b/Runtime/Scriptables/WorldAnalysisUser.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..93b285fec331be825e710a4e62a25a83a3ddf88e --- /dev/null +++ b/Runtime/Scriptables/WorldAnalysisUser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01f9889f0a04026429aa8459e181e973 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/OpenAPI/BaseClient.cs b/Runtime/Scripts/OpenAPI/BaseClient.cs new file mode 100644 index 0000000000000000000000000000000000000000..c93808e38b86fb42ae9cfbf4ebb57fd3737b2dbb --- /dev/null +++ b/Runtime/Scripts/OpenAPI/BaseClient.cs @@ -0,0 +1,38 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace ETSI.ARF.OpenAPI.WorldAnalysis +{ + /// <summary> + /// Simple class to debug the requests + /// </summary> + public class BaseClient + { + static public bool EnableClientLog = true; + public string lastJsonText; + public long lastPayload; + + protected void _prepareRequest(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpRequestMessage request, string url) + { + if (EnableClientLog) + { + Debug.Log("[REST][URL] Send request: " + client.BaseAddress + url); + Debug.Log("[REST][URL] Send request: " + request); + } + } + + protected void _processResponse(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpResponseMessage response) + { + lastJsonText = response.Content.ReadAsStringAsync().Result.ToString(); + lastPayload = response.Content.Headers.ContentLength.Value; + + var status_ = (int)response.StatusCode; + + if (EnableClientLog) + { + Debug.Log("[REST][Data] Status: " + status_ + " Response: " + client.BaseAddress + " Len: " + lastPayload + " JSON: " + lastJsonText); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/OpenAPI/BaseClient.cs.meta b/Runtime/Scripts/OpenAPI/BaseClient.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..0af7d2c3954aa947ddeaad3e15d96a65ce00ff58 --- /dev/null +++ b/Runtime/Scripts/OpenAPI/BaseClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 696362f892252db4ca192c6eccbbfa25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/OpenAPI/DataModels.cs b/Runtime/Scripts/OpenAPI/DataModels.cs new file mode 100644 index 0000000000000000000000000000000000000000..91d04fc170eaa3f828c803928f87feb1fd404229 --- /dev/null +++ b/Runtime/Scripts/OpenAPI/DataModels.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace ETSI.ARF.OpenAPI.WorldAnalysis +{ + public interface IModel + { + public System.Guid Uuid { get; set; } // Bug: SylR: Why is Uuid not capitalized (UUID)??? + + public string ToJson(); + } + + // Class to monitor the server + public class Server : IModel + { + public System.Guid Uuid { get; set; } + public string Name { get; set; } + + public Server(string name) + { + Uuid = Guid.Empty; + Name = name; + } + + public string ToJson() { return JsonUtility.ToJson(this); } + } + + // + // Implement here some constructors + // + public partial class Pose : IModel + { + public Pose() + { + Uuid = Guid.NewGuid(); + } + + public string ToJson() { return JsonUtility.ToJson(this); } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/OpenAPI/DataModels.cs.meta b/Runtime/Scripts/OpenAPI/DataModels.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..ba6ef3620f111f2a823fd0ea0582be00142f58c7 --- /dev/null +++ b/Runtime/Scripts/OpenAPI/DataModels.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90e60e9d41d419146b3b6207e4ef556e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs b/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs index d9ac029a49a0168ec25aba84e3b9d7179aef420b..a59f80749dfa04a5343156f87799fee5b15a3ddb 100644 --- a/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs +++ b/Runtime/Scripts/OpenAPI/Generated/WorldAnalysisOpenAPI.cs @@ -24,11 +24,11 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] public partial class WorldAnalysisClient { - private ETSI.ARF.OpenAPI.IHttpClient _httpClient; + private ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient _httpClient; private static System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings, true); #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public WorldAnalysisClient(ETSI.ARF.OpenAPI.IHttpClient httpClient) + public WorldAnalysisClient(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient httpClient) #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { _httpClient = httpClient; @@ -45,9 +45,9 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis static partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings); - partial void PrepareRequest(ETSI.ARF.OpenAPI.IHttpClient client, System.Net.Http.HttpRequestMessage request, string url); - partial void PrepareRequest(ETSI.ARF.OpenAPI.IHttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); - partial void ProcessResponse(ETSI.ARF.OpenAPI.IHttpClient client, System.Net.Http.HttpResponseMessage response); + partial void PrepareRequest(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpRequestMessage request, string url); + partial void PrepareRequest(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); + partial void ProcessResponse(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpResponseMessage response); /// <summary> /// Test the server availability. diff --git a/Runtime/Scripts/OpenAPI/ResponseObject.cs b/Runtime/Scripts/OpenAPI/ResponseObject.cs new file mode 100644 index 0000000000000000000000000000000000000000..fa21f3d4ff04edaf83f1576c3a3eb7af5384aece --- /dev/null +++ b/Runtime/Scripts/OpenAPI/ResponseObject.cs @@ -0,0 +1,65 @@ +// The Fraunhofer HHI Unity Framework +// ___________ .__ _____ ___ ___ ___ ___ .___ +// \_ _____/___________ __ __ ____ | |__ _____/ ____\___________ / | \ / | \| | +// | __) \_ __ \__ \ | | \/ \| | \ / _ \ __\/ __ \_ __ \ / ~ \/ ~ \ | +// | \ | | \// __ \| | / | \ Y ( <_> ) | \ ___/| | \/ \ Y /\ Y / | +// \___ / |__| (____ /____/|___| /___| /\____/|__| \___ >__| \___|_ / \___|_ /|___| +// \/ \/ \/ \/ \/ \/ \/ +// (C) Fraunhofer HHI, 2024 + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using UnityEngine; + +namespace ETSI.ARF.OpenAPI.WorldAnalysis +{ + public class CancelToken + { + protected CancellationTokenSource tokenSource; + protected CancellationToken ct; + + public CancellationToken cancellationToken { get => ct; } + + public void Cancel() + { + tokenSource.Cancel(); + } + } + + public class ResponseObject<T> : CancelToken + { + // Management stuffs + static int ID = 0; + public int transactionId = 0; + public string message = ""; // custom message, type of data... + + // Time monitoring + public TimeSpan DeltaTime { get => responseTime - requestTime; } + public DateTime requestTime; + public DateTime responseTime; + + // Incoming data + public T result; + public int payload; // size of data + + //public string result = ""; // text result + //public object data = null; // custom result + + // Callback + public Action<ResponseObject<T>> callback; + + + public ResponseObject(string msg, Action<ResponseObject<T>> func = null) + { + requestTime = DateTime.Now; + message = msg; + callback = func; + transactionId = ++ID; + + tokenSource = new CancellationTokenSource(); + ct = tokenSource.Token; + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/OpenAPI/ResponseObject.cs.meta b/Runtime/Scripts/OpenAPI/ResponseObject.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..0f1afb54c82dbe646694e4340bffebb314c0abdc --- /dev/null +++ b/Runtime/Scripts/OpenAPI/ResponseObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82dc58594acebf747bd716fd00fcfb10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/OpenAPI/UnityWebRequestHttpClient.cs b/Runtime/Scripts/OpenAPI/UnityWebRequestHttpClient.cs new file mode 100644 index 0000000000000000000000000000000000000000..8d696aa6a621edc3cfcb038e31d7cb43cba61290 --- /dev/null +++ b/Runtime/Scripts/OpenAPI/UnityWebRequestHttpClient.cs @@ -0,0 +1,225 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: June 2024 +// + +// Depends on UniTask to support cancellation token and GetAwaiter: https://github.com/Cysharp/UniTask +// Otherwise, the code can be adapted using https://gist.github.com/krzys-h/9062552e33dd7bd7fe4a6c12db109a1a + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +//using Cysharp.Threading.Tasks; + +using UnityEngine; +using UnityEngine.Networking; + +namespace ETSI.ARF.OpenAPI.WorldAnalysis +{ + public interface IHttpClient + { + public Uri BaseAddress { get; set; } + public HttpRequestHeaders DefaultRequestHeaders { get; } + + public Task<HttpResponseMessage> SendAsync(HttpRequestMessage message, HttpCompletionOption option, + CancellationToken token); + + public void Dispose(); + } + + public class BasicHTTPClient : IHttpClient + { + + public BasicHTTPClient() { } + + public BasicHTTPClient(string baseUri) + { + BaseAddress = new Uri(baseUri); + _httpClient.BaseAddress = BaseAddress; + } + + public BasicHTTPClient(Uri baseUri) + { + BaseAddress = baseUri; + _httpClient.BaseAddress = BaseAddress; + } + + public Uri BaseAddress { get; set; } + public HttpRequestHeaders DefaultRequestHeaders => _httpClient.DefaultRequestHeaders; + + private readonly HttpClient _httpClient = new HttpClient(); + + public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage message, HttpCompletionOption option, CancellationToken token) + { + return await _httpClient.SendAsync(message, option, token); + } + + public void Dispose() + { + _httpClient.Dispose(); + DefaultRequestHeaders.Clear(); + BaseAddress = null; + } + } + + public class UnityWebRequestHttpClient : IHttpClient + { + public UnityWebRequestHttpClient() { } + + public UnityWebRequestHttpClient(string baseUri) + { + BaseAddress = new Uri(baseUri); + } + + public UnityWebRequestHttpClient(Uri baseUri) + { + BaseAddress = baseUri; + } + + public Uri BaseAddress { get; set; } + public HttpRequestHeaders DefaultRequestHeaders => _httpClient.DefaultRequestHeaders; + + private readonly HttpClient _httpClient = new HttpClient(); + + public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage message, HttpCompletionOption option, CancellationToken token) + { + var content = await (message.Content?.ReadAsStringAsync() ?? Task.FromResult("")); + var webRequest = GetUnityWebRequest(message.Method.Method, message.RequestUri, content); + + AppendHeaders(webRequest); + + Debug.Log("[HTTP] Request " + webRequest.uri.ToString()); + try + { + //SylR + webRequest.SendWebRequest(); + while (!webRequest.isDone) + { + if (token.IsCancellationRequested) + { + Debug.Log($"Task '{ message.RequestUri }' cancelled"); + token.ThrowIfCancellationRequested(); + } + await Task.Yield(); + } + + //await webRequest + // .SendWebRequest() + // .WithCancellation(cancellationToken: token); + } + catch (Exception) + { + webRequest.Dispose(); + throw; + } + + Debug.Log("[HTTP] Result: " + webRequest.result.ToString()); + + var responseMessage = CreateHttpResponseMessage(webRequest); + webRequest.Dispose(); + + Debug.Log("[HTTP] Response len: " + responseMessage.Content.Headers.ContentLength); + + return responseMessage; + } + + public void Dispose() + { + _httpClient.Dispose(); + DefaultRequestHeaders.Clear(); + BaseAddress = null; + } + + private UnityWebRequest GetUnityWebRequest(string method, Uri endpoint, string content = "") + { + var requestUri = BaseAddress.AbsoluteUri + endpoint; + var webRequest = UnityWebRequest.Get(requestUri); + webRequest.method = method; + + webRequest.disposeUploadHandlerOnDispose = true; + webRequest.disposeDownloadHandlerOnDispose = true; + + if (!string.IsNullOrEmpty(content)) + { + var data = new System.Text.UTF8Encoding().GetBytes(content); + webRequest.uploadHandler = new UploadHandlerRaw(data); + webRequest.SetRequestHeader("Content-Type", "application/json"); + //webRequest.SetRequestHeader("Content-Type", "image/jpeg"); + } + return webRequest; + } + + private void AppendHeaders(UnityWebRequest webRequest) + { + using var enumerator = DefaultRequestHeaders.GetEnumerator(); + + while (enumerator.MoveNext()) + { + var (key, value) = enumerator.Current; + webRequest.SetRequestHeader(key, value.First()); + } + } + + private HttpResponseMessage CreateHttpResponseMessage(UnityWebRequest webRequest) + { + var responseContent = webRequest.downloadHandler?.text; + + var response = new HttpResponseMessage(); + response.Content = new StringContent(responseContent); + response.StatusCode = (HttpStatusCode)webRequest.responseCode; + + Dictionary<string, string> headers = webRequest.GetResponseHeaders(); + + if (headers != null) + { + Debug.Log("[HTTP] Header: " + headers.Count.ToString()); + foreach (var h in headers) + { + switch (h.Key.ToLower().Trim()) + { + case "content-type": + { + var trimmed = h.Value.ToLower().Split(";").FirstOrDefault(); + response.Content.Headers.ContentType = new MediaTypeHeaderValue(trimmed); + break; + } + case "content-length": + response.Content.Headers.ContentLength = long.Parse(h.Value); + break; + + default: + if (h.Value == "gzip") + { + // bug??? + } + else + response.Headers.Add(h.Key, h.Value); + break; + } + } + } + return response; + } + } + +} \ No newline at end of file diff --git a/Runtime/Scripts/OpenAPI/UnityWebRequestHttpClient.cs.meta b/Runtime/Scripts/OpenAPI/UnityWebRequestHttpClient.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..7524d3a6df1ef4571c48f2fb69cf16df944ae7b4 --- /dev/null +++ b/Runtime/Scripts/OpenAPI/UnityWebRequestHttpClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4aa105d9487dc27408feffefde9e4475 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/OpenAPI/WorldAnalysisClient.cs b/Runtime/Scripts/OpenAPI/WorldAnalysisClient.cs new file mode 100644 index 0000000000000000000000000000000000000000..852ee38e38cc2939a5ae0f73f3394378ddb4b4a4 --- /dev/null +++ b/Runtime/Scripts/OpenAPI/WorldAnalysisClient.cs @@ -0,0 +1,28 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Networking; + +namespace ETSI.ARF.OpenAPI.WorldAnalysis +{ + /// <summary> + /// Catch the pre/pos request methods from the autogenerated classes + /// </summary> + public partial class WorldAnalysisClient : BaseClient + { + partial void PrepareRequest(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpRequestMessage request, string url) + { + _prepareRequest(client, request, url); + } + + partial void PrepareRequest(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder) + { + // do something... + } + + partial void ProcessResponse(ETSI.ARF.OpenAPI.WorldAnalysis.IHttpClient client, System.Net.Http.HttpResponseMessage response) + { + _processResponse(client, response); + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/OpenAPI/WorldAnalysisClient.cs.meta b/Runtime/Scripts/OpenAPI/WorldAnalysisClient.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..077447f195474d1946102043313d4a3d3962d465 --- /dev/null +++ b/Runtime/Scripts/OpenAPI/WorldAnalysisClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 748d04737c53fc04697ac6888226e399 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/REST.meta b/Runtime/Scripts/REST.meta new file mode 100644 index 0000000000000000000000000000000000000000..29c8716969dec7d6c68b209bced78f0a55b1e777 --- /dev/null +++ b/Runtime/Scripts/REST.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6f0fd52fd30564a4c838a545fe0d00ec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/REST/AdminRequest.cs b/Runtime/Scripts/REST/AdminRequest.cs new file mode 100644 index 0000000000000000000000000000000000000000..991052665a677fe50c1e5d03997b69a922fab000 --- /dev/null +++ b/Runtime/Scripts/REST/AdminRequest.cs @@ -0,0 +1,101 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: March 2024 +// + +using System; +using System.Threading.Tasks; +using UnityEngine; + +using ETSI.ARF.OpenAPI; +using ETSI.ARF.OpenAPI.WorldAnalysis; + +namespace ETSI.ARF.WorldAnalysis.REST +{ + public class AdminRequest : RequestBase<string> + { + // + // Wrapper for the endpoints + // + static public string PingSync(WorldAnalysisServer ws) + { + wsServer = ws; + var httpClient = new BasicHTTPClient(ws.URI); + apiClient = new WorldAnalysisClient(httpClient); + + string response = apiClient.GetPing(); + return response; + } + + static public ResponseObject<string> PingAsync(WorldAnalysisServer ws, Action<ResponseObject<string>> func) + { + wsServer = ws; + var httpClient = new UnityWebRequestHttpClient(ws.URI); + apiClient = new WorldAnalysisClient(httpClient); + + Debug.Log("[REST] Request Ping..."); + ResponseObject<string> ro = new ResponseObject<string>("Request Ping", func); + apiClient.GetPingAsync(ro.cancellationToken).ContinueWith(OnReceiveObject<string>, ro); + return ro; + } + + static public string AdminSync(WorldAnalysisServer ws) + { + wsServer = ws; + var httpClient = new BasicHTTPClient(ws.URI); + apiClient = new WorldAnalysisClient(httpClient); + + string response = apiClient.GetAdmin(); + return response; + } + + static public ResponseObject<string> AdminAsync(WorldAnalysisServer ws, Action<ResponseObject<string>> func) + { + wsServer = ws; + var httpClient = new UnityWebRequestHttpClient(ws.URI); + apiClient = new WorldAnalysisClient(httpClient); + + Debug.Log("[REST] Request Admin..."); + ResponseObject<string> ro = new ResponseObject<string>("Request Admin", func); + apiClient.GetAdminAsync(ro.cancellationToken).ContinueWith(OnReceiveObject<string>, ro); + return ro; + } + + static public string VersionSync(WorldAnalysisServer ws) + { + wsServer = ws; + var httpClient = new BasicHTTPClient(ws.URI); + apiClient = new WorldAnalysisClient(httpClient); + + string response = apiClient.GetVersion(); + return response; + } + + static public ResponseObject<string> VersionAsync(WorldAnalysisServer ws, Action<ResponseObject<string>> func) + { + wsServer = ws; + var httpClient = new UnityWebRequestHttpClient(ws.URI); + apiClient = new WorldAnalysisClient(httpClient); + + Debug.Log("[REST] Request Version..."); + ResponseObject<string> ro = new ResponseObject<string>("Request Version", func); + apiClient.GetVersionAsync(ro.cancellationToken).ContinueWith(OnReceiveObject<string>, ro); + return ro; + } + } +} diff --git a/Runtime/Scripts/REST/AdminRequest.cs.meta b/Runtime/Scripts/REST/AdminRequest.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..29a5fd8305acfc92e3b7b9ac33b9b0ebc5c4bbaa --- /dev/null +++ b/Runtime/Scripts/REST/AdminRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f287a535887d14c46859e33386b90b0e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/REST/RequestBase.cs b/Runtime/Scripts/REST/RequestBase.cs new file mode 100644 index 0000000000000000000000000000000000000000..6650e8f0da7986b274e9ce020a9d915299464933 --- /dev/null +++ b/Runtime/Scripts/REST/RequestBase.cs @@ -0,0 +1,79 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: March 2024 +// + +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using UnityEngine; + +using ETSI.ARF.OpenAPI; +using ETSI.ARF.OpenAPI.WorldAnalysis; + +namespace ETSI.ARF.WorldAnalysis.REST +{ + public class RequestBase<T> // where T : Trackable, WorldAnchor, WorldLink + { + static protected WorldAnalysisServer wsServer; + static protected WorldAnalysisClient apiClient; + + static protected string token = "ARF_Permission"; + + // Cache the current list + static public Dictionary<Guid, object> listOfObjects = new Dictionary<Guid, object>(); + + + // + // Helpers + // + static protected void OnReceiveObject<TObj>(Task<TObj> t, object id) + { + if (t.IsCompleted) + { + ResponseObject<TObj> o = (ResponseObject<TObj>)id; + o.responseTime = DateTime.Now; + o.result = t.Result; + Debug.Log($"[REST] Server Response = {o.result.ToString()} (ID={o.transactionId}, Msg={o.message})"); + + o.callback?.Invoke(o); + } + else Debug.Log("[REST] OpenAPI Timeout!"); + } + + static protected void OnReceiveListOfObjects<TObj>(Task<List<TObj>> t, object id) where TObj : IModel + { + if (t.IsCompleted) + { + ResponseObject<List<TObj>> o = (ResponseObject<List<TObj>>)id; + o.responseTime = DateTime.Now; + o.result = t.Result; + Debug.Log($"[REST] Server Response = Got {o.result.Count} entrie(s) (ID={o.transactionId}, Msg={o.message})"); + + listOfObjects.Clear(); + foreach (var i in o.result) + { + listOfObjects.Add(i.Uuid, i); + } + o.callback?.Invoke(o); + } + else Debug.Log("[REST] OpenAPI Timeout!"); + } + + } +} diff --git a/Runtime/Scripts/REST/RequestBase.cs.meta b/Runtime/Scripts/REST/RequestBase.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..2bb32b0f9b414c3d10937f86fc75b89a6d599183 --- /dev/null +++ b/Runtime/Scripts/REST/RequestBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6453e5289606a848ae29ddffa0f7288 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/WorldAnalysisInfo.cs b/Runtime/Scripts/WorldAnalysisInfo.cs new file mode 100644 index 0000000000000000000000000000000000000000..b461d5e4feb56906eb920c21d5e4c8aca637d4e5 --- /dev/null +++ b/Runtime/Scripts/WorldAnalysisInfo.cs @@ -0,0 +1,45 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2024 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: August 2024 +// + +using ETSI.ARF.WorldAnalysis; +using UnityEngine; + +public class WorldAnalysisInfo : MonoBehaviour +{ + public WorldAnalysisServer worldAnalysisServer; + + //public bool isServerAlive() + //{ + // if (worldStorageServer == null) return false; + // return !string.IsNullOrEmpty(ETSI.ARF.WorldStorage.REST.AdminRequest.Ping(worldStorageServer)); + //} + + //public string GetServerState() + //{ + // if (worldStorageServer == null) return "No Server Defined!"; + // return ETSI.ARF.WorldStorage.REST.AdminRequest.GetAdminInfo(worldStorageServer); + //} + + //public string GetAPIVersion() + //{ + // if (worldStorageServer == null) return "Unknown Version!"; + // return ETSI.ARF.WorldStorage.REST.AdminRequest.GetVersion(worldStorageServer); + //} +} diff --git a/Runtime/Scripts/WorldAnalysisInfo.cs.meta b/Runtime/Scripts/WorldAnalysisInfo.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..3190dcd83b56ce0b5aace0a0ae69d234922dee5b --- /dev/null +++ b/Runtime/Scripts/WorldAnalysisInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 269d5f98c3c478c4983c24ec09d10a70 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/WorldAnalysisREST.cs b/Runtime/Scripts/WorldAnalysisREST.cs index 5c18cebd58911b541edc3ef1a2809d7ac73a6b1a..ca881ccf6ac770dcc857c323484b98e8d2e0249b 100644 --- a/Runtime/Scripts/WorldAnalysisREST.cs +++ b/Runtime/Scripts/WorldAnalysisREST.cs @@ -1,11 +1,23 @@ +using System; using UnityEngine; using ETSI.ARF.OpenAPI.WorldAnalysis; +using ETSI.ARF.WorldAnalysis; using static WorldAnalysisInterface; -using System; +using ETSI.ARF.WorldAnalysis.REST; //Implementation of the WorldAnalysis interface public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface { + static protected string token = "ARF_Permission"; + + public WorldAnalysisServer waServer; + + // For sync calls + private WorldAnalysisClient apiClient; + + // For async calls + private WorldAnalysisClient apiClientAsync; + #region Unity_Methods @@ -14,6 +26,13 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface /// </summary> protected void Awake() { + // sync + var httpClient = new BasicHTTPClient(waServer.URI); + apiClient = new WorldAnalysisClient(httpClient); + + // async + //var httpClientAsync = new UnityWebRequestHttpClient(waServer.URI); + //apiClientAsync = new WorldAnalysisClient(httpClientAsync); } /// <summary> @@ -32,10 +51,48 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface #endregion + #region Test methods + public void CheckServer() + { + string ping = AdminRequest.PingSync(waServer); + string state = AdminRequest.AdminSync(waServer); + string ver = AdminRequest.VersionSync(waServer); + Debug.Log("[REST] WA Ping: " + ping); + Debug.Log("[REST] WA State: " + state); + Debug.Log("[REST] WA Version: " + ver); + } - #region ARF_API + public string GetWebSocketEndpoint() + { + string res = "empty"; + + SubscriptionSingleRequest param = new SubscriptionSingleRequest(); + param.Mode = Mode_WorldAnalysis.DEVICE_TO_TRACKABLES; + param.Target = Guid.Parse("fa8bbe40-8052-11ec-a8a3-0242ac120002"); // test + + SubscriptionSingle response = apiClient.SubscribeToPose(token, "1", param); + res = response.WebsocketUrl; + return res; + } + + public void PrintCapabilities() + { + string res = "Capabilities:"; + + Response2 cap = apiClient.GetCapabilities(token, "1"); + foreach (var item in cap.Capabilities) + { + res += "\n" + item.TrackableType; + } + Debug.Log("[REST] Capabilities: " + res); + } + #endregion - public AskFrameRateResult SetPoseEstimationFramerate(string token, PoseConfigurationTrackableType type, EncodingInformationStructure encodingInformation, int minimumFramerate) + #region ARF_API + // + // Implementation of the endpoints + // + public AskFrameRateResult SetPoseEstimationFramerate(string token, PoseConfigurationTrackableType type, EncodingInformationStructure encodingInformation, int minimumFramerate) { return AskFrameRateResult.NOT_SUPPORTED; ///We cannot set any framerate for tracking on ARKit and ARCore } @@ -47,7 +104,7 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface } - public PoseEstimationResult[] GetLastPoses(string token, Guid[] uuids, Mode_WorldAnalysis [] modes, out ETSI.ARF.OpenAPI.WorldAnalysis.Pose[] poses) + public PoseEstimationResult[] GetLastPoses(string token, Guid[] uuids, Mode_WorldAnalysis[] modes, out ETSI.ARF.OpenAPI.WorldAnalysis.Pose[] poses) { poses = null; return null; @@ -59,7 +116,7 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface return InformationSubscriptionResult.OK; } - public InformationSubscriptionResult[] SubscribeToPoses(string token, Guid[] uuids, Mode_WorldAnalysis [] modes, PoseCallback callback, ref int validity, out Guid[] subscriptionUUIDs) + public InformationSubscriptionResult[] SubscribeToPoses(string token, Guid[] uuids, Mode_WorldAnalysis[] modes, PoseCallback callback, ref int validity, out Guid[] subscriptionUUIDs) { subscriptionUUIDs = null; return null; @@ -90,7 +147,7 @@ public class WorldAnalysisREST : MonoBehaviour, WorldAnalysisInterface return CapabilityResult.OK; } - public CapabilityResult GetCapability(string token, Guid uuid, out bool isSupported, out TypeWorldStorage type, out Capability [] capability) + public CapabilityResult GetCapability(string token, Guid uuid, out bool isSupported, out TypeWorldStorage type, out Capability[] capability) { isSupported = false; type = TypeWorldStorage.UNKNOWN;