/// <summary> /// Reads the country code of the system locale. /// </summary> /// <param name="country">Country code defined in ISO 3166, or an empty string. Valid only if <c>MLResult.Code.Ok</c> is returned, empty string otherwise.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the country code was retrieved successfully. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an unspecified error. /// </returns> public static MLResult GetSystemCountry(out string country) { IntPtr outCountry = IntPtr.Zero; MLResult result; try { MLResult.Code resultCode = NativeBindings.MLLocaleGetSystemCountry(ref outCountry); result = MLResult.Create(resultCode); if (result.IsOk) { country = MLConvert.DecodeUTF8(outCountry); } else { country = string.Empty; MLPluginLog.ErrorFormat("MLLocale.GetSystemCountry failed. Reason: {0}", result); } } catch (System.DllNotFoundException) { MLPluginLog.Error("MLLocale.GetSystemCountry failed. Reason: MLLocale API is currently available only on device."); result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLLocale.GetSystemCountry failed. Reason: Dll not found."); country = string.Empty; } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLLocale.GetSystemCountry failed. Reason: API symbols not found."); result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLLocale.GetSystemCountry failed. Reason: API symbols not found."); country = string.Empty; } return(result); }
/// <summary> /// Starts the HeadTracking API. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if connected to MLContacts successfully. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if necessary privilege is missing. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the operation failed with an unspecified error. /// </returns> protected override MLResult StartAPI() { MLResult.Code resultCode = MLResult.Code.UnspecifiedFailure; try { resultCode = NativeBindings.MLHeadTrackingCreate(ref _instance.handle); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLHeadTracking.StartAPI failed to create native head tracker."); } resultCode = NativeBindings.MLHeadTrackingGetStaticData(_instance.handle, ref _instance.staticDataNative); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLHeadTracking.StartAPI failed to get static date from the native head tracker."); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLHeadTracking.StartAPI failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure)); } return(MLResult.Create(resultCode)); }
/// <summary> /// Stores the specified data under the specified key. An existing key would be overwritten. /// </summary> /// <param name="dataKey">The key string associated with the data.</param> /// <param name="data">The data byte array to store.</param> /// <returns> /// MLResult.Result will be<c> MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to internal invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// MLResult.Result will be <c>MLResult.Code.SecureStorageIOFailure</c> if an I/O failure occurred. /// </returns> public static MLResult StoreData(string dataKey, byte[] data) { try { // Early exit if array is invalid. if (data == null) { return(MLResult.Create(MLResult.Code.InvalidParam, "Data parameter was null")); } // Early exit if string key is invalid. MLResult result = CheckKey(dataKey); if (!result.IsOk) { return(result); } MLResult.Code resultCode = MLSecureStorageNativeBindings.MLSecureStoragePutBlob(dataKey, data, (uint)data.Length); result = MLResult.Create(resultCode); return(result); } catch (System.DllNotFoundException) { MLPluginLog.Error(DllNotFoundError); throw; } }
/// <summary> /// External call for querying the last known fine location. /// The accuracy field of the MLLocation.Location provides the estimate accuracy radius in meters. /// Returns the last known fine location data on success and returns the last queried fine location data on failure. Latitude and Longitude of /// 0 should be assumed an Invalid Location. /// </summary> /// <param name="fineLocation">Where to store the last known fine location. Only updates when getting the location succeeds. Latitude and Longitude of 0 should be assumed an Invalid Location.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the location was queried successfully. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an internal error. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if there was an invalid location. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there was a lack of privilege(s). /// MLResult.Result will be <c>MLResult.Code.LocationProviderNotFound</c> if there was no provider or an invalid request was made. /// MLResult.Result will be <c>MLResult.Code.LocationNetworkConnection</c> if there was no internet connection. /// MLResult.Result will be <c>MLResult.Code.LocationNoLocation</c> if the location could not be found. /// </returns> public static MLResult GetLastFineLocation(out Location fineLocation) { try { if (MLLocation.IsValidInstance()) { MLResult result = NativeBindings.MLLocationGetLastLocation(out fineLocation, true); if (result.IsOk) { _instance.lastValidFineLocation = fineLocation; } else { MLPluginLog.ErrorFormat("MLLocation.GetLastFineLocation failed to get location. Reason: {0}", result); } return(result); } else { fineLocation = new Location(); MLPluginLog.ErrorFormat("MLLocation.GetLastFineLocation failed. Reason: No Instance for MLLocation."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLLocation.GetLastFineLocation failed. Reason: No Instance for MLLocation.")); } } catch (System.EntryPointNotFoundException) { fineLocation = new Location(); MLPluginLog.Error("MLLocation.GetLastFineLocation failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLLocation.GetLastFineLocation failed. Reason: API symbols not found.")); } }
/// <summary> /// Retrieves the data associated with the specified key. /// </summary> /// <param name="dataKey">The key for the data that is being requested.</param> /// <param name="data">A valid array of bytes to store retrieved data.</param> /// <returns> /// MLResult.Result will be<c> MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to internal invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// MLResult.Result will be <c>MLResult.Code.SecureStorageBlobNotFound</c> if the dataKey was not found. /// MLResult.Result will be <c>MLResult.Code.SecureStorageIOFailure</c> if an I/O failure occurred. /// </returns> public static MLResult GetData(string dataKey, ref byte[] data) { try { MLResult result = CheckKey(dataKey); if (!result.IsOk) { return(result); } IntPtr outputBytes = IntPtr.Zero; ulong dataLength = 0; MLResult.Code resultCode = MLSecureStorageNativeBindings.MLSecureStorageGetBlob(dataKey, ref outputBytes, ref dataLength); result = MLResult.Create(resultCode); // Are there situations where the result is Ok but no data is available? if (result.IsOk && dataLength > 0 && outputBytes != IntPtr.Zero) { data = new byte[dataLength]; Marshal.Copy(outputBytes, data, 0, (int)dataLength); MLSecureStorageNativeBindings.MLSecureStorageFreeBlobBuffer(outputBytes); } return(result); } catch (System.DllNotFoundException) { MLPluginLog.Error(DllNotFoundError); throw; } }
/// <summary> /// ReleaseClientCredentials releases all resources associated with the /// MLTokenAgentClientCredentials structure that was returned by the library. /// </summary> /// <param name="clientCredentials">Reference to the clientCredentials object.</param> public static void CleanupClientCredentialsMemory(MLTokenAgent.ClientCredentials clientCredentials) { if (clientCredentials.CurrentRequest != null) { MLPluginLog.Warning("This client has an ongoing request and cannot have it's memory released."); } IntPtr clientCredentialsPtr = clientCredentialsPtrMap.ContainsKey(clientCredentials) ? clientCredentialsPtrMap[clientCredentials] : IntPtr.Zero; if (clientCredentialsPtr != IntPtr.Zero) { try { MLResult.Code resultCode = MLTokenAgent.NativeBindings.MLTokenAgentReleaseClientCredentials(clientCredentialsPtr); if (resultCode != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLTokenAgent.CleanupClientCredentialsMemory failed. Reason: {0}", resultCode); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLTokenAgent.CleanupClientCredentialsMemory failed. Reason: API symbols not found."); } } }
/// <summary> /// Begin querying for found objects. /// </summary> /// <param name="callback">Callback used to report query results.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> private MLResult BeginObjectQuery(QueryResultsDelegate callback) { try { if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.tracker)) { MLPluginLog.Error("MLFoundObject.BeginObjectQuery failed to request found objects. Reason: Tracker handle is invalid"); return(MLResult.Create(MLResult.Code.InvalidParam)); } NativeBindings.QueryFilterNative queryFilter = new NativeBindings.QueryFilterNative(); MLResult.Code resultCode = NativeBindings.MLFoundObjectQuery(_instance.tracker, ref queryFilter, out ulong queryHandle); MLResult result = MLResult.Create(resultCode); if (!result.IsOk) { MLPluginLog.ErrorFormat("MLFoundObject.BeginObjectQuery failed to request objects. Reason: {0}", resultCode); return(result); } // Create query object to prepresent this newly registered found object query. NativeBindings.Query query = new NativeBindings.Query(callback, queryFilter, result); MLFoundObjects._instance.pendingQueries.Add(queryHandle, query); return(result); } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLFoundObjects.BeginObjectQuery failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLFoundObjects.BeginObjectQuery failed. Reason: API symbols not found")); } }
/// <summary> /// GetClientCredentials is a blocking function that accesses the cloud and /// returns a MLTokenAgentClientCredentials structure containing the users credentials and /// tokens for a particular service (Audience). /// The library deduces the Audience being requested from the name of the calling service. /// </summary> /// <param name="clientCredentials">Reference to the clientCredentials object.</param> /// <param name="credentials">Reference to the credentials struct of the clientCredentials object.</param> /// <param name="tokens">Reference to the tokens struct of the clientCredentials object.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to internal invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// MLResult.Result will be <c>MLResult.Code.AllocFailed</c> if failed to allocate memory. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if necessary privilege is missing. /// MLResult.Result will be <c>MLResult.Code.TokenAgent*</c> if a token specific failure occurred during the operation. /// </returns> public static MLResult.Code GetClientCredentials(MLTokenAgent.ClientCredentials clientCredentials, ref MLTokenAgent.Credentials credentials, ref MLTokenAgent.Tokens tokens) { try { IntPtr clientCredentialsPtr = clientCredentialsPtrMap.ContainsKey(clientCredentials) ? clientCredentialsPtrMap[clientCredentials] : IntPtr.Zero; MLResult.Code resultCode = MLTokenAgent.NativeBindings.MLTokenAgentGetClientCredentials(ref clientCredentialsPtr); if (MLResult.IsOK(resultCode)) { clientCredentialsPtrMap.Remove(clientCredentials); clientCredentialsPtrMap.Add(clientCredentials, clientCredentialsPtr); MLTokenAgent.NativeBindings.ClientCredentialsNative clientCredentialsNative = (MLTokenAgent.NativeBindings.ClientCredentialsNative)Marshal.PtrToStructure(clientCredentialsPtr, typeof(MLTokenAgent.NativeBindings.ClientCredentialsNative)); credentials = clientCredentialsNative.Credentials; tokens = clientCredentials.Tokens; } else { credentials = new Credentials(); tokens = new Tokens(); } return(resultCode); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLTokenAgent.NativeBindings.GetClientCredentials failed. Reason: API symbols not found."); return(MLResult.Code.UnspecifiedFailure); } }
/// <summary> /// Invokes the MLTokenAgentGetClientCredentials() function asynchronously (in a different thread). /// </summary> /// <param name="clientCredentials">Reference to the clientCredentials object.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the operation completed successfully. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the operation failed with an unspecified error. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the profile or out_future were 0 (null). /// MLResult.Result will be <c>MLResult.Code.AllocFailed</c> if the operation failed to allocate memory. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if the caller does not have the ClientCredentialsRead privilege. /// MLResult.Result will be <c>MLResult.Code.TokenAgent*</c> if a token specific failure occurred during the operation. /// </returns> public static MLResult.Code RequestClientCredentialsAsync(MLTokenAgent.ClientCredentials clientCredentials) { IntPtr clientCredentialsFuturePtr = clientCredentialsFuturePtrMap.ContainsKey(clientCredentials) ? clientCredentialsFuturePtrMap[clientCredentials] : IntPtr.Zero; try { MLResult.Code resultCode = MLTokenAgent.NativeBindings.MLTokenAgentGetClientCredentialsAsync(ref clientCredentialsFuturePtr); if (MLResult.IsOK(resultCode)) { clientCredentialsFuturePtrMap.Remove(clientCredentials); clientCredentialsFuturePtrMap.Add(clientCredentials, clientCredentialsFuturePtr); } else if (resultCode == MLResult.Code.PrivilegeDenied) { MLPluginLog.Warning("MLTokenAgent.NativeBindings.RequestClientCredentialsAsync failed. Reason: Caller does not have IdentityRead Privilege."); } else { MLPluginLog.ErrorFormat("MLTokenAgent.NativeBindings.RequestClientCredentialsAsync failed. Reason: {0}", resultCode); } return(resultCode); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLTokenAgent.NativeBindings.RequestClientCredentialsAsync failed. Reason: API symbols not found."); return(MLResult.Code.UnspecifiedFailure); } }
/// <summary> /// Loads the persistent data from the given file. /// </summary> /// <param name="fileName">Name of the file to load.</param> /// <returns>MLContentBindings from file contents if found, null if not found.</returns> public MLContentBindings Load(string fileName) { string fullPath = Path.Combine(Application.persistentDataPath, fileName); //open a file MLPluginLog.DebugFormat("Reading persistence data from : {0}", fullPath); if (fullPath != null && File.Exists(fullPath)) { StreamReader reader = new StreamReader(fullPath); if (reader != null) { string jsonString = reader.ReadToEnd(); MLPluginLog.DebugFormat("Found json of: {0}", jsonString); _data = JsonUtility.FromJson <MLContentBindings>(jsonString); reader.Dispose(); } else { MLPluginLog.Error("MLPersistentFileStorage.Load failed to create StreamReader."); } } else { MLPluginLog.DebugFormat("File was not found: {0}", fullPath); } return(_data); }
/// <summary> /// Requests the specified privileges. This may possibly solicit consent from the end-user. /// </summary> /// <param name="privilegeId">The privilege to request.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted. /// MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started. /// </returns> public static MLResult RequestPrivilege(MLPrivileges.Id privilegeId) { try { if (MLPrivileges.IsValidInstance()) { MLResult.Code requestPrivilegeResult = NativeBindings.MLPrivilegesRequestPrivilege(privilegeId); MLResult result = MLResult.Create(requestPrivilegeResult); if (result.Result != MLResult.Code.PrivilegeGranted) { MLPluginLog.ErrorFormat("MLPrivileges.RequestPrivilege failed to request {0}. Reason: {1}", privilegeId, result); } return(result); } else { MLPluginLog.ErrorFormat("MLPrivileges.RequestPrivilege failed. Reason: No Instance for MLPrivileges."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.RequestPrivilege failed. Reason: No Instance for MLPrivileges.")); } } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLPrivileges.RequestPrivilege failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.RequestPrivilege failed. Reason: API symbols not found.")); } }
/// <summary> /// Begin querying for planes. /// </summary> /// <param name="queryParams">All values are required, omitting values may result in unexpected behavior.</param> /// <param name="callback">Callback used to report query results.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> private MLResult BeginPlaneQuery(QueryParams queryParams, QueryResultsDelegate callback) { if (!NativeBindings.MLHandleIsValid(this.planesTracker)) { MLPluginLog.Error("MLPlanes.BeginPlaneQuery failed to request planes. Reason: Tracker handle is invalid"); return(MLResult.Create(MLResult.Code.InvalidParam)); } // Convert to native plane query parameters. NativeBindings.QueryParamsNative planeQuery = NativeBindings.QueryParamsNative.Create(); planeQuery.Data = queryParams; // Register the query with the native library and store native handle. ulong handle = MagicLeapNativeBindings.InvalidHandle; MLResult.Code resultCode = NativeBindings.MLPlanesQueryBegin(this.planesTracker, ref planeQuery, ref handle); if (resultCode != MLResult.Code.Ok) { MLResult result = MLResult.Create(resultCode); MLPluginLog.ErrorFormat("MLPlanes.BeginPlaneQuery failed to request planes. Reason: {0}", result); return(result); } // Create query object to prepresent this newly registered plane query. NativeBindings.Query query = new NativeBindings.Query((QueryResultsDelegate)callback, planeQuery.MaxResults, this.IsRequestingBoundaries(planeQuery.Flags)); this.pendingQueries.Add(handle, query); return(MLResult.Create(MLResult.Code.Ok)); }
/// <summary> /// Generic store function for all value types. /// Using BinaryFormatter.Serialize() to serialize data to bytes. /// </summary> /// <typeparam name="T">The type of data that is being retrieved.</typeparam> /// <param name="dataKey">The key string associated with the data.</param> /// <param name="value">The generic type value to store.</param> /// <returns> /// MLResult.Result will be<c> MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to internal invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// MLResult.Result will be <c>MLResult.Code.SecureStorageIOFailure</c> if an I/O failure occurred. /// </returns> public static MLResult StoreData <T>(string dataKey, T value) where T : struct { // TODO: use non-template version of StoreData after converting value to byte array try { MLResult result = CheckKey(dataKey); if (!result.IsOk) { return(result); } byte[] valueByteArray = SerializeData(value); if (valueByteArray == null) { return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "Data serialization failed")); } MLResult.Code resultCode = MLSecureStorageNativeBindings.MLSecureStoragePutBlob(dataKey, valueByteArray, (uint)valueByteArray.Length); result = MLResult.Create(resultCode); return(result); } catch (System.DllNotFoundException) { MLPluginLog.Error(DllNotFoundError); throw; } }
/// <summary> /// Request the list of detected found objects. /// Callback will never be called while request is still pending. /// </summary> /// <param name="queryFilter">Filter used to customize query results.</param> /// <param name="callback"> /// Callback used to report query results. /// Callback MLResult code will never be <c>MLResult.Code.Pending</c>. /// </param> /// <returns> /// MLResult.Result inside callback will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result inside callback will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result inside callback will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public static MLResult GetObjectsAsync(Query.Filter queryFilter, QueryResultsDelegate callback) { if (MLFoundObjects.IsValidInstance()) { // Don't allow null callbacks to be registered. if (callback == null) { MLPluginLog.Error("MLFoundObjects.GetObjects failed. Reason: Passed input callback is null."); return(MLResult.Create(MLResult.Code.InvalidParam)); } MLThreadDispatch.ScheduleWork(() => { _instance.BeginObjectQueryAsync(queryFilter, callback); return(true); }); return(MLResult.Create(MLResult.Code.Ok)); } else { MLPluginLog.ErrorFormat("MLFoundObjects.GetObjects failed. Reason: No Instance for MLFoundObjects"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLFoundObjects.GetFoundObjects failed. Reason: No Instance for MLFoundObjects")); } }
/// <summary> /// Gets the offset position/rotation values and the PCF of the current Perception root. /// </summary> /// <param name="offsetPosition">Stores the value of the current offset from the root's position.</param> /// <param name="offsetRotation">Stores the value of the current offset from the root's rotation.</param> /// <param name="pcf">Stores the reference to the current root PCF.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if operation completed successfully. /// MLResult.Result will be <c>MLResult.Code.MLPerceptionNotStarted</c> if unable to retrieve the Perception System. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error. /// </returns> public static MLResult GetPerceptionRoot(out Vector3 offsetPosition, out Quaternion offsetRotation, out PCF pcf) { offsetPosition = Vector3.zero; offsetRotation = Quaternion.identity; pcf = new PCF(new MagicLeapNativeBindings.MLCoordinateFrameUID()); if (MLPersistentCoordinateFrames.IsValidInstance()) { try { MLResult.Code resultCode = NativeBindings.MLPerceptionGetRootCoordinateFrame(out MagicLeapNativeBindings.MLCoordinateFrameUID cfuid, out MagicLeapNativeBindings.MLTransform mlTransform); if (MLResult.IsOK(resultCode)) { offsetPosition = MLConvert.ToUnity(mlTransform.Position); offsetRotation = MLConvert.ToUnity(mlTransform.Rotation); return(MLResult.Create(MLResult.Code.Ok)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: {0}", MLResult.CodeToString(resultCode)); return(MLResult.Create(resultCode)); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: API symbols not found.")); } } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Gets the most recent Head Tracking state. /// </summary> /// <param name="state">Some MLHeadTracking.State object to be filled with current state information.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the head tracking state was successfully received. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the outState parameter was not valid (null). /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed to receive head tracking state. /// </returns> public static MLResult GetState(out State state) { state = new State(); if (MLHeadTracking.IsValidInstance()) { try { MLResult.Code resultCode = NativeBindings.MLHeadTrackingGetState(_instance.handle, ref _instance.stateNative); state.Mode = (TrackingMode)_instance.stateNative.Mode; state.Confidence = _instance.stateNative.Confidence; state.Error = (TrackingError)_instance.stateNative.Error; state.Handle = _instance.handle; return(MLResult.Create(resultCode)); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLHeadTracking.GetState failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure)); } } else { MLPluginLog.ErrorFormat("MLHeadTracking.GetState failed. Reason: No Instance for MLHeadTracking."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLHeadTracking.GetState failed. Reason: No Instance for MLHeadTracking.")); } }
/// <summary> /// Register a unique schema for <c>OAuth</c> redirect handler. The caller needs to ensure that the schema is unique. /// If the schema is already registered the function will return an error. The handler /// will be called once the authorization procedure has been completed. /// The caller should register two schema callbacks. The first will be for /// authorization redirect and the second schema will in case the user cancels /// the authentication. /// </summary> /// <param name="schema">A unique string that will match the redirect uri schema</param> /// <param name="callback">MLDispatch <c>OAuth</c> callback function</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the new schema has been registered correctly. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if SecureBrowserWindow privilege is denied. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the operation failed with an unspecified error. /// MLResult.Result will be <c>MLResult.Code.SchemaAlreadyRegistered</c> if the schema already is registered. /// MLResult.Result will be <c>MLResult.Code.Dispatch*</c> if a dispatch specific error occurred. /// </returns> public static MLResult OAuthRegisterSchema(string schema, ref OAuthHandler callback) { try { NativeBindings.OAuthCallbacksNative newSchema = NativeBindings.OAuthCallbacksNative.Create(); newSchema.OnReplyComplete = OAuthOnReplyNative; int newID = uniqueID + 1; MLResult.Code resultCode = NativeBindings.MLDispatchOAuthRegisterSchemaEx(schema, ref newSchema, new IntPtr(newID)); if (MLResult.IsOK(resultCode)) { OAuthPair newEntry = new OAuthPair(schema, callback); oAuthCallbacks.Add(newID, newEntry); uniqueID = newID; } return(MLResult.Create(resultCode)); } catch (System.DllNotFoundException) { MLPluginLog.Error(DllNotFoundExceptionError); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, DllNotFoundExceptionError)); } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLDispatch API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLDispatch API symbols not found")); } }
/// <summary> /// Gets the result string for a MLResult.Code. Use MLResult.CodeToString(MLResult.Code) to get the string value of any MLResult.Code. /// </summary> /// <param name="result">The MLResult.Code to be requested.</param> /// <returns>A pointer to the result string.</returns> internal static IntPtr GetResultString(MLResult.Code result) { try { if (MLIdentity.IsValidInstance()) { try { return(NativeBindings.MLIdentityGetResultString(result)); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLIdentity.GetResultString failed. Reason: API symbols not found."); } return(IntPtr.Zero); } else { MLPluginLog.ErrorFormat("MLIdentity.GetResultString failed. Reason: No Instance for MLIdentity."); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLIdentity.GetResultString failed. Reason: API symbols not found."); } return(IntPtr.Zero); }
/// <summary> /// Updates the state of the PCF. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if operation completed successfully. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to an invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there was a lack of privileges. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error. /// MLResult.Result will be <c>MLResult.Code.PassableWorldLowMapQuality</c> if map quality is too low for content persistence. Continue building the map. /// MLResult.Result will be <c>MLResult.Code.PassableWorldNotFound</c> if the passed CFUID is not available. /// MLResult.Result will be <c>MLResult.Code.PassableWorldUnableToLocalize</c> if currently unable to localize into any map. Continue building the map. /// </returns> private MLResult UpdateState() { if (MLPersistentCoordinateFrames.IsValidInstance()) { try { NativeBindings.FrameStateNative nativeState = NativeBindings.FrameStateNative.Create(); MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFramesGetFrameState(MLPersistentCoordinateFrames._instance.nativeTracker, in this.cfuid, ref nativeState); if (!MLResult.IsOK(resultCode)) { MLPluginLog.ErrorFormat("PCF.UpdateState failed to get frame state. Reason: {0}", MLResult.CodeToString(resultCode)); return(MLResult.Create(resultCode, string.Format("PCF.UpdateState failed to get frame state. Reason: {0}", MLResult.CodeToString(resultCode)))); } this.FrameState = nativeState.Data(); return(MLResult.Create(resultCode)); } catch (EntryPointNotFoundException) { MLPluginLog.Error("PCF.UpdateState failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "PCF.UpdateState failed. Reason: API symbols not found.")); } } else { MLPluginLog.ErrorFormat("PCF.UpdateState failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "PCF.UpdateState failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Start tracking hands with all key poses disabled. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed to initialize the native hand tracker. /// </returns> protected override MLResult.Code StartAPI() { this.left = new Hand(MLHandTracking.HandType.Left); this.right = new Hand(MLHandTracking.HandType.Right); // Initialize KeyPoseManager, to register the gesture subsystem. this.keyposeManager = new KeyposeManager(Left, Right); try { // Attempt to start the tracker & validate. NativeBindings.SetHandGesturesEnabled(true); if (!NativeBindings.IsHandGesturesEnabled()) { MLPluginLog.Error("MLHandTracking.StartAPI failed to initialize the native hand tracker."); return(MLResult.Code.UnspecifiedFailure); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLHandTracking.StartAPI failed. Reason: API symbols not found."); return(MLResult.Code.UnspecifiedFailure); } return(MLResult.Code.Ok); }
/// <summary> /// Enables or disables an array of key poses. /// Enabling too many key poses will currently lead to decreased sensitivity to each /// individual key pose. /// </summary> /// <param name="keyPoses">The list of key poses to affect.</param> /// <param name="enable">Enable or disable key poses.</param> /// <param name="exclusive"> /// When enabling and this is true, only the list of provided key poses /// are enabled, all other previously-enabled key poses get disabled. No effect if /// parameter enable is false. /// </param> /// <returns> /// True if the chosen key poses were successfully enabled/disabled and applied to the key pose config. /// </returns> public bool EnableKeyPoses(MLHandTracking.HandKeyPose[] keyPoses, bool enable, bool exclusive = false) { if (keyPoses == null || keyPoses.Length <= 0) { MLPluginLog.Error("KeyPoseManager.EnableKeyPoses passed key poses array is null or empty."); return(false); } if (enable) { // Enable the hand tracking pipeline. this.config.HandTrackingPipelineEnabled = true; if (exclusive) { // Disable all other previous key poses. this.SetKeyPoseConfig(0); } } foreach (var keyPoseType in keyPoses) { SetKeyPoseConfig(this.config, keyPoseType, enable); } return(this.ApplyConfig()); }
/// <summary> /// Retrieves if there's currently internet connection. /// </summary> /// <param name="isConnected">Reference to populate with whether or not there's internet connectivity.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if isConnected parameter is invalid. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if necessary privilege is missing. /// MLResult.Result will be <c>MLResult.Code.ServiceNotAvailable</c> if the corresponding service is not available. /// MLResult.Result will be <c>MLResult.Code.ServiceError </c> if the corresponding service returned with error. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public static MLResult IsInternetConnected(ref bool isConnected) { MLResult finalResult = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLNetworking.IsInternetConnected failed due to internal error"); try { isConnected = false; MLResult.Code result = MLNetworkingNativeBindings.MLNetworkingIsInternetConnected(ref isConnected); if (result != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLNetworking.IsInternetConnected failed to check if device is connected to internet. Reason: {0}", result); isConnected = false; } finalResult = MLResult.Create(result); } catch (System.DllNotFoundException) { MLPluginLog.Error("MLNetworking API is currently available only on device."); finalResult = MLResult.Create(MLResult.Code.UnspecifiedFailure, "Dll not found"); } catch (System.EntryPointNotFoundException) { string errorMessage = string.Format("MLNetworking API symbols not found"); finalResult = MLResult.Create(MLResult.Code.UnspecifiedFailure, errorMessage); } return(finalResult); }
/// <summary> /// Retrieves data from the current Wi-Fi network. /// </summary> /// <param name="wifiData">Reference to the struct to populate.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the given parameter is invalid. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if necessary privilege is missing. /// MLResult.Result will be <c>MLResult.Code.ServiceNotAvailable</c> if the corresponding service is not available. /// MLResult.Result will be <c>MLResult.Code.ServiceError</c> if the corresponding service returned with error. /// MLResult.Result will be <c>MLResult.Code.WiFiDataStructureVersionError</c> if the version number in the given struct is not recognized. /// MLResult.Result will be <c>MLResult.Code.WiFiServiceInvalidState</c> if the Wi-Fi service is not in the right state. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> public static MLResult GetWifiData(ref MLNetworking.WifiData wifiData) { MLResult finalResult = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLNetworking.GetWifiData failed due to internal error"); try { MLNetworkingNativeBindings.WifiDataNative wifiDataInternal = MLNetworkingNativeBindings.WifiDataNative.Create(); MLResult.Code result = MLNetworkingNativeBindings.MLNetworkingGetWiFiData(ref wifiDataInternal); if (result != MLResult.Code.Ok) { MLPluginLog.ErrorFormat("MLNetworking.GetWifiData failed to get Wi-Fi data. Reason: {0}", result); wifiData = new MLNetworking.WifiData(); } else { wifiData = wifiDataInternal.Data; } finalResult = MLResult.Create(result); } catch (System.DllNotFoundException) { MLPluginLog.Error("MLNetworking API is currently available only on device."); finalResult = MLResult.Create(MLResult.Code.UnspecifiedFailure, "Dll not found"); } catch (System.EntryPointNotFoundException) { string errorMessage = string.Format("MLNetworking API symbols not found"); finalResult = MLResult.Create(MLResult.Code.UnspecifiedFailure, errorMessage); } return(finalResult); }
/// <summary> /// Begin querying for found objects. /// </summary> /// <param name="filter">Filter to use for this query.</param> /// <param name="callback">Callback used to report query results.</param> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error. /// </returns> private MLResult BeginObjectQueryAsync(Query.Filter filter, QueryResultsDelegate callback) { try { if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.handle)) { MLPluginLog.Error("MLFoundObjects.BeginObjectQuery failed to request found objects. Reason: Tracker handle is invalid"); return(MLResult.Create(MLResult.Code.InvalidParam)); } NativeBindings.QueryFilterNative nativeQueryFilter = new NativeBindings.QueryFilterNative(); nativeQueryFilter.Data = filter; MLResult.Code resultCode = NativeBindings.MLFoundObjectQuery(_instance.handle, ref nativeQueryFilter, out ulong queryHandle); MLResult result = MLResult.Create(resultCode); if (!result.IsOk) { MLPluginLog.ErrorFormat("MLFoundObjects.BeginObjectQuery failed to request objects. Reason: {0}", resultCode); return(result); } // Add query to the list of pendingQueries. Query query = Query.Create(callback, filter); MLFoundObjects._instance.pendingQueries.TryAdd(queryHandle, query); return(result); } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLFoundObjects.BeginObjectQuery failed. Reason: API symbols not found"); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLFoundObjects.BeginObjectQuery failed. Reason: API symbols not found")); } }
/// <summary> /// Creates an Image Target based on the provided parameters. /// </summary> /// <param name="name">The name to give the Image Target.</param> /// <param name="image">The image that represents the target.</param> /// <param name="width">The width of the Image Target.</param> /// <param name="callback">The callback to use for any status updates of the new Image Target.</param> /// <param name="isStationary">Set this to true if the position of this Image Target in the physical world is fixed and the local geometry is planar.</param> /// <returns>The newly created Image Target.</returns> private Target CreateTarget(string name, Texture2D image, float width, MLImageTracker.Target.OnImageResultDelegate callback, bool isStationary) { if (string.IsNullOrEmpty(name)) { MLPluginLog.Error("MLImageTracker.CreateTarget failed to add MLImageTracker.Target to ImageTracker. Reason: The unique name provided is null or empty."); return(null); } if (image == null) { MLPluginLog.ErrorFormat("MLImageTracker.CreateTarget failed to add MLImageTracker.Target \"{0}\" to ImageTracker. Reason: The Texture2D image provided is null.", name); return(null); } if (callback == null) { MLPluginLog.ErrorFormat("MLImageTracker.CreateTarget failed to add MLImageTracker.Target \"{0}\" to ImageTracker. Reason: The callback function provided is null.", name); return(null); } // Check to see if a version of this image is already tracked. // Currently this only checks for unique names. if (this.targetList.FindIndex((Target target) => target.TargetSettings.Name.Equals(name)) > -1) { MLPluginLog.ErrorFormat("MLImageTracker.CreateTarget failed to add MLImageTracker.Target \"{0}\" to ImageTracker. Reason: A target with the same name is already added to this tracker.", name); return(null); } return(new Target(name, image, width, callback, this.handle, isStationary)); }
/// <summary> /// Sets the localization status based on if PCFs can currently be found /// </summary> private void SetLocalizationStatus() { if (MLPersistentCoordinateFrames.IsValidInstance()) { try { MLResult result = MLResult.Create(MLResult.Code.Ok); uint numPCFs = 0; MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFrameGetCount(MLPersistentCoordinateFrames._instance.nativeTracker, ref numPCFs); if (!MLResult.IsOK(resultCode)) { if (resultCode == MLResult.Code.PassableWorldLowMapQuality || resultCode == MLResult.Code.PassableWorldUnableToLocalize) { MLPluginLog.WarningFormat("Map quality not sufficient enough for MLPersistentCoordinateFrames.SetLocalizationStatus. Reason: {0}", MLResult.CodeToString(resultCode)); } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: {0}", MLResult.IsOK(resultCode) ? "No PCFs could be found." : MLResult.CodeToString(resultCode)); } result = MLResult.Create(resultCode, string.Format("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: {0}", MLResult.IsOK(resultCode) ? "No PCFs could be found." : MLResult.CodeToString(resultCode))); } bool foundPCFs = result.IsOk && numPCFs > 0; if (!MLPersistentCoordinateFrames.IsLocalized && foundPCFs) { MLPersistentCoordinateFrames.IsLocalized = true; MLPersistentCoordinateFrames.OnLocalized?.Invoke(IsLocalized); } else if (MLPersistentCoordinateFrames.IsLocalized && !foundPCFs) { List <PCF> allPCFs = new List <PCF>(MLPersistentCoordinateFrames._instance.mapAllPCFs.Values); MLPersistentCoordinateFrames._instance.mapTrackedPCFs.Clear(); MLPersistentCoordinateFrames._instance.mapAllPCFs.Clear(); MLPersistentCoordinateFrames.IsLocalized = false; foreach (PCF pcf in allPCFs) { pcf.Update(); } MLPersistentCoordinateFrames._instance.mapUpdatedPCFsThisFrame.Clear(); MLPersistentCoordinateFrames.OnLocalized?.Invoke(MLPersistentCoordinateFrames.IsLocalized); } } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: API symbols not found."); } } else { MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetLocalizationStatus failed. Reason: No Instance for MLPersistentCoordinateFrames."); } }
/// <summary> /// Updates the PCF's pose and state. /// </summary> /// <returns> /// MLResult.Result will be <c>MLResult.Code.Ok</c> if operation was successful. /// MLResult.Result will be <c>MLResult.Code.SnapshotPoseNotFound</c> if the PCF could not be found in the current map. /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to an invalid input parameter. /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there was a lack of privileges. /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error. /// MLResult.Result will be <c>MLResult.Code.PassableWorldLowMapQuality</c> if map quality is too low for content persistence. Continue building the map. /// MLResult.Result will be <c>MLResult.Code.PassableWorldNotFound</c> if the passed CFUID is not available. /// MLResult.Result will be <c>MLResult.Code.PassableWorldUnableToLocalize</c> if currently unable to localize into any map. Continue building the map. /// </returns> public MLResult Update() { if (MLPersistentCoordinateFrames.IsValidInstance()) { if (!MLPersistentCoordinateFrames._instance.mapUpdatedPCFsThisFrame.ContainsKey(this.cfuid)) { MLPersistentCoordinateFrames._instance.mapUpdatedPCFsThisFrame.Add(this.cfuid, this); try { MLResult result = MLResult.Create(MLResult.Code.Ok); if (MLPersistentCoordinateFrames.IsLocalized) { if (MagicLeapNativeBindings.UnityMagicLeap_TryGetPose(this.CFUID, out Pose newPose)) { this.Pose = newPose; result = this.UpdateState(); if (!result.IsOk) { MLPluginLog.ErrorFormat("PCF.Update failed because PCF.UpdateState failed. Reason: {0}", result); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, string.Format("PCF.Update failed because PCF.UpdateState failed. Reason: {0}", result))); } this.CurrentResultCode = MLResult.Code.Ok; } else { result = MLResult.Create(MLResult.Code.UnspecifiedFailure, string.Format("PCF.Update failed. Reason: No pose could be found for the CFUID {0}", this.cfuid)); this.CurrentResultCode = MLResult.Code.SnapshotPoseNotFound; } } else { this.CurrentResultCode = MLResult.Code.SnapshotPoseNotFound; } return(result); } catch (EntryPointNotFoundException) { MLPluginLog.Error("PCF.Update failed. Reason: API symbols not found."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "PCF.Update failed. Reason: API symbols not found.")); } } else { return(MLResult.Create(MLResult.Code.Ok)); } } else { MLPluginLog.ErrorFormat("PCF.Update failed. Reason: No Instance for MLPersistentCoordinateFrames."); return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "PCF.Update failed. Reason: No Instance for MLPersistentCoordinateFrames.")); } }
/// <summary> /// Update all eye data. /// </summary> protected override void Update() { List <InputDevice> devices = new List <InputDevice>(); #if UNITY_2019_3_OR_NEWER InputDevices.GetDevicesWithCharacteristics(InputDeviceCharacteristics.EyeTracking, devices); #else InputDevices.GetDevicesAtXRNode(XRNode.Head, devices); #endif foreach (var device in devices) { // Controller/EyeTracking - use the same definition, so we must check. if (device.isValid) { // Eyes if (device.TryGetFeatureValue(CommonUsages.eyesData, out UnityEngine.XR.Eyes deviceEyes)) { if (LeftEye != null) { this.UpdateEye(device, deviceEyes, MLEye.EyeType.Left); } if (RightEye != null) { this.UpdateEye(device, deviceEyes, MLEye.EyeType.Right); } // Fixation Point if (deviceEyes.TryGetFixationPoint(out Vector3 deviceFixationPoint)) { MLEyes.FixationPoint = deviceFixationPoint; } // Fixation Confidence if (device.TryGetFeatureValue(MagicLeapHeadUsages.FixationConfidence, out float deviceFixationConfidence)) { MLEyes.FixationConfidence = deviceFixationConfidence; } // Calibration Status if (device.TryGetFeatureValue(MagicLeapHeadUsages.EyeCalibrationStatus, out uint deviceCalibrationStatus)) { MLEyes.CalibrationStatus = (Calibration)deviceCalibrationStatus; } } } else { MLPluginLog.Error("MLEyes.Update failed to locate a valid tracker."); } } }
/// <summary> /// Gets the result string for a MLResult.Code. /// </summary> /// <param name="result">The MLResult.Code to be requested.</param> /// <returns>A pointer to the result string.</returns> internal static IntPtr GetResultString(MLResult.Code result) { try { return(NativeBindings.MLDispatchGetResultString(result)); } catch (System.EntryPointNotFoundException) { MLPluginLog.Error("MLDispatch.GetResultString failed. Reason: API symbols not found"); } return(IntPtr.Zero); }
/// <summary> /// Caches the current status of the this.config object. /// </summary> /// <returns>True if the this.config object was updated successfully.</returns> private bool ApplyConfig() { try { NativeBindings.UpdateConfiguration(ref this.config); } catch (EntryPointNotFoundException) { MLPluginLog.Error("MLHandTracking.ApplyConfig failed. Reason: API symbols not found"); } return(true); }