# HG changeset patch # User Laurent Bessard # Date 1380669695 -7200 # Node ID c1e6c712cc350e70f5dc806e581e163454980658 # Parent 204ef2daa33cc00e140fdcb42c9adb5f7be88e71 Replaced old graphic viewer blocks loading process by xslt stylesheet diff -r 204ef2daa33c -r c1e6c712cc35 PLCControler.py --- a/PLCControler.py Tue Oct 01 09:24:02 2013 +0200 +++ b/PLCControler.py Wed Oct 02 01:21:35 2013 +0200 @@ -29,6 +29,7 @@ import os,sys,re import datetime from time import localtime +from collections import OrderedDict, namedtuple from plcopen import * from graphics.GraphicCommons import * @@ -308,7 +309,6 @@ self.process_children(context, tagname_infos) tagname = etree.Element('tagname') tagname.text = self.GetTagName(tagname_infos) - print etree.tostring(tagname) try: output_parent.append(tagname) except: @@ -346,6 +346,158 @@ os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt")) #------------------------------------------------------------------------------- +# Helpers object for generating pou block instances list +#------------------------------------------------------------------------------- + +_BoolValue = lambda x: x in ["true", "0"] + +_Point = namedtuple("Point", ["x", "y"]) + +_BlockInstanceInfos = namedtuple("BlockInstanceInfos", + ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"]) + +_BlockSpecificValues = ( + namedtuple("BlockSpecificValues", + ["name", "execution_order"]), + [str, int]) +_VariableSpecificValues = ( + namedtuple("VariableSpecificValues", + ["name", "value_type", "execution_order"]), + [str, str, int]) +_ConnectionSpecificValues = ( + namedtuple("ConnectionSpecificValues", ["name"]), + [str]) + +_PowerRailSpecificValues = ( + namedtuple("PowerRailSpecificValues", ["connectors"]), + [int]) + +_LDElementSpecificValues = ( + namedtuple("LDElementSpecificValues", + ["name", "negated", "edge", "storage", "execution_order"]), + [str, _BoolValue, str, str, int]) + +_DivergenceSpecificValues = ( + namedtuple("DivergenceSpecificValues", ["connectors"]), + [int]) + +_SpecificValuesTuples = { + "comment": ( + namedtuple("CommentSpecificValues", ["content"]), + [str]), + "input": _VariableSpecificValues, + "output": _VariableSpecificValues, + "inout": _VariableSpecificValues, + "connector": _ConnectionSpecificValues, + "continuation": _ConnectionSpecificValues, + "leftPowerRail": _PowerRailSpecificValues, + "rightPowerRail": _PowerRailSpecificValues, + "contact": _LDElementSpecificValues, + "coil": _LDElementSpecificValues, + "step": ( + namedtuple("StepSpecificValues", ["name", "initial", "action"]), + [str, _BoolValue, lambda x: x]), + "transition": ( + namedtuple("TransitionSpecificValues", + ["priority", "condition_type", "condition", "connection"]), + [int, str, str, lambda x: x]), + "selectionDivergence": _DivergenceSpecificValues, + "selectionConvergence": _DivergenceSpecificValues, + "simultaneousDivergence": _DivergenceSpecificValues, + "simultaneousConvergence": _DivergenceSpecificValues, + "jump": ( + namedtuple("JumpSpecificValues", ["target"]), + [str]), + "actionBlock": ( + namedtuple("ActionBlockSpecificValues", ["actions"]), + [lambda x: x]), +} + +_InstanceConnectionInfos = namedtuple("InstanceConnectionInfos", + ["name", "negated", "edge", "position", "links"]) + +_ConnectionLinkInfos = namedtuple("ConnectionLinkInfos", + ["refLocalId", "formalParameter", "points"]) + +_ActionInfos = namedtuple("ActionInfos", + ["qualifier", "type", "value", "duration", "indicator"]) + +def _translate_args(translations, args): + return [translate(arg[0]) if len(arg) > 0 else None + for translate, arg in + zip(translations, args)] + +class BlockInstanceFactory: + + 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([str] + [int] * 5, args) + + [specific_values, [], []])) + + self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance + + def AddInstanceConnection(self, context, *args): + connection_args = _translate_args( + [str, str, _BoolValue, str, int, int], 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, str], args) + [[]])) + self.CurrentConnection.links.append(self.CurrentLink) + + def AddLinkPoint(self, context, *args): + self.CurrentLink.points.append(_Point( + *_translate_args([int, int], args))) + + def AddAction(self, context, *args): + if len(self.SpecificValues) == 0: + self.SpecificValues.append([[]]) + translated_args = _translate_args([str] * 5, args) + if translated_args[0] is None: + translated_args[0] = "" + self.SpecificValues[0][0].append(_ActionInfos(*translated_args)) + +pou_block_instances_xslt = etree.parse( + os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) + +#------------------------------------------------------------------------------- # Undo Buffer for PLCOpenEditor #------------------------------------------------------------------------------- @@ -636,7 +788,6 @@ return None def GetPouVariables(self, tagname, debug = False): - vars = [] pou_type = None project = self.GetProject(debug) if project is not None: @@ -1616,8 +1767,8 @@ basetype_type = basetype.getLocalTag() return (basetype.getname() if basetype_type == "derived" else basetype_type.upper()) - elif basetype_content_type == "derived": - return basetype_content_type.getname() + return (basetype_content.getname() if basetype_content_type == "derived" + else basetype_content_type.upper()) return None # Return Base Type of given possible derived type @@ -2289,25 +2440,22 @@ return new_id, connections - # Return the current pou editing instances idx - def GetEditedElementInstancesIds(self, tagname, debug = False): + def GetEditedElementInstancesInfos(self, tagname, debug = False): + element_instances = OrderedDict() element = self.GetEditedElement(tagname, debug) if element is not None: - return element.getinstancesIds() - return [] - - # Return the current pou editing informations - def GetEditedElementInstanceInfos(self, tagname, id, debug = False): - element = self.GetEditedElement(tagname, debug) - if element is not None: - instance = element.getinstance(id) - if instance is not None: - infos = instance.getinfos() - if infos["type"] in ["input", "output", "inout"]: - var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug) - infos["specific_values"]["value_type"] = var_type - return infos - return 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 def ClearEditedElementExecutionOrder(self, tagname): element = self.GetEditedElement(tagname) @@ -2319,29 +2467,6 @@ if element is not None: element.compileexecutionOrder() - # Return the variable type of the given pou - def GetEditedElementVarValueType(self, tagname, varname, debug = False): - project = self.GetProject(debug) - if project is not None: - words = tagname.split("::") - if words[0] in ["P","T","A"]: - pou = self.Project.getpou(words[1]) - if pou is not None: - if words[0] == "T" and varname == words[2]: - return "BOOL" - if words[1] == varname: - return self.GetPouInterfaceReturnType(pou)[0] - for type, varlist in pou.getvars(): - for var in varlist.getvariable(): - if var.getname() == varname: - vartype_content = var.gettype().getcontent() - vartype_content_type = vartype_content.getLocalTag() - if vartype_content_type == "derived": - return vartype_content.getname() - else: - return vartype_content_type.upper() - return None - def SetConnectionWires(self, connection, connector): wires = connector.GetWires() idx = 0 diff -r 204ef2daa33c -r c1e6c712cc35 editors/Viewer.py --- a/editors/Viewer.py Tue Oct 01 09:24:02 2013 +0200 +++ b/editors/Viewer.py Wed Oct 02 01:21:35 2013 +0200 @@ -84,36 +84,38 @@ def GetVariableCreationFunction(variable_type): def variableCreationFunction(viewer, id, specific_values): return FBD_Variable(viewer, variable_type, - specific_values["name"], - specific_values["value_type"], + specific_values.name, + specific_values.value_type, id, - specific_values["executionOrder"]) + specific_values.execution_order) return variableCreationFunction def GetConnectorCreationFunction(connector_type): def connectorCreationFunction(viewer, id, specific_values): return FBD_Connector(viewer, connector_type, - specific_values["name"], id) + specific_values.name, id) return connectorCreationFunction def commentCreationFunction(viewer, id, specific_values): - return Comment(viewer, specific_values["content"], id) + return Comment(viewer, specific_values.content, id) def GetPowerRailCreationFunction(powerrail_type): def powerRailCreationFunction(viewer, id, specific_values): return LD_PowerRail(viewer, powerrail_type, id, - specific_values["connectors"]) + specific_values.connectors) return powerRailCreationFunction +MODIFIER_VALUE = lambda x: x if x is not None else 'none' + CONTACT_TYPES = {(True, "none"): CONTACT_REVERSE, (False, "rising"): CONTACT_RISING, (False, "falling"): CONTACT_FALLING} def contactCreationFunction(viewer, id, specific_values): - contact_type = CONTACT_TYPES.get((specific_values.get("negated", False), - specific_values.get("edge", "none")), + contact_type = CONTACT_TYPES.get((specific_values.negated, + MODIFIER_VALUE(specific_values.edge)), CONTACT_NORMAL) - return LD_Contact(viewer, contact_type, specific_values["name"], id) + return LD_Contact(viewer, contact_type, specific_values.name, id) COIL_TYPES = {(True, "none", "none"): COIL_REVERSE, (False, "none", "set"): COIL_SET, @@ -122,38 +124,38 @@ (False, "falling", "none"): COIL_FALLING} def coilCreationFunction(viewer, id, specific_values): - coil_type = COIL_TYPES.get((specific_values.get("negated", False), - specific_values.get("edge", "none"), - specific_values.get("storage", "none")), + coil_type = COIL_TYPES.get((specific_values.negated, + MODIFIER_VALUE(specific_values.edge), + MODIFIER_VALUE(specific_values.storage)), COIL_NORMAL) - return LD_Coil(viewer, coil_type, specific_values["name"], id) + return LD_Coil(viewer, coil_type, specific_values.name, id) def stepCreationFunction(viewer, id, specific_values): - step = SFC_Step(viewer, specific_values["name"], - specific_values.get("initial", False), id) - if specific_values.get("action", None): + step = SFC_Step(viewer, specific_values.name, + specific_values.initial, id) + if specific_values.action is not None: step.AddAction() connector = step.GetActionConnector() - connector.SetPosition(wx.Point(*specific_values["action"]["position"])) + connector.SetPosition(wx.Point(*specific_values.action.position)) return step def transitionCreationFunction(viewer, id, specific_values): - transition = SFC_Transition(viewer, specific_values["condition_type"], - specific_values.get("condition", None), - specific_values["priority"], id) + transition = SFC_Transition(viewer, specific_values.condition_type, + specific_values.condition, + specific_values.priority, id) return transition def GetDivergenceCreationFunction(divergence_type): def divergenceCreationFunction(viewer, id, specific_values): return SFC_Divergence(viewer, divergence_type, - specific_values["connectors"], id) + specific_values.connectors, id) return divergenceCreationFunction def jumpCreationFunction(viewer, id, specific_values): - return SFC_Jump(viewer, specific_values["target"], id) + return SFC_Jump(viewer, specific_values.target, id) def actionBlockCreationFunction(viewer, id, specific_values): - return SFC_ActionBlock(viewer, specific_values["actions"], id) + return SFC_ActionBlock(viewer, specific_values.actions, id) ElementCreationFunctions = { "input": GetVariableCreationFunction(INPUT), @@ -1089,13 +1091,10 @@ self.ResetBuffer() instance = {} # List of ids of already loaded blocks - ids = self.Controler.GetEditedElementInstancesIds(self.TagName, debug = self.Debug) + instances = self.Controler.GetEditedElementInstancesInfos(self.TagName, debug = self.Debug) # Load Blocks until they are all loaded - while len(ids) > 0: - instance = self.Controler.GetEditedElementInstanceInfos( - self.TagName, ids.popitem(0)[0], debug = self.Debug) - if instance is not None: - self.loadInstance(instance, ids, selection) + while len(instances) > 0: + self.loadInstance(instances.popitem(0)[1], instances, selection) if (selection is not None and isinstance(self.SelectedElement, Graphic_Group)): @@ -1221,119 +1220,119 @@ self.SelectedElement = group # Load instance from given informations - def loadInstance(self, instance, ids, selection): - self.current_id = max(self.current_id, instance["id"]) - creation_function = ElementCreationFunctions.get(instance["type"], None) + def loadInstance(self, instance, remaining_instances, selection): + self.current_id = max(self.current_id, instance.id) + creation_function = ElementCreationFunctions.get(instance.type, None) connectors = {"inputs" : [], "outputs" : []} - specific_values = instance["specific_values"] + specific_values = instance.specific_values if creation_function is not None: - element = creation_function(self, instance["id"], specific_values) + element = creation_function(self, instance.id, specific_values) if isinstance(element, SFC_Step): - if len(instance["inputs"]) > 0: + if len(instance.inputs) > 0: element.AddInput() else: element.RemoveInput() - if len(instance["outputs"]) > 0: + if len(instance.outputs) > 0: element.AddOutput() - if isinstance(element, SFC_Transition) and specific_values["condition_type"] == "connection": + if isinstance(element, SFC_Transition) and specific_values.condition_type == "connection": connector = element.GetConditionConnector() - self.CreateWires(connector, instance["id"], specific_values["connection"]["links"], ids, selection) + self.CreateWires(connector, instance.id, specific_values.connection.links, remaining_instances, selection) else: executionControl = False - for input in instance["inputs"]: - if input["negated"]: - connectors["inputs"].append((input["name"], None, "negated")) - elif input["edge"]: - connectors["inputs"].append((input["name"], None, input["edge"])) + for input in instance.inputs: + input_edge = MODIFIER_VALUE(input.edge) + if input.negated: + connectors["inputs"].append((input.name, None, "negated")) + elif input_edge: + connectors["inputs"].append((input.name, None, input_edge)) else: - connectors["inputs"].append((input["name"], None, "none")) - for output in instance["outputs"]: - if output["negated"]: - connectors["outputs"].append((output["name"], None, "negated")) - elif output["edge"]: - connectors["outputs"].append((output["name"], None, output["edge"])) + connectors["inputs"].append((input.name, None, "none")) + for output in instance.outputs: + output_edge = MODIFIER_VALUE(output.edge) + if output.negated: + connectors["outputs"].append((output.name, None, "negated")) + elif output_edge: + connectors["outputs"].append((output.name, None, output_edge)) else: - connectors["outputs"].append((output["name"], None, "none")) + connectors["outputs"].append((output.name, None, "none")) if len(connectors["inputs"]) > 0 and connectors["inputs"][0][0] == "EN": connectors["inputs"].pop(0) executionControl = True if len(connectors["outputs"]) > 0 and connectors["outputs"][0][0] == "ENO": connectors["outputs"].pop(0) executionControl = True - if specific_values["name"] is None: - specific_values["name"] = "" - element = FBD_Block(self, instance["type"], specific_values["name"], - instance["id"], len(connectors["inputs"]), + block_name = specific_values.name if specific_values.name is not None else "" + element = FBD_Block(self, instance.type, block_name, + instance.id, len(connectors["inputs"]), connectors=connectors, executionControl=executionControl, - executionOrder=specific_values["executionOrder"]) + executionOrder=specific_values.execution_order) if isinstance(element, Comment): self.AddComment(element) else: self.AddBlock(element) connectors = element.GetConnectors() - element.SetPosition(instance["x"], instance["y"]) - element.SetSize(instance["width"], instance["height"]) - for i, output_connector in enumerate(instance["outputs"]): + element.SetPosition(instance.x, instance.y) + element.SetSize(instance.width, instance.height) + for i, output_connector in enumerate(instance.outputs): + connector_pos = wx.Point(*output_connector.position) if isinstance(element, FBD_Block): - connector = element.GetConnector( - wx.Point(*output_connector["position"]), - output_name = output_connector["name"]) + connector = element.GetConnector(connector_pos, + output_name = output_connector.name) elif i < len(connectors["outputs"]): connector = connectors["outputs"][i] else: connector = None if connector is not None: - if output_connector.get("negated", False): + if output_connector.negated: connector.SetNegated(True) - if output_connector.get("edge", "none") != "none": - connector.SetEdge(output_connector["edge"]) + if output_connector.edge is not None: + connector.SetEdge(output_connector.edge) if connectors["outputs"].index(connector) == i: - connector.SetPosition(wx.Point(*output_connector["position"])) - for i, input_connector in enumerate(instance["inputs"]): + connector.SetPosition(connector_pos) + for i, input_connector in enumerate(instance.inputs): + connector_pos = wx.Point(*input_connector.position) if isinstance(element, FBD_Block): - connector = element.GetConnector( - wx.Point(*input_connector["position"]), - input_name = input_connector["name"]) + connector = element.GetConnector(connector_pos, + input_name = input_connector.name) elif i < len(connectors["inputs"]): connector = connectors["inputs"][i] else: connector = None if connector is not None: if connectors["inputs"].index(connector) == i: - connector.SetPosition(wx.Point(*input_connector["position"])) - if input_connector.get("negated", False): + connector.SetPosition(connector_pos) + if input_connector.negated: connector.SetNegated(True) - if input_connector.get("edge", "none") != "none": - connector.SetEdge(input_connector["edge"]) - if not self.CreateWires(connector, instance["id"], input_connector["links"], ids, selection): + if input_connector.edge is not None: + connector.SetEdge(input_connector.edge) + if not self.CreateWires(connector, instance.id, input_connector.links, remaining_instances, selection): element.RefreshModel() element.RefreshConnectors() - if selection is not None and selection[0].get(instance["id"], False): + if selection is not None and selection[0].get(instance.id, False): self.SelectInGroup(element) - def CreateWires(self, start_connector, id, links, ids, selection=None): + def CreateWires(self, start_connector, id, links, remaining_instances, selection=None): links_connected = True for link in links: - refLocalId = link["refLocalId"] + refLocalId = link.refLocalId if refLocalId is None: links_connected = False continue - if ids.pop(refLocalId, False): - new_instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, refLocalId, debug = self.Debug) - if new_instance is not None: - self.loadInstance(new_instance, ids, selection) + new_instance = remaining_instances.pop(refLocalId, None) + if new_instance is not None: + self.loadInstance(new_instance, remaining_instances, selection) connected = self.FindElementById(refLocalId) if connected is None: links_connected = False continue - points = link["points"] + points = link.points end_connector = connected.GetConnector( - wx.Point(points[-1][0], points[-1][1]) + wx.Point(points[-1].x, points[-1].y) if len(points) > 0 else wx.Point(0, 0), - link["formalParameter"]) + link.formalParameter) if end_connector is not None: if len(points) > 0: wire = Wire(self) diff -r 204ef2daa33c -r c1e6c712cc35 graphics/SFC_Objects.py --- a/graphics/SFC_Objects.py Tue Oct 01 09:24:02 2013 +0200 +++ b/graphics/SFC_Objects.py Wed Oct 02 01:21:35 2013 +0200 @@ -1894,18 +1894,18 @@ self.ColSize = [0, 0, 0] min_height = 0 for action in self.Actions: - width, height = self.Parent.GetTextExtent(action["qualifier"]) + width, height = self.Parent.GetTextExtent(action.qualifier) self.ColSize[0] = max(self.ColSize[0], width + 10) row_height = height - if action.has_key("duration"): - width, height = self.Parent.GetTextExtent(action["duration"]) + if action.duration is not None: + width, height = self.Parent.GetTextExtent(action.duration) row_height = max(row_height, height) self.ColSize[0] = max(self.ColSize[0], width + 10) - width, height = self.Parent.GetTextExtent(action["value"]) + width, height = self.Parent.GetTextExtent(action.value) row_height = max(row_height, height) self.ColSize[1] = max(self.ColSize[1], width + 10) - if action.get("indicator", "") != "": - width, height = self.Parent.GetTextExtent(action["indicator"]) + if action.indicator is not None: + width, height = self.Parent.GetTextExtent(action.indicator) row_height = max(row_height, height) self.ColSize[2] = max(self.ColSize[2], width + 10) min_height += row_height + 5 @@ -2022,39 +2022,39 @@ if i != 0: dc.DrawLine(self.Pos.x, self.Pos.y + i * line_size, self.Pos.x + self.Size[0], self.Pos.y + i * line_size) - qualifier_size = dc.GetTextExtent(action["qualifier"]) - if action.has_key("duration"): + qualifier_size = dc.GetTextExtent(action.qualifier) + if action.duration is not None: qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) / 2, self.Pos.y + i * line_size + line_size / 2 - qualifier_size[1]) - duration_size = dc.GetTextExtent(action["duration"]) + duration_size = dc.GetTextExtent(action.duration) duration_pos = (self.Pos.x + (colsize[0] - duration_size[0]) / 2, self.Pos.y + i * line_size + line_size / 2) - dc.DrawText(action["duration"], duration_pos[0], duration_pos[1]) + dc.DrawText(action.duration, duration_pos[0], duration_pos[1]) else: qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) / 2, self.Pos.y + i * line_size + (line_size - qualifier_size[1]) / 2) - dc.DrawText(action["qualifier"], qualifier_pos[0], qualifier_pos[1]) - content_size = dc.GetTextExtent(action["value"]) + dc.DrawText(action.qualifier, qualifier_pos[0], qualifier_pos[1]) + content_size = dc.GetTextExtent(action.value) content_pos = (self.Pos.x + colsize[0] + (colsize[1] - content_size[0]) / 2, self.Pos.y + i * line_size + (line_size - content_size[1]) / 2) - dc.DrawText(action["value"], content_pos[0], content_pos[1]) - if action.has_key("indicator"): - indicator_size = dc.GetTextExtent(action["indicator"]) + dc.DrawText(action.value, content_pos[0], content_pos[1]) + if action.indicator is not None: + indicator_size = dc.GetTextExtent(action.indicator) indicator_pos = (self.Pos.x + colsize[0] + colsize[1] + (colsize[2] - indicator_size[0]) / 2, self.Pos.y + i * line_size + (line_size - indicator_size[1]) / 2) - dc.DrawText(action["indicator"], indicator_pos[0], indicator_pos[1]) + dc.DrawText(action.indicator, indicator_pos[0], indicator_pos[1]) if not getattr(dc, "printing", False): action_highlights = self.Highlights.get(i, {}) for name, attribute_highlights in action_highlights.iteritems(): if name == "qualifier": - DrawHighlightedText(dc, action["qualifier"], attribute_highlights, qualifier_pos[0], qualifier_pos[1]) + DrawHighlightedText(dc, action.qualifier, attribute_highlights, qualifier_pos[0], qualifier_pos[1]) elif name == "duration": - DrawHighlightedText(dc, action["duration"], attribute_highlights, duration_pos[0], duration_pos[1]) + DrawHighlightedText(dc, action.duration, attribute_highlights, duration_pos[0], duration_pos[1]) elif name in ["reference", "inline"]: - DrawHighlightedText(dc, action["value"], attribute_highlights, content_pos[0], content_pos[1]) + DrawHighlightedText(dc, action.value, attribute_highlights, content_pos[0], content_pos[1]) elif name == "indicator": - DrawHighlightedText(dc, action["indicator"], attribute_highlights, indicator_pos[0], indicator_pos[1]) + DrawHighlightedText(dc, action.indicator, attribute_highlights, indicator_pos[0], indicator_pos[1]) # Draw input connector self.Input.Draw(dc) diff -r 204ef2daa33c -r c1e6c712cc35 plcopen/plcopen.py --- a/plcopen/plcopen.py Tue Oct 01 09:24:02 2013 +0200 +++ b/plcopen/plcopen.py Wed Oct 02 01:21:35 2013 +0200 @@ -1874,145 +1874,8 @@ setattr(cls, "Search", _SearchInElement) return cls -def _getexecutionOrder(instance, specific_values): - executionOrder = instance.getexecutionOrderId() - if executionOrder is None: - executionOrder = 0 - specific_values["executionOrder"] = executionOrder - -def _getdefaultmodifiers(instance, infos): - infos["negated"] = instance.getnegated() - infos["edge"] = instance.getedge() - -def _getinputmodifiers(instance, infos): - infos["negated"] = instance.getnegatedIn() - infos["edge"] = instance.getedgeIn() - -def _getoutputmodifiers(instance, infos): - infos["negated"] = instance.getnegatedOut() - infos["edge"] = instance.getedgeOut() - -MODIFIERS_FUNCTIONS = {"default": _getdefaultmodifiers, - "input": _getinputmodifiers, - "output": _getoutputmodifiers} - -def _getconnectioninfos(instance, connection, links=False, modifiers=None, parameter=False): - infos = {"position": connection.getrelPositionXY()} - if parameter: - infos["name"] = instance.getformalParameter() - MODIFIERS_FUNCTIONS.get(modifiers, lambda x, y: None)(instance, infos) - if links: - infos["links"] = [] - connections = connection.getconnections() - if connections is not None: - for link in connections: - dic = {"refLocalId": link.getrefLocalId(), - "points": link.getpoints(), - "formalParameter": link.getformalParameter()} - infos["links"].append(dic) - return infos - -def _getelementinfos(instance): - return {"id": instance.getlocalId(), - "x": instance.getx(), - "y": instance.gety(), - "height": instance.getheight(), - "width": instance.getwidth(), - "specific_values": {}, - "inputs": [], - "outputs": []} - -def _getvariableinfosFunction(type, input, output): - def getvariableinfos(self): - infos = _getelementinfos(self) - infos["type"] = type - specific_values = infos["specific_values"] - specific_values["name"] = self.getexpression() - _getexecutionOrder(self, specific_values) - if input and output: - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "input")) - infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "output")) - elif input: - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "default")) - elif output: - infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "default")) - return infos - return getvariableinfos - -def _getconnectorinfosFunction(type): - def getconnectorinfos(self): - infos = _getelementinfos(self) - infos["type"] = type - infos["specific_values"]["name"] = self.getname() - if type == "connector": - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) - elif type == "continuation": - infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) - return infos - return getconnectorinfos - -def _getpowerrailinfosFunction(type): - def getpowerrailinfos(self): - infos = _getelementinfos(self) - infos["type"] = type - if type == "rightPowerRail": - for connectionPointIn in self.getconnectionPointIn(): - infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True)) - infos["specific_values"]["connectors"] = len(infos["inputs"]) - elif type == "leftPowerRail": - for connectionPointOut in self.getconnectionPointOut(): - infos["outputs"].append(_getconnectioninfos(self, connectionPointOut)) - infos["specific_values"]["connectors"] = len(infos["outputs"]) - return infos - return getpowerrailinfos - -def _getldelementinfosFunction(ld_element_type): - def getldelementinfos(self): - infos = _getelementinfos(self) - infos["type"] = ld_element_type - specific_values = infos["specific_values"] - specific_values["name"] = self.getvariable() - _getexecutionOrder(self, specific_values) - specific_values["negated"] = self.getnegated() - specific_values["edge"] = self.getedge() - if ld_element_type == "coil": - specific_values["storage"] = self.getstorage() - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) - infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) - return infos - return getldelementinfos - -DIVERGENCE_TYPES = {(True, True): "simultaneousDivergence", - (True, False): "selectionDivergence", - (False, True): "simultaneousConvergence", - (False, False): "selectionConvergence"} - -def _getdivergenceinfosFunction(divergence, simultaneous): - def getdivergenceinfos(self): - infos = _getelementinfos(self) - infos["type"] = DIVERGENCE_TYPES[(divergence, simultaneous)] - if divergence: - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) - for connectionPointOut in self.getconnectionPointOut(): - infos["outputs"].append(_getconnectioninfos(self, connectionPointOut)) - infos["specific_values"]["connectors"] = len(infos["outputs"]) - else: - for connectionPointIn in self.getconnectionPointIn(): - infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True)) - infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) - infos["specific_values"]["connectors"] = len(infos["inputs"]) - return infos - return getdivergenceinfos - cls = _initElementClass("comment", "commonObjects") if cls: - def getinfos(self): - infos = _getelementinfos(self) - infos["type"] = "comment" - infos["specific_values"]["content"] = self.getcontentText() - return infos - setattr(cls, "getinfos", getinfos) - def setcontentText(self, text): self.content.setanyText(text) setattr(cls, "setcontentText", setcontentText) @@ -2042,19 +1905,6 @@ return bbox setattr(cls, "getBoundingBox", getBoundingBox) - def getinfos(self): - infos = _getelementinfos(self) - infos["type"] = self.gettypeName() - specific_values = infos["specific_values"] - specific_values["name"] = self.getinstanceName() - _getexecutionOrder(self, specific_values) - for variable in self.inputVariables.getvariable(): - infos["inputs"].append(_getconnectioninfos(variable, variable.connectionPointIn, True, "default", True)) - for variable in self.outputVariables.getvariable(): - infos["outputs"].append(_getconnectioninfos(variable, variable.connectionPointOut, False, "default", True)) - return infos - setattr(cls, "getinfos", getinfos) - def updateElementName(self, old_name, new_name): if self.typeName == old_name: self.typeName = new_name @@ -2092,14 +1942,6 @@ return search_result setattr(cls, "Search", Search) -cls = _initElementClass("leftPowerRail", "ldObjects") -if cls: - setattr(cls, "getinfos", _getpowerrailinfosFunction("leftPowerRail")) - -cls = _initElementClass("rightPowerRail", "ldObjects", "multiple") -if cls: - setattr(cls, "getinfos", _getpowerrailinfosFunction("rightPowerRail")) - def _UpdateLDElementName(self, old_name, new_name): if self.variable == old_name: self.variable = new_name @@ -2114,60 +1956,24 @@ cls = _initElementClass("contact", "ldObjects", "single") if cls: - setattr(cls, "getinfos", _getldelementinfosFunction("contact")) setattr(cls, "updateElementName", _UpdateLDElementName) setattr(cls, "updateElementAddress", _UpdateLDElementAddress) setattr(cls, "Search", _getSearchInLDElement("contact")) cls = _initElementClass("coil", "ldObjects", "single") if cls: - setattr(cls, "getinfos", _getldelementinfosFunction("coil")) setattr(cls, "updateElementName", _UpdateLDElementName) setattr(cls, "updateElementAddress", _UpdateLDElementAddress) setattr(cls, "Search", _getSearchInLDElement("coil")) cls = _initElementClass("step", "sfcObjects", "single") if cls: - def getinfos(self): - infos = _getelementinfos(self) - infos["type"] = "step" - specific_values = infos["specific_values"] - specific_values["name"] = self.getname() - specific_values["initial"] = self.getinitialStep() - if self.connectionPointIn is not None: - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) - if self.connectionPointOut is not None: - infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) - if self.connectionPointOutAction is not None: - specific_values["action"] = _getconnectioninfos(self, self.connectionPointOutAction) - return infos - setattr(cls, "getinfos", getinfos) - def Search(self, criteria, parent_infos=[]): return _Search([("name", self.getname())], criteria, parent_infos + ["step", self.getlocalId()]) setattr(cls, "Search", Search) cls = _initElementClass("transition", "sfcObjects") if cls: - def getinfos(self): - infos = _getelementinfos(self) - infos["type"] = "transition" - specific_values = infos["specific_values"] - priority = self.getpriority() - if priority is None: - priority = 0 - specific_values["priority"] = priority - condition = self.getconditionContent() - specific_values["condition_type"] = condition["type"] - if specific_values["condition_type"] == "connection": - specific_values["connection"] = _getconnectioninfos(self, condition["value"], True) - else: - specific_values["condition"] = condition["value"] - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) - infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) - return infos - setattr(cls, "getinfos", getinfos) - def setconditionContent(self, condition_type, value): if self.condition is None: self.addcondition() @@ -2278,32 +2084,8 @@ return search_result setattr(cls, "Search", Search) -cls = _initElementClass("selectionDivergence", "sfcObjects", "single") -if cls: - setattr(cls, "getinfos", _getdivergenceinfosFunction(True, False)) - -cls = _initElementClass("selectionConvergence", "sfcObjects", "multiple") -if cls: - setattr(cls, "getinfos", _getdivergenceinfosFunction(False, False)) - -cls = _initElementClass("simultaneousDivergence", "sfcObjects", "single") -if cls: - setattr(cls, "getinfos", _getdivergenceinfosFunction(True, True)) - -cls = _initElementClass("simultaneousConvergence", "sfcObjects", "multiple") -if cls: - setattr(cls, "getinfos", _getdivergenceinfosFunction(False, True)) - cls = _initElementClass("jumpStep", "sfcObjects", "single") if cls: - def getinfos(self): - infos = _getelementinfos(self) - infos["type"] = "jump" - infos["specific_values"]["target"] = self.gettargetName() - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) - return infos - setattr(cls, "getinfos", getinfos) - def Search(self, criteria, parent_infos): return _Search([("target", self.gettargetName())], criteria, parent_infos + ["jump", self.getlocalId()]) setattr(cls, "Search", Search) @@ -2361,14 +2143,6 @@ cls = _initElementClass("actionBlock", "commonObjects", "single") if cls: - def getinfos(self): - infos = _getelementinfos(self) - infos["type"] = "actionBlock" - infos["specific_values"]["actions"] = self.getactions() - infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) - return infos - setattr(cls, "getinfos", getinfos) - def setactions(self, actions): self.action = [] for params in actions: @@ -2440,21 +2214,18 @@ cls = _initElementClass("inVariable", "fbdObjects") if cls: - setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True)) setattr(cls, "updateElementName", _UpdateIOElementName) setattr(cls, "updateElementAddress", _UpdateIOElementAddress) setattr(cls, "Search", _SearchInIOVariable) cls = _initElementClass("outVariable", "fbdObjects", "single") if cls: - setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False)) setattr(cls, "updateElementName", _UpdateIOElementName) setattr(cls, "updateElementAddress", _UpdateIOElementAddress) setattr(cls, "Search", _SearchInIOVariable) cls = _initElementClass("inOutVariable", "fbdObjects", "single") if cls: - setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True)) setattr(cls, "updateElementName", _UpdateIOElementName) setattr(cls, "updateElementAddress", _UpdateIOElementAddress) setattr(cls, "Search", _SearchInIOVariable) @@ -2465,7 +2236,6 @@ cls = _initElementClass("continuation", "commonObjects") if cls: - setattr(cls, "getinfos", _getconnectorinfosFunction("continuation")) setattr(cls, "Search", _SearchInConnector) def updateElementName(self, old_name, new_name): @@ -2475,7 +2245,6 @@ cls = _initElementClass("connector", "commonObjects", "single") if cls: - setattr(cls, "getinfos", _getconnectorinfosFunction("connector")) setattr(cls, "Search", _SearchInConnector) def updateElementName(self, old_name, new_name): diff -r 204ef2daa33c -r c1e6c712cc35 plcopen/pou_block_instances.xslt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plcopen/pou_block_instances.xslt Wed Oct 02 01:21:35 2013 +0200 @@ -0,0 +1,1 @@ +0inputoutputoutputSTRINGWSTRINGBOOLinputoutput0connectionreferenceinlinejumpreferenceinline \ No newline at end of file diff -r 204ef2daa33c -r c1e6c712cc35 plcopen/pou_block_instances.ysl2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plcopen/pou_block_instances.ysl2 Wed Oct 02 01:21:35 2013 +0200 @@ -0,0 +1,358 @@ +include yslt.yml2 +estylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" + xmlns:xhtml="http://www.w3.org/1999/xhtml" + xmlns:ns="pou_block_instances_ns" + extension-element-prefixes="ns" + exclude-result-prefixes="ns" { + + template "text()"; + + template "ppx:pou" { + apply "ppx:body/*[self::ppx:FBD or self::ppx:LD or self::ppx:SFC]/*"; + } + + function "add_instance" { + param "type"; + variable "instance" { + > «ns:AddBlockInstance($type, @localId, ppx:position/@x, ppx:position/@y, @width, @height)» + } + } + + function "execution_order" { + choose { + when "@executionOrderId" > «@executionOrderId» + otherwise > 0 + } + } + + function "ConnectionInfos" { + param "type"; + param "modifiers"; + param "formalParameter"; + variable "negated" { + choose { + when "$modifiers='input'" > «@negatedIn» + when "$modifiers='output'" > «@negatedOut» + otherwise > «@negated» + } + } + variable "edge" { + choose { + when "$modifiers='input'" > «@edgeIn» + when "$modifiers='output'" > «@edgeOut» + otherwise > «@edge» + } + } + variable "instance_connection" { + > «ns:AddInstanceConnection($type, $formalParameter, $negated, $edge, ppx:relPosition/@x, ppx:relPosition/@y)» + } + } + + template "ppx:position" { + variable "link_point" { + > «ns:AddLinkPoint(@x, @y)» + } + } + + template "ppx:connection" { + variable "connection_link" { + > «ns:AddConnectionLink(@refLocalId, @formalParameter)» + } + apply "ppx:position"; + } + + template "ppx:connectionPointIn" { + param "modifiers"; + param "formalParameter"; + call "ConnectionInfos" { + with "type" > input + with "modifiers" > «$modifiers» + with "formalParameter" > «$formalParameter» + } + apply "ppx:connection"; + } + + template "ppx:connectionPointOut" { + param "modifiers"; + param "formalParameter"; + call "ConnectionInfos" { + with "type" > output + with "modifiers" > «$modifiers» + with "formalParameter" > «$formalParameter» + } + } + + template "ppx:connectionPointOutAction" { + call "ConnectionInfos" { + with "type" > output + } + } + + template "ppx:comment" { + variable "type" > «local-name()» + variable "instance_specific_values" { + > «ns:SetSpecificValues(ppx:content/xhtml:p/text())» + } + call "add_instance" { + with "type" > «$type» + } + } + + template "ppx:block" { + variable "execution_order" { + call "execution_order"; + } + variable "instance_specific_values" { + > «ns:SetSpecificValues(@instanceName, $execution_order)» + } + call "add_instance" { + with "type" > «@typeName» + } + foreach "ppx:inputVariables/ppx:variable" { + apply "ppx:connectionPointIn" { + with "formalParameter" > «@formalParameter» + } + } + foreach "ppx:outputVariables/ppx:variable" { + apply "ppx:connectionPointOut" { + with "formalParameter" > «@formalParameter» + } + } + } + + template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived" { + > «@name» + } + + template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:string" { + > STRING + } + + template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:wstring" { + > WSTRING + } + + template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*" { + > «local-name()» + } + + function "VariableBlockInfos" { + param "type"; + variable "expression" > «ppx:expression/text()» + variable "value_type" { + choose { + when "ancestor::ppx:transition[@name=$expression]" > BOOL + when "ancestor::ppx:pou[@name=$expression]" { + apply "ancestor::ppx:pou/child::ppx:interface/ppx:returnType" + } + otherwise { + apply "ancestor::ppx:pou/child::ppx:interface/*/ppx:variable[@name=$expression]/ppx:type" + } + } + } + variable "execution_order" { + call "execution_order"; + } + variable "instance_specific_values" { + > «ns:SetSpecificValues($expression, $value_type, $execution_order)» + } + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn" { + with "modifiers" { + choose { + when "$type='inout'" > input + otherwise > + } + } + } + apply "ppx:connectionPointOut" { + with "modifiers" { + choose { + when "$type='inout'" > output + otherwise > + } + } + } + } + + template "ppx:inVariable" { + call "VariableBlockInfos" with "type", "'input'"; + } + + template "ppx:outVariable" { + call "VariableBlockInfos" with "type", "'output'"; + } + + template "ppx:inOutVariable" { + call "VariableBlockInfos" with "type", "'inout'"; + } + + template "ppx:connector|ppx:continuation" { + variable "type" > «local-name()» + variable "instance_specific_values" { + > «ns:SetSpecificValues(@name)» + } + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn"; + apply "ppx:connectionPointOut"; + } + + template "ppx:leftPowerRail|ppx:rightPowerRail" { + variable "type" > «local-name()» + variable "connectors" { + choose { + when "$type='leftPowerRail'" > «count(ppx:connectionPointOut)» + otherwise > «count(ppx:connectionPointIn)» + } + } + variable "instance_specific_values" { + > «ns:SetSpecificValues($connectors)» + } + call "add_instance" { + with "type" > «$type» + } + choose { + when "$type='leftPowerRail'" { + apply "ppx:connectionPointOut"; + } + otherwise { + apply "ppx:connectionPointIn"; + } + } + } + + template "ppx:contact|ppx:coil" { + variable "type" > «local-name()» + variable "storage" { + choose { + when "$type='coil'" > «@storage» + otherwise > + } + } + variable "execution_order" { + call "execution_order"; + } + variable "instance_specific_values" { + > «ns:SetSpecificValues(ppx:variable/text(), @negated, @edge, $storage, $execution_order)» + } + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn"; + apply "ppx:connectionPointOut"; + } + + template "ppx:step" { + variable "type" > «local-name()» + variable "instance_specific_values" { + > «ns:SetSpecificValues(@name, @initialStep)» + } + apply "ppx:connectionPointOutAction"; + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn"; + apply "ppx:connectionPointOut"; + } + + template "ppx:transition" { + variable "type" > «local-name()» + variable "priority" { + choose { + when "@priority" > «@priority» + otherwise > 0 + } + } + variable "condition_type" { + choose { + when "ppx:condition/ppx:connectionPointIn" > connection + when "ppx:condition/ppx:reference" > reference + when "ppx:condition/ppx:inline" > inline + otherwise > + } + } + variable "condition" { + choose { + when "ppx:reference" > «ppx:condition/ppx:reference/@name» + when "ppx:inline" > «ppx:condition/ppx:inline/ppx:body/ppx:ST/xhtml:p/text()» + otherwise > + } + } + variable "instance_specific_values" { + > «ns:SetSpecificValues($priority, $condition_type, $condition)» + } + apply "ppx:condition/ppx:connectionPointIn"; + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn"; + apply "ppx:connectionPointOut"; + } + + template "ppx:selectionDivergence|ppx:selectionConvergence|ppx:simultaneousDivergence|ppx:simultaneousConvergence" { + variable "type" > «local-name()» + variable "connectors" { + choose { + when "ppx:selectionDivergence|ppx:simultaneousDivergence" { + > «count(ppx:connectionPointOut)» + } + otherwise > «count(ppx:connectionPointIn)» + } + } + variable "instance_specific_values" { + > «ns:SetSpecificValues($connectors)» + } + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn"; + apply "ppx:connectionPointOut"; + } + + template "ppx:jumpStep" { + variable "type" > jump + variable "instance_specific_values" { + > «ns:SetSpecificValues(@targetName)» + } + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn"; + } + + template "ppx:action" { + variable "type" { + choose { + when "ppx:reference" > reference + when "ppx:inline" > inline + otherwise > + } + } + variable "value" { + choose { + when "ppx:reference" > «ppx:reference/@name» + when "ppx:inline" > «ppx:inline/ppx:ST/xhtml:p/text()» + otherwise > + } + } + variable "actionBlock_action" { + > «ns:AddAction(@qualifier, $type, $value, @duration, @indicator)» + } + } + + template "ppx:actionBlock" { + variable "type" > «local-name()» + variable "instance_specific_values" { + > «ns:SetSpecificValues()» + } + apply "ppx:action"; + call "add_instance" { + with "type" > «$type» + } + apply "ppx:connectionPointIn"; + } +} \ No newline at end of file