public void AddCallback(CallbackInterface cb, long owner_id)
        {
            CallbackInfo info = new CallbackInfo {
                Callback = cb, RemovalId = owner_id
            };

            //ROS.Debug()( $"[{ThisNode.Name}] CallbackQueue@{cbthread.ManagedThreadId}: Add callback owner: {owner_id} {cb.ToString()}" );

            lock ( mutex )
            {
                if (!enabled)
                {
                    return;
                }
                callbacks.Add(info);
                //ROS.Debug()( $"[{ThisNode.Name}] CallbackQueue@{cbthread.ManagedThreadId}: Added" );
                count++;
            }
            lock ( idInfoMutex )
            {
                if (!idInfo.ContainsKey(owner_id))
                {
                    idInfo.Add(owner_id, new IDInfo {
                        calling_rw_mutex = new object(), id = owner_id
                    });
                }
            }
            NotifyOne();
        }
Esempio n. 2
0
        private CallOneResult CallOne(TLS tls)
        {
            CallbackInfo info = tls.Head;

            if (info == null)
            {
                return(CallOneResult.Empty);
            }
            IDInfo idinfo = null;

            idinfo = GetIdInfo(info.RemovalId);
            if (idinfo != null)
            {
                CallbackInterface cb = info.Callback;
                lock (idinfo.calling_rw_mutex)
                {
                    CallbackInterface.CallResult result = CallbackInterface.CallResult.Invalid;
                    tls.SpliceOut(info);
                    if (!info.MarkedForRemoval)
                    {
                        try
                        {
                            result = cb.Call();
                        }
                        catch (Exception ex)
                        {
                            ROS.Error()($"[{ThisNode.Name}] Error during callback. Error: {ex.ToString()}, Stacktrace: {ex.StackTrace}");
                        }
                    }
                    if (result == CallbackInterface.CallResult.TryAgain && !info.MarkedForRemoval)
                    {
                        lock ( mutex )
                        {
                            callbacks.Add(info);
                            count++;
                        }
                        return(CallOneResult.TryAgain);
                    }
                }
                return(CallOneResult.Called);
            }
            CallbackInfo cbi = tls.SpliceOut(info);

            if (cbi != null)
            {
                cbi.Callback.Call();
            }
            return(CallOneResult.Called);
        }
Esempio n. 3
0
        public Subscriber Subscribe(string topic, string messageType, int queueSize, CallbackInterface cb, bool allowConcurrentCallbacks = false)
        {
            if (callbackQueue == null)
            {
                callbackQueue = ROS.GlobalCallbackQueue;
            }

            var message = RosMessage.Generate(messageType);
            var ops     = new SubscribeOptions(topic, message.MessageType, message.MD5Sum(), queueSize, new SubscriptionCallbackHelper <RosMessage>(message.MessageType, cb.SendEvent))
            {
                callback_queue             = callbackQueue,
                allow_concurrent_callbacks = allowConcurrentCallbacks
            };

            ops.callback_queue.AddCallback(cb);
            return(subscribe(ops));
        }
Esempio n. 4
0
        /// <summary>
        ///     Creates a subscriber
        /// </summary>
        /// <typeparam name="M">Topic type</typeparam>
        /// <param name="topic">Topic name</param>
        /// <param name="queueSize">How many messages to qeueue</param>
        /// <param name="cb">Function to fire when a message is recieved</param>
        /// <param name="allowConcurrentCallbacks">Probably breaks things when true</param>
        /// <returns>A subscriber</returns>
        public Subscriber subscribe <M>(string topic, int queueSize, CallbackInterface cb, bool allowConcurrentCallbacks)
            where M : RosMessage, new()
        {
            if (callbackQueue == null)
            {
                callbackQueue = ROS.GlobalCallbackQueue;
            }

            var ops = new SubscribeOptions <M>(topic, queueSize, cb.SendEvent)
            {
                callback_queue             = callbackQueue,
                allow_concurrent_callbacks = allowConcurrentCallbacks
            };

            ops.callback_queue.AddCallback(cb);
            return(subscribe(ops));
        }
        public CallOneResult CallOne(TLS tls)
        {
            CallbackInfo info = tls.Head;

            if (info == null)
            {
                return(CallOneResult.Empty);
            }
            IDInfo idinfo = null;

            idinfo = GetIdInfo(info.RemovalId);
            if (idinfo != null)
            {
                CallbackInterface cb = info.Callback;
                lock (idinfo.calling_rw_mutex)
                {
                    CallbackInterface.CallResult result = CallbackInterface.CallResult.Invalid;
                    tls.SpliceOut(info);
                    if (!info.MarkedForRemoval)
                    {
                        result = cb.Call();
                    }
                    if (result == CallbackInterface.CallResult.TryAgain && !info.MarkedForRemoval)
                    {
                        lock ( mutex )
                        {
                            callbacks.Add(info);
                            count++;
                        }
                        return(CallOneResult.TryAgain);
                    }
                }
                return(CallOneResult.Called);
            }
            CallbackInfo cbi = tls.SpliceOut(info);

            if (cbi != null)
            {
                cbi.Callback.Call();
            }
            return(CallOneResult.Called);
        }
