class ConveyorActor(OperatorActor): def __init__(self, conveyor: ConveyorBelt): super().__init__() self.conveyor = conveyor self.supervisor: ActorRef = None self.reminder_actor: ActorRef = None self.reminder_interval_seconds = .5 def on_start(self): self._register(self.conveyor.location, {const.UNIT_TYPE_KEY: const.CONVEYOR_TYPE}) self.supervisor = ActorRegistry().get_by_class(SupervisorActor)[0] def _handle_interact_with_plotter_message( self, message: InteractWithPlotterMessage): other_actor = message.actor_ref self.conveyor.put() other_actor.ask(PlotMessage(), block=True) self.conveyor.take() def _handle_interact_with_conveyor_message( self, message: InteractWithConveyorMessage): logging.log( logging.DEBUG, f'CVB: Conveyor at {self.conveyor.location} gives sheet to Covneyor at {message.location}' ) other_actor = message.actor_ref other_actor.ask(TurnTowardsMessage(self.conveyor.location), block=True) self.conveyor.put() self.supervisor.tell(InstructionRequest(other_actor)) def _handle_turn_towards_message(self, message: TurnTowardsMessage): location = message.location self.turn_towards(location) return def _handle_interact_with_message(self, message: InteractWithMessage): if message.action == Action.GIVE: self.conveyor.put() logging.log( logging.DEBUG, f'CVB: Conveyor at {self.conveyor.location} gave sheet to Actor at {message.location}' ) elif message.action == Action.TAKE: self.conveyor.take() logging.log( logging.DEBUG, f'CVB: Conveyor at {self.conveyor.location} took sheet from Actor at {message.location}' ) def on_receive(self, message): if isinstance(message, BaseInteractionMessage): location = message.location self.turn_towards(location) if isinstance(message, InteractWithPlotterMessage): self._handle_interact_with_plotter_message(message) elif isinstance(message, InteractWithConveyorMessage): self._handle_interact_with_conveyor_message(message) elif isinstance(message, InteractWithMessage): self._handle_interact_with_message(message) elif isinstance(message, TurnTowardsMessage): self._handle_turn_towards_message(message) # ask for further instructions if not isinstance(message, TurnTowardsMessage): self.supervisor.tell(InstructionRequest(self.actor_ref)) def turn_towards(self, location: Location): target_direction = util.relative_direction_of(location, self.conveyor.location) steps_over_cw = 0 tmp_dir = self.conveyor.direction while tmp_dir != target_direction: steps_over_cw += 1 tmp_dir = const.Direction((tmp_dir.value + 1) % 4) turn_cmd = (self.conveyor.turn_clockwise, self.conveyor.turn_counter_clockwise)[steps_over_cw > 2] while self.conveyor.direction != target_direction: turn_cmd() while self.conveyor.is_turning(): pass logging.log( logging.DEBUG, f'CVB: Conveyor at {self.conveyor.location} now facing {self.conveyor.direction}' )