plugins/python/modules/svgui/svgui_server.py
changeset 381 5c0f34a9ab00
parent 371 b7cb57a2da08
equal deleted inserted replaced
380:46d7d2ce84d2 381:5c0f34a9ab00
     6 from nevow import rend, appserver, inevow, tags, loaders, athena
     6 from nevow import rend, appserver, inevow, tags, loaders, athena
     7 import simplejson as json
     7 import simplejson as json
     8 
     8 
     9 svgfile = '%(svgfile)s'
     9 svgfile = '%(svgfile)s'
    10 
    10 
    11 svguiWidgets={}
    11 svguiWidgets = {}
       
    12 
       
    13 currentId = 0
       
    14 def getNewId():
       
    15     global currentId
       
    16     currentId += 1
       
    17     return currentId
    12 
    18 
    13 class SvguiWidget:
    19 class SvguiWidget:
    14     
    20     
    15     def __init__(self, classname, back_id, **kwargs):
    21     def __init__(self, classname, id, **kwargs):
    16         self.classname = classname
    22         self.classname = classname
    17         self.back_id = back_id
    23         self.id = id
    18         self.attrs = kwargs.copy()
    24         self.attrs = kwargs.copy()
    19         self.lastattrs = kwargs.copy()
    25         self.inputs = {}
       
    26         self.outputs = {}
    20         self.inhibit = False
    27         self.inhibit = False
    21         self.changed = False
    28         self.changed = False
    22 
    29 
    23     def setattr(self, attrname, value):
    30     def setinput(self, attrname, value):
    24         self.attrs[attrname] = value
    31         self.inputs[attrname] = value
    25         
    32         
    26     def getattr(self, attrname):
    33     def getinput(self, attrname, default=None):
    27         return self.args.get(attrname, None)
    34         if not self.inputs.has_key(attrname):
       
    35             self.inputs[attrname] = default
       
    36         return self.inputs[attrname]
    28 
    37 
    29     def update(self, **kwargs):
    38     def setoutput(self, attrname, value):
       
    39         if self.outputs.get(attrname) != value:
       
    40             self.outputs[attrname] = value
       
    41             self.changed = True
       
    42             self.RefreshInterface()
       
    43         
       
    44     def updateoutputs(self, **kwargs):
    30         for attrname, value in kwargs.iteritems():
    45         for attrname, value in kwargs.iteritems():
    31             if self.lastattrs.get(attrname, None) != value:
    46             if self.outputs.get(attrname) != value:
       
    47                 self.outputs[attrname] = value
    32                 self.changed = True
    48                 self.changed = True
    33                 self.attrs[attrname] = value
    49         self.RefreshInterface()
    34                 self.lastattrs[attrname] = value
    50         
       
    51     def RefreshInterface(self):
    35         interface = website.getHMI()
    52         interface = website.getHMI()
    36         if interface is not None and self.changed and not self.inhibit:
    53         if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit:
    37             self.changed = False
    54             self.changed = False
    38             interface.sendData(self)
    55             d = interface.sendData(self)
    39         
    56             if d is not None:
    40         return self.attrs["state"]
    57                 self.inhibit = True
       
    58                 d.addCallback(self.InterfaceRefreshed)
       
    59     
       
    60     def InterfaceRefreshed(self, result):
       
    61         self.inhibit = False
       
    62         if self.changed:
       
    63             self.RefreshInterface()
    41 
    64 
    42 def convert_to_builtin_type(obj):
    65 def get_object_init_state(obj):
    43     # Convert objects to a dictionary of their representation
    66     # Convert objects to a dictionary of their representation
    44     d = { '__class__':obj.classname,
    67     attrs = obj.attrs.copy()
    45           'back_id':obj.back_id,
    68     attrs.update(obj.inputs)
    46           'kwargs':json.dumps(obj.attrs),
    69     d = { '__class__': obj.classname,
       
    70           'id': obj.id,
       
    71           'kwargs': json.dumps(attrs),
    47           }
    72           }
    48     return d
    73     return d
    49 
    74 
    50 def dataToSend():
    75 def get_object_current_state(obj):
    51     gadgets = []
    76     # Convert objects to a dictionary of their representation
    52     for gadget in svguiWidgets.values():
    77     d = { '__class__': obj.classname,
    53         gadgets.append(unicode(json.dumps(gadget, default=convert_to_builtin_type, indent=2), 'ascii'))
    78           'id': obj.id,
    54     return gadgets
    79           'kwargs': json.dumps(obj.outputs),
       
    80           }
       
    81     return d
    55 
    82 
    56 
    83 class SVGUI_HMI(website.PLCHMI):
    57 class SVGUI_HMI(athena.LiveElement):
       
    58     jsClass = u"LiveSVGPage.LiveSVGWidget"
    84     jsClass = u"LiveSVGPage.LiveSVGWidget"
    59     
    85     
    60     docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[                                    
    86     docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[                                    
    61                                          tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))),
    87                                          tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))),
    62                                          ])
    88                                          ])
       
    89     
       
    90     def HMIinitialisation(self):
       
    91         gadgets = []
       
    92         for gadget in svguiWidgets.values():
       
    93             gadgets.append(unicode(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii'))
       
    94         d = self.callRemote('init', gadgets)
       
    95         d.addCallback(self.HMIinitialised)
       
    96     
       
    97     def sendData(self,data):
       
    98         if self.initialised:
       
    99             return self.callRemote('receiveData',unicode(json.dumps(data, default=get_object_current_state, indent=2), 'ascii'))
       
   100         return None
       
   101         
       
   102     def setattr(self, id, attrname, value):
       
   103         svguiWidgets[id].setinput(attrname, value)
    63 
   104 
    64     def sendData(self,data):
   105 def createSVGUIControl(*args, **kwargs):
    65         objDefer = self.callRemote('receiveData',unicode(json.dumps(data, default=convert_to_builtin_type, indent=2), 'ascii'))
   106     id = getNewId()
       
   107     gad = SvguiWidget(args[0], id, **kwargs)
       
   108     svguiWidgets[id] = gad
       
   109     gadget = [unicode(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')]
       
   110     interface = website.getHMI()
       
   111     if isinstance(interface, SVGUI_HMI) and interface.initialised:
       
   112         interface.callRemote('init', gadget)
       
   113     return id
    66 
   114 
    67     def initClient(self):
   115 def setAttr(id, attrname, value):
    68         self.callRemote('init', dataToSend())
   116     gad = svguiWidgets.get(id, None)
    69     
   117     if gad is not None:
    70     def setattr(self, id, attrname, value):
   118         gad.setoutput(attrname, value)
    71         svguiWidgets[id].setattr(attrname, value)
       
    72 
   119 
    73 def SVGUI(*args, **kwargs):
   120 def updateAttr(id, **kwargs):
    74     classname, back_id = args
   121     gad = svguiWidgets.get(id, None)
    75     gad = svguiWidgets.get(back_id, None)
   122     if gad is not None:
    76     if gad is None:
   123         gad.updateoutput(**kwargs)
    77         gad = SvguiWidget(classname, back_id, **kwargs)
       
    78         svguiWidgets[back_id] = gad
       
    79         gadget = [unicode(json.dumps(gad, default=convert_to_builtin_type, indent=2), 'ascii')]
       
    80         interface = website.getHMI()
       
    81         if interface is not None:
       
    82             interface.callRemote('init', gadget)
       
    83 
   124 
    84     return gad.update(**kwargs)
   125 def getAttr(id, attrname, default=None):
       
   126     gad = svguiWidgets.get(id, None)
       
   127     if gad is not None:
       
   128         return gad.getinput(attrname, default)
       
   129     return default
       
   130