Esempio n. 6
0
        public void AddCallback(CallbackInterface cb, object owner = null)
        {
            if (cb == null)
            {
                throw new ArgumentNullException(nameof(cb));
            }

            lock (gate)
            {
                if (!enabled)
                {
                    return;
                }

                callbacks.Add(new CallbackInfo {
                    Callback = cb, Owner = owner
                });
                NotifyOne();
            }
        }
Esempio n. 7
0
        public CallOneResult CallOne()
        {
            CallbackInfo call;

            lock (gate)
            {
                if (!enabled)
                {
                    return(CallOneResult.Disabled);
                }

                if (callbacks.Count == 0)
                {
                    return(CallOneResult.Empty);
                }

                call = callbacks.Front;
                callbacks.PopFront();

                calling += 1;
            }

            var owner = call.Owner;

            try
            {
                CallbackInterface cb = call.Callback;
                var result           = CallbackInterface.CallResult.Invalid;

                if (owner != null)
                {
                    Monitor.Enter(owner);
                }

                try
                {
                    result = cb.Call();
                }
                catch (Exception ex)
                {
                    ROS.Error()("Error during callback. Error: %s, Stacktrace: %s", ex.ToString(), ex.StackTrace);
                }

                if (result == CallbackInterface.CallResult.TryAgain)
                {
                    lock (gate)
                    {
                        callbacks.PushBack(call);
                    }
                    return(CallOneResult.TryAgain);
                }

                return(CallOneResult.Called);
            }
            finally
            {
                if (owner != null)
                {
                    Monitor.Exit(owner);
                }

                lock (gate)
                {
                    calling -= 1;
                }
            }
        }
 public void AddCallback(CallbackInterface callback)
 {
     AddCallback(callback, callback.Uid);
 }
Esempio n. 9
0
 protected ISubscriptionCallbackHelper(CallbackInterface Callback)
 {
     this.Callback = Callback;
 }
Esempio n. 10
0
 public SubscriptionCallbackHelper(CallbackInterface q)
     : base(q)
 {
 }
Esempio n. 11
0
 public Subscriber Subscribe(string topic, string messageType, int queueSize, CallbackInterface cb, bool allowConcurrentCallbacks = false) =>
 SubscribeAsync(topic, messageType, queueSize, cb, allowConcurrentCallbacks).Result;
Esempio n. 12
0
 public Subscriber Subscribe <M>(string topic, int queueSize, CallbackInterface cb, bool allowConcurrentCallbacks) where M : RosMessage, new() =>
 SubscribeAsync <M>(topic, queueSize, cb, allowConcurrentCallbacks).Result;
Esempio n. 13
0
        public async Task <Subscriber> SubscribeAsync(string topic, string messageType, int queueSize, CallbackInterface cb, bool allowConcurrentCallbacks = false)
        {
            if (callbackQueue == null)
            {
                callbackQueue = ROS.GlobalCallbackQueue;
            }

            var message = RosMessage.Generate(messageType);
            var ops     = new SubscribeOptions(topic, message.MessageType, message.MD5Sum(), queueSize, new SubscriptionCallbackHelper <RosMessage>(message.MessageType, cb.SendEvent))
            {
                CallbackQueue            = callbackQueue,
                AllowConcurrentCallbacks = allowConcurrentCallbacks
            };

            ops.CallbackQueue.AddCallback(cb, ops.CallbackHelper);
            return(await SubscribeAsync(ops).ConfigureAwait(false));
        }
Esempio n. 14
0
        /// <summary>
        ///     Creates a subscriber
        /// </summary>
        /// <typeparam name="M">Topic type</typeparam>
        /// <param name="topic">Topic name</param>
        /// <param name="queueSize">How many messages to qeueue</param>
        /// <param name="cb">Function to fire when a message is recieved</param>
        /// <param name="allowConcurrentCallbacks">Probably breaks things when true</param>
        /// <returns>A subscriber</returns>
        public async Task <Subscriber> SubscribeAsync <M>(string topic, int queueSize, CallbackInterface cb, bool allowConcurrentCallbacks)
            where M : RosMessage, new()
        {
            if (callbackQueue == null)
            {
                callbackQueue = ROS.GlobalCallbackQueue;
            }

            var ops = new SubscribeOptions <M>(topic, queueSize, cb.SendEvent)
            {
                CallbackQueue            = callbackQueue,
                AllowConcurrentCallbacks = allowConcurrentCallbacks
            };

            ops.CallbackQueue.AddCallback(cb, ops.CallbackHelper);
            return(await SubscribeAsync(ops).ConfigureAwait(false));
        }