pub(crate) fn step<
            FH: FrameHandler<DummyCtx<S, TimerId, SendMeta>, RecvMeta, Buf<Vec<u8>>>,
        >(
            &mut self,
        ) -> StepResult
        where
            DummyCtx<S, TimerId, SendMeta>: TimerHandler<TimerId>,
            TimerId: core::fmt::Debug,
        {
            self.collect_frames();

            let next_step = if let Some(t) = self.next_step() {
                t
            } else {
                return StepResult::new_idle();
            };

            // This assertion holds the contract that `next_step` does not
            // return a time in the past.
            assert!(next_step >= self.current_time);
            let mut ret = StepResult::new(next_step.duration_since(self.current_time), 0, 0);
            // Move time forward:
            self.current_time = next_step;
            for (_, ctx) in self.contexts.iter_mut() {
                ctx.timers.instant.time = next_step;
            }

            // Dispatch all pending frames:
            while let Some(InstantAndData(t, _)) = self.pending_frames.peek() {
                // TODO(https://github.com/rust-lang/rust/issues/53667): Remove
                // this break once let_chains is stable.
                if *t > self.current_time {
                    break;
                }
                // We can unwrap because we just peeked.
                let frame = self.pending_frames.pop().unwrap().1;
                FH::handle_frame(
                    self.context(frame.dst_context),
                    frame.meta,
                    Buf::new(frame.frame, ..),
                );
                ret.frames_sent += 1;
            }

            // Dispatch all pending timers.
            for (_, ctx) in self.contexts.iter_mut() {
                // We have to collect the timers before dispatching them, to
                // avoid an infinite loop in case handle_timer schedules another
                // timer for the same or older DummyInstant.
                let mut timers = Vec::<TimerId>::new();
                while let Some(InstantAndData(t, id)) = ctx.timers.timers.peek() {
                    // TODO(https://github.com/rust-lang/rust/issues/53667):
                    // Remove this break once let_chains is stable.
                    if *t > ctx.now() {
                        break;
                    }
                    timers.push(*id);
                    assert_ne!(ctx.timers.timers.pop(), None);
                }

                for t in timers {
                    ctx.handle_timer(t);
                    ret.timers_fired += 1;
                }
            }

            ret
        }
/// Performs a single step in network simulation.
///
/// `step` performs a single logical step in the collection of
/// `Ctx`s held by this `DummyNetwork`. A single step consists of
/// the following operations:
///
/// - All pending frames, kept in each `DummyCtx`, are mapped to their
///   destination context/device pairs and moved to an internal
///   collection of pending frames.
/// - The collection of pending timers and scheduled frames is inspected
///   and a simulation time step is retrieved, which will cause a next
///   event to trigger. The simulation time is updated to the new time.
/// - All scheduled frames whose deadline is less than or equal to the
///   new simulation time are sent to their destinations, handled using
///   the `FH` type parameter.
/// - All timer events whose deadline is less than or equal to the new
///   simulation time are fired.
///
/// If any new events are created during the operation of frames or
/// timers, they **will not** be taken into account in the current
/// `step`. That is, `step` collects all the pending events before
/// dispatching them, ensuring that an infinite loop can't be created as
/// a side effect of calling `step`.
///
/// The return value of `step` indicates which of the operations were
/// performed.
///
/// # Panics
///
/// If `DummyNetwork` was set up with a bad `links`, calls to `step` may
/// panic when trying to route frames to their context/device
/// destinations.
Performs a single step in network simulation.

All pending frames, kept in each `DummyCtx`, are mapped to their
destination context/device pairs and moved to an internal
collection of pending frames.
The collection of pending timers and scheduled frames is inspected
and a simulation time step is retrieved, which will cause a next
event to trigger. The simulation time is updated to the new time.
All scheduled frames whose deadline is less than or equal to the
new simulation time are sent to their destinations, handled using
the `FH` type parameter.
All timer events whose deadline is less than or equal to the new
simulation time are fired.

If any new events are created during the operation of frames or
timers, they **will not** be taken into account in the current
`step`. That is, `step` collects all the pending events before
dispatching them, ensuring that an infinite loop can't be created as
a side effect of calling `step`.

