]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
String -> PyObject + support of invocation of methods recursively.
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 31 Oct 2014 10:18:45 +0000 (11:18 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 31 Oct 2014 10:18:45 +0000 (11:18 +0100)
idl/SALOME_SDS.idl
src/SALOMESDS/SALOMEGlobalVarHelper.py
src/SALOMESDS/SALOMESDS_BasicDataServer.cxx
src/SALOMESDS/SALOMESDS_BasicDataServer.hxx
src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_DataScopeServer.hxx
src/SALOMESDS/SALOMESDS_RefCountServ.cxx
src/SALOMESDS/SALOMESDS_RefCountServ.hxx
src/SALOMESDS/SALOMESDS_StringDataServer.cxx
src/SALOMESDS/SALOMESDS_StringDataServer.hxx

index d77538f73cc33042a03e985b1cc0bd570306c7c5..381d9947c14859224975c3b729762c9280a21ea2 100644 (file)
 //
 // Author : Anthony GEAY (EDF R&D)
 
+#include "SALOME_GenericObj.idl"
+
 module SALOME
 {
   typedef sequence<string> StringVec;
   typedef sequence<octet> ByteVec;
   
-  interface BasicDataServer
+  interface BasicDataServer : GenericObj
   {
     string getVarName();
+    string getScopeName();
     void setReadOnlyStatus();
     void setRWStatus();
   };
 
-  /*interface PythonDataServer : BasicDataServer
-  {
-  };*/
-
   interface StringDataServer : BasicDataServer
   {
     void setSerializedContent(in ByteVec newValue);
     ByteVec fetchSerializedContent();
-    ByteVec invokePythonMethodOn(in string method, in ByteVec args);
+    StringDataServer invokePythonMethodOn(in string method, in ByteVec args);
   };
 
   interface DataServerManager;
@@ -50,6 +49,7 @@ module SALOME
     StringVec listVars();
     BasicDataServer retrieveVar(in string varName);
     StringDataServer createGlobalStringVar(in string varName);
+    StringDataServer createGlobalTmpVar(in ByteVec newValue);
     void shutdownIfNotHostedByDSM();
   };
 
index 3de94933cfa905051a1171a5e110a5b28cbccf02..8ceaf4522c59290998e92674e542451ada770d28 100644 (file)
 import SALOME
 import cPickle
 
-class SALOMEGlobalVarMethodHelper:
-    def __init__(self,varPtr,meth):
+class SALOMEGlobalVarHelper:
+    def __init__(self,varPtr,isTemporaryVar=False):
         assert(isinstance(varPtr,SALOME._objref_StringDataServer))
         self._var_ptr=varPtr
-        self._meth=meth
+        if not isTemporaryVar:
+            self._var_ptr.Register()
+        self._is_temp=isTemporaryVar
         pass
 
-    def __call__(self,*args):
-        #print "__call__ %s : %s"%(self._meth,str(args))
-        ret=self._var_ptr.invokePythonMethodOn(self._meth,cPickle.dumps(args,cPickle.HIGHEST_PROTOCOL))
-        return cPickle.loads(ret)
-    pass
-
-class SALOMEGlobalVarHelper:
-    def __init__(self,varPtr):
-        assert(isinstance(varPtr,SALOME._objref_StringDataServer))
-        self._var_ptr=varPtr
+    def __del__(self):
+        self._var_ptr.UnRegister()
         pass
     
     def assign(self,elt):
@@ -46,9 +40,9 @@ class SALOMEGlobalVarHelper:
         self._var_ptr.setSerializedContent(st)
         pass
         
-    def __getattr__(self,*args):
-        #print "__getattr__,%s"%(str(args))
-        return SALOMEGlobalVarMethodHelper(self._var_ptr,args[0])
+    def __getattr__(self,meth):
+        #print "__getattr__,%s"%(meth)
+        return SALOMEGlobalVarMethodHelper(self._var_ptr,meth)
 
     def __str__(self):
         return self.local_copy().__str__()
@@ -59,3 +53,25 @@ class SALOMEGlobalVarHelper:
     def local_copy(self):
         return cPickle.loads(self._var_ptr.fetchSerializedContent())    
     pass
+
+class SALOMEGlobalVarMethodHelper:
+    def __init__(self,varPtr,meth):
+        assert(isinstance(varPtr,SALOME._objref_StringDataServer))
+        self._var_ptr=varPtr
+        self._var_ptr.Register()
+        self._meth=meth
+        pass
+
+    def __call__(self,*args):
+        #print "__call__ %s : %s"%(self._meth,str(args))
+        ret=self._var_ptr.invokePythonMethodOn(self._meth,cPickle.dumps(args,cPickle.HIGHEST_PROTOCOL))
+        ret=SALOMEGlobalVarHelper(ret,True)
+        if self._meth not in ["__len__","__coerce__"]:
+            return ret
+        else:
+            return ret.local_copy()
+
+    def __del__(self):
+        self._var_ptr.UnRegister()
+        pass
+    pass
index b376b87729a0b38c8ecedbc1905d71c07000449b..d002d2fb9bd33b8ef6428b3e2f7ea66fd5b20e4c 100644 (file)
@@ -19,6 +19,7 @@
 // Author : Anthony GEAY (EDF R&D)
 
 #include "SALOMESDS_BasicDataServer.hxx"
+#include "SALOMESDS_DataScopeServer.hxx"
 #include "SALOMESDS_Exception.hxx"
 
 #include <sstream>
@@ -37,6 +38,11 @@ char *BasicDataServer::getVarName()
   return CORBA::string_dup(_var_name.c_str());
 }
 
