targets and connectors are nor extensible
authorEdouard Tisserant
Sat, 19 May 2012 19:00:55 +0200
changeset 733 915be999f3f0
parent 732 c4b0f117e106
child 734 5c42cafaee15
targets and connectors are nor extensible
ProjectController.py
c_ext/.cvsignore
canfestival/.cvsignore
connectors/.cvsignore
connectors/PYRO/__init__.py
connectors/__init__.py
images/.cvsignore
runtime/.cvsignore
targets/.cvsignore
targets/Linux/.cvsignore
targets/Xenomai/.cvsignore
targets/__init__.py
--- a/ProjectController.py	Sat May 19 15:54:16 2012 +0200
+++ b/ProjectController.py	Sat May 19 19:00:55 2012 +0200
@@ -55,7 +55,7 @@
             <xsd:element name="TargetType">
               <xsd:complexType>
                 <xsd:choice minOccurs="0">
-                """+targets.targetchoices+"""
+                """+targets.GetTargetChoices()+"""
                 </xsd:choice>
               </xsd:complexType>
             </xsd:element>
@@ -559,20 +559,7 @@
         """
         # Get target, module and class name
         targetname = self.GetTarget().getcontent()["name"]
-        modulename = "targets." + targetname
-        classname = targetname + "_target"
-
-        # Get module reference
-        try :
-            targetmodule = getattr(__import__(modulename), targetname)
-
-        except Exception, msg:
-            self.logger.write_error(_("Can't find module for target %s!\n")%targetname)
-            self.logger.write_error(str(msg))
-            return None
-        
-        # Get target class
-        targetclass = getattr(targetmodule, classname)
+        targetclass = targets.GetBuilder(targetname)
 
         # if target already 
         if self._builder is None or not isinstance(self._builder,targetclass):
@@ -695,7 +682,7 @@
         self.GetIECProgramsAndVariables()
 
         # prepare debug code
-        debug_code = targets.code("plc_debug") % {
+        debug_code = targets.GetCode("plc_debug") % {
            "buffer_size": reduce(lambda x, y: x + y, [DebugTypesSize.get(v["type"], 0) for v in self._VariablesList], 0),
            "programs_declarations":
                "\n".join(["extern %(type)s %(C_path)s;"%p for p in self._ProgramList]),
@@ -737,7 +724,7 @@
 
         # Generate main, based on template
         if not self.BeremizRoot.getDisable_Extensions():
-            plc_main_code = targets.code("plc_common_main") % {
+            plc_main_code = targets.GetCode("plc_common_main") % {
                 "calls_prototypes":"\n".join([(
                       "int __init_%(s)s(int argc,char **argv);\n"+
                       "void __cleanup_%(s)s(void);\n"+
@@ -757,14 +744,14 @@
                       "__cleanup_%s();"%locstrs[i-1] for i in xrange(len(locstrs), 0, -1)])
                 }
         else:
-            plc_main_code = targets.code("plc_common_main") % {
+            plc_main_code = targets.GetCode("plc_common_main") % {
                 "calls_prototypes":"\n",
                 "retrieve_calls":"\n",
                 "publish_calls":"\n",
                 "init_calls":"\n",
                 "cleanup_calls":"\n"
                 }
-        plc_main_code += targets.targetcode(self.GetTarget().getcontent()["name"])
+        plc_main_code += targets.GetTargetCode(self.GetTarget().getcontent()["name"])
         return plc_main_code
 
         
--- a/c_ext/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-*.pyc
--- a/canfestival/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-*.pyc
--- a/connectors/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-*.pyc
--- a/connectors/PYRO/__init__.py	Sat May 19 15:54:16 2012 +0200
+++ b/connectors/PYRO/__init__.py	Sat May 19 19:00:55 2012 +0200
@@ -30,7 +30,6 @@
 #
 # for connectors that do not support DNS-SD, this attribute can be omitted
 # or set to an empty list.
-supported_dnssd_services = ["_PYRO._tcp.local."]
 
 def PYRO_connector_factory(uri, confnodesroot):
     """
--- a/connectors/__init__.py	Sat May 19 15:54:16 2012 +0200
+++ b/connectors/__init__.py	Sat May 19 19:00:55 2012 +0200
@@ -23,28 +23,20 @@
 
 from os import listdir, path
 
-import PYRO
 
 _base_path = path.split(__file__)[0]
 
-connector_types = [name for name in listdir(_base_path)
-                        if path.isdir(path.join(_base_path, name))
-                            and name.lower() != ".hg"
-                            and not name.startswith("__")]
-
-# a dict from a URI scheme (connector name) to connector module
-connector_modules = {}
 
 # a dict from a DNS-SD service type to a connector module that support it
-dnssd_connectors = {}
+dnssd_connectors = {"_PYRO._tcp.local.":"PYRO"}
 
