On 17-12-21, 10:12, Bartosz Golaszewski wrote:
No, it's a different story altogether. In C the buffer allocates memory for events and when you "get" an event, you only have a pointer to the memory space in the buffer that you must not free. But you can "copy" an event with gpiod_edge_event_copy() which returns you a deep copy of the event that will survive the parent and that must be freed with gpiod_edge_event_free(). This is done so that by default we try to limit the number of allocations (as there can be a lot of events) unless the user decides to manually copy the event.
In C++ I used that mechanism together with the buffer's const event_get() and event's copy assignment operator. "Getting" an event returns a const reference to the event (still in buffer's memory) but copying it triggers a deep copy. The memory management is of course handled by the destructor.
This is not used in Python as speed is no longer a concern and we'd be creating new python objects anyway. But in Rust, I think it makes sense to reuse this mechanism.
Ahh, what about this then, it just caches all the values when the event is requested ?
pub struct EdgeEvent { event_type: LineEdgeEvent, timestamp: Duration, line_offset: u32, global_seqno: u64, line_seqno: u64, }
impl EdgeEvent { /// Get an event stored in the buffer. pub fn new(buffer: &EdgeEventBuffer, index: u64) -> Result<Self> { let event = unsafe { bindings::gpiod_edge_event_buffer_get_event(buffer.buffer(), index) }; if event.is_null() { return Err(Error::OperationFailed( "Gpio EdgeEvent buffer-get-event", IoError::last(), )); }
Ok(Self { event_type: LineEdgeEvent::new(unsafe { bindings::gpiod_edge_event_get_event_type(event) } as u32)?,
timestamp: Duration::from_nanos(unsafe { bindings::gpiod_edge_event_get_timestamp(event) }),
line_offset: unsafe { bindings::gpiod_edge_event_get_line_offset(event) }, global_seqno: unsafe { bindings::gpiod_edge_event_get_global_seqno(event) }, line_seqno: unsafe { bindings::gpiod_edge_event_get_line_seqno(event) }, }) }
/// Get the event type. pub fn get_event_type(&self) -> LineEdgeEvent { self.event_type }
/// Get the timestamp of the event. pub fn get_timestamp(&self) -> Duration { self.timestamp }
/// Get the offset of the line on which the event was triggered. pub fn get_line_offset(&self) -> u32 { self.line_offset }
/// Get the global sequence number of this event. /// /// Returns sequence number of the event relative to all lines in the /// associated line request. pub fn get_global_seqno(&self) -> u64 { self.global_seqno }
/// Get the event sequence number specific to concerned line. /// /// Returns sequence number of the event relative to this line within the /// lifetime of the associated line request. pub fn get_line_seqno(&self) -> u64 { self.line_seqno } }