diff -r 3edd2f19bce2 -r e0424e96e3fd svgui/svgui_server.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgui/svgui_server.py Sat May 12 11:21:10 2012 +0200 @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import os + +from nevow import rend, appserver, inevow, tags, loaders, athena +import simplejson as json + +svgfile = '%(svgfile)s' + +svguiWidgets = {} + +currentId = 0 +def getNewId(): + global currentId + currentId += 1 + return currentId + +class SvguiWidget: + + def __init__(self, classname, id, **kwargs): + self.classname = classname + self.id = id + self.attrs = kwargs.copy() + self.inputs = {} + self.outputs = {} + self.inhibit = False + self.changed = False + + def setinput(self, attrname, value): + self.inputs[attrname] = value + + def getinput(self, attrname, default=None): + if not self.inputs.has_key(attrname): + self.inputs[attrname] = default + return self.inputs[attrname] + + def setoutput(self, attrname, value): + if self.outputs.get(attrname) != value: + self.outputs[attrname] = value + self.changed = True + self.RefreshInterface() + + def updateoutputs(self, **kwargs): + for attrname, value in kwargs.iteritems(): + if self.outputs.get(attrname) != value: + self.outputs[attrname] = value + self.changed = True + self.RefreshInterface() + + def RefreshInterface(self): + interface = website.getHMI() + if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit: + self.changed = False + d = interface.sendData(self) + if d is not None: + self.inhibit = True + d.addCallback(self.InterfaceRefreshed) + + def InterfaceRefreshed(self, result): + self.inhibit = False + if self.changed: + self.RefreshInterface() + +def get_object_init_state(obj): + # Convert objects to a dictionary of their representation + attrs = obj.attrs.copy() + attrs.update(obj.inputs) + d = { '__class__': obj.classname, + 'id': obj.id, + 'kwargs': json.dumps(attrs), + } + return d + +def get_object_current_state(obj): + # Convert objects to a dictionary of their representation + d = { '__class__': obj.classname, + 'id': obj.id, + 'kwargs': json.dumps(obj.outputs), + } + return d + +class SVGUI_HMI(website.PLCHMI): + jsClass = u"LiveSVGPage.LiveSVGWidget" + + docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[ + tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))), + ]) + + def HMIinitialisation(self): + gadgets = [] + for gadget in svguiWidgets.values(): + gadgets.append(unicode(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii')) + d = self.callRemote('init', gadgets) + d.addCallback(self.HMIinitialised) + + def sendData(self,data): + if self.initialised: + return self.callRemote('receiveData',unicode(json.dumps(data, default=get_object_current_state, indent=2), 'ascii')) + return None + + def setattr(self, id, attrname, value): + svguiWidgets[id].setinput(attrname, value) + +def createSVGUIControl(*args, **kwargs): + id = getNewId() + gad = SvguiWidget(args[0], id, **kwargs) + svguiWidgets[id] = gad + gadget = [unicode(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')] + interface = website.getHMI() + if isinstance(interface, SVGUI_HMI) and interface.initialised: + interface.callRemote('init', gadget) + return id + +def setAttr(id, attrname, value): + gad = svguiWidgets.get(id, None) + if gad is not None: + gad.setoutput(attrname, value) + +def updateAttr(id, **kwargs): + gad = svguiWidgets.get(id, None) + if gad is not None: + gad.updateoutput(**kwargs) + +def getAttr(id, attrname, default=None): + gad = svguiWidgets.get(id, None) + if gad is not None: + return gad.getinput(attrname, default) + return default +