-for t in connector_types:
-    new_module = getattr(__import__("connectors." + t), t)
-    connector_modules[t] = new_module
-    
-    if hasattr(new_module, "supported_dnssd_services"):
-        for st in new_module.supported_dnssd_services:
-            dnssd_connectors[st] = new_module
+def _GetLocalConnectorClassFactory(name):
+    return lambda:getattr(__import__(name,globals(),locals()), name + "_connector_factory")
+
+connectors = {name:_GetLocalConnectorClassFactory(name) 
+                  for name in listdir(_base_path) 
+                      if path.isdir(path.join(_base_path, name)) 
+                          and not name.startswith("__")}
 
 def ConnectorFactory(uri, confnodesroot):
     """
@@ -52,16 +44,14 @@
     or None if cannot connect to URI
     """
     servicetype = uri.split("://")[0]
-    if servicetype in connector_types:
+    if servicetype in connectors:
         # import module according to uri type
-        connectormodule = connector_modules[servicetype]
-        factoryname = servicetype + "_connector_factory"
-        return getattr(connectormodule, factoryname)(uri, confnodesroot)
+        connectorclass = connectors[servicetype]()
     elif servicetype == "LOCAL":
+        from PYRO import PYRO_connector_factory as connectorclass
         runtime_port = confnodesroot.AppFrame.StartLocalRuntime(taskbaricon=True)
-        return PYRO.PYRO_connector_factory(
-                       "PYRO://127.0.0.1:"+str(runtime_port), 
-                       confnodesroot)
+        uri="PYRO://127.0.0.1:"+str(runtime_port)
     else :
         return None    
+    return connectorclass(uri, confnodesroot)
 
--- a/images/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-ico48.png
-ico16.png
-ico24.png
--- a/runtime/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-*.pyc
--- a/targets/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-*.pyc
--- a/targets/Linux/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-*.pyc
--- a/targets/Xenomai/.cvsignore	Sat May 19 15:54:16 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-*.pyc
--- a/targets/__init__.py	Sat May 19 15:54:16 2012 +0200
+++ b/targets/__init__.py	Sat May 19 19:00:55 2012 +0200
@@ -33,50 +33,49 @@
 from os import listdir, path
 
 _base_path = path.split(__file__)[0]
+def _GetLocalTargetClassFactory(name):
+    return lambda:getattr(__import__(name,globals(),locals()), name+"_target")
 
-targets = [name for name in listdir(_base_path) 
-                   if path.isdir(path.join(_base_path, name)) 
-                       and not name.startswith("__")]
+targets = {name: {"xsd":path.join(_base_path, name, "XSD"), 
+                  "class":_GetLocalTargetClassFactory(name),
+                  "code": path.join(path.split(__file__)[0],name,"plc_%s_main.c"%name)}
+                for name in listdir(_base_path) 
+                    if path.isdir(path.join(_base_path, name)) 
+                       and not name.startswith("__")}
+
 toolchains = [name for name in listdir(_base_path) 
                        if not path.isdir(path.join(_base_path, name)) 
-                            and name.endswith(".py") 
-                            and not name.startswith("__") 
-                            and not name.endswith(".pyc")]
+                          and name.endswith(".py") 
+                          and not name.startswith("__")]
 
-DictXSD_toolchain = {}
-DictXSD_target = {}
+def GetBuilder(targetname):
+    return targets[targetname]["class"]()
 
-targetchoices = ""
+def GetTargetChoices():
+    DictXSD_toolchain = {}
+    targetchoices = ""
 
-# Get all xsd toolchains
-for toolchain in toolchains :
-     toolchainname = path.splitext(toolchain)[0]
-     xsdfilename = path.join(_base_path, "XSD_%s"%(toolchainname))
-     if path.isfile(xsdfilename):
-         xsd_toolchain_string = ""
-         for line in open(xsdfilename).readlines():
-             xsd_toolchain_string += line
-         DictXSD_toolchain[toolchainname] = xsd_toolchain_string
+    # Get all xsd toolchains
+    for toolchain in toolchains :
+         toolchainname = path.splitext(toolchain)[0]
+         xsdfilename = path.join(_base_path, "XSD_%s"%(toolchainname))
+         if path.isfile(xsdfilename):
+             xsd_toolchain_string = ""
+             for line in open(xsdfilename).readlines():
+                 xsd_toolchain_string += line
+             DictXSD_toolchain[toolchainname] = xsd_toolchain_string
 
-# Get all xsd targets 
-for targetname in targets:
-    xsdfilename = path.join(_base_path, targetname, "XSD")
-    if path.isfile(xsdfilename):
-        xsd_target_string = ""
-        for line in open(xsdfilename).readlines():
-            xsd_target_string += line
-        DictXSD_target[targetname] = xsd_target_string%DictXSD_toolchain
+    # Get all xsd targets 
+    for targetname,nfo in targets.iteritems():
+        xsd_string = open(nfo["xsd"]).read()
+        targetchoices +=  xsd_string%DictXSD_toolchain
 
-for target in DictXSD_target.keys():
-    targetchoices += DictXSD_target[target]
+    return targetchoices
 
-def targetcode(target_name, code_name=None):
-    if code_name is None:
-        code_name="plc_%s_main.c"%target_name
-    filename = path.join(path.split(__file__)[0], target_name, code_name)
-    return open(filename).read()
+def GetTargetCode(targetname):
+    return open(targets[targetname]["code"]).read()
 
-def code(name):
+def GetCode(name):
     filename = path.join(path.split(__file__)[0],name + ".c")
     return open(filename).read()