get_next_destination #22
No reviewers
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
priority
high
priority
low
priority
medium
question
wontfix
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
TTK4145/elevator!22
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "get_next_destination"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #13
WIP: get_next_destinationto get_next_destination@ -207,0 +212,4 @@/// Get a mutable reference to a call by index./// Only available in tests to allow setting call state without exposing internals.#[cfg(test)]unsure if this is allowed?
idk
@ -392,0 +410,4 @@/// Set the current floor for _this_ elevator./// Only available in tests to avoid exposing this as a general interface.#[cfg(test)]pub fn set_current_floor_for_test(&mut self, floor: Option<Destination>) {still unshure about this
you can in tests just do
{
self.elevators
.get_mut(&self.id)
.expect("Failed to get own elevator")
.set_current_floor(floor);
}
@ -392,0 +419,4 @@/// Set the direction for _this_ elevator./// Only available in tests to avoid exposing this as a general interface.#[cfg(test)]same as over
@ -461,0 +509,4 @@// Check for unassigned/newfor call in calls {if call.get_call_state() != CallState::New {i think you have filter functions for this
https://medium.com/@jannden/33-most-useful-rust-iterator-methods-b56eb608de76
but it works
I tried but it just gives more errors later in the code, so I'm gonna keep the for
@ -612,0 +650,4 @@/// Looks through all calls with CallState New and returns the destination of the closest one in the correct direction/// All calls are considered if the elevator is Idle/// Returns None if there is no callspub fn get_next_destination(&self) -> Option<Destination> {have you seen how the elevator is implemented in elevator controller?
i think i would take a look at it too
Implemented like this
destination: Option,
So it should be ok like this
Some small stuff
@ -612,0 +669,4 @@// Filter by direction// Elevator moving up, skip calls below current floor// Elevator moving down, skip calls above current floorif ((elevator_direction == Some(Direction::Up)) && (elevator_current_floor >= call_destination))Please tidy this up by moving things out of the if statement, currently the comment is required for me to understand the code.
e.g.
@ -834,1 +911,4 @@/// Create a SystemState with no calls/// Used for get_next_destination testsfn create_empty_system_state() -> (SystemState, SystemStateChannelHandles) {If it is only used for tests then it should be marked with
#[cfg(test)].I do also believe that this function already exists elsewhere, but I am too lazy to confirm.
I only found create_stateful_system_state, but will mark as with #[cfg(test)]
@ -612,0 +660,4 @@// Check for unassigned/newfor call in calls {if call.get_call_state() != CallState::New {This will make it so if an elevator has taken a call, then dies for some reason, that call will not be serviced.
Use clone_applicable_calls() function instead of the if
@ -612,0 +676,4 @@// Check distancelet distance = call_destination.abs_diff(elevator_current_floor);new_calls.push((call.get_call_id(), distance, call.get_direction(), call.get_destination()));Could you make a struct to represent this rather than en tuple?
The struct can be local to this function, but it would help with readability.
This is now a struct
@ -76,1 +76,4 @@}/// Function takes the floor as a Destination and returns a u8pub fn floor_number(&self) -> u8 {I am unsure if it is more proper to have this function or to implement
Into<u8>.Into is now implemented
@ -77,0 +77,4 @@/// Function takes the floor as a Destination and returns a u8pub fn floor_number(&self) -> u8 {*self as u8 + 1This is error prone and dependent on the order of the elements in the enum.
Assign values to the enum rather than using the default, inferred values.
It now matches directly
pub fn floor_number(&self) -> u8 {
match self {
Destination::Floor1 => 1,
Destination::Floor2 => 2,
Destination::Floor3 => 3,
Destination::Floor4 => 4,
}
}
Implement the use of this function in
set_destinationin the SystemState impl.@ -462,2 +474,4 @@}/// Get the [HashMap] with [ElevatorInfo] as a referencepub fn get_elevator_hashmap_as_ref(&self) -> &HashMap<ElevatorId, ElevatorInfo> {Unused function, remove.
Removed
.
@ -155,3 +156,3 @@// Busy wait until there is a call to servicelet mut num_calls_to_service: usize =/*let mut num_calls_to_service: usize =Remove commented code
removed
@ -186,0 +203,4 @@state.elevators.close_door();}tokio::time::sleep(Duration::from_millis(100)).await;Why do we sleep here?
It worked better with the delay
@ -297,1 +315,3 @@tokio::select! {let result = get_floor_destination(state.clone()).await;assert_eq!(result, None);Why do we do some computation, then assert it to be None? Could this not just be deleted?
Probably can, it is an older test and the functionality of the function has changed a little bit after. Used to have more logic after
@ -298,0 +316,4 @@let result = get_floor_destination(state.clone()).await;assert_eq!(result, None);/*tokio::select! {Delete commented out code.
deleted
@ -28,3 +28,3 @@/// testing the "real" recv data did not return consistentlyasync fn recv(sync_notification_rx: &mut mpsc::UnboundedReceiver<()>) {loop {sync_notification_rx.recv().await;The
.awaitmethod onrecv()has previosuly been shown to be unpredictable.What was the basis for changing back to it?
The loop was blocking other functions from running. I haven't tested with more elevators so I don't really know if this will still be unpredictable or if it will work fine. But it was changed because it didn't let the functions in elevator_controller run at all
It should do that with the yield in the loop.
Closed due to the creation of #42
@ -30,1 +30,3 @@loop {sync_notification_rx.recv().await;/*loop {Delete commented out code.
deleted
@ -673,0 +709,4 @@/// Returns None if there is no callspub fn get_next_destination(&self) -> (Option<Destination>, Option<Direction>) {/// One single applicable call, with necessary values to calculate next destinationstruct ApplicableCalls {Two things:
Type name is in plural, but only represents singular datapoint.
Why do we create this type rather than just using
ElevatorCall?Mostly because not all the fields are needed. Seemed easier while writing it, but if it's an easy change it can be changed
For thing 1: It is now singular
For thing 2: I could probably have used ElevatorCall. However, I don't really want to change it now, so

@ -671,2 +704,4 @@}/// Get the elevator's next [Destination]/// Looks through all calls with CallState New and returns the destination of the closest one in th e correct directionWhat's with the "in th e correct"?
looks like ive accidentally hit tab or something like that in the middle. Spaces removed now
@ -673,0 +707,4 @@/// Looks through all calls with CallState New and returns the destination of the closest one in th e correct direction/// All calls are considered if the elevator is Idle/// Returns None if there is no callspub fn get_next_destination(&self) -> (Option<Destination>, Option<Direction>) {Why do we use a tuple here instead of a struct?
Additionally, by the looks of it this function always returns either
(Some, Some)or(None, None), as such a return type ofResult<(Destination, Direction>seems more appropriate.This is true, will change and see if it breaks other things
Update: it does break other things. Probably should have from the start though
@ -237,2 +243,4 @@/// The timestamp of the last update from this elevatorlast_seen: ElevatorTime,/// The ID of the current call of the elevatorcurrent_call_id: Option<SmallUid>,:o, I see this was added here as well, very nice!
@ -141,2 +141,3 @@/// Returns the [`Destination`]async fn get_floor_destination(system_state: Arc<RwLock<SystemState>>) -> Destination {async fn get_floor_destination(system_state: Arc<RwLock<SystemState>>) -> Option<Destination> {debug!("get_floor_destination called");trace?
sure
@ -155,3 +156,3 @@// Busy wait until there is a call to servicelet mut num_calls_to_service: usize =/*let mut num_calls_to_service: usize =either way, delete unused code
@ -196,4 +216,1 @@).await;debug!("Current floor is {:?}", current_floor);move with current floor declaration
@ -186,0 +197,4 @@Some(destination) => destination,None => {// No calls - close doors before returningdebug!("No calls found, closing door");why do we need to close the door? can it not be open?
Having them stay open sometimes caused problems with deleting the call it just serviced. It's also kinda weird to have an elevator just stand there with open doors?
okay
@ -186,0 +203,4 @@state.elevators.close_door();}tokio::time::sleep(Duration::from_millis(100)).await;why sleep?
It worked better with (10/10 nap the problems away)
@ -186,0 +204,4 @@}tokio::time::sleep(Duration::from_millis(100)).await;return;add comment here to say that the whole function returns
@ -259,6 +276,7 @@ async fn elevator_controller(system_state: Arc<RwLock<SystemState>>, elevator: E/// Task for the elevator_controllerpub async fn elevator_controller_task(state: Arc<RwLock<SystemState>>, elevator: Elevator) -> ! {loop {debug!("elevator_controller_task loop iteration");remove or move to trace
Forgot to take it away before, it was just there to see if we ever went into the loop at one point (spoiler alert: we do now)
@ -300,3 +322,3 @@},_ = tokio::time::sleep(std::time::Duration::from_millis(100)) => {}}}*/remove unused code
and either fix the test, or remove the whole empty test
Will remove, as this test is written before the functionality slightly changed and it is not fully accurate anymore
@ -30,1 +30,3 @@loop {sync_notification_rx.recv().await;/*loop {why is this commented out?
Because it was busy waiting and blocking other functions from running (hence all the extra debugs all over the place). This might be an issue just when on one laptop, but we will see quickly when we do with 3
@ -673,0 +708,4 @@/// All calls are considered if the elevator is Idle/// Returns None if there is no callspub fn get_next_destination(&self) -> (Option<Destination>, Option<Direction>) {/// One single applicable call, with necessary values to calculate next destinationmove struct out?
(In reality I should have used an existing one, however I think changing to using that is gonna take time). This struct was made here because I only use it here however
not compiling