/// <summary> /// Process blocking event. /// </summary> /// <param name="targetObjectId">Target object id for which to process.</param> /// <param name="eventToProcess">Event to be processed.</param> /// <param name="caller">Parent Network id from which this is called. Set NetworkId.Invalid if no parent.</param> /// <param name="eventHandler">Handler for processing event.</param> /// <param name="isBlockedHandler">Handler for checking if processing of events should be canceled.</param> /// <param name="postProcessQueue">Queue that should be post processed.</param> /// <returns>True if was success.</returns> private bool ProcessBlockingEvent(NetworkId targetObjectId, MyBufferedEvent eventToProcess, NetworkId caller, Handler eventHandler, IsBlockedHandler isBlockedHandler, ref Queue <NetworkId> postProcessQueue) { if (isBlockedHandler(eventToProcess.TargetObjectId, eventToProcess.BlockingObjectId)) { return(false); } bool result = this.TryLiftBarrier(eventToProcess.BlockingObjectId); // If success than we can proceede with blocking event. // If not, that means barrier holder have some events before actual barrier. Then we need to process that first. if (result) { eventHandler(eventToProcess.Stream, eventToProcess.TargetObjectId, eventToProcess.BlockingObjectId, eventToProcess.EventId, eventToProcess.Sender); if (eventToProcess.BlockingObjectId.IsValid && !eventToProcess.BlockingObjectId.Equals(caller)) { postProcessQueue.Enqueue(eventToProcess.BlockingObjectId); } } else { bool success = ProcessEvents(eventToProcess.BlockingObjectId, eventHandler, isBlockedHandler, targetObjectId); return(success); } return(true); }
/// <summary> /// Tries to process events for prarticular object id (network id). /// </summary> /// <param name="targetObjectId">Target object network id.</param> /// <param name="eventHandler">Handler for processing events.</param> /// <param name="isBlockedHandler">Handler for checking if processing of events should be canceled.</param> /// <param name="caller">Parent Network id from which this is called. Set NetworkId.Invalid if no parent.</param> /// <returns>True if all sucessfull.</returns> public bool ProcessEvents(NetworkId targetObjectId, Handler eventHandler, IsBlockedHandler isBlockedHandler, NetworkId caller) { // Unblock it for now (may be blocked again in the handler). MyObjectEventsBuffer eventsBuffer; bool fullyProcessed = false; // Queue of network objects that have to be processed at the end. Queue <NetworkId> postProcessQueue = new Queue <NetworkId>(); if (!m_buffer.TryGetValue(targetObjectId, out eventsBuffer)) { return(false); } // Already processing so no need to do again. if (eventsBuffer.IsProcessing) { return(false); } eventsBuffer.IsProcessing = true; bool result = this.ProcessEventsBuffer(eventsBuffer, targetObjectId, eventHandler, isBlockedHandler, caller, ref postProcessQueue); eventsBuffer.IsProcessing = false; if (!result) { return(false); } // If there are still events here that means it is still blocked! if (eventsBuffer.Events.Count == 0) { ReturnList(eventsBuffer.Events); eventsBuffer.Events = null; fullyProcessed = true; } // If not fully processed it has to stay in the buffer if (fullyProcessed) { m_buffer.Remove(targetObjectId); } // Process network objects that are outside of processing stack. while (postProcessQueue.Count > 0) { NetworkId netId = postProcessQueue.Dequeue(); ProcessEvents(netId, eventHandler, isBlockedHandler, targetObjectId); } return(true); }
private bool ProcessEventsBuffer(MyObjectEventsBuffer eventsBuffer, NetworkId targetObjectId, Handler eventHandler, IsBlockedHandler isBlockedHandler, NetworkId caller, ref Queue <NetworkId> postProcessQueue) { while (eventsBuffer.Events.Count > 0) { bool success = true; MyBufferedEvent e = eventsBuffer.Events.Peek(); if (e.IsBarrier) { success = this.ProcessBarrierEvent(targetObjectId, e, eventHandler, isBlockedHandler); } else { // If you have blocking entity id, than try to check if it has your barrier on top, // If yes, than process yourself, and put the other id to process later. // If no, than process that id first, as you cannot proceede without it. if (e.BlockingObjectId.IsValid) { success = this.ProcessBlockingEvent(targetObjectId, e, caller, eventHandler, isBlockedHandler, ref postProcessQueue); } else { eventHandler(e.Stream, e.TargetObjectId, e.BlockingObjectId, e.EventId, e.Sender); } if (success) { e.Stream.CheckTerminator(); eventsBuffer.Events.Dequeue(); ReturnEvent(e); } } if (!success) { eventsBuffer.IsProcessing = false; return(false); } } return(true); }
/// <summary> /// Process barrier event. /// </summary> /// <param name="targetObjectId">Target of the barrier event.</param> /// <param name="eventToProcess">Event to process.</param> /// <param name="eventHandler">Handler for processing event.</param> /// <param name="isBlockedHandler">Handler for checking if processing of events should be canceled.</param> /// <returns>True if success.</returns> private bool ProcessBarrierEvent(NetworkId targetObjectId, MyBufferedEvent eventToProcess, Handler eventHandler, IsBlockedHandler isBlockedHandler) { if (isBlockedHandler(eventToProcess.TargetObjectId, eventToProcess.BlockingObjectId)) { return(false); } bool success = ProcessEvents(eventToProcess.BlockingObjectId, eventHandler, isBlockedHandler, targetObjectId); return(success); }
/// <summary> /// Process blocking event. /// </summary> /// <param name="targetObjectId">Target object id for which to process.</param> /// <param name="eventToProcess">Event to be processed.</param> /// <param name="caller">Parent Network id from which this is called. Set NetworkId.Invalid if no parent.</param> /// <param name="eventHandler">Handler for processing event.</param> /// <param name="isBlockedHandler">Handler for checking if processing of events should be canceled.</param> /// <param name="postProcessQueue">Queue that should be post processed.</param> /// <returns>True if was success.</returns> private bool ProcessBlockingEvent(NetworkId targetObjectId, MyBufferedEvent eventToProcess, NetworkId caller, Handler eventHandler, IsBlockedHandler isBlockedHandler, ref Queue<NetworkId> postProcessQueue) { if (isBlockedHandler(eventToProcess.TargetObjectId, eventToProcess.BlockingObjectId)) { return false; } bool result = this.TryLiftBarrier(eventToProcess.BlockingObjectId); // If success than we can proceede with blocking event. // If not, that means barrier holder have some events before actual barrier. Then we need to process that first. if (result) { eventHandler(eventToProcess.Stream, eventToProcess.TargetObjectId, eventToProcess.BlockingObjectId, eventToProcess.EventId, eventToProcess.Sender); if (eventToProcess.BlockingObjectId.IsValid && !eventToProcess.BlockingObjectId.Equals(caller)) postProcessQueue.Enqueue(eventToProcess.BlockingObjectId); } else { bool success = ProcessEvents(eventToProcess.BlockingObjectId, eventHandler, isBlockedHandler, targetObjectId); return success; } return true; }
/// <summary> /// Process barrier event. /// </summary> /// <param name="targetObjectId">Target of the barrier event.</param> /// <param name="eventToProcess">Event to process.</param> /// <param name="eventHandler">Handler for processing event.</param> /// <param name="isBlockedHandler">Handler for checking if processing of events should be canceled.</param> /// <returns>True if success.</returns> private bool ProcessBarrierEvent(NetworkId targetObjectId, MyBufferedEvent eventToProcess, Handler eventHandler, IsBlockedHandler isBlockedHandler) { if (isBlockedHandler(eventToProcess.TargetObjectId, eventToProcess.BlockingObjectId)) { return false; } bool success = ProcessEvents(eventToProcess.BlockingObjectId, eventHandler, isBlockedHandler, targetObjectId); return success; }
private bool ProcessEventsBuffer(MyObjectEventsBuffer eventsBuffer, NetworkId targetObjectId, Handler eventHandler, IsBlockedHandler isBlockedHandler, NetworkId caller, ref Queue<NetworkId> postProcessQueue) { while (eventsBuffer.Events.Count > 0) { bool success = true; MyBufferedEvent e = eventsBuffer.Events.Peek(); if (e.IsBarrier) { success = this.ProcessBarrierEvent(targetObjectId, e, eventHandler, isBlockedHandler); } else { // If you have blocking entity id, than try to check if it has your barrier on top, // If yes, than process yourself, and put the other id to process later. // If no, than process that id first, as you cannot proceede without it. if (e.BlockingObjectId.IsValid) { success = this.ProcessBlockingEvent(targetObjectId, e, caller, eventHandler, isBlockedHandler, ref postProcessQueue); } else { eventHandler(e.Stream, e.TargetObjectId, e.BlockingObjectId, e.EventId, e.Sender); } if (success) { eventsBuffer.Events.Dequeue(); ReturnEvent(e); } } if(!success) { eventsBuffer.IsProcessing = false; return false; } } return true; }
/// <summary> /// Tries to process events for prarticular object id (network id). /// </summary> /// <param name="targetObjectId">Target object network id.</param> /// <param name="eventHandler">Handler for processing events.</param> /// <param name="isBlockedHandler">Handler for checking if processing of events should be canceled.</param> /// <param name="caller">Parent Network id from which this is called. Set NetworkId.Invalid if no parent.</param> /// <returns>True if all sucessfull.</returns> public bool ProcessEvents(NetworkId targetObjectId, Handler eventHandler, IsBlockedHandler isBlockedHandler, NetworkId caller) { // Unblock it for now (may be blocked again in the handler). MyObjectEventsBuffer eventsBuffer; bool fullyProcessed = false; // Queue of network objects that have to be processed at the end. Queue<NetworkId> postProcessQueue = new Queue<NetworkId>(); if (!m_buffer.TryGetValue(targetObjectId, out eventsBuffer)) return false; // Already processing so no need to do again. if (eventsBuffer.IsProcessing) return false; eventsBuffer.IsProcessing = true; bool result = this.ProcessEventsBuffer(eventsBuffer, targetObjectId, eventHandler, isBlockedHandler, caller, ref postProcessQueue); eventsBuffer.IsProcessing = false; if (!result) { return false; } // If there are still events here that means it is still blocked! if (eventsBuffer.Events.Count == 0) { ReturnList(eventsBuffer.Events); eventsBuffer.Events = null; fullyProcessed = true; } // If not fully processed it has to stay in the buffer if(fullyProcessed) m_buffer.Remove(targetObjectId); // Process network objects that are outside of processing stack. while (postProcessQueue.Count > 0) { NetworkId netId = postProcessQueue.Dequeue(); ProcessEvents(netId, eventHandler, isBlockedHandler, targetObjectId); } return true; }