Пример #1
0
        /**
         * Processes the callbacks in the callback queue.
         */
        protected void ProcessCallbacks()
        {
            // If we are busy then nothing to do at the moment.

            RSCommandSequence safeSeq = null;

            lock (callbackQueue)
            {
                if (isBusy)
                {
                    return;
                }

                // Check if we have left-over work to do.
                if (currentCmdSequence != null)
                {
                    // Indicate that we are busy. This prevents any process_callbacks calls
                    // generated by the callbacks to be processed immediately.
                    isBusy = true;

                    // We need to split up the stored command sequence into chunks
                    // that are safe to send.
                    safeSeq = currentCmdSequence.GetSafeSubsequence();

                    // If no more commands left in m_current_cmd_sequence, set it to
                    // null. Otherwise keep it and process it again next call.
                    if (currentCmdSequence.Commands.Count == 0)
                    {
                        currentCmdSequence = null;
                    }

                    ProcessCommands(safeSeq);
                    return;
                }

                // If no callbacks in the queue, then we are done for now.
                if (callbackQueue.Count == 0)
                {
                    return;
                }

                // Indicate that we are busy.
                isBusy = true;

                // The command sequence we need to fill with commands from callbacks.
                RSCommandSequence seq = null;

                // Go through all the current callbacks (and any callbacks
                // added by those callbacks) until we hit a binary command
                // or a callback using a different stateData instance.
                int callbackCount = 0;
                while (callbackQueue.Count > 0)
                {
                    CallbackWrapper frontCallback = callbackQueue.Peek();

                    // Create the command sequence if not done yet.
                    if (seq == null)
                    {
                        seq = new RSCommandSequence(this, frontCallback.StateData);
                    }

                    // Check if the next callback is using the same StateData.
                    // If not we need to stop and process the current command
                    // sequence first.
                    if (frontCallback.StateData != seq.StateData)
                    {
                        break;
                    }

                    // Next callback is using the same state data, so call it
                    // and add the commands to seq.
                    frontCallback = callbackQueue.Dequeue();
                    try
                    {
                        frontCallback.Callback(seq);
                    }
                    catch (Exception e)
                    {
                        // Error
                        Logger.Log("error", "Error in callback: " + frontCallback + "\n- " + e.ToString());
                    }

                    callbackCount++;

                    // If we get a sequence containing binary commands we
                    // need to stop, otherwise continue calling callbacks if
                    // there are any left.
                    if (seq.ContainsRenderCommands)
                    {
                        break;
                    }
                }

                // We need to split up the command sequence into chunks that are safe to send.
                safeSeq = seq.GetSafeSubsequence();

                // If there are still commands in the sequence, then we need
                // to store it and continue processing it later.
                if (seq.Commands.Count > 0)
                {
                    currentCmdSequence = seq;
                }
            }

            ProcessCommands(safeSeq);
        }