+char *BasicDataServer::getScopeName()
+{
+  return _father->getScopeName();
+}
+
 /*!
  * Called remotely -> to protect against throw
  */
@@ -53,6 +59,21 @@ void BasicDataServer::setRWStatus()
   _is_read_only=false;
 }
 
+void BasicDataServer::Register()
+{
+  incrRef();
+}
+
+void BasicDataServer::UnRegister()
+{
+  decrRef();
+}
+
+void BasicDataServer::Destroy()
+{
+  enforcedRelease();
+}
+
 void BasicDataServer::checkReadOnlyStatusRegardingConstness(const char *sender) const
 {
   if(isReadOnly())
index 5edd934c57de6b41edacb936a119d02d5ac7bfae..d6139aabccabbbfb247e3fd082a438989331c06d 100644 (file)
@@ -37,8 +37,14 @@ namespace SALOMESDS
   public:
     BasicDataServer(DataScopeServer *father, const std::string& varName);
     char *getVarName();
+    char *getScopeName();
     void setReadOnlyStatus();
     void setRWStatus();
+  public:
+    void Register();
+    void UnRegister();
+    void Destroy();
+  public:
     std::string getVarNameCpp() const { return _var_name; }
   protected:
     void checkReadOnlyStatusRegardingConstness(const char *sender) const;
index 0d76735056976ba8e6b4d271e17748afa1f6abc9..7b529a59fb57065389b7203ffb3e92aa42cb5129 100644 (file)
@@ -30,6 +30,8 @@
 
 using namespace SALOMESDS;
 
+std::size_t DataScopeServer::COUNTER=0;
+
 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName)
 {
 }
@@ -118,6 +120,22 @@ SALOME::StringDataServer_ptr DataScopeServer::createGlobalStringVar(const char *
   return SALOME::StringDataServer::_narrow(ret);
 }
 
