# HG changeset patch # User Laurent Bessard # Date 1381746524 -7200 # Node ID debc97102b2361a695dc419e71cde9297d6dab70 # Parent e9e17d3b284998ff30f631809a1bd4a65972ae63 Added support for optimizing debug, preventing to filling buffers with only the last value for debug data consumers that only show the current state diff -r e9e17d3b2849 -r debc97102b23 ProjectController.py --- a/ProjectController.py Mon Oct 14 10:49:04 2013 +0200 +++ b/ProjectController.py Mon Oct 14 12:28:44 2013 +0200 @@ -1202,7 +1202,7 @@ self.IECdebug_lock.acquire() IECPathsToPop = [] for IECPath,data_tuple in self.IECdebug_datas.iteritems(): - WeakCallableDict, data_log, status, fvalue = data_tuple + WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple if len(WeakCallableDict) == 0: # Callable Dict is empty. # This variable is not needed anymore! @@ -1268,10 +1268,13 @@ WeakKeyDictionary(), # Callables [], # Data storage [(tick, data),...] "Registered", # Variable status - None] # Forced value + None, + buffer_list] # Forced value self.IECdebug_datas[IECPath] = IECdebug_data - - IECdebug_data[0][callableobj]=(args, kwargs) + else: + IECdebug_data[4] |= buffer_list + + IECdebug_data[0][callableobj]=(buffer_list, args, kwargs) self.IECdebug_lock.release() @@ -1286,6 +1289,12 @@ IECdebug_data[0].pop(callableobj,None) if len(IECdebug_data[0]) == 0: self.IECdebug_datas.pop(IECPath) + else: + IECdebug_data[4] = reduce( + lambda x, y: x|y, + [buffer_list for buffer_list,args,kwargs + in IECdebug_data[0].itervalues()], + False) self.IECdebug_lock.release() self.ReArmDebugRegisterTimer() @@ -1330,16 +1339,15 @@ def CallWeakcallables(self, IECPath, function_name, *cargs): data_tuple = self.IECdebug_datas.get(IECPath, None) if data_tuple is not None: - WeakCallableDict, data_log, status, fvalue = data_tuple + WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple #data_log.append((debug_tick, value)) - for weakcallable,(args,kwargs) in WeakCallableDict.iteritems(): + for weakcallable,(buffer_list,args,kwargs) in WeakCallableDict.iteritems(): function = getattr(weakcallable, function_name, None) if function is not None: - if status == "Forced" and cargs[1] == fvalue: - function(*(cargs + (True,) + args), **kwargs) + if buffer_list: + function(*(cargs + args), **kwargs) else: - function(*(cargs + args), **kwargs) - # This will block thread if more than one call is waiting + function(*(tuple([lst[-1] for lst in cargs]) + args), **kwargs) def GetTicktime(self): return self._Ticktime @@ -1365,13 +1373,19 @@ #print [dict.keys() for IECPath, (dict, log, status, fvalue) in self.IECdebug_datas.items()] if plc_status == "Started": self.IECdebug_lock.acquire() - if len(debug_vars) == len(self.DebugValuesBuffers): + if (len(debug_vars) == len(self.DebugValuesBuffers) and + len(debug_vars) == len(self.TracedIECPath)): if debug_getvar_retry > DEBUG_RETRIES_WARN: self.logger.write(_("... debugger recovered\n")) debug_getvar_retry = 0 - for values_buffer, value in zip(self.DebugValuesBuffers, debug_vars): - if value is not None: - values_buffer.append(value) + for IECPath, values_buffer, value in zip(self.TracedIECPath, self.DebugValuesBuffers, debug_vars): + IECdebug_data = self.IECdebug_datas.get(IECPath, None) + if IECdebug_data is not None and value is not None: + forced = IECdebug_data[2:4] == ["Forced", value] + if not IECdebug_data[4] and len(values_buffer) > 0: + values_buffer[-1] = (value, forced) + else: + values_buffer.append((value, forced)) self.DebugTicks.append(debug_tick) self.IECdebug_lock.release() if debug_getvar_retry == DEBUG_RETRIES_WARN: diff -r e9e17d3b2849 -r debc97102b23 controls/DebugVariablePanel/DebugVariableItem.py --- a/controls/DebugVariablePanel/DebugVariableItem.py Mon Oct 14 10:49:04 2013 +0200 +++ b/controls/DebugVariablePanel/DebugVariableItem.py Mon Oct 14 12:28:44 2013 +0200 @@ -232,14 +232,14 @@ return (self.Parent.IsNumType(self.VariableType) or self.VariableType in ["STRING", "WSTRING"]) - def NewValues(self, ticks, values, forced=False): + def NewValues(self, ticks, values): """ Function called by debug thread when a new debug value is available @param tick: PLC tick when value was captured @param value: Value captured @param forced: Forced flag, True if value is forced (default: False) """ - DebugDataConsumer.NewValues(self, ticks, values, forced, raw=None) + DebugDataConsumer.NewValues(self, ticks[-1], values[-1], raw=None) if self.Data is not None: @@ -247,13 +247,12 @@ last_raw_data = (self.RawData[-1] if len(self.RawData) > 0 else None) last_raw_data_idx = len(self.RawData) - 1 - - # Translate forced flag to float for storing in Data table - forced_value = float(forced) data_values = [] - for tick, value in zip(ticks, values): - + for tick, (value, forced) in zip(ticks, values): + # Translate forced flag to float for storing in Data table + forced_value = float(forced) + # String data value is CRC num_value = (binascii.crc32(value) & STRING_CRC_MASK if self.VariableType in ["STRING", "WSTRING"] diff -r e9e17d3b2849 -r debc97102b23 controls/DebugVariablePanel/DebugVariablePanel.py --- a/controls/DebugVariablePanel/DebugVariablePanel.py Mon Oct 14 10:49:04 2013 +0200 +++ b/controls/DebugVariablePanel/DebugVariablePanel.py Mon Oct 14 12:28:44 2013 +0200 @@ -754,7 +754,7 @@ if idx is None: idx = len(self.GraphicPanels) item = DebugVariableItem(self, iec_path, True) - result = self.AddDataConsumer(iec_path.upper(), item) + result = self.AddDataConsumer(iec_path.upper(), item, True) if result is not None or force: self.Freeze() @@ -832,7 +832,7 @@ if source_item is None: item = DebugVariableItem(self, source, True) if item.IsNumVariable(): - result = self.AddDataConsumer(source.upper(), item) + result = self.AddDataConsumer(source.upper(), item, True) if result is not None or force: source_item = item if source_item is not None and source_item.IsNumVariable(): diff -r e9e17d3b2849 -r debc97102b23 controls/DebugVariablePanel/DebugVariableViewer.py --- a/controls/DebugVariablePanel/DebugVariableViewer.py Mon Oct 14 10:49:04 2013 +0200 +++ b/controls/DebugVariablePanel/DebugVariableViewer.py Mon Oct 14 12:28:44 2013 +0200 @@ -149,7 +149,7 @@ self.RemoveItem(item) else: # If it exist, resubscribe and refresh data type - self.ParentWindow.AddDataConsumer(iec_path.upper(), item) + self.ParentWindow.AddDataConsumer(iec_path.upper(), item, True) item.RefreshVariableType() def ResetItemsData(self): diff -r e9e17d3b2849 -r debc97102b23 editors/DebugViewer.py --- a/editors/DebugViewer.py Mon Oct 14 10:49:04 2013 +0200 +++ b/editors/DebugViewer.py Mon Oct 14 12:28:44 2013 +0200 @@ -106,7 +106,7 @@ # Subscribe tick to new data producer if producer is not None: - producer.SubscribeDebugIECVariable("__tick__", self) + producer.SubscribeDebugIECVariable("__tick__", self, True) # Unsubscribe tick from old data producer if getattr(self, "DataProducer", None) is not None: @@ -134,7 +134,7 @@ # Save inhibit flag self.Inhibited = inhibit - def AddDataConsumer(self, iec_path, consumer): + def AddDataConsumer(self, iec_path, consumer, buffer_list=False): """ Subscribe data consumer to DataProducer @param iec_path: Path in PLC of variable needed by data consumer @@ -148,7 +148,7 @@ # Subscribe data consumer to DataProducer result = self.DataProducer.SubscribeDebugIECVariable( - iec_path, consumer) + iec_path, consumer, buffer_list) if result is not None and consumer != self: # Store data consumer if successfully subscribed and inform @@ -178,7 +178,7 @@ """ # Subscribe tick if needed if self.SubscribeTick and self.Debug and self.DataProducer is not None: - self.DataProducer.SubscribeDebugIECVariable("__tick__", self) + self.DataProducer.SubscribeDebugIECVariable("__tick__", self, True) def UnsubscribeAllDataConsumers(self, tick=True): """ diff -r e9e17d3b2849 -r debc97102b23 graphics/DebugDataConsumer.py --- a/graphics/DebugDataConsumer.py Mon Oct 14 10:49:04 2013 +0200 +++ b/graphics/DebugDataConsumer.py Mon Oct 14 12:28:44 2013 +0200 @@ -197,7 +197,7 @@ """ self.DataType = data_type - def NewValues(self, ticks, values, forced=False, raw="BOOL"): + def NewValues(self, tick, values, raw="BOOL"): """ Function called by debug thread when a new debug value is available @param tick: PLC tick when value was captured @@ -205,7 +205,7 @@ @param forced: Forced flag, True if value is forced (default: False) @param raw: Data type of values not translated (default: 'BOOL') """ - tick, value = ticks[-1], values[-1] + value, forced = values # Translate value to IEC literal if self.DataType != raw: