pub fn bulk_read_cb<Read, F>(
		&mut self,
		reads: &[Read],
		mut on_response: F,
	) -> Result<(), WriteError>
	where
		Read: AsRef<BulkRead>,
		F: FnMut(Result<BulkData<&[u8]>, ReadError>),
	{
		for i in 0..reads.len() {
			for j in i + 1..reads.len() {
				if reads[i].as_ref().motor_id == reads[j].as_ref().motor_id {
					panic!("bulk_read_cb: motor ID {} used multiple at index {} and {}", reads[i].as_ref().motor_id, i, j)
				}
			}
		}

		self.write_instruction(packet_id::BROADCAST, instruction_id::SYNC_READ, 5 * reads.len(), |buffer| {
			for (i, read) in reads.iter().enumerate() {
				let read = read.as_ref();
				let buffer = &mut buffer[i..][..5];
				write_u8_le(&mut buffer[0..], read.motor_id);
				write_u16_le(&mut buffer[1..], read.address);
				write_u16_le(&mut buffer[3..], read.count);
			}
		})?;
		for read in reads {
			let read = read.as_ref();
			let response = self.read_status_response().and_then(|response| {
				crate::InvalidPacketId::check(response.packet_id(), read.motor_id)?;
				crate::InvalidParameterCount::check(response.parameters().len(), read.count.into())?;
				Ok(response)
			});

			match response {
				Ok(response) => on_response(Ok(BulkData {
					motor_id: read.motor_id,
					address: read.address,
					data: response.parameters(),
				})),
				Err(e) => on_response(Err(e)),
			}
		}
		Ok(())
	}
/// Synchronously read arbitrary data ranges from multiple motors in one command.
///
/// Unlike the sync read instruction, a bulk read can be used to read a different amount of data from a different address for each motor.
///
/// The `on_response` function is called for the reply from each motor.
/// If the function fails to write the instruction, an error is returned and the function is not called.
///
/// # Panics
/// The protocol forbids specifying the same motor ID multiple times.
/// This function panics if the same motor ID is used for more than one read.
Synchronously read arbitrary data ranges from multiple motors in one command.
Unlike the sync read instruction, a bulk read can be used to read a different amount of data from a different address for each motor.

The `on_response` function is called for the reply from each motor.
If the function fails to write the instruction, an error is returned and the function is not called.
Synchronously read arbitrary data ranges from multiple motors in one command . Unlike the sync read instruction a bulk read can be used to read a different amount of data from a different address for each motor . The ` on_response ` function is called for the reply from each motor . If the function fails to write the instruction an error is returned and the function is not called .
pub fn bulk_read_cb<Read, F>(
		&mut self,
		reads: &[Read],
		mut on_response: F,
	) -> Result<(), WriteError>
	where
		Read: AsRef<BulkRead>,
		F: FnMut(Result<BulkData<&[u8]>, ReadError>),
	{
		for i in 0..reads.len() {
			for j in i + 1..reads.len() {
				if reads[i].as_ref().motor_id == reads[j].as_ref().motor_id {
					panic!("bulk_read_cb: motor ID {} used multiple at index {} and {}", reads[i].as_ref().motor_id, i, j)
				}
			}
		}
		self.write_instruction(packet_id::BROADCAST, instruction_id::SYNC_READ, 5 * reads.len(), |buffer| {
			for (i, read) in reads.iter().enumerate() {
				let read = read.as_ref();
				let buffer = &mut buffer[i..][..5];
				write_u8_le(&mut buffer[0..], read.motor_id);
				write_u16_le(&mut buffer[1..], read.address);
				write_u16_le(&mut buffer[3..], read.count);
			}
		})?;
		for read in reads {
			let read = read.as_ref();
			let response = self.read_status_response().and_then(|response| {
				crate::InvalidPacketId::check(response.packet_id(), read.motor_id)?;
				crate::InvalidParameterCount::check(response.parameters().len(), read.count.into())?;
				Ok(response)
			});
			match response {
				Ok(response) => on_response(Ok(BulkData {
					motor_id: read.motor_id,
					address: read.address,
					data: response.parameters(),
				})),
				Err(e) => on_response(Err(e)),
			}
		}
		Ok(())
	}
pub fn bulk_read_cb < Read , F > ( & mut self , reads : & [ Read ] , mut on_response : F , ) -> Result < ( ) , WriteError > where Read : AsRef < BulkRead > , F : FnMut ( Result < BulkData < & [ u8 ] > , ReadError > ) , { for i in 0 .. reads . len ( ) { for j in i + 1 .. reads . len ( ) { if reads [ i ] . as_ref ( ) . motor_id == reads [ j ] . as_ref ( ) . motor_id { panic ! ( " " reads [ i ] as_ref ( ) motor_id i j ) } } } self . write_instruction ( packet_id :: BROADCAST , instruction_id :: SYNC_READ , 5 * reads . len ( ) , | buffer | { for ( i , read ) in reads . iter ( ) . enumerate ( ) { let read = read . as_ref ( ) ; let buffer = & mut buffer [ i .. ] [ .. 5 ] ; write_u8_le ( & mut buffer [ 0 .. ] , read . motor_id ) ; write_u16_le ( & mut buffer [ 1 .. ] , read . address ) ; write_u16_le ( & mut buffer [ 3 .. ] , read . count ) ; } } ) ? ; for read in reads { let read = read . as_ref ( ) ; let response = self . read_status_response ( ) . and_then ( | response | { crate :: InvalidPacketId :: check ( response . packet_id ( ) , read . motor_id ) ? ; crate :: InvalidParameterCount :: check ( response . parameters ( ) . len ( ) , read . count . into ( ) ) ? ; Ok ( response ) } ) ; match response { Ok ( response ) => on_response ( Ok ( BulkData { motor_id : read . motor_id , address : read . address , data : response . parameters ( ) , } ) ) , Err ( e ) => on_response ( Err ( e ) ) , } } Ok ( ( ) ) }
Synchronously read arbitrary data ranges from multiple motors in one command.
Synchronously read arbitrary data ranges from multiple motors in one command .
&mut self
reads
&[Read]
on_response
F
&mut self
reads
&[Read]
on_response
F
panics
The protocol forbids specifying the same motor ID multiple times.
This function panics if the same motor ID is used for more than one read.
The protocol forbids specifying the same motor ID multiple times . This function panics if the same motor ID is used for more than one read .