+/*!
+ * Called remotely -> to protect against throw
+ */
+SALOME::StringDataServer_ptr DataScopeServer::createGlobalTmpVar(const SALOME::ByteVec& newValue)
+{
+  static const char TMP_VAR_NAME[]="TmP";
+  std::string vn(BuildTmpVarNameFrom(TMP_VAR_NAME));
+  StringDataServer *retCpp(new StringDataServer(this,vn));
+  retCpp->setPOA(_poa);
+  retCpp->setSerializedContent(newValue);
+  //
+  PortableServer::ObjectId_var id(_poa->activate_object(retCpp));
+  CORBA::Object_var ret(_poa->id_to_reference(id));
+  return SALOME::StringDataServer::_narrow(ret);
+}
+
 void DataScopeServer::shutdownIfNotHostedByDSM()
 {
   SALOME_NamingService ns(_orb);
@@ -162,10 +180,6 @@ void DataScopeServer::initializePython(int argc, char *argv[])
   _locals=PyDict_New();
   PyObject *tmp(PyList_New(0));
   _pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
-  //Py_XDECREF(tmp);
-  //if(PyRun_String("import cPickle\n",Py_single_input,_globals,_locals)!=0)
-  //  throw Exception("DataScopeServer::setPOAAndRegister : cPickle is not available !");
-  /*_pickler=PyDict_GetItemString(_globals,"cPickle");*/
 }
 
 /*!
@@ -179,6 +193,13 @@ void DataScopeServer::setPOAAndRegister(PortableServer::POA_var poa, SALOME::Dat
   ns.Register(ptr,fullScopeName.c_str());
 }
 
+std::string DataScopeServer::BuildTmpVarNameFrom(const std::string& varName)
+{
+  std::ostringstream oss;
+  oss << varName << "@" << COUNTER++;
+  return oss.str();
+}
+
 std::vector< std::string > DataScopeServer::getAllVarNames() const
 {
   std::size_t sz(_vars.size());
index 8c71a524fd8564aff8cedf6df269484087bb87fb..ca4976d1a160d9a5341fb6881388c246e9aefe7a 100644 (file)
@@ -46,6 +46,7 @@ namespace SALOMESDS
     SALOME::StringVec *listVars();
     SALOME::BasicDataServer_ptr retrieveVar(const char *varName);
     SALOME::StringDataServer_ptr createGlobalStringVar(const char *varName);
+    SALOME::StringDataServer_ptr createGlobalTmpVar(const SALOME::ByteVec& newValue);
     void shutdownIfNotHostedByDSM();
     ~DataScopeServer();
   public:
@@ -54,6 +55,8 @@ namespace SALOMESDS
     PyObject *getGlobals() const { return _globals; }
     PyObject *getLocals() const { return _locals; }
     PyObject *getPickler() const { return _pickler; }
+    PortableServer::POA_var getPOA() { return _poa; }
+    static std::string BuildTmpVarNameFrom(const std::string& varName);
   private:
     std::vector< std::string> getAllVarNames() const;
     CORBA::Object_var activateWithDedicatedPOA(BasicDataServer *ds);
@@ -65,6 +68,7 @@ namespace SALOMESDS
     CORBA::ORB_var _orb;
     std::string _name;
     std::list< std::pair< SALOME::BasicDataServer_var, AutoRefCountPtr<BasicDataServer> > > _vars;
+    static std::size_t COUNTER;
   };
 }
 
index ca572817f96799c54e28ae5459a6cca11a636c8a..b21d5a9dcb7e47cc888b40d8d520771d378e9ebb 100644 (file)
@@ -32,13 +32,20 @@ bool RefCountServ::decrRef() const
   bool ret((--_cnt)==0);
   if(ret)
     {
-      PortableServer::ObjectId_var oid = (const_cast<RefCountServ *>(this))->_default_POA()->servant_to_id(const_cast<RefCountServ *>(this));
-      (const_cast<RefCountServ *>(this))->_default_POA()->deactivate_object(oid);
-      (const_cast<RefCountServ *>(this))->_remove_ref();
+      RefCountServ *thisNC(const_cast<RefCountServ *>(this));
+      thisNC->enforcedRelease();
     }
   return ret;
 }
 
+void RefCountServ::enforcedRelease()
+{
+  PortableServer::POA_var poa(getPOA());
+  PortableServer::ObjectId_var oid(poa->servant_to_id(this));
+  poa->deactivate_object(oid);
+  _remove_ref();
+}
+
 RefCountServ::RefCountServ():_cnt(1)
 {
 }
index 56582e3adc63d6223e4b7be8412c961f4c4dcaff..0ec2d95ab95ab4e040ad789aa80d45cd4b19ab57 100644 (file)
@@ -30,7 +30,9 @@ namespace SALOMESDS
   public:
     void incrRef() const;
     bool decrRef() const;
+    virtual PortableServer::POA_var getPOA() = 0;
   protected:
+    void enforcedRelease();
     RefCountServ();
     RefCountServ(const RefCountServ& other);
     virtual ~RefCountServ();
index 1bbc0236a54ae7f70b61ae42c4e9c85daf86a53f..77e5796e1f63b085fb49fa9c34e81eb97984f388 100644 (file)
 #include "SALOMESDS_DataScopeServer.hxx"
 #include "SALOMESDS_Exception.hxx"
 
+#include <iostream>
 #include <sstream>
 
 using namespace SALOMESDS;
 
-StringDataServer::StringDataServer(DataScopeServer *father, const std::string& varName):BasicDataServer(father,varName)
+StringDataServer::StringDataServer(DataScopeServer *father, const std::string& varName):BasicDataServer(father,varName),_self(Py_None)
+{
+  Py_XINCREF(Py_None);
+}
+
+//! obj is consumed
+StringDataServer::StringDataServer(DataScopeServer *father, const std::string& varName, PyObject *obj):BasicDataServer(father,varName),_self(obj)
 {
 }
 
 StringDataServer::~StringDataServer()
 {
+  std::cerr << "~~~~~~~~~~ StringDataServer : " << getVarNameCpp() << std::endl;
+  Py_XDECREF(_self);
 }
 
 /*!
@@ -40,7 +49,9 @@ StringDataServer::~StringDataServer()
 void StringDataServer::setSerializedContent(const SALOME::ByteVec& newValue)
 {
   checkReadOnlyStatusRegardingConstness("StringDataServer::setSerializedContent : read only var !");
-  FromByteSeqToCpp(newValue,_data);
+  std::string data;
+  FromByteSeqToCpp(newValue,data);
+  setNewPyObj(getPyObjFromPickled(data));
 }
 
 /*!
@@ -48,38 +59,46 @@ void StringDataServer::setSerializedContent(const SALOME::ByteVec& newValue)
  */
 SALOME::ByteVec *StringDataServer::fetchSerializedContent()
 {
-  return FromCppToByteSeq(_data);
+  Py_XINCREF(_self);//because pickelize consume _self
+  return FromCppToByteSeq(pickelize(_self));
 }
 
 /*!
  * Called remotely -> to protect against throw
  */
