public int Update(float deltaTime, int maxEvents = int.MaxValue, bool startNewEvents = true) { if (criticalException != null) { throw criticalException; } int eventsProcessed = 0; eventQueue.NewFrame(); scheduler.NewFrame(deltaTime); try { for (int i = 0; i < maxEvents; i++) { if (!eventQueue.TryDequeue(out IEvent ev)) { break; } switch (ev) { case ICoroutineEvent cev: { eventsProcessed++; Exception ex = scheduler.Update(cev); if (ex != null) { throw ex; } } break; case FullReactorEvent rev: { if (rev.ReplyID != 0) { eventsProcessed++; if (pendingRPCWaits.TryGetValue(rev.ReplyID, out RPCWait value)) { pendingRPCWaits.Remove(rev.ReplyID); value.Trigger(rev); continue; } listener?.OnMissedReplyEvent(rev.Source, rev.Event, rev.ReplyID); continue; } if (startNewEvents) { currentEvent = rev; currentInCriticalSection = false; try { OnEvent(rev.Event); } catch (Exception ex) { if (currentInCriticalSection) { throw ex; } else { listener?.OnValidationException(ex); } } currentInCriticalSection = true; currentEvent = null; } else { eventQueue.EnqueueNextFrame(rev); } } break; default: throw new ReactorException("Invalid event type"); } } } catch (Exception ex) { listener?.OnCriticalException(ex); criticalException = ex; throw ex; } return(eventsProcessed); }