The return value of `step` indicates which of the operations were
performed.
Performs a single step in network simulation . All pending frames kept in each ` DummyCtx ` are mapped to their destination context / device pairs and moved to an internal collection of pending frames . The collection of pending timers and scheduled frames is inspected and a simulation time step is retrieved which will cause a next event to trigger . The simulation time is updated to the new time . All scheduled frames whose deadline is less than or equal to the new simulation time are sent to their destinations handled using the ` FH ` type parameter . All timer events whose deadline is less than or equal to the new simulation time are fired . If any new events are created during the operation of frames or timers they ** will not ** be taken into account in the current ` step ` . That is ` step ` collects all the pending events before dispatching them ensuring that an infinite loop can ' t be created as a side effect of calling ` step ` . The return value of ` step ` indicates which of the operations were performed .
pub(crate) fn step<
            FH: FrameHandler<DummyCtx<S, TimerId, SendMeta>, RecvMeta, Buf<Vec<u8>>>,
        >(
            &mut self,
        ) -> StepResult
        where
            DummyCtx<S, TimerId, SendMeta>: TimerHandler<TimerId>,
            TimerId: core::fmt::Debug,
        {
            self.collect_frames();
            let next_step = if let Some(t) = self.next_step() {
                t
            } else {
                return StepResult::new_idle();
            };
            // This assertion holds the contract that `next_step` does not
            // return a time in the past.
            assert!(next_step >= self.current_time);
            let mut ret = StepResult::new(next_step.duration_since(self.current_time), 0, 0);
            // Move time forward:
            self.current_time = next_step;
            for (_, ctx) in self.contexts.iter_mut() {
                ctx.timers.instant.time = next_step;
            }
            // Dispatch all pending frames:
            while let Some(InstantAndData(t, _)) = self.pending_frames.peek() {
                // TODO(https://github.com/rust-lang/rust/issues/53667): Remove
                // this break once let_chains is stable.
                if *t > self.current_time {
                    break;
                }
                // We can unwrap because we just peeked.
                let frame = self.pending_frames.pop().unwrap().1;
                FH::handle_frame(
                    self.context(frame.dst_context),
                    frame.meta,
                    Buf::new(frame.frame, ..),
                );
                ret.frames_sent += 1;
            }
            // Dispatch all pending timers.
            for (_, ctx) in self.contexts.iter_mut() {
                // We have to collect the timers before dispatching them, to
                // avoid an infinite loop in case handle_timer schedules another
                // timer for the same or older DummyInstant.
                let mut timers = Vec::<TimerId>::new();
                while let Some(InstantAndData(t, id)) = ctx.timers.timers.peek() {
                    // TODO(https://github.com/rust-lang/rust/issues/53667):
                    // Remove this break once let_chains is stable.
                    if *t > ctx.now() {
                        break;
                    }
                    timers.push(*id);
                    assert_ne!(ctx.timers.timers.pop(), None);
                }
                for t in timers {
                    ctx.handle_timer(t);
                    ret.timers_fired += 1;
                }
            }
            ret
        }
pub ( crate ) fn step < FH : FrameHandler < DummyCtx < S , TimerId , SendMeta > , RecvMeta , Buf < Vec < u8 > > > , > ( & mut self , ) -> StepResult where DummyCtx < S , TimerId , SendMeta > : TimerHandler < TimerId > , TimerId : core :: fmt :: Debug , { self . collect_frames ( ) ; let next_step = if let Some ( t ) = self . next_step ( ) { t } else { return StepResult :: new_idle ( ) ; } ; // This assertion holds the contract that `next_step` does not // return a time in the past. assert ! ( next_step self current_time ) ; let mut ret = StepResult :: new ( next_step . duration_since ( self . current_time ) , 0 , 0 ) ; // Move time forward: self . current_time = next_step ; for ( _ , ctx ) in self . contexts . iter_mut ( ) { ctx . timers . instant . time = next_step ; } // Dispatch all pending frames: while let Some ( InstantAndData ( t , _ ) ) = self . pending_frames . peek ( ) { // TODO(https://github.com/rust-lang/rust/issues/53667): Remove // this break once let_chains is stable. if * t > self . current_time { break ; } // We can unwrap because we just peeked. let frame = self . pending_frames . pop ( ) . unwrap ( ) . 1 ; FH :: handle_frame ( self . context ( frame . dst_context ) , frame . meta , Buf :: new ( frame . frame , .. ) , ) ; ret . frames_sent += 1 ; } // Dispatch all pending timers. for ( _ , ctx ) in self . contexts . iter_mut ( ) { // We have to collect the timers before dispatching them, to // avoid an infinite loop in case handle_timer schedules another // timer for the same or older DummyInstant. let mut timers = Vec :: < TimerId > :: new ( ) ; while let Some ( InstantAndData ( t , id ) ) = ctx . timers . timers . peek ( ) { // TODO(https://github.com/rust-lang/rust/issues/53667): // Remove this break once let_chains is stable. if * t > ctx . now ( ) { break ; } timers . push ( * id ) ; assert_ne ! ( ctx timers timers pop ( ) None ) ; } for t in timers { ctx . handle_timer ( t ) ; ret . timers_fired += 1 ; } } ret }
Performs a single step in network simulation.
Performs a single step in network simulation .
&mut self
&mut self
panics
If `DummyNetwork` was set up with a bad `links`, calls to `step` may
panic when trying to route frames to their context/device
destinations.
If ` DummyNetwork ` was set up with a bad ` links ` calls to ` step ` may panic when trying to route frames to their context / device destinations .