-SALOME::ByteVec *StringDataServer::invokePythonMethodOn(const char *method, const SALOME::ByteVec& args)
+SALOME::StringDataServer_ptr StringDataServer::invokePythonMethodOn(const char *method, const SALOME::ByteVec& args)
 {
-  PyObject *self(getPyObjFromPickled(_data));
+  if(!_self)
+    throw Exception("StringDataServer::invokePythonMethodOn : self is NULL !");
   std::string argsCpp;
   FromByteSeqToCpp(args,argsCpp);
   PyObject *argsPy(getPyObjFromPickled(argsCpp));
   //
-  PyObject *selfMeth(PyObject_GetAttrString(self,method));
+  PyObject *selfMeth(PyObject_GetAttrString(_self,method));
   if(!selfMeth)
     {
       std::ostringstream oss; oss << "StringDataServer::invokePythonMethodOn : Method \"" << method << "\" is not available !";
       throw Exception(oss.str());
     }
-  PyObject *res(PyObject_CallObject(selfMeth,argsPy));
+  PyObject *res(PyObject_CallObject(selfMeth,argsPy));// self can have been modified by this call !
+  Py_XDECREF(selfMeth);
+  Py_XDECREF(argsPy);
   if(!res)
     {
       std::ostringstream oss; oss << "StringDataServer::invokePythonMethodOn : Problem during invokation serverside of Method \"" << method << "\" !";
       throw Exception(oss.str());
     }
-  _data=pickelize(self);// if it is a non const method !
-  std::string retCpp(pickelize(res));
-  // to test : res and self
-  Py_XDECREF(selfMeth);
-  //
-  Py_XDECREF(argsPy);
-  return FromCppToByteSeq(retCpp);
+  StringDataServer *ret(new StringDataServer(_father,DataScopeServer::BuildTmpVarNameFrom(getVarNameCpp()),res));
+  PortableServer::POA_var poa(_father->getPOA());
+  ret->setPOA(poa);
+  PortableServer::ObjectId_var id(poa->activate_object(ret));
+  CORBA::Object_var obj(poa->id_to_reference(id));
+  return SALOME::StringDataServer::_narrow(obj);
+}
+
+PortableServer::POA_var StringDataServer::getPOA()
+{
+  return _poa;
 }
 
 void StringDataServer::FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret)
@@ -137,3 +156,14 @@ std::string StringDataServer::pickelize(PyObject *obj)
   Py_XDECREF(retPy);
   return ret;
 }
+
+//! obj is consumed by this method.
+void StringDataServer::setNewPyObj(PyObject *obj)
+{
+  if(!obj)
+    throw Exception("StringDataServer::setNewPyObj : trying to assign a NULL pyobject in this !");
+  if(obj==_self)
+    return ;
+  Py_XDECREF(_self);
+  _self=obj;
+}
index 94be7af61d7a96996887d8b08e90cb46637db1d0..bb266a05841fb3135de4c508b1fbcf5cd93822cc 100644 (file)
@@ -34,18 +34,24 @@ namespace SALOMESDS
   {
   public:
     StringDataServer(DataScopeServer *father, const std::string& varName);
+    StringDataServer(DataScopeServer *father, const std::string& varName, PyObject *obj);
     ~StringDataServer();
     void setSerializedContent(const SALOME::ByteVec& newValue);
     SALOME::ByteVec *fetchSerializedContent();
-    SALOME::ByteVec *invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
+    SALOME::StringDataServer_ptr invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
+  public:
+    void setPOA(PortableServer::POA_var poa) { _poa=poa; }
   private:
+    PortableServer::POA_var getPOA();
     static void FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret);
     static SALOME::ByteVec *FromCppToByteSeq(const std::string& strToBeConv);
     PyObject *getPyObjFromPickled(const std::string& pickledData);
     std::string pickelize(PyObject *obj);
+    void setNewPyObj(PyObject *obj);
   private:
     static const char FAKE_VAR_NAME_FOR_WORK[];
-    std::string _data;
+    PyObject *_self;
+    PortableServer::POA_var _poa;
   };
 }