/** * 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); }