diff --git a/contrib/onelab/python/OnelabClient.py b/contrib/onelab/python/OnelabClient.py index a09fea29bb3e685e1fb8f1c189adabd604880582..3d6da4ae6d4b0653adb8801b35c7613a065f0d5b 100755 --- a/contrib/onelab/python/OnelabClient.py +++ b/contrib/onelab/python/OnelabClient.py @@ -13,15 +13,15 @@ class _parameter() : _membersbase = [ ('name', 'string'), ('label', 'string', ''), ('help', 'string', ''), ('neverChanged', 'int', 0), ('changed', 'int', 1), ('visible', 'int', 1), - ('read_only', 'int', 0), ('attributes', ('dict', 'string', 'string'), {}), + ('readOnly', 'int', 0), ('attributes', ('dict', 'string', 'string'), {}), ('clients', ('list', 'string'), []) ] _members = { 'string' : _membersbase + [ - ('value', 'string'), ('kind', 'string', 'generic'), ('choices', ('list', 'string'), []) + ('value', 'string',''), ('kind', 'string', 'generic'), ('choices', ('list', 'string'), []) ], 'number' : _membersbase + [ - ('value', 'float'), + ('value', 'float',0), ('min', 'float', -sys.float_info.max), ('max', 'float', sys.float_info.max), ('step', 'float', 0.), ('index', 'int', -1), ('choices', ('list', 'float'), []), ('labels', ('dict', 'float', 'string'), {}) @@ -66,7 +66,14 @@ class _parameter() : print('onelab parameter type mismatch') for p in _parameter._members[self.type]: setattr(self, p[0], fromcharitem(l, p[1])) - + return self + + def modify(self, **param) : + for i in _parameter._members[self.type] : + if i[0] in param : + setattr(self, i[0], param[i[0]]) #NB: no else statement => update + + class client : _GMSH_START = 1 _GMSH_STOP = 2 @@ -77,9 +84,10 @@ class client : _GMSH_PARAMETER_QUERY = 24 _GMSH_CONNECT = 27 _GMSH_OLPARSE = 28 - _GMSH_PARAM_NOT_FOUND = 29 - _GMSH_OPTION_1 = 100 - + _GMSH_PARAMETER_NOT_FOUND = 29 + _GMSH_PARAMETER_CLEAR = 31 + _GMSH_PARAMETER_UPDATE = 32 + def _receive(self) : def buffered_receive(l) : msg = b'' @@ -106,28 +114,63 @@ class client : self._createSocket() self.socket.send(struct.pack('ii%is' %len(m), t, len(m), m)) - def _define_parameter(self, param) : + def _declare_parameter(self, param) : if not self.socket : return self._send(self._GMSH_PARAMETER_QUERY, param.tochar()) (t, msg) = self._receive() if t == self._GMSH_PARAMETER : - param.fromchar(msg) - elif t == self._GMSH_PARAM_NOT_FOUND : - self._send(self._GMSH_PARAMETER, param.tochar()) - - def setString(self, name, value, **param): - param = _parameter('string', name=name, value=value, **param) - self._define_parameter(param) - return param.value - - def setNumber(self, name, value, **param): - if "labels" in param : + self._send(self._GMSH_PARAMETER_UPDATE, param.tochar()) #enrich a previous decl. + elif t == self._GMSH_PARAMETER_NOT_FOUND : + self._send(self._GMSH_PARAMETER, param.tochar()) #declaration + #print param.tochar() + + def declareNumber(self, name, **param): + if 'labels' in param : param["choices"] = param["labels"].keys() - p = _parameter('number', name=name, value=value, **param) - self._define_parameter(p) + p = _parameter('number', name=name, **param) + if 'value' not in param : #make the parameter readOnly + p.readOnly = 1 + p.attributes={'Highlight':'Orchid'} + self._declare_parameter(p) return p.value + def declareString(self, name, **param): + p = _parameter('string', name=name, **param) + if 'value' not in param : #make the parameter readOnly + p.readOnly = 1 + p.attributes={'Highlight':'Orchid'} + self._declare_parameter(p) + return p.value + + def setNumber(self, name, **param): + if not self.socket : + return + p = _parameter('number', name=name) + self._send(self._GMSH_PARAMETER_QUERY, p.tochar()) + (t, msg) = self._receive() + if t == self._GMSH_PARAMETER : + p.fromchar(msg).modify(**param) + self._send(self._GMSH_PARAMETER, p.tochar()) + elif t == self._GMSH_PARAMETER_NOT_FOUND : + p.modify(**param) + self._send(self._GMSH_PARAMETER, p.tochar()) + return p.value + + def setString(self, name, **param): + if not self.socket : + return + p = _parameter('string', name=name) + self._send(self._GMSH_PARAMETER_QUERY, p.tochar()) + (t, msg) = self._receive() + if t == self._GMSH_PARAMETER : #modify an existing parameter + p.fromchar(msg).modify(**param) + self._send(self._GMSH_PARAMETER, p.tochar()) + elif t == self._GMSH_PARAMETER_NOT_FOUND : #create a new parameter + p.modify(**param) + self._send(self._GMSH_PARAMETER, p.tochar()) + return p.value + def _get_parameter(self, param, warn_if_not_found=True) : if not self.socket : return @@ -135,29 +178,35 @@ class client : (t, msg) = self._receive() if t == self._GMSH_PARAMETER : param.fromchar(msg) - elif t == self._GMSH_PARAM_NOT_FOUND and warn_if_not_found : + elif t == self._GMSH_PARAMETER_NOT_FOUND and warn_if_not_found : print 'Unknown parameter %s' %(param.name) def getNumber(self, name, warn_if_not_found=True): - param = _parameter('number', name=name, value=0) + param = _parameter('number', name=name) self._get_parameter(param, warn_if_not_found) return param.value def getString(self, name, warn_if_not_found=True): - param = _parameter('string', name=name, value='void') + param = _parameter('string', name=name) self._get_parameter(param, warn_if_not_found) return param.value - def showGeometry(self, filename) : + def geometry(self, filename) : if not self.socket or not filename : return + #if self.action == 'compute' and self.getString('Gmsh/MergedGeo', False) == filename : if self.getString('Gmsh/MergedGeo', False) == filename : return else : - self.setString('Gmsh/MergedGeo', filename) + self.setString('Gmsh/MergedGeo', value=filename) if filename[0] != '/' : filename = os.getcwd() + "/" + filename self._send(self._GMSH_MERGE_FILE, filename) + + def mesh(self, filename) : + if not self.socket : + return + self._send(self._GMSH_PARSE_STRING, 'Mesh 3; Save "' + filename + '";') def mergeFile(self, filename) : if not self.socket : @@ -191,13 +240,16 @@ class client : if t == self._GMSH_STOP : self.NumSubClients -= 1 - def run(self, name, command): - msg = [name, command] + def run(self, name, command, arguments): if not self.socket : return + if self.action == "check": + msg = [name, command] + else: + msg = [name, command + ' ' + arguments] self._send(self._GMSH_CONNECT, '\0'.join(msg)) self.NumSubClients +=1 - self._wait_on_subclients() + self._wait_on_subclients() # makes the subclient blocking def __init__(self): self.socket = None @@ -211,18 +263,16 @@ class client : self._createSocket() self._send(self._GMSH_START, str(os.getpid())) self.action = self.getString('python/Action') + self.setNumber('IsPyMetamodel',value=1,visible=0) if self.action == "initialize": exit(0) def __del__(self) : + self._wait_on_subclients() + #print "Calling destructor of %s with %d subclients" %(self.name, self.NumSubClients) if self.socket : - self._wait_on_subclients() self._send(self._GMSH_STOP, 'Goodbye!') self.socket.close() -## wait_on_clients -## a la fin de sub_client -## envoyer GMSH_STOP seulement si les sous-clients sont termines. -## et modif dans onelabGroup run pour interdire au main -## de fermer les sockets de clients non-termines. +