--- a/PLCControler.py Fri Aug 02 08:58:09 2013 +0900
+++ b/PLCControler.py Sun Aug 04 22:55:12 2013 +0900
@@ -210,7 +210,8 @@
self.NextCompiledProject = None
self.CurrentCompiledProject = None
self.ConfNodeTypes = []
- self.ProgramFilePath = ""
+ self.TotalTypesDict = StdBlckDct.copy()
+ self.TotalTypes = StdBlckLst[:]
def GetQualifierTypes(self):
return plcopen.QualifierList
@@ -1534,25 +1535,34 @@
# Function that add a new confnode to the confnode list
def AddConfNodeTypesList(self, typeslist):
self.ConfNodeTypes.extend(typeslist)
+ addedcat = [{"name": _("%s POUs") % confnodetypes["name"],
+ "list": confnodetypes["types"].GetCustomBlockTypes()}
+ for confnodetypes in typeslist]
+ self.TotalTypes.extend(addedcat)
+ for cat in addedcat:
+ for desc in cat["list"]:
+ BlkLst = self.TotalTypesDict.setdefault(desc["name"],[])
+ BlkLst.append((section["name"], desc))
# Function that clear the confnode list
def ClearConfNodeTypes(self):
- for i in xrange(len(self.ConfNodeTypes)):
- self.ConfNodeTypes.pop(0)
+ self.ConfNodeTypes = []
+ self.TotalTypesDict = StdBlckDct.copy()
+ self.TotalTypes = StdBlckLst[:]
def GetConfNodeBlockTypes(self):
return [{"name": _("%s POUs") % confnodetypes["name"],
"list": confnodetypes["types"].GetCustomBlockTypes()}
for confnodetypes in self.ConfNodeTypes]
- def GetConfNodeDataTypes(self, exclude = "", only_locatables = False):
+ def GetConfNodeDataTypes(self, exclude = None, only_locatables = False):
return [{"name": _("%s Data Types") % confnodetypes["name"],
"list": [datatype["name"] for datatype in confnodetypes["types"].GetCustomDataTypes(exclude, only_locatables)]}
for confnodetypes in self.ConfNodeTypes]
- def GetConfNodeDataType(self, type):
+ def GetConfNodeDataType(self, typename):
for confnodetype in self.ConfNodeTypes:
- datatype = confnodetype["types"].getdataType(type)
+ datatype = confnodetype["types"].getdataType(typename)
if datatype is not None:
return datatype
return None
@@ -1592,61 +1602,59 @@
return global_vars
# Function that returns the block definition associated to the block type given
- def GetBlockType(self, type, inputs = None, debug = False):
+ def GetBlockType(self, typename, inputs = None, debug = False):
result_blocktype = None
- for category in BlockTypes + self.GetConfNodeBlockTypes():
- for blocktype in category["list"]:
- if blocktype["name"] == type:
- if inputs is not None and inputs != "undefined":
- block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
- if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True):
- return blocktype
+ for sectioname, blocktype in self.TotalTypesDict.get(typename,[]):
+ if inputs is not None and inputs != "undefined":
+ block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
+ if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True):
+ return blocktype
+ else:
+ if result_blocktype is not None:
+ if inputs == "undefined":
+ return None
else:
- if result_blocktype is not None:
- if inputs == "undefined":
- return None
- else:
- result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]]
- result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]]
- return result_blocktype
- result_blocktype = blocktype.copy()
+ result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]]
+ result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]]
+ return result_blocktype
+ result_blocktype = blocktype.copy()
if result_blocktype is not None:
return result_blocktype
project = self.GetProject(debug)
if project is not None:
- return project.GetCustomBlockType(type, inputs)
+ return project.GetCustomBlockType(typename, inputs)
return None
# Return Block types checking for recursion
def GetBlockTypes(self, tagname = "", debug = False):
- type = None
+ typename = None
words = tagname.split("::")
- if self.Project:
- name = ""
+ name = None
+ project = self.GetProject(debug)
+ if project is not None:
+ blocktypes = []
if words[0] in ["P","T","A"]:
name = words[1]
- type = self.GetPouType(name, debug)
- if type == "function":
- blocktypes = []
- for category in BlockTypes + self.GetConfNodeBlockTypes():
- cat = {"name" : category["name"], "list" : []}
- for block in category["list"]:
- if block["type"] == "function":
- cat["list"].append(block)
- if len(cat["list"]) > 0:
- blocktypes.append(cat)
- else:
- blocktypes = [category for category in BlockTypes + self.GetConfNodeBlockTypes()]
- project = self.GetProject(debug)
- if project is not None:
- blocktypes.append({"name" : USER_DEFINED_POUS, "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")})
- return blocktypes
+ typename = self.GetPouType(name, debug)
+ if typename == "function":
+ for category in self.TotalTypes:
+ cat = {"name" : category["name"], "list" : []}
+ for block in category["list"]:
+ if block["type"] == "function":
+ cat["list"].append(block)
+ if len(cat["list"]) > 0:
+ blocktypes.append(cat)
+ blocktypes.append({"name" : USER_DEFINED_POUS,
+ "list": project.GetCustomBlockTypes(name,
+ typename == "function" or words[0] == "T")})
+ return blocktypes
+ return self.TotalTypes
# Return Function Block types checking for recursion
def GetFunctionBlockTypes(self, tagname = "", debug = False):
blocktypes = []
- for category in BlockTypes + self.GetConfNodeBlockTypes():
- for block in category["list"]:
+ for blocks in self.TotalTypesDict.itervalues():
+ for sectioname,block in blocks:
if block["type"] == "functionBlock":
blocktypes.append(block["name"])
project = self.GetProject(debug)
@@ -1661,7 +1669,7 @@
# Return Block types checking for recursion
def GetBlockResource(self, debug = False):
blocktypes = []
- for category in BlockTypes[:-1]:
+ for category in StdBlckLst[:-1]:
for blocktype in category["list"]:
if blocktype["type"] == "program":
blocktypes.append(blocktype["name"])
@@ -1677,8 +1685,8 @@
else:
datatypes = []
project = self.GetProject(debug)
- if project is not None:
- name = ""
+ name = None
+ if project is not None:
words = tagname.split("::")
if words[0] in ["D"]:
name = words[1]
--- a/plcopen/plcopen.py Fri Aug 02 08:58:09 2013 +0900
+++ b/plcopen/plcopen.py Sun Aug 04 22:55:12 2013 +0900
@@ -26,7 +26,7 @@
from structures import *
from types import *
import os, re
-
+from collections import OrderedDict
"""
Dictionary that makes the relation between var names in plcopen and displayed values
"""
@@ -177,7 +177,7 @@
cls.CustomDataTypeRange = {}
cls.CustomTypeHierarchy = {}
cls.ElementUsingTree = {}
- cls.CustomBlockTypes = []
+ cls.CustomBlockTypes = OrderedDict()
def setname(self, name):
self.contentHeader.setname(name)
@@ -443,7 +443,7 @@
# Update Block types with user-defined pou added
def RefreshCustomBlockTypes(self):
# Reset the tree of user-defined pou cross-use
- self.CustomBlockTypes = []
+ self.CustomBlockTypes = OrderedDict()
for pou in self.getpous():
self.AddCustomBlockType(pou)
setattr(cls, "RefreshCustomBlockTypes", RefreshCustomBlockTypes)
@@ -497,7 +497,7 @@
block_infos["outputs"].append((var.getname(), var_type["name"], "none"))
block_infos["usage"] = "\n (%s) => (%s)" % (", ".join(["%s:%s" % (input[1], input[0]) for input in block_infos["inputs"]]),
", ".join(["%s:%s" % (output[1], output[0]) for output in block_infos["outputs"]]))
- self.CustomBlockTypes.append(block_infos)
+ self.CustomBlockTypes[pou_name]=block_infos
setattr(cls, "AddCustomBlockType", AddCustomBlockType)
def AddElementUsingTreeInstance(self, name, type_infos):
@@ -633,14 +633,14 @@
setattr(cls, "GetEnumeratedDataTypeValues", GetEnumeratedDataTypeValues)
# Function that returns the block definition associated to the block type given
- def GetCustomBlockType(self, type, inputs = None):
- for customblocktype in self.CustomBlockTypes:
+ def GetCustomBlockType(self, typename, inputs = None):
+ customblocktype = self.CustomBlockTypes.get(typename,None)
+ if customblocktype is not None:
if inputs is not None and inputs != "undefined":
customblock_inputs = tuple([var_type for name, var_type, modifier in customblocktype["inputs"]])
- same_inputs = inputs == customblock_inputs
+ if inputs == customblock_inputs:
+ return customblocktype
else:
- same_inputs = True
- if customblocktype["name"] == type and same_inputs:
return customblocktype
return None
setattr(cls, "GetCustomBlockType", GetCustomBlockType)
@@ -648,32 +648,31 @@
# Return Block types checking for recursion
def GetCustomBlockTypes(self, exclude = None, onlyfunctions = False):
if exclude is not None:
- return [customblocktype for customblocktype in self.CustomBlockTypes
+ return [customblocktype for name,customblocktype in self.CustomBlockTypes.iteritems()
if (customblocktype["type"] != "program"
- and customblocktype["name"] != exclude
- and not self.ElementIsUsedBy(exclude, customblocktype["name"])
+ and name != exclude
+ and not self.ElementIsUsedBy(exclude, name)
and not (onlyfunctions and customblocktype["type"] != "function"))]
- return [customblocktype for customblocktype in self.CustomBlockTypes
+ return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
if (customblocktype["type"] != "program"
and not (onlyfunctions and customblocktype["type"] != "function"))]
setattr(cls, "GetCustomBlockTypes", GetCustomBlockTypes)
# Return Function Block types checking for recursion
- def GetCustomFunctionBlockTypes(self, exclude = ""):
- customblocktypes = []
- for customblocktype in self.CustomBlockTypes:
- if customblocktype["type"] == "functionBlock" and customblocktype["name"] != exclude and not self.ElementIsUsedBy(exclude, customblocktype["name"]):
- customblocktypes.append(customblocktype["name"])
- return customblocktypes
+ def GetCustomFunctionBlockTypes(self, exclude = None):
+ if exclude is not None:
+ return [customblocktype for name,customblocktype in self.CustomBlockTypes.iteritems()
+ if (customblocktype["type"] == "functionBlock"
+ and name != exclude
+ and not self.ElementIsUsedBy(exclude, name))]
+ return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
+ if customblocktype["type"] == "functionBlock"]
setattr(cls, "GetCustomFunctionBlockTypes", GetCustomFunctionBlockTypes)
# Return Block types checking for recursion
def GetCustomBlockResource(self):
- customblocktypes = []
- for customblocktype in self.CustomBlockTypes:
- if customblocktype["type"] == "program":
- customblocktypes.append(customblocktype["name"])
- return customblocktypes
+ return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
+ if customblocktype["type"] == "program"]
setattr(cls, "GetCustomBlockResource", GetCustomBlockResource)
# Return Data Types checking for recursion
--- a/plcopen/structures.py Fri Aug 02 08:58:09 2013 +0900
+++ b/plcopen/structures.py Sun Aug 04 22:55:12 2013 +0900
@@ -250,7 +250,7 @@
- The default modifier which can be "none", "negated", "rising" or "falling"
"""
-BlockTypes = [{"name" : _("Standard function blocks"), "list":
+StdBlckLst = [{"name" : _("Standard function blocks"), "list":
[{"name" : "SR", "type" : "functionBlock", "extensible" : False,
"inputs" : [("S1","BOOL","none"),("R","BOOL","none")],
"outputs" : [("Q1","BOOL","none")],
@@ -663,9 +663,12 @@
std_decl = get_standard_funtions(csv_file_to_table(open(os.path.join(os.path.split(__file__)[0],"iec_std.csv"))))#, True)
-BlockTypes.extend(std_decl)
-
-for section in BlockTypes:
+StdBlckLst.extend(std_decl)
+
+# Dictionary to speedup block type fetching by name
+StdBlckDct = {}
+
+for section in StdBlckLst:
for desc in section["list"]:
words = desc["comment"].split('"')
if len(words) > 1:
@@ -676,7 +679,8 @@
" ) => (" +
str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in desc["outputs"]]).strip("[]").replace("'",'') +
" )")
-
+ BlkLst = StdBlckDct.setdefault(desc["name"],[])
+ BlkLst.append((section["name"], desc))
#-------------------------------------------------------------------------------
# Languages Keywords
@@ -687,7 +691,7 @@
POU_BLOCK_START_KEYWORDS = ["FUNCTION", "FUNCTION_BLOCK", "PROGRAM"]
POU_BLOCK_END_KEYWORDS = ["END_FUNCTION", "END_FUNCTION_BLOCK", "END_PROGRAM"]
POU_KEYWORDS = ["EN", "ENO", "F_EDGE", "R_EDGE"] + POU_BLOCK_START_KEYWORDS + POU_BLOCK_END_KEYWORDS
-for category in BlockTypes:
+for category in StdBlckLst:
for block in category["list"]:
if block["name"] not in POU_KEYWORDS:
POU_KEYWORDS.append(block["name"])