# HG changeset patch # User Edouard Tisserant # Date 1623838502 -7200 # Node ID 5f7445b582d4eb2d89361f5ba5554542490a8227 # Parent 3cc5663af196c74f3ba689bd456018b543686292 IDE: Fixed variable traces graphs RingBuffers. Removed an apparently useless wxCallAfter in trend graph that was leading to pydeadobject exception on wxGTK when double-clicking. diff -r 3cc5663af196 -r 5f7445b582d4 controls/DebugVariablePanel/DebugVariableItem.py --- a/controls/DebugVariablePanel/DebugVariableItem.py Mon Jun 14 16:48:39 2021 +0200 +++ b/controls/DebugVariablePanel/DebugVariableItem.py Wed Jun 16 12:15:02 2021 +0200 @@ -384,7 +384,7 @@ ticks = self.Data.view[:, 0] # Get nearest data from tick - idx = np.searchsorted(ticks, tick) + idx = min(np.searchsorted(ticks, tick), self.Data.count - 1) # Adjust data index according to constraint if adjust < 0 and ticks[idx] > tick and idx > 0 or \ diff -r 3cc5663af196 -r 5f7445b582d4 controls/DebugVariablePanel/DebugVariablePanel.py --- a/controls/DebugVariablePanel/DebugVariablePanel.py Mon Jun 14 16:48:39 2021 +0200 +++ b/controls/DebugVariablePanel/DebugVariablePanel.py Wed Jun 16 12:15:02 2021 +0200 @@ -357,9 +357,13 @@ # Force refresh if graph is fixed because range of data received # is too small to fill data range selected - if self.Fixed and \ - self.Ticks.view[-1] - self.Ticks.view[0] < self.CurrentRange: - self.Force = True + if self.Fixed : + if self.Ticks.view[-1] - self.Ticks.view[0] < self.CurrentRange: + self.Force = True + if self.Ticks.view[0] > self.StartTick: + self.StartTick = self.Ticks.view[0] + self.Force = True + self.HasNewData = False self.RefreshView() @@ -388,14 +392,14 @@ if self.CursorTick is not None: cursor_tick = max(self.Ticks.view[0], min(self.CursorTick + move, self.Ticks.view[-1])) - cursor_tick_idx = np.searchsorted(self.Ticks.view, cursor_tick) + cursor_tick_idx = min(np.searchsorted(self.Ticks.view, cursor_tick), self.Ticks.count - 1) if self.Ticks.view[cursor_tick_idx] == self.CursorTick: cursor_tick_idx = max(0, min(cursor_tick_idx + abs(move) // move, self.Ticks.count - 1)) self.CursorTick = self.Ticks.view[cursor_tick_idx] self.StartTick = max( - self.Ticks.view[np.searchsorted(self.Ticks.view, self.CursorTick + self.CurrentRange)], + self.Ticks.view[min(np.searchsorted(self.Ticks.view, self.CursorTick - self.CurrentRange), self.Ticks.count - 1)], min(self.StartTick, self.CursorTick)) self.RefreshCanvasPosition() self.UpdateCursorTick() @@ -605,7 +609,7 @@ def SetCanvasPosition(self, tick): tick = max(self.Ticks.view[0], min(tick, self.Ticks.view[-1] - self.CurrentRange)) - self.StartTick = self.Ticks.view[np.searchsorted(self.Ticks.view, tick)] + self.StartTick = self.Ticks.view[min(np.searchsorted(self.Ticks.view, tick), self.Ticks.count - 1)] self.Fixed = True self.RefreshCanvasPosition() self.ForceRefresh() @@ -631,7 +635,7 @@ tick = self.StartTick + self.CurrentRange / 2. new_start_tick = min(tick - (tick - self.StartTick) * self.CurrentRange / current_range, self.Ticks.view[-1] - self.CurrentRange) - self.StartTick = self.Ticks.view[np.searchsorted(self.Ticks.view, - new_start_tick)] + self.StartTick = self.Ticks.view[min(np.searchsorted(self.Ticks.view, new_start_tick), self.Ticks.count - 1)] self.Fixed = new_start_tick < self.Ticks.view[-1] - self.CurrentRange self.ForceRefresh() diff -r 3cc5663af196 -r 5f7445b582d4 controls/DebugVariablePanel/DebugVariableTextViewer.py --- a/controls/DebugVariablePanel/DebugVariableTextViewer.py Mon Jun 14 16:48:39 2021 +0200 +++ b/controls/DebugVariablePanel/DebugVariableTextViewer.py Wed Jun 16 12:15:02 2021 +0200 @@ -270,7 +270,7 @@ """ # Execute callback on button under mouse pointer if it exists x, y = event.GetPosition() - wx.CallAfter(self.HandleButton, x, y) + self.HandleButton(x, y) event.Skip() def OnLeftDClick(self, event): diff -r 3cc5663af196 -r 5f7445b582d4 controls/DebugVariablePanel/RingBuffer.py --- a/controls/DebugVariablePanel/RingBuffer.py Mon Jun 14 16:48:39 2021 +0200 +++ b/controls/DebugVariablePanel/RingBuffer.py Wed Jun 16 12:15:02 2021 +0200 @@ -12,36 +12,32 @@ class RingBuffer(object): - def __init__(self, width=None, size=65536, padding=None): + def __init__(self, width=None, size=131072, padding=None): self.size = size self.padding = size if padding is None else padding shape = (self.size+self.padding,) if width : shape += (width,) self.buffer = np.zeros(shape) - self.counter = 0 - self.full = False + self.cursor = 0 def append(self, data): """this is an O(n) operation""" - data = data[-self.padding:] + data = data[-self.size:] n = len(data) - if self.remaining < n: self.compact() - self.buffer[self.counter+self.size:][:n] = data - self.counter += n + if self.size + self.padding - self.cursor < n: + self.compact() + self.buffer[self.cursor:][:n] = data + self.cursor += n @property def count(self): - return self.counter if not self.full else self.size - - @property - def remaining(self): - return self.padding-self.counter + return min(self.size, self.cursor) @property def view(self): """this is always an O(1) operation""" - return self.buffer[self.counter:][:self.size] + return self.buffer[max(0, self.cursor - self.size):][:self.count] def compact(self): """ @@ -49,7 +45,6 @@ and this cost is amortized over the whole padding space """ print 'compacting' - self.buffer[:self.size] = self.view - self.counter = 0 - self.full = True + self.buffer[:self.count] = self.view + self.cursor -= self.size