GetEditedElementInstancesInfos now optimized as well. Forgotten because not using [R.I.P]LibraryResolver, but still XSLT compiling was hapenning on each call.
--- a/PLCControler.py Tue Feb 20 15:09:01 2018 +0100
+++ b/PLCControler.py Fri Feb 23 11:16:25 2018 +0100
@@ -31,9 +31,6 @@
import re
import datetime
from time import localtime
-from collections import OrderedDict, namedtuple
-
-from lxml import etree
import util.paths as paths
from plcopen import *
@@ -42,6 +39,7 @@
from plcopen.InstancesPathCollector import InstancesPathCollector
from plcopen.POUVariablesCollector import POUVariablesCollector
from plcopen.InstanceTagnameCollector import InstanceTagnameCollector
+from plcopen.BlockInstanceCollector import BlockInstanceCollector
from plcopen.VariableInfoCollector import VariableInfoCollector
from graphics.GraphicCommons import *
from PLCGenerator import *
@@ -50,162 +48,6 @@
ScriptDirectory = paths.AbsDir(__file__)
-# -------------------------------------------------------------------------------
-# Helpers object for generating pou block instances list
-# -------------------------------------------------------------------------------
-
-
-_Point = namedtuple("Point", ["x", "y"])
-
-_BlockInstanceInfos = namedtuple(
- "BlockInstanceInfos",
- ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
-
-_BlockSpecificValues = (
- namedtuple("BlockSpecificValues",
- ["name", "execution_order"]),
- [_StringValue, int])
-_VariableSpecificValues = (
- namedtuple("VariableSpecificValues",
- ["name", "value_type", "execution_order"]),
- [_StringValue, _StringValue, int])
-_ConnectionSpecificValues = (
- namedtuple("ConnectionSpecificValues", ["name"]),
- [_StringValue])
-
-_PowerRailSpecificValues = (
- namedtuple("PowerRailSpecificValues", ["connectors"]),
- [int])
-
-_LDElementSpecificValues = (
- namedtuple("LDElementSpecificValues",
- ["name", "negated", "edge", "storage", "execution_order"]),
- [_StringValue, _BoolValue, _StringValue, _StringValue, int])
-
-_DivergenceSpecificValues = (
- namedtuple("DivergenceSpecificValues", ["connectors"]),
- [int])
-
-_SpecificValuesTuples = {
- "comment": (
- namedtuple("CommentSpecificValues", ["content"]),
- [_StringValue]),
- "input": _VariableSpecificValues,
- "output": _VariableSpecificValues,
- "inout": _VariableSpecificValues,
- "connector": _ConnectionSpecificValues,
- "continuation": _ConnectionSpecificValues,
- "leftPowerRail": _PowerRailSpecificValues,
- "rightPowerRail": _PowerRailSpecificValues,
- "contact": _LDElementSpecificValues,
- "coil": _LDElementSpecificValues,
- "step": (
- namedtuple("StepSpecificValues", ["name", "initial", "action"]),
- [_StringValue, _BoolValue, lambda x: x]),
- "transition": (
- namedtuple("TransitionSpecificValues",
- ["priority", "condition_type", "condition", "connection"]),
- [int, _StringValue, _StringValue, lambda x: x]),
- "selectionDivergence": _DivergenceSpecificValues,
- "selectionConvergence": _DivergenceSpecificValues,
- "simultaneousDivergence": _DivergenceSpecificValues,
- "simultaneousConvergence": _DivergenceSpecificValues,
- "jump": (
- namedtuple("JumpSpecificValues", ["target"]),
- [_StringValue]),
- "actionBlock": (
- namedtuple("ActionBlockSpecificValues", ["actions"]),
- [lambda x: x]),
-}
-
-_InstanceConnectionInfos = namedtuple(
- "InstanceConnectionInfos",
- ["name", "negated", "edge", "position", "links"])
-
-_ConnectionLinkInfos = namedtuple(
- "ConnectionLinkInfos",
- ["refLocalId", "formalParameter", "points"])
-
-
-class _ActionInfos(object):
- __slots__ = ["qualifier", "type", "value", "duration", "indicator"]
-
- def __init__(self, *args):
- for attr, value in zip(self.__slots__, args):
- setattr(self, attr, value if value is not None else "")
-
- def copy(self):
- return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__])
-
-
-class BlockInstanceFactory(object):
-
- def __init__(self, block_instances):
- self.BlockInstances = block_instances
- self.CurrentInstance = None
- self.SpecificValues = None
- self.CurrentConnection = None
- self.CurrentLink = None
-
- def SetSpecificValues(self, context, *args):
- self.SpecificValues = list(args)
- self.CurrentInstance = None
- self.CurrentConnection = None
- self.CurrentLink = None
-
- def AddBlockInstance(self, context, *args):
- specific_values_tuple, specific_values_translation = \
- _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
-
- if args[0][0] == "step" and len(self.SpecificValues) < 3 or \
- args[0][0] == "transition" and len(self.SpecificValues) < 4:
- self.SpecificValues.append([None])
- elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1:
- self.SpecificValues.append([[]])
- specific_values = specific_values_tuple(*_translate_args(
- specific_values_translation, self.SpecificValues))
- self.SpecificValues = None
-
- self.CurrentInstance = _BlockInstanceInfos(
- *(_translate_args([_StringValue, int] + [float] * 4, args) +
- [specific_values, [], []]))
-
- self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
-
- def AddInstanceConnection(self, context, *args):
- connection_args = _translate_args(
- [_StringValue] * 2 + [_BoolValue, _StringValue] + [float] * 2, args)
-
- self.CurrentConnection = _InstanceConnectionInfos(
- *(connection_args[1:4] + [
- _Point(*connection_args[4:6]), []]))
-
- if self.CurrentInstance is not None:
- if connection_args[0] == "input":
- self.CurrentInstance.inputs.append(self.CurrentConnection)
- else:
- self.CurrentInstance.outputs.append(self.CurrentConnection)
- else:
- self.SpecificValues.append([self.CurrentConnection])
-
- def AddConnectionLink(self, context, *args):
- self.CurrentLink = _ConnectionLinkInfos(
- *(_translate_args([int, _StringValue], args) + [[]]))
- self.CurrentConnection.links.append(self.CurrentLink)
-
- def AddLinkPoint(self, context, *args):
- self.CurrentLink.points.append(_Point(
- *_translate_args([float] * 2, args)))
-
- def AddAction(self, context, *args):
- if len(self.SpecificValues) == 0:
- self.SpecificValues.append([[]])
- translated_args = _translate_args([_StringValue] * 5, args)
- self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
-
-
-pou_block_instances_xslt = etree.parse(
- os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt"))
# Length of the buffer
@@ -308,6 +150,7 @@
self.InstancesPathCollector = InstancesPathCollector(self)
self.POUVariablesCollector = POUVariablesCollector(self)
self.InstanceTagnameCollector = InstanceTagnameCollector(self)
+ self.BlockInstanceCollector = BlockInstanceCollector(self)
self.VariableInfoCollector = VariableInfoCollector(self)
# Reset PLCControler internal variables
@@ -2112,21 +1955,10 @@
return new_id, connections
def GetEditedElementInstancesInfos(self, tagname, debug=False):
- element_instances = OrderedDict()
element = self.GetEditedElement(tagname, debug)
if element is not None:
- factory = BlockInstanceFactory(element_instances)
-
- pou_block_instances_xslt_tree = etree.XSLT(
- pou_block_instances_xslt,
- extensions={
- ("pou_block_instances_ns", name): getattr(factory, name)
- for name in ["AddBlockInstance", "SetSpecificValues",
- "AddInstanceConnection", "AddConnectionLink",
- "AddLinkPoint", "AddAction"]})
-
- pou_block_instances_xslt_tree(element)
- return element_instances
+ return self.BlockInstanceCollector.Collect(element, debug)
+ return {}
def ClearEditedElementExecutionOrder(self, tagname):
element = self.GetEditedElement(tagname)
--- a/dialogs/ActionBlockDialog.py Tue Feb 20 15:09:01 2018 +0100
+++ b/dialogs/ActionBlockDialog.py Fri Feb 23 11:16:25 2018 +0100
@@ -29,7 +29,7 @@
import wx.lib.buttons
from controls import CustomGrid, CustomTable
-from PLCControler import _ActionInfos
+from plcopen.BlockInstanceCollector import _ActionInfos
from util.BitmapLibrary import GetBitmap
from util.TranslationCatalogs import NoTranslate
# -------------------------------------------------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plcopen/BlockInstanceCollector.py Fri Feb 23 11:16:25 2018 +0100
@@ -0,0 +1,188 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# This file is part of Beremiz.
+# See COPYING file for copyrights details.
+
+from __future__ import absolute_import
+from plcopen.XSLTModelQuery import XSLTModelQuery, _StringValue, _BoolValue, _translate_args
+from collections import OrderedDict, namedtuple
+
+# -------------------------------------------------------------------------------
+# Helpers object for generating pou block instances list
+# -------------------------------------------------------------------------------
+
+
+_Point = namedtuple("Point", ["x", "y"])
+
+_BlockInstanceInfos = namedtuple(
+ "BlockInstanceInfos",
+ ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
+
+_BlockSpecificValues = (
+ namedtuple("BlockSpecificValues",
+ ["name", "execution_order"]),
+ [_StringValue, int])
+_VariableSpecificValues = (
+ namedtuple("VariableSpecificValues",
+ ["name", "value_type", "execution_order"]),
+ [_StringValue, _StringValue, int])
+_ConnectionSpecificValues = (
+ namedtuple("ConnectionSpecificValues", ["name"]),
+ [_StringValue])
+
+_PowerRailSpecificValues = (
+ namedtuple("PowerRailSpecificValues", ["connectors"]),
+ [int])
+
+_LDElementSpecificValues = (
+ namedtuple("LDElementSpecificValues",
+ ["name", "negated", "edge", "storage", "execution_order"]),
+ [_StringValue, _BoolValue, _StringValue, _StringValue, int])
+
+_DivergenceSpecificValues = (
+ namedtuple("DivergenceSpecificValues", ["connectors"]),
+ [int])
+
+_SpecificValuesTuples = {
+ "comment": (
+ namedtuple("CommentSpecificValues", ["content"]),
+ [_StringValue]),
+ "input": _VariableSpecificValues,
+ "output": _VariableSpecificValues,
+ "inout": _VariableSpecificValues,
+ "connector": _ConnectionSpecificValues,
+ "continuation": _ConnectionSpecificValues,
+ "leftPowerRail": _PowerRailSpecificValues,
+ "rightPowerRail": _PowerRailSpecificValues,
+ "contact": _LDElementSpecificValues,
+ "coil": _LDElementSpecificValues,
+ "step": (
+ namedtuple("StepSpecificValues", ["name", "initial", "action"]),
+ [_StringValue, _BoolValue, lambda x: x]),
+ "transition": (
+ namedtuple("TransitionSpecificValues",
+ ["priority", "condition_type", "condition", "connection"]),
+ [int, _StringValue, _StringValue, lambda x: x]),
+ "selectionDivergence": _DivergenceSpecificValues,
+ "selectionConvergence": _DivergenceSpecificValues,
+ "simultaneousDivergence": _DivergenceSpecificValues,
+ "simultaneousConvergence": _DivergenceSpecificValues,
+ "jump": (
+ namedtuple("JumpSpecificValues", ["target"]),
+ [_StringValue]),
+ "actionBlock": (
+ namedtuple("ActionBlockSpecificValues", ["actions"]),
+ [lambda x: x]),
+}
+
+_InstanceConnectionInfos = namedtuple(
+ "InstanceConnectionInfos",
+ ["name", "negated", "edge", "position", "links"])
+
+_ConnectionLinkInfos = namedtuple(
+ "ConnectionLinkInfos",
+ ["refLocalId", "formalParameter", "points"])
+
+
+class _ActionInfos(object):
+ __slots__ = ["qualifier", "type", "value", "duration", "indicator"]
+
+ def __init__(self, *args):
+ for attr, value in zip(self.__slots__, args):
+ setattr(self, attr, value if value is not None else "")
+
+ def copy(self):
+ return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__])
+
+
+class BlockInstanceFactory(object):
+
+ def __init__(self, block_instances):
+ self.BlockInstances = block_instances
+ self.CurrentInstance = None
+ self.SpecificValues = None
+ self.CurrentConnection = None
+ self.CurrentLink = None
+
+ def SetSpecificValues(self, context, *args):
+ self.SpecificValues = list(args)
+ self.CurrentInstance = None
+ self.CurrentConnection = None
+ self.CurrentLink = None
+
+ def AddBlockInstance(self, context, *args):
+ specific_values_tuple, specific_values_translation = \
+ _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
+
+ if args[0][0] == "step" and len(self.SpecificValues) < 3 or \
+ args[0][0] == "transition" and len(self.SpecificValues) < 4:
+ self.SpecificValues.append([None])
+ elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1:
+ self.SpecificValues.append([[]])
+ specific_values = specific_values_tuple(*_translate_args(
+ specific_values_translation, self.SpecificValues))
+ self.SpecificValues = None
+
+ self.CurrentInstance = _BlockInstanceInfos(
+ *(_translate_args([_StringValue, int] + [float] * 4, args) +
+ [specific_values, [], []]))
+
+ self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
+
+ def AddInstanceConnection(self, context, *args):
+ connection_args = _translate_args(
+ [_StringValue] * 2 + [_BoolValue, _StringValue] + [float] * 2, args)
+
+ self.CurrentConnection = _InstanceConnectionInfos(
+ *(connection_args[1:4] + [
+ _Point(*connection_args[4:6]), []]))
+
+ if self.CurrentInstance is not None:
+ if connection_args[0] == "input":
+ self.CurrentInstance.inputs.append(self.CurrentConnection)
+ else:
+ self.CurrentInstance.outputs.append(self.CurrentConnection)
+ else:
+ self.SpecificValues.append([self.CurrentConnection])
+
+ def AddConnectionLink(self, context, *args):
+ self.CurrentLink = _ConnectionLinkInfos(
+ *(_translate_args([int, _StringValue], args) + [[]]))
+ self.CurrentConnection.links.append(self.CurrentLink)
+
+ def AddLinkPoint(self, context, *args):
+ self.CurrentLink.points.append(_Point(
+ *_translate_args([float] * 2, args)))
+
+ def AddAction(self, context, *args):
+ if len(self.SpecificValues) == 0:
+ self.SpecificValues.append([[]])
+ translated_args = _translate_args([_StringValue] * 5, args)
+ self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
+
+
+class BlockInstanceCollector(XSLTModelQuery):
+ """ object for collecting instances path list"""
+ def __init__(self, controller):
+ XSLTModelQuery.__init__(self,
+ controller,
+ "pou_block_instances.xslt",
+ [(name, self.FactoryCaller(name))
+ for name in ["AddBlockInstance",
+ "SetSpecificValues",
+ "AddInstanceConnection",
+ "AddConnectionLink",
+ "AddLinkPoint",
+ "AddAction"]])
+
+ def FactoryCaller(self, funcname):
+ def CallFactory(*args):
+ return getattr(self.factory, funcname)(*args)
+ return CallFactory
+
+ def Collect(self, root, debug):
+ element_instances = OrderedDict()
+ self.factory = BlockInstanceFactory(element_instances)
+ self._process_xslt(root, debug)
+ self.factory = None
+ return element_instances
--- a/plcopen/pou_block_instances.xslt Tue Feb 20 15:09:01 2018 +0100
+++ b/plcopen/pou_block_instances.xslt Fri Feb 23 11:16:25 2018 +0100
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="pou_block_instances_ns" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
+<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="beremiz" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
<xsl:output method="xml"/>
<xsl:template match="text()"/>
<xsl:template match="ppx:pou[ppx:body]|ppx:transition[ppx:body]|ppx:action[ppx:body]">
--- a/plcopen/pou_block_instances.ysl2 Tue Feb 20 15:09:01 2018 +0100
+++ b/plcopen/pou_block_instances.ysl2 Fri Feb 23 11:16:25 2018 +0100
@@ -1,7 +1,7 @@
include yslt_noindent.yml2
istylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
- xmlns:ns="pou_block_instances_ns"
+ xmlns:ns="beremiz"
extension-element-prefixes="ns"
exclude-result-prefixes="ns" {