/// <summary>
        /// Process pending requests and call the callback specified in the startup config.
        /// </summary>
        private void ProcessPendingQueriesAsync()
        {
            MLThreadDispatch.ScheduleWork(() =>
            {
                try
                {
                    if (_instance.pendingQueries.Count > 0)
                    {
                        // Process each individual pending query to get updated status.
                        foreach (ulong handle in _instance.pendingQueries.Keys)
                        {
                            // Request the update.
                            MLResult.Code resultCode = NativeBindings.MLFoundObjectGetResultCount(_instance.handle, handle, out uint resultCount);

                            if (MLResult.IsOK(resultCode))
                            {
                                FoundObject[] foundObjects = new FoundObject[resultCount];

                                // For each found object in the query, get it's reference and property values from the API.
                                for (uint objectIndex = 0; objectIndex < resultCount; objectIndex++)
                                {
                                    NativeBindings.FoundObjectNative nativeFoundObject = new NativeBindings.FoundObjectNative();

                                    // Get the object reference from the API.
                                    resultCode = NativeBindings.MLFoundObjectGetResult(_instance.handle, handle, objectIndex, ref nativeFoundObject);

                                    if (MLResult.IsOK(resultCode))
                                    {
                                        Dictionary <string, string> properties = new Dictionary <string, string>();

                                        // Get the object's properties from the API.
                                        if (nativeFoundObject.PropertyCount > 0)
                                        {
                                            NativeBindings.PropertyNative objectProperty = new NativeBindings.PropertyNative();
                                            for (uint propertyIndex = 0; propertyIndex < nativeFoundObject.PropertyCount; propertyIndex++)
                                            {
                                                resultCode = NativeBindings.MLFoundObjectGetProperty(_instance.handle, nativeFoundObject.Id, propertyIndex, ref objectProperty);

                                                if (MLResult.IsOK(resultCode))
                                                {
                                                    properties.Add(new string(objectProperty.Key).Replace("\0", string.Empty).ToLower(), new string(objectProperty.Value).Replace("\0", string.Empty));
                                                }
                                                else
                                                {
                                                    MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to get found object property. Reason: {0}", MLResult.CodeToString(resultCode));
                                                }
                                            }
                                        }

                                        FoundObject foundObject = nativeFoundObject.Data;

                                        // Currently the only valid object properties are: label, score
                                        foundObject.Label         = properties.ContainsKey("label") ? properties["label"] : string.Empty;
                                        foundObject.Confidence    = properties.ContainsKey("score") ? Convert.ToSingle(properties["score"]) : 0f;
                                        foundObjects[objectIndex] = foundObject;
                                    }
                                    else
                                    {
                                        MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to get found object. Reason: {0}", MLResult.CodeToString(resultCode));
                                        _instance.errorQueries.Add(handle);
                                    }
                                }

                                if (!_instance.completedQueries.Contains(handle))
                                {
                                    _instance.completedQueries.Add(handle);
                                }

                                Query query = _instance.pendingQueries[handle];

                                // Dispatch list of found objects back to main.
                                MLThreadDispatch.ScheduleMain(() =>
                                {
                                    query.Callback(MLResult.Create(resultCode), foundObjects);
                                });
                            }
                            else
                            {
                                MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to query found objects. Reason: {0}", MLResult.CodeToString(resultCode));
                                _instance.errorQueries.Add(handle);
                            }
                        }

                        foreach (ulong handle in _instance.errorQueries)
                        {
                            _instance.pendingQueries.TryRemove(handle, out Query q);
                        }

                        _instance.errorQueries.Clear();

                        foreach (ulong handle in _instance.completedQueries)
                        {
                            _instance.pendingQueries.TryRemove(handle, out Query q);
                        }

                        _instance.completedQueries.Clear();
                    }
                }
                catch (System.EntryPointNotFoundException)
                {
                    MLPluginLog.Error("MLFoundObjects.ProcessPendingQueries failed. Reason: API symbols not found");
                }

                return(true);
            });
        }
Exemple #2
0
        /// <summary>
        /// Process pending requests and call the callback specified in the startup config.
        /// </summary>
        private void ProcessPendingQueries()
        {
            try
            {
                if (_instance.pendingQueries.Count > 0)
                {
                    // Process each individual pending query to get updated status.
                    foreach (ulong handle in _instance.pendingQueries.Keys)
                    {
                        NativeBindings.Query query = _instance.pendingQueries[handle];

                        // Request the update.
                        MLResult.Code resultCode = NativeBindings.MLFoundObjectGetResultCount(_instance.tracker, handle, out uint resultCount);

                        if (MLResult.IsOK(resultCode))
                        {
                            for (uint objectIndex = 0; objectIndex < resultCount; objectIndex++)
                            {
                                NativeBindings.FoundObjectNative foundObject = new NativeBindings.FoundObjectNative();

                                resultCode = NativeBindings.MLFoundObjectGetResult(_instance.tracker, handle, objectIndex, ref foundObject);
                                if (MLResult.IsOK(resultCode))
                                {
                                    List <KeyValuePair <string, string> > properties = null;
                                    if (foundObject.PropertyCount > 0)
                                    {
                                        NativeBindings.PropertyNative objectProperty = new NativeBindings.PropertyNative();
                                        properties = new List <KeyValuePair <string, string> >();

                                        for (uint propertyIndex = 0; propertyIndex < foundObject.PropertyCount; propertyIndex++)
                                        {
                                            resultCode = NativeBindings.MLFoundObjectGetProperty(_instance.tracker, foundObject.Id, propertyIndex, ref objectProperty);
                                            if (MLResult.IsOK(resultCode))
                                            {
                                                properties.Add(new KeyValuePair <string, string>(new string(objectProperty.Key), new string(objectProperty.Value)));
                                            }
                                            else
                                            {
                                                MLPluginLog.ErrorFormat("MLFoundObject.ProcessPendingQueries failed to get found object property. Reason: {0}", MLResult.CodeToString(resultCode));
                                            }
                                        }
                                    }

                                    if (!_instance.completedQueries.ContainsKey(handle))
                                    {
                                        _instance.completedQueries.Add(handle, new List <Tuple <NativeBindings.Query, FoundObject, List <KeyValuePair <string, string> > > >());
                                    }

                                    _instance.completedQueries[handle].Add(new Tuple <NativeBindings.Query, FoundObject, List <KeyValuePair <string, string> > >(
                                                                               query,
                                                                               new FoundObject
                                    {
                                        Id            = MLConvert.ToUnity(foundObject.Id),
                                        PropertyCount = foundObject.PropertyCount,
                                        Position      = MLConvert.ToUnity(foundObject.Position),
                                        Rotation      = MLConvert.ToUnity(foundObject.Rotation),
                                        Size          = MLConvert.ToUnity(foundObject.Size)
                                    },
                                                                               properties));
                                }
                                else
                                {
                                    MLPluginLog.ErrorFormat("MLFoundObject.ProcessPendingQueries failed to get found object. Reason: {0}", MLResult.CodeToString(resultCode));
                                    _instance.errorQueries.Add(handle);
                                }
                            }
                        }
                        else
                        {
                            MLPluginLog.ErrorFormat("MLFoundObjects.ProcessPendingQueries failed to query found objects. Reason: {0}", MLResult.CodeToString(resultCode));
                            _instance.errorQueries.Add(handle);
                        }
                    }

                    foreach (ulong handle in _instance.errorQueries)
                    {
                        _instance.pendingQueries.Remove(handle);
                    }

                    _instance.errorQueries.Clear();

                    foreach (KeyValuePair <ulong, List <Tuple <NativeBindings.Query, FoundObject, List <KeyValuePair <string, string> > > > > handle in _instance.completedQueries)
                    {
                        for (int i = 0; i < handle.Value.Count; ++i)
                        {
                            handle.Value[i].Item1.Callback(handle.Value[i].Item2, handle.Value[i].Item3);
                        }

                        _instance.pendingQueries.Remove(handle.Key);
                    }

                    _instance.completedQueries.Clear();
                }
            }
            catch (System.EntryPointNotFoundException)
            {
                MLPluginLog.Error("MLFoundObjects.ProcessPendingQueries failed. Reason: API symbols not found");
            }
        }