Salome HOME
Merge branch 'agy/ParallelContainerLaunch'
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 7 Oct 2014 09:59:17 +0000 (11:59 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 7 Oct 2014 09:59:17 +0000 (11:59 +0200)
135 files changed:
doc/principes.rst
doc/schemapy.rst
src/bases/AutoLocker.hxx [new file with mode: 0644]
src/bases/AutoRefCnt.hxx [new file with mode: 0644]
src/bases/CMakeLists.txt
src/bases/Mutex.hxx
src/bases/MutexPT.cxx
src/bases/MutexPT.hxx
src/bases/Test/basesTest.cxx
src/bases/ThreadPT.cxx
src/bases/ThreadPT.hxx
src/engine/AnyInputPort.cxx
src/engine/AnyOutputPort.cxx
src/engine/Bloc.cxx
src/engine/Bloc.hxx
src/engine/CMakeLists.txt
src/engine/ComponentInstance.cxx
src/engine/ComponentInstance.hxx
src/engine/ComposedNode.cxx
src/engine/ComposedNode.hxx
src/engine/Container.cxx
src/engine/Container.hxx
src/engine/ElementaryNode.cxx
src/engine/ElementaryNode.hxx
src/engine/Executor.cxx
src/engine/Executor.hxx
src/engine/HomogeneousPoolContainer.cxx [new file with mode: 0644]
src/engine/HomogeneousPoolContainer.hxx [new file with mode: 0644]
src/engine/InlineNode.cxx
src/engine/InlineNode.hxx
src/engine/Loop.cxx
src/engine/Loop.hxx
src/engine/Node.cxx
src/engine/Node.hxx
src/engine/Proc.cxx
src/engine/Proc.hxx
src/engine/PropertyInterface.hxx
src/engine/RefCounter.cxx
src/engine/RefCounter.hxx
src/engine/ServerNode.cxx
src/engine/ServerNode.hxx
src/engine/ServiceNode.cxx
src/engine/ServiceNode.hxx
src/engine/StaticDefinedComposedNode.cxx
src/engine/StaticDefinedComposedNode.hxx
src/engine/Switch.cxx
src/engine/Switch.hxx
src/engine/Task.hxx
src/engine/Test/ComponentInstanceTest.cxx
src/engine/Test/ComponentInstanceTest.hxx
src/engine/Test/ContainerTest.cxx
src/engine/Test/ContainerTest.hxx
src/engine/VisitorSaveSchema.cxx
src/engine/VisitorSaveState.cxx
src/engine/VisitorSaveState.hxx
src/engine_swig/engtypemaps.i
src/engine_swig/pilot.i
src/engine_swig/pypilot.i
src/genericgui/CMakeLists.txt
src/genericgui/EditionComponent.cxx
src/genericgui/EditionContainer.cxx
src/genericgui/EditionContainer.hxx
src/genericgui/EditionSalomeNode.cxx
src/genericgui/EditionSalomeNode.hxx
src/genericgui/EditionScript.cxx
src/genericgui/EditionScript.hxx
src/genericgui/FormAdvParamContainer.cxx [new file with mode: 0644]
src/genericgui/FormAdvParamContainer.hxx [new file with mode: 0644]
src/genericgui/FormAdvParamContainer.ui [new file with mode: 0644]
src/genericgui/FormContainer.cxx
src/genericgui/FormContainer.hxx
src/genericgui/FormContainer.ui
src/genericgui/FormContainerBase.cxx [new file with mode: 0644]
src/genericgui/FormContainerBase.hxx [new file with mode: 0644]
src/genericgui/FormContainerDecorator.cxx [new file with mode: 0644]
src/genericgui/FormContainerDecorator.hxx [new file with mode: 0644]
src/genericgui/FormHPContainer.cxx [new file with mode: 0644]
src/genericgui/FormHPContainer.hxx [new file with mode: 0644]
src/genericgui/FormHPContainer.ui [new file with mode: 0644]
src/genericgui/FormParamContainer.ui [new file with mode: 0644]
src/genericgui/GenericGui.cxx
src/genericgui/GenericGui.hxx
src/genericgui/GuiEditor.cxx
src/genericgui/GuiEditor.hxx
src/genericgui/ItemEdition.cxx
src/genericgui/Menus.cxx
src/hmi/commandsProc.cxx
src/hmi/commandsProc.hxx
src/hmi/guiContext.hxx
src/hmi/guiObservers.cxx
src/hmi/guiObservers.hxx
src/runtime/AutoGIL.hxx [new file with mode: 0644]
src/runtime/CMakeLists.txt
src/runtime/CORBAComponent.cxx
src/runtime/CORBAComponent.hxx
src/runtime/CORBANode.cxx
src/runtime/CORBAPorts.cxx
src/runtime/CppComponent.cxx
src/runtime/CppComponent.hxx
src/runtime/CppContainer.cxx
src/runtime/CppContainer.hxx
src/runtime/DistributedPythonNode.cxx
src/runtime/DistributedPythonNode.hxx
src/runtime/PythonNode.cxx
src/runtime/PythonNode.hxx
src/runtime/RuntimeSALOME.cxx
src/runtime/SalomeComponent.cxx
src/runtime/SalomeComponent.hxx
src/runtime/SalomeContainer.cxx
src/runtime/SalomeContainer.hxx
src/runtime/SalomeContainerHelper.cxx [new file with mode: 0644]
src/runtime/SalomeContainerHelper.hxx [new file with mode: 0644]
src/runtime/SalomeContainerTmpForHP.cxx [new file with mode: 0644]
src/runtime/SalomeContainerTmpForHP.hxx [new file with mode: 0644]
src/runtime/SalomeContainerTools.cxx [new file with mode: 0644]
src/runtime/SalomeContainerTools.hxx [new file with mode: 0644]
src/runtime/SalomeHPComponent.cxx [new file with mode: 0644]
src/runtime/SalomeHPComponent.hxx [new file with mode: 0644]
src/runtime/SalomeHPContainer.cxx [new file with mode: 0644]
src/runtime/SalomeHPContainer.hxx [new file with mode: 0644]
src/runtime/SalomeHPContainerTools.cxx [new file with mode: 0644]
src/runtime/SalomeHPContainerTools.hxx [new file with mode: 0644]
src/runtime/SalomePythonComponent.cxx
src/runtime/SalomePythonComponent.hxx
src/runtime/SalomePythonNode.cxx
src/runtime/XMLNode.cxx
src/runtime_swig/SALOMERuntime.i
src/yacsloader/containerParsers.cxx
src/yacsloader/containerParsers.hxx
src/yacsloader/procParsers.hxx
src/yacsloader/serverParsers.hxx
src/yacsloader_swig/Test/StdAloneYacsLoaderTest1.py [changed mode: 0755->0644]
src/yacsloader_swig/Test/YacsLoaderInSessionTest.sh.in
src/yacsloader_swig/Test/testSaveLoadRun.py [new file with mode: 0644]
src/yacsloader_swig/loader.i

index d827077ceefdc27200e5aacaa748a19fa7e9fe3c..88c24d43f332c3baedc811bdc4059e8338660b18 100644 (file)
@@ -580,12 +580,53 @@ To create this type of node:
 
 Containers
 ---------------------
-The SALOME platform executes its components after loading them in containers.  A SALOME container is a process managed 
-by the platform that may be executed on any known resource.
-A YACS container is used to define component placement constraints without necessarily precisely defining the resource 
-to be used or the container name.
-The YACS container has a name.  Constraints are given in the form of container properties.  
-The current list of properties is as follows:
+
+**WARNING !** Their are two notions of containers in the Salome world that must be clearly distinguished.
+
+- YACS container, that will be explained extensively here.
+- KERNEL container which is a single process managed by the plateform that may be executed on any resource in the resource catalog of the current SALOME application.
+   This single process can perform a set of jobs.
+
+To avoid misleading, in this chapter, container word will be systematically explicited.
+
+YACS Container objects are used in the definition of a scheme to define constraints on the placement of some tasks (run remotely) of a YACS scheme. YACS containers objects are parts of a scheme as nodes are.
+So the job of the conceptor of a YACS scheme is to correctly allocate remotely executed elementary nodes over YACS container objects of the scheme to respect the states of KERNEL components running on KERNEL container and the states of KERNEL container itself.
+Exactly one YACS container is attached (directy or indirectly through YACS components) to elementary nodes (or tasks) that can be run remotely.
+
+The tasks (elementary nodes) that can be run remotely are ( or the tasks that are attached to a YACS container are ) :
+
+- Python script node.
+- Python function node.
+- Salome node.
+
+So all elementary nodes of a scheme (whatever their types in the list above) that are supposed to be executed remotely are supposed to be attached to a set of YACS container objects.
+
+YACS container can be seen as a placement request at edition time of a scheme. **During the execution of a scheme, a YACS container is incarnated into one or several KERNEL containers** depending on the type of the YACS container.
+
+Presently, there are 3 types of containers that incarnates the 3 different mapping strategies between YACS container and KERNEL container :
+
+- Mono YACS container : The most simple. There is exactly one KERNEL container attached on one mono YACS container. **WARNING**, this type of YACS container can be dangerous into the context of foreach because several tasks can be invoked in parallel inside of a same process that can leads to problem if the service owning this YACS container is not thread safe. This type of YACS container leads to no special treatment from Executor point of view.
+- Multi YACS container : There is as KERNEL containers attached on a multi YACS container as there are YACS component instances attached to it in the scheme. In the context of foreach, it can leads to a pool of KERNEL containers attached to a YACS container. The KERNEL container is obtained using as key the pointer to the YACS component object. This type of YACS container leads to no special treatment from Executor point of view.
+- HP YACS container : HP stands for Homogeneous Pool of KERNEL container. A HP YACS container is mapped to a fixed size set of KERNEL containers. This pool is homogeneous which means that each of the KERNEL container inside the pool can be used indifferentely (and will be used during execution) by the nodes attached to a same HP YACS container. The KERNEL container is obtainer using the requesting node. Contrary to the 2 YACS containers type above, the Executor is active with that type of YACS container by performing, if needed, a cutoff towards remotely executed tasks list in READY state regarding the availability of different YACS HP containers.
+
+To create containers from TUI, see :ref:`py_container_creation`.
+
+All of these 3 types of YACS containers are sharing a common important features : set of properties.
+
+Properties are a set of (key,value) pairs which are designed to be forwarded directly to the KERNEL (expected "name" property and "attached_on_cloning" property, see :ref:`containers_aoc_property`) when a task attached to the YACS container has LOAD status during the execution of a scheme.
+
+The array below presents extensively the list of available keys and corresponding values expected that are common to 3 types of YACS container.
+Those properties (excepted "name" and "attached_on_cloning" property) are the way to specify the request to the KERNEL when the mapping will be requested by the Executor of YACS.
+For your information the dump in XML file of each YACS container object contains exclusively those (key,value) pairs.
+
+- To set properties from GUI to a YACS container, see :ref:`pp_for_container`.
+- To set properties from python interface, see :ref:`py_container`.
+
+.. note:: One important property is the "container_name" that must not be confused with property "name". "name" is relative to YACS container only (that will appear in XML file)
+  "container_name" is a part of the request at run time when attaching KERNEL container with YACS container. Warning, the behaviour of mapping is sensitive to the fact that
+  "container_name" property is empty or not.
+
+.. note:: HP YACS containers have 2 additionnal properties compared to Mono and Multi YACS Container. The first one is the "SizeOfPool" that defines the size of the set of KERNEL containers. The second one is "InitializeScriptKey" which contains the string of a python code that will be passed to each of the KERNEL containers of the pool to initialize it (if necessary).
 
 .. tabularcolumns:: |p{3cm}|p{3cm}|p{10cm}|
 
@@ -594,6 +635,7 @@ Name                  Type            Type of constraint
 =================== ============= =============================================
 name                  string       if given imposes the resource to use. If not given, the resource manager will try
                                    to find the best resource according to the constraints given by the other attributes.
+attached_on_cloning   bool         By default false for Multi and Mono YACS containers. Always true and not settable for HP containers. See :ref:`containers_aoc_property`
 container_name        string       if given imposes the SALOME container name
 hostname              string       if given imposes the machine (constraint used if name is not given)
 policy               "best",       Choose the best or the first or the next in 
@@ -625,6 +667,24 @@ Undefined criteria are ignored. The price of each criterion is:
  - medium (2) if the expected value of the criterion is less than the value of the criterion in the resource
  - the lowest (1) if the expected value of the criterion is higher than the value of the criterion in the resource
 
+.. _containers_aoc_property:
+
+Attached On cloning property
+''''''''''''''''''''''''''''''
+
+A specific chapter is dedicated to that property of YACS container. This property is only used by YACS not forwarded at all to KERNEL. The value of this property is either False or True.
+This property is writable and by default set to false for mono YACS container and multi YACS container. For HP YACS container this property is not writable and set to true.
+This property controles the behaviour of the YACS container it belongs to when cloning is triggered.
+
+A cloning is triggered during execution of a scheme for ForEachLoop and OptimizerLoop nodes of the scheme.
+In fact, when a ForEachLoop or OpmizerLoop node is executed it immediatly clones nbOfBranches times the node inside it (and performs right connections on these copies) using Node::clone method that recurvively creates a deep copy of the node.
+
+The question is : What is done for deep copied elementary nodes executed remotely ? Are the copied node and base node share the same YACS container object or Are the copied node is lying on a deep copy of the YACS container of the base node ?
+
+It is here where "attached_on_cloning" property of YACS container is considered. If false, a deep copy of YACS container is done when cloning of remotely executed node is done. If true, the cloned node and the node itself will share the same YACS container.
+
+So it appears natural that HP YACS containers have this property set to true because it is the aim of HP YACS container to share a same pool of workers accross all the nodes especially in the ForEachLoop or OptimizerLoop context.
+
 .. _catalogResources:
 
 The resources catalog
index c4d4598ea859ebf6ed5c34321d6e2d6ac1f6a686..3880dcf16000fdf1aab176a53bb9b2078e9dc6c6 100644 (file)
@@ -601,6 +601,25 @@ is defined by the class async in the python module myalgo2.py::
   p.edAddLink(ol.getOutputPort("evalSamples"),n.getInputPort("p1"))
   p.edAddLink(n.getOutputPort("p1"),ol.getInputPort("evalResults"))
 
+.. _py_container_creation:
+
+Creation of the three type of containers
+''''''''''''''''''''''''''''''''''''''''
+
+To create a mono YACS container simply invoke::
+
+   my_mono_cont=p.createContainer("MyMonoCont","Salome")
+   my_mono_cont.setProperty("type","mono")
+
+To create a multi YACS container simply invoke::
+
+   my_multi_cont=p.createContainer("MyMultiCont","Salome")
+   my_multi_cont.setProperty("type","multi")
+
+To create a HP YACS container simply invoke::
+
+   my_hp_cont=p.createContainer("MyHPCont","HPSalome")
+
 .. _py_container:
 
 Definition of containers
diff --git a/src/bases/AutoLocker.hxx b/src/bases/AutoLocker.hxx
new file mode 100644 (file)
index 0000000..8960361
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __AUTOLOCKER_HXX__
+#define __AUTOLOCKER_HXX__
+
+#include "Exception.hxx"
+
+namespace YACS
+{
+  namespace BASES
+  {
+    template<class T>
+    class AutoLocker
+    {
+    public:
+      AutoLocker(T *m):_ptr(m) { _ptr->lock(); }
+      ~AutoLocker() { _ptr->unLock(); }
+    private:
+      T *_ptr;
+    };
+  }
+}
+
+#endif
diff --git a/src/bases/AutoRefCnt.hxx b/src/bases/AutoRefCnt.hxx
new file mode 100644 (file)
index 0000000..592c5b9
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __AUTOREFCNT_HXX__
+#define __AUTOREFCNT_HXX__
+
+#include "Exception.hxx"
+
+namespace YACS
+{
+  namespace BASES
+  {
+    template<class T>
+    class AutoRefCnt
+    {
+    public:
+      AutoRefCnt(const AutoRefCnt& other):_ptr(0) { referPtr(other._ptr); }
+      AutoRefCnt(T *ptr=0):_ptr(ptr) { }
+      ~AutoRefCnt() { destroyPtr(); }
+      bool operator==(const AutoRefCnt& other) const { return _ptr==other._ptr; }
+      bool operator==(const T *other) const { return _ptr==other; }
+      AutoRefCnt &operator=(const AutoRefCnt& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; }
+      AutoRefCnt &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+      T *operator->() { return _ptr ; }
+      const T *operator->() const { return _ptr; }
+      T& operator*() { return *_ptr; }
+      const T& operator*() const { return *_ptr; }
+      operator T *() { return _ptr; }
+      operator const T *() const { return _ptr; }
+      T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; }
+    private:
+      void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); }
+      void destroyPtr() { if(_ptr) _ptr->decrRef(); }
+    private:
+      T *_ptr;
+    };
+
+    template<class T, class U>
+    typename YACS::BASES::AutoRefCnt<U> DynamicCast(typename YACS::BASES::AutoRefCnt<T>& autoSubPtr) throw()
+    {
+      T *subPtr(autoSubPtr);
+      U *ptr(dynamic_cast<U *>(subPtr));
+      typename YACS::BASES::AutoRefCnt<U> ret(ptr);
+      if(ptr)
+        ptr->incrRef();
+      return ret;
+    }
+
+    template<class T, class U>
+    typename YACS::BASES::AutoRefCnt<U> DynamicCastSafe(typename YACS::BASES::AutoRefCnt<T>& autoSubPtr)
+    {
+      T *subPtr(autoSubPtr);
+      U *ptr(dynamic_cast<U *>(subPtr));
+      if(subPtr && !ptr)
+        throw Exception("DynamicCastSafe : U is not a subtype of T !");
+      typename YACS::BASES::AutoRefCnt<U> ret(ptr);
+      if(ptr)
+        ptr->incrRef();
+      return ret;
+    }
+
+    template<class T>
+    class AutoCppPtr
+    {
+    public:
+      AutoCppPtr(T *ptr=0):_ptr(ptr) {  }
+      ~AutoCppPtr() { destroyPtr(); }
+      AutoCppPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+      T *operator->() { return _ptr ; }
+      const T *operator->() const { return _ptr; }
+      T& operator*() { return *_ptr; }
+      const T& operator*() const { return *_ptr; }
+      operator T *() { return _ptr; }
+      operator const T *() const { return _ptr; }
+    private:
+      void destroyPtr() { delete _ptr; }
+    private:
+      T *_ptr;
+    };
+  }
+}
+
+#endif
index 95bb14f9f97d7889bc0f6fc8d37bfedaf1d529c5..d2cf1373bc5204059a0a50ff64533dd215a701ee 100644 (file)
@@ -44,6 +44,8 @@ SET(YACSBases_HEADERS
   DynLibLoader.hxx
   DynLibLoaderWin.hxx
   Exception.hxx
+  AutoRefCnt.hxx
+  AutoLocker.hxx
   Mutex.hxx
   MutexPT.hxx
   Semaphore.hxx
index 0dcf0a1fcd62d71c252656182db1e2e4673b6b40..997d02b9b039f9660e35434573016c554328915c 100644 (file)
@@ -49,12 +49,6 @@ namespace YACS
   {
     typedef MutexPT Mutex;
     typedef ConditionPT Condition;
-    struct Lock
-    {
-      YACS::BASES::Mutex * _mutex;
-      Lock(YACS::BASES::Mutex * mutex) : _mutex(mutex) {_mutex->lock();};
-      ~Lock() {_mutex->unlock();};
-    };
   }
 }
 #else
index 5d94acc9e6432d6da013f317466e49faacc82041..97aecb0a5da9a4afa03f00ceae264a3ea889d561 100644 (file)
@@ -38,7 +38,7 @@ void MutexPT::lock()
   pthread_mutex_lock(&_mutexDesc);
 }
 
-void MutexPT::unlock()
+void MutexPT::unLock()
 {
   pthread_mutex_unlock(&_mutexDesc);
 }
index cbe22aa4d17abe006144d0b21c2f13cac5224323..af9a73e199df74fc32db81423f5e23b286af149e 100644 (file)
@@ -36,7 +36,7 @@ namespace YACS
       MutexPT();
       ~MutexPT();
       void lock();
-      void unlock();
+      void unLock();
       friend class ConditionPT;
     private:
       pthread_mutex_t _mutexDesc;
index 544ff6e030c250f4c3dcde7bd8fd166f320176fb..056cf2d1ef9cac4b8047dd0ed0a387994bffb887 100644 (file)
@@ -86,7 +86,7 @@ void *BasesTest::th2_1(void *)
       tmp = tmp+1;
       Thread::sleep(1000);
       _value = tmp;
-      _m.unlock();
+      _m.unLock();
       Thread::sleep(100000);
     }
   return 0;
@@ -120,7 +120,7 @@ void BasesTest::get_resources(int id, int amount)
     }
   _resources -= amount;
   _ownedResources[id] = amount;
-  _m.unlock(); 
+  _m.unLock();
 }
 
 void BasesTest::free_resources(int id, int amount)
@@ -133,7 +133,7 @@ void BasesTest::free_resources(int id, int amount)
       _waiting = 0;
       _cond.notify_all();
     }
-  _m.unlock();
+  _m.unLock();
 }
 
 int BasesTest::count_resources()
@@ -147,7 +147,7 @@ int BasesTest::count_resources()
       {
         totOwned += _ownedResources[i];
       }
-    _m.unlock();
+    _m.unLock();
   }
   int total = resources + totOwned;
   DEBTRACE("resources:: owned by threads: " << totOwned << " remaining: " << resources << " total: " << total);
index c0bbf234840217d11fc63b19f8b03891f92df824..21f1ddb88cf2e783276dbd1f1f74755a74cf418a 100644 (file)
 
 using namespace YACS::BASES;
 
+ThreadPT::ThreadPT()
+{
+}
+
 ThreadPT::ThreadPT(ThreadJob funcPtr, void *stack, size_t stackSize)
+{
+  go(funcPtr,stack,stackSize);
+}
+
+void ThreadPT::go(ThreadJob funcPtr, void *stack, size_t stackSize)
 {
   int err;
   void **stackT=(void **) stack;
index 290bc7aa308662e1dfaf6b10ec816db688c76e09..946a2904dcd5b22053164719b24cf8177ea72bfc 100644 (file)
@@ -33,7 +33,9 @@ namespace YACS
     public:
       typedef void *(*ThreadJob)(void*);
     public:
+      ThreadPT();
       ThreadPT(ThreadJob funcPtr, void *stack, size_t stackSize = 0);
+      void go(ThreadJob funcPtr, void *stack, size_t stackSize = 0);
       bool operator==(const ThreadPT& other);
       void join();
       static void detach();
index dceb3b4764cd8489f6596167940d7a6d2e79a74f..f204b5cb84b1459ca358e41a2f95abe48e95bba1 100644 (file)
 
 #include "AnyInputPort.hxx"
 #include "TypeCode.hxx"
-#include <iostream>
-#include <sstream>
 #include "Mutex.hxx"
+#include "AutoLocker.hxx"
 
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
 
+#include <iostream>
+#include <sstream>
+
 using namespace YACS::ENGINE;
 using namespace std;
 
@@ -83,7 +85,7 @@ void AnyInputPort::exRestoreInit()
 
 void AnyInputPort::put(Any *data)
 {
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
   if(_value)
     _value->decrRef();
   _value=data;
@@ -105,7 +107,7 @@ void *AnyInputPort::get() const
 
 std::string AnyInputPort::getAsString()
 {
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
   return getRuntime()->convertNeutralAsString(edGetType(),_value);
 }
 
index 792b487b5ce2bb9a07ad20fcc92dd48d265f4852..cdd7ccac1be8b3af2112a126d38d0af515c8e3d3 100644 (file)
@@ -18,8 +18,9 @@
 //
 
 #include "AnyOutputPort.hxx"
-#include "Any.hxx"
+#include "AutoLocker.hxx"
 #include "Runtime.hxx"
+#include "Any.hxx"
 
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
@@ -47,7 +48,7 @@ AnyOutputPort::~AnyOutputPort()
 //! store the current dispatched value
 void AnyOutputPort::setValue(Any *data) 
 {
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
   if(_data)
     _data->decrRef();
   _data = data; 
@@ -73,6 +74,6 @@ void AnyOutputPort::put(YACS::ENGINE::Any *data) throw(ConversionException)
 
 std::string AnyOutputPort::getAsString()
 {
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
   return getRuntime()->convertNeutralAsString(edGetType(),_data);
 }
index 422e3947099d20254774fec16953c5ee051f032c..b12217dfb02b919e2637203f5cced5bc8e102a35 100644 (file)
@@ -229,10 +229,6 @@ Node *Bloc::getChildByShortName(const std::string& name) const throw(YACS::Excep
   throw Exception(what);
 }
 
-void Bloc::selectRunnableTasks(std::vector<Task *>& tasks)
-{
-}
-
 bool Bloc::areAllSubNodesDone() const
 {
   for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
index dce0ee4853d8a2958531d929f7b9a9993fe59a34..98f2e0fc0b6f9d6920fe16c4b105216d452a9c12 100644 (file)
@@ -52,7 +52,6 @@ namespace YACS
       std::list<Node *> getChildren() const { return _setOfNode; }
       std::list<Node *> edGetDirectDescendants() const { return _setOfNode; }
       Node *getChildByShortName(const std::string& name) const throw(Exception);
-      void selectRunnableTasks(std::vector<Task *>& tasks);
       virtual void writeDot(std::ostream &os) const;
       void accept(Visitor *visitor);
       template<bool direction>
index e9d752691af2585953cf49f858394290d83dbb22..2eb5ba3a50c9c864cde36c025dc4a88411152e52 100644 (file)
@@ -154,6 +154,7 @@ SET(YACSlibEngine_SOURCES
   ComponentInstance.cxx
   Dispatcher.cxx
   Container.cxx
+  HomogeneousPoolContainer.cxx
   DeploymentTree.cxx
   Logger.cxx
   LogRecord.cxx
index ff83a2e58b54ce946b7035a00fc41a304097e781..4e5a7957e586ada04b18b82e491d8840a823e3bb 100644 (file)
@@ -49,9 +49,9 @@ int ComponentInstance::_total = 0;
 
 const char ComponentInstance::NULL_FILE_REPR[]="No repr specified for ComponentInstance";
 
-void ComponentInstance::setContainer(Container *cont)
+bool ComponentInstance::setContainer(Container *cont)
 {
-  if (cont == _container) return;
+  if (cont == _container) return false;
   
   if(cont)
     cont->checkCapabilityToDealWith(this);
@@ -60,6 +60,7 @@ void ComponentInstance::setContainer(Container *cont)
   _container=cont;
   if(_container)
     _container->incrRef();
+  return true;
 }
 
 ComponentInstance::ComponentInstance(const std::string& name):_compoName(name),_isAttachedOnCloning(false),_container(0),_anonymous(true)
@@ -127,6 +128,11 @@ string ComponentInstance::getKind() const
   return KIND;
 }
 
+std::string ComponentInstance::getKindForNode() const
+{
+  return KIND;
+}
+
 void ComponentInstance::shutdown(int level)
 {
 }
index c56a13131480d3a4d5520dcaae2670f6f86f21cd..ff1fefa7844535fb0d2171f88f9bf450d8597c4e 100644 (file)
@@ -31,8 +31,9 @@ namespace YACS
 {
   namespace ENGINE
   {
-    class Container;
+    class Task;
     class ServiceNode;
+    class Container;
 
     class YACSLIBENGINE_EXPORT ComponentInstance : public PropertyInterface, public RefCounter
     {
@@ -47,21 +48,23 @@ namespace YACS
       virtual void setAnonymous(bool anon) { _anonymous = anon; };
       virtual bool isAnonymous() { return _anonymous; };
       int getNumId() const { return _numId; }
-      virtual void setContainer(Container *cont);
+      virtual bool setContainer(Container *cont);
       Container *getContainer() const { return _container; }
 //! Load the component instance
-      virtual void load() = 0;
+      virtual void load(Task *askingNode) = 0;
 //! Unload the component instance
-      virtual void unload() = 0;
+      virtual void unload(Task *askingNode) = 0;
 //! Indicate if the component instance is loaded (true) or not
-      virtual bool isLoaded() = 0;
+      virtual bool isLoaded(Task *askingNode) const = 0;
       virtual void attachOnCloning() const;
       virtual void dettachOnCloning() const;
       bool isAttachedOnCloning() const;
       virtual std::string getFileRepr() const;
       virtual ServiceNode* createNode(const std::string& name)=0;
       virtual ComponentInstance *clone() const = 0;
+      virtual ComponentInstance *cloneAlways() const = 0;
       virtual std::string getKind() const;
+      virtual std::string getKindForNode() const;
       static const char KIND[];
       virtual void shutdown(int level);
     protected:
index aa9f9b5842bb23fb1715c15ac59b6287c9b56fea..5bf110794a9169267a6071c59b5e72697a5355ef 100644 (file)
@@ -109,6 +109,45 @@ void ComposedNode::performDuplicationOfPlacement(const Node& other)
     }
 }
 
+void ComposedNode::performShallowDuplicationOfPlacement(const Node& other)
+{
+  const ComposedNode &otherC=*(dynamic_cast<const ComposedNode *>(&other));
+  DeploymentTree treeToDup=otherC.getDeploymentTree();
+  list< ElementaryNode * > clones=otherC.getRecursiveConstituents();
+  vector<Container *> conts=treeToDup.getAllContainers();
+  //iterate on all containers
+  for(vector<Container *>::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
+    {
+      vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
+      Container *contCloned((*iterCt));
+
+      //iterate on all component instances linked to the container
+      for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
+        {
+          vector<Task *> tasks=treeToDup.getTasksLinkedToComponent(*iterCp);
+          ComponentInstance *curCloned((*iterCp));
+          curCloned->setContainer(contCloned);
+          for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
+            {
+              //No risk for static cast : appendTask called by ComposedNode.
+              list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
+              //No risk here to because called only on cloning process...
+              ServiceNode *nodeC=(ServiceNode *)getChildByName(otherC.getChildName(*res));
+              nodeC->setComponent(curCloned);
+            }
+        }
+
+      // iterate on all tasks linked to the container
+      vector<Task *> tasks=treeToDup.getTasksLinkedToContainer(*iterCt);
+      for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
+        {
+          std::list< ElementaryNode * >::iterator res=find(clones.begin(),clones.end(),(ElementaryNode *)(*iterT));
+          InlineFuncNode *nodeC=(InlineFuncNode *)getChildByName(otherC.getChildName(*res));
+          nodeC->setContainer(contCloned);
+        }
+    }
+}
+
 bool ComposedNode::isFinished()
 {
   if(_state==YACS::DONE)return true;
index 11bdbf6149596f9a6962bf61e389bcd6d8f11e8c..fcd0e13f16dd5026b51f376e03e61ab2f59c9a02 100644 (file)
@@ -51,6 +51,7 @@ namespace YACS
       ComposedNode(const std::string& name);
       ComposedNode(const ComposedNode& other, ComposedNode *father);
       void performDuplicationOfPlacement(const Node& other);
+      void performShallowDuplicationOfPlacement(const Node& other);
     public:
       virtual ~ComposedNode();
       bool isFinished();
index 2827536692aeacb99a4b18218fe0dc84041a5e2f..e3eccbf06ca23fb36a660382bea62453b3bccc1f 100644 (file)
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
 
+#include <sstream>
+
 using namespace std;
 using namespace YACS::ENGINE;
 
+const char Container::KIND_ENTRY[]="container_kind";
+
+const char Container::AOC_ENTRY[]="attached_on_cloning";
+
 Container::Container():_isAttachedOnCloning(false),_proc(0)
 {
 }
@@ -34,6 +40,22 @@ Container::~Container()
 {
 }
 
+std::string Container::getDiscreminantStrOfThis(const Task *askingNode) const
+{
+  const void *ptr(this);
+  std::ostringstream oss; oss << ptr;
+  return oss.str();
+}
+
+/*!
+ * If \a val is equal to true the current container 'this' is not destined to be deeply copied on clone call.
+ * If \a val is equal to false the current container 'this' is destined to be deeply copied on clone call.
+ */
+void Container::setAttachOnCloningStatus(bool val) const
+{
+  _isAttachedOnCloning=val;
+}
+
 /*!
  * By calling this method the current container 'this' is not destined to be deeply copied on clone call.
  */
@@ -64,28 +86,9 @@ bool Container::isSupportingRTODefNbOfComp() const
   return true;
 }
 
-void Container::setProperty(const std::string& name, const std::string& value)
+void Container::setProperties(const std::map<std::string,std::string>& properties)
 {
-  DEBTRACE("Container::setProperty " << name << " " << value);
-  _propertyMap[name]=value;
+  for (std::map<std::string,std::string>::const_iterator it=properties.begin();it!=properties.end();++it)
+    setProperty((*it).first,(*it).second);
 }
 
-std::string Container::getProperty(const std::string& name)
-{
-  DEBTRACE("Container::getProperty " << name );
-  return _propertyMap[name];
-}
-
-void Container::setProperties(std::map<std::string,std::string> properties)
-{
-  _propertyMap.clear();
-  std::map<std::string,std::string>::iterator it;
-  for (it = properties.begin(); it != properties.end(); ++it)
-    {
-      setProperty((*it).first, (*it).second); // setProperty virtual and derived
-    }
-}
-
-void Container::shutdown(int level)
-{
-}
index f193cbe8038099897883aa60751a41b43da60b17..83415f5039217c7a92fee167e96eabcb40b0dbe9 100644 (file)
@@ -33,8 +33,10 @@ namespace YACS
   {
     class ComponentInstance;
     class Proc;
+    class Task;
     /*!
      * This is an abstract class, that represents an abstract process in which ComponentInstances can be launched and run.
+     * An instance of this will be mapped to one and only one physical container (except in the foreach context)
      */
     class YACSLIBENGINE_EXPORT Container : public RefCounter
     {
@@ -44,35 +46,43 @@ namespace YACS
       virtual ~Container();
 #endif
     public:
+      virtual std::string getKind() const = 0;
       //Execution only methods
-      virtual bool isAlreadyStarted(const ComponentInstance *inst) const = 0;
-      virtual void start(const ComponentInstance *inst) throw(Exception) = 0;
-      virtual std::string getPlacementId(const ComponentInstance *inst) const = 0;
-      virtual std::string getFullPlacementId(const ComponentInstance *inst) const = 0;
+      virtual std::string getDiscreminantStrOfThis(const Task *askingNode) const;
+      virtual bool isAlreadyStarted(const Task *askingNode) const = 0;
+      virtual void start(const Task *askingNode) throw(Exception) = 0;
+      virtual std::string getPlacementId(const Task *askingNode) const = 0;
+      virtual std::string getFullPlacementId(const Task *askingNode) const = 0;
       //Edition only methods
+      virtual void setAttachOnCloningStatus(bool val) const;
       virtual void attachOnCloning() const;
       virtual void dettachOnCloning() const;
-      bool isAttachedOnCloning() const;
+      virtual bool isAttachedOnCloning() const;
+      virtual void lock() = 0;
+      virtual void unLock() = 0;
       //! \b WARNING ! clone behaviour \b MUST be in coherence with what is returned by isAttachedOnCloning() method
       virtual Container *clone() const = 0;
+      virtual Container *cloneAlways() const = 0;
       virtual bool isSupportingRTODefNbOfComp() const;
       virtual void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception) = 0;
-      virtual void setProperty(const std::string& name,const std::string& value);
-      virtual std::string getProperty(const std::string& name);
-      std::map<std::string,std::string> getProperties() { return _propertyMap; };
-      virtual void setProperties(std::map<std::string,std::string> properties);
-      std::string getName() const { return _name; };
+      virtual void setProperty(const std::string& name,const std::string& value) = 0;
+      virtual std::string getProperty(const std::string& name) const = 0;
+      virtual void clearProperties() = 0;
+      virtual void addComponentName(const std::string& name) = 0;
+      virtual std::map<std::string,std::string> getProperties() const = 0;
+      virtual std::map<std::string,std::string> getResourceProperties(const std::string& name) const = 0;
+      virtual void setProperties(const std::map<std::string,std::string>& properties);
+      std::string getName() const { return _name; }
       //! \b WARNING ! name is used in edition to identify different containers, it is not the runtime name of the container
-      void setName(std::string name) { _name = name; };
-      void setProc(Proc* proc) { _proc = proc; };
-      Proc* getProc() { return _proc; };
-      virtual void shutdown(int level);
-      virtual std::map<std::string,std::string> getResourceProperties(const std::string& name) { return _propertyMap; };
-
+      void setName(std::string name) { _name = name; }
+      void setProc(Proc* proc) { _proc = proc; }
+      Proc* getProc() { return _proc; }
+      virtual void shutdown(int level) = 0;
+      static const char KIND_ENTRY[];
+      static const char AOC_ENTRY[];
     protected:
       std::string _name;
       mutable bool _isAttachedOnCloning;
-      std::map<std::string,std::string> _propertyMap;
       Proc* _proc;
     };
   }
index 145d5e56f64aa2f6e28960a9c87add6e2b5b45be..290fa7babcfc3f404ea34ff039d2536d699589b6 100644 (file)
@@ -69,6 +69,10 @@ void ElementaryNode::performDuplicationOfPlacement(const Node& other)
 {
 }
 
+void ElementaryNode::performShallowDuplicationOfPlacement(const Node& other)
+{
+}
+
 ElementaryNode::~ElementaryNode()
 {
   for(list<InputPort *>::iterator iter1=_setOfInputPort.begin();iter1!=_setOfInputPort.end();iter1++)
@@ -111,6 +115,11 @@ ComponentInstance *ElementaryNode::getComponent()
   return 0;
 }
 
+const ComponentInstance *ElementaryNode::getComponent() const
+{
+  return 0;
+}
+
 Container *ElementaryNode::getContainer()
 {
   return 0;
index 8cfb57759d7a9e20cb9fadb20d30174ea12eb637..091c7e98adff9af6190de54561fd3676271d7fe2 100644 (file)
@@ -56,12 +56,14 @@ namespace YACS
       ElementaryNode(const std::string& name);
       ElementaryNode(const ElementaryNode& other, ComposedNode *father);
       void performDuplicationOfPlacement(const Node& other);
+      void performShallowDuplicationOfPlacement(const Node& other);
     public:
       virtual ~ElementaryNode();
       void exUpdateState();
       void init(bool start=true);
       bool isDeployable() const;
       ComponentInstance *getComponent();
+      const ComponentInstance *getComponent() const;
       Container *getContainer();
       YACS::StatesForNode getState() const;
       void getReadyTasks(std::vector<Task *>& tasks);
index 1f958a0efafc76c0e1c088a0fe163d327f0eccb2..ca8ca84bf89bf9322d278a3dfb05a3ccd590d9c9 100644 (file)
 
 #include "Executor.hxx"
 #include "Task.hxx"
+#include "AutoLocker.hxx"
 #include "Scheduler.hxx"
 #include "Dispatcher.hxx"
 #include "Container.hxx"
+#include "HomogeneousPoolContainer.hxx"
 #include "ComponentInstance.hxx"
 
 #include "VisitorSaveState.hxx"
+#include "ServiceNode.hxx"
 #include "ComposedNode.hxx"
 
 #include <iostream>
@@ -136,10 +139,9 @@ void Executor::RunA(Scheduler *graph,int debug, bool fromScratch)
       if(debug>2)_displayDot(graph);
 
       {//Critical section
-        _mutexForSchedulerUpdate.lock();
+        YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
         tasks=graph->getNextTasks(isMore);
         graph->selectRunnableTasks(tasks);
-        _mutexForSchedulerUpdate.unlock();
       }//End of critical section
 
       if(debug>2)_displayDot(graph);
@@ -154,9 +156,8 @@ void Executor::RunA(Scheduler *graph,int debug, bool fromScratch)
       if(debug>1)_displayDot(graph);
 
       {//Critical section
-        _mutexForSchedulerUpdate.lock();
+        YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
         _toContinue=!graph->isFinished();
-        _mutexForSchedulerUpdate.unlock();
       }//End of critical section
       DEBTRACE("_toContinue: " << _toContinue);
 
@@ -232,7 +233,7 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
   DEBTRACE("Executor::RunB debug: "<< graph->getName() <<" "<< debug<<" fromScratch: "<<fromScratch);
 
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _mainSched = graph;
     _root = dynamic_cast<ComposedNode *>(_mainSched);
     if (!_root) throw Exception("Executor::Run, Internal Error!");
@@ -254,7 +255,6 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
     gettimeofday(&_start, NULL);
 #endif
 
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
 
   if (debug > 1) _displayDot(graph);
@@ -293,11 +293,11 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
       DEBTRACE("--- events...");
       if (debug > 2) _displayDot(graph);
       { // --- Critical section
-        _mutexForSchedulerUpdate.lock();
+        YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
         _tasks=graph->getNextTasks(isMore);
         numberAllTasks=_numberOfRunningTasks+_tasks.size();
         graph->selectRunnableTasks(_tasks);
-        _mutexForSchedulerUpdate.unlock();
+        FilterTasksConsideringContainers(_tasks);
       } // --- End of critical section
       if (debug > 2) _displayDot(graph);
       if (_executorState == YACS::RUNNING)
@@ -305,8 +305,8 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
           if (checkBreakPoints()) break; // end of thread requested, OK to exit at once;
           if (debug > 0) _displayDot(graph);
           DEBTRACE("---");
-          for (iter = _tasks.begin(); iter != _tasks.end(); iter++)
-            loadTask(*iter);
+          //loadTasks(_tasks);
+          loadParallelTasks(_tasks);
           if (debug > 1) _displayDot(graph);
           DEBTRACE("---");
           launchTasks(_tasks);
@@ -315,7 +315,7 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
       if (debug > 1) _displayDot(graph);
       { // --- Critical section
         DEBTRACE("---");
-        _mutexForSchedulerUpdate.lock();
+        YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
         //It is possible that the graph is finished but it remains running tasks (it's an error but we must take it into account)
         if(_numberOfRunningTasks == 0)
           _toContinue = !graph->isFinished();
@@ -343,7 +343,6 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
             sendEvent("executor");
             _condForPilot.notify_all();
           }
-        _mutexForSchedulerUpdate.unlock();
       } // --- End of critical section
       if (debug > 0) _displayDot(graph);
       DEBTRACE("_toContinue: " << _toContinue);
@@ -352,7 +351,7 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
   DEBTRACE("End of main Loop");
 
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     if ( _toContinue) // --- break while(): request to stop detected on checkBreakPoints()
       {
         DEBTRACE("stop requested: End soon");
@@ -360,7 +359,6 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch)
         _toContinue = false;
         sendEvent("executor");
       }
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
   if ( _dumpOnErrorRequested && _errorDetected)
     {
@@ -399,13 +397,12 @@ bool Executor::isNotFinished()
 void Executor::setStopOnError(bool dumpRequested, std::string xmlFile)
 {
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _dumpErrorFile=xmlFile;
     _stopOnErrorRequested=true;
     _dumpOnErrorRequested = dumpRequested;
     if (dumpRequested && xmlFile.empty())
       throw YACS::Exception("dump on error requested and no filename given for dump");
-    _mutexForSchedulerUpdate.unlock();
     DEBTRACE("_dumpErrorFile " << _dumpErrorFile << " " << _dumpOnErrorRequested);
   } // --- End of critical section
 }
@@ -417,9 +414,8 @@ void Executor::setStopOnError(bool dumpRequested, std::string xmlFile)
 void Executor::unsetStopOnError()
 {
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _stopOnErrorRequested=false;
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
 }
 
@@ -433,10 +429,9 @@ void Executor::setExecMode(YACS::ExecutionMode mode)
 {
   DEBTRACE("Executor::setExecMode(YACS::ExecutionMode mode) " << mode);
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _isRunningunderExternalControl=true;
     _execMode = mode;
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
 }
 
@@ -454,7 +449,7 @@ bool Executor::resumeCurrentBreakPoint()
   bool ret = false;
   //bool doDump = false;
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _isRunningunderExternalControl=true;
     DEBTRACE("_executorState: " << _executorState);
     switch (_executorState)
@@ -481,7 +476,6 @@ bool Executor::resumeCurrentBreakPoint()
           // debug: no easy way to verify if main loop is acutally waiting on condition
         }
       }
-    _mutexForSchedulerUpdate.unlock();
     DEBTRACE("---");
     //if (doDump) saveState(_dumpErrorFile);
   } // --- End of critical section
@@ -496,10 +490,9 @@ void Executor::setListOfBreakPoints(std::list<std::string> listOfBreakPoints)
 {
   DEBTRACE("Executor::setListOfBreakPoints(std::list<std::string> listOfBreakPoints)");
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _isRunningunderExternalControl=true;
     _listOfBreakPoints = listOfBreakPoints;
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
 }
 
@@ -515,7 +508,7 @@ std::list<std::string> Executor::getTasksToLoad()
   list<string> listOfNodesToLoad;
   listOfNodesToLoad.clear();
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _isRunningunderExternalControl=true;
     switch (_executorState)
       {
@@ -535,7 +528,6 @@ std::list<std::string> Executor::getTasksToLoad()
           break;
         }
       }
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
   return listOfNodesToLoad;
 }
@@ -555,7 +547,7 @@ bool Executor::setStepsToExecute(std::list<std::string> listToExecute)
   vector<Task *>::iterator iter;
   vector<Task *> restrictedTasks;
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _isRunningunderExternalControl=true;
     switch (_executorState)
       {
@@ -589,7 +581,6 @@ bool Executor::setStepsToExecute(std::list<std::string> listToExecute)
           break;
         }
       }
-    _mutexForSchedulerUpdate.unlock();
     } // --- End of critical section
 
   _tasks.clear();
@@ -616,7 +607,7 @@ void Executor::waitPause()
 {
   DEBTRACE("Executor::waitPause()" << _executorState);
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _isRunningunderExternalControl=true;
     switch (_executorState)
       {
@@ -636,7 +627,6 @@ void Executor::waitPause()
           break;
         }
       }
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
   DEBTRACE("---");
 }
@@ -735,7 +725,7 @@ bool Executor::checkBreakPoints()
       {
         bool stop = false;
         { // --- Critical section
-          _mutexForSchedulerUpdate.lock();
+          YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
           _tasksSave = _tasks;
           for (iter=_tasks.begin(); iter!=_tasks.end(); iter++)
             {
@@ -762,11 +752,8 @@ bool Executor::checkBreakPoints()
               sendEvent("executor");
               _condForPilot.notify_all();
             }
-          //_mutexForSchedulerUpdate.unlock(); 
-          //} // --- End of critical section
           if (stop && !_isOKToEnd) waitResume(); // wait until pilot calls resumeCurrentBreakPoint(), mutex released during wait 
           if (_isOKToEnd) endRequested = true;
-          _mutexForSchedulerUpdate.unlock();
         } // --- End of critical section
           if (stop) DEBTRACE("wake up from waitResume");
         break;
@@ -775,7 +762,7 @@ bool Executor::checkBreakPoints()
     case YACS::STEPBYSTEP:
       {
         { // --- Critical section
-          _mutexForSchedulerUpdate.lock();
+          YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
           _tasksSave = _tasks;
           _listOfTasksToLoad.clear();
           for (iter=_tasks.begin(); iter!=_tasks.end(); iter++)
@@ -793,7 +780,6 @@ bool Executor::checkBreakPoints()
             waitResume(); // wait until pilot calls resumeCurrentBreakPoint(), mutex released during wait
                           // or, if no pilot, wait until no more running tasks (stop on error)
           if (_isOKToEnd) endRequested = true;
-          _mutexForSchedulerUpdate.unlock();
         } // --- End of critical section
         DEBTRACE("wake up from waitResume");
         break;
@@ -827,66 +813,91 @@ void Executor::waitResume()
 void Executor::loadTask(Task *task)
 {
   DEBTRACE("Executor::loadTask(Task *task)");
-  if(task->getState() != YACS::TOLOAD)return;
-  traceExec(task, "state:TOLOAD");
+  if(task->getState() != YACS::TOLOAD)
+    return;
+  traceExec(task, "state:TOLOAD", ComputePlacement(task));
   {//Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _mainSched->notifyFrom(task,YACS::START);
-    _mutexForSchedulerUpdate.unlock();
   }//End of critical section
   try
     {
-      traceExec(task, "load");
+      traceExec(task, "load", ComputePlacement(task));
       task->load();
-      traceExec(task, "initService");
+      traceExec(task, "initService", ComputePlacement(task));
       task->initService();
     }
   catch(Exception& ex) 
     {
       std::cerr << ex.what() << std::endl;
       {//Critical section
-        _mutexForSchedulerUpdate.lock();
+        YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
         task->aborted();
         _mainSched->notifyFrom(task,YACS::ABORT);
-        traceExec(task, "state:"+Node::getStateName(task->getState()));
-        _mutexForSchedulerUpdate.unlock();
+        traceExec(task, "state:"+Node::getStateName(task->getState()), ComputePlacement(task));
       }//End of critical section
     }
   catch(...) 
     {
       std::cerr << "Load failed" << std::endl;
       {//Critical section
-        _mutexForSchedulerUpdate.lock();
+        YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
         task->aborted();
         _mainSched->notifyFrom(task,YACS::ABORT);
-        traceExec(task, "state:"+Node::getStateName(task->getState()));
-        _mutexForSchedulerUpdate.unlock();
+        traceExec(task, "state:"+Node::getStateName(task->getState()), ComputePlacement(task));
       }//End of critical section
     }
 }
 
+struct threadargs
+{
+  Task *task;
+  Scheduler *sched;
+  Executor *execInst;
+};
+
+void Executor::loadTasks(const std::vector<Task *>& tasks)
+{
+  for(std::vector<Task *>::const_iterator iter = _tasks.begin(); iter != _tasks.end(); iter++)
+    loadTask(*iter);
+}
+
+void Executor::loadParallelTasks(const std::vector<Task *>& tasks)
+{
+  std::vector<Thread> ths(tasks.size());
+  std::size_t ithread(0);
+  for(std::vector<Task *>::const_iterator iter = _tasks.begin(); iter != _tasks.end(); iter++, ithread++)
+    {
+      DEBTRACE("Executor::loadParallelTasks(Task *task)");
+      struct threadargs *args(new threadargs);
+      args->task = (*iter);
+      args->sched = _mainSched;
+      args->execInst = this;
+      ths[ithread].go(functionForTaskLoad, args, _threadStackSize);
+    }
+  for(ithread=0;ithread<tasks.size();ithread++)
+    ths[ithread].join();
+}
 
 //! Execute a list of tasks possibly connected through datastream links
 /*!
  *  \param tasks  : a list of tasks to execute
  *
  */
-void Executor::launchTasks(std::vector<Task *>& tasks)
+void Executor::launchTasks(const std::vector<Task *>& tasks)
 {
-  vector<Task *>::iterator iter;
   //First phase, make datastream connections
-  for(iter=tasks.begin();iter!=tasks.end();iter++)
+  for(vector<Task *>::const_iterator iter=tasks.begin();iter!=tasks.end();iter++)
     {
       YACS::StatesForNode state=(*iter)->getState();
       if(state != YACS::TOLOAD && state != YACS::TORECONNECT)continue;
       try
         {
           (*iter)->connectService();
-          traceExec(*iter, "connectService");
+          traceExec(*iter, "connectService",ComputePlacement(*iter));
           {//Critical section
-            _mutexForSchedulerUpdate.lock();
+            YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
             (*iter)->connected();
-            _mutexForSchedulerUpdate.unlock();
           }//End of critical section
         }
       catch(Exception& ex) 
@@ -895,18 +906,17 @@ void Executor::launchTasks(std::vector<Task *>& tasks)
           try
             {
               (*iter)->disconnectService();
-              traceExec(*iter, "disconnectService");
+              traceExec(*iter, "disconnectService",ComputePlacement(*iter));
             }
           catch(...) 
             {
               // Disconnect has failed
-              traceExec(*iter, "disconnectService failed, ABORT");
+              traceExec(*iter, "disconnectService failed, ABORT",ComputePlacement(*iter));
             }
           {//Critical section
-            _mutexForSchedulerUpdate.lock();
+            YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
             (*iter)->aborted();
             _mainSched->notifyFrom(*iter,YACS::ABORT);
-            _mutexForSchedulerUpdate.unlock();
           }//End of critical section
         }
       catch(...) 
@@ -915,18 +925,17 @@ void Executor::launchTasks(std::vector<Task *>& tasks)
           try
             {
               (*iter)->disconnectService();
-              traceExec(*iter, "disconnectService");
+              traceExec(*iter, "disconnectService",ComputePlacement(*iter));
             }
           catch(...) 
             {
               // Disconnect has failed
-              traceExec(*iter, "disconnectService failed, ABORT");
+              traceExec(*iter, "disconnectService failed, ABORT",ComputePlacement(*iter));
             }
           {//Critical section
-            _mutexForSchedulerUpdate.lock();
+            YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
             (*iter)->aborted();
             _mainSched->notifyFrom(*iter,YACS::ABORT);
-            _mutexForSchedulerUpdate.unlock();
           }//End of critical section
         }
       if((*iter)->getState() == YACS::ERROR)
@@ -942,38 +951,31 @@ void Executor::launchTasks(std::vector<Task *>& tasks)
               try
                 {
                   t->disconnectService();
-                  traceExec(t, "disconnectService");
+                  traceExec(t, "disconnectService",ComputePlacement(*iter));
                 }
               catch(...)
                 {
                   // Disconnect has failed
-                  traceExec(t, "disconnectService failed, ABORT");
+                  traceExec(t, "disconnectService failed, ABORT",ComputePlacement(*iter));
                 }
               {//Critical section
-                _mutexForSchedulerUpdate.lock();
+                YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
                 t->aborted();
                 _mainSched->notifyFrom(t,YACS::ABORT);
-                _mutexForSchedulerUpdate.unlock();
               }//End of critical section
-              traceExec(t, "state:"+Node::getStateName(t->getState()));
+              traceExec(t, "state:"+Node::getStateName(t->getState()),ComputePlacement(*iter));
             }
         }
-      traceExec(*iter, "state:"+Node::getStateName((*iter)->getState()));
+      traceExec(*iter, "state:"+Node::getStateName((*iter)->getState()),ComputePlacement(*iter));
     }
 
   //Second phase, execute each task in a thread
-  for(iter=tasks.begin();iter!=tasks.end();iter++)
+  for(vector<Task *>::const_iterator iter=tasks.begin();iter!=tasks.end();iter++)
     {
       launchTask(*iter);
     }
 }
 
-struct threadargs {
-  Task *task;
-  Scheduler *sched;
-  Executor *execInst;
-};
-
 //! Execute a Task in a thread
 /*!
  *  \param task  : Task to execute
@@ -1027,14 +1029,13 @@ void Executor::launchTask(Task *task)
   args->sched = _mainSched;
   args->execInst = this;
 
-  traceExec(task, "launch");
+  traceExec(task, "launch",ComputePlacement(task));
 
   { // --- Critical section
-    _mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
     _numberOfRunningTasks++;
     _runningTasks.insert(task);
     task->begin(); //change state to ACTIVATED
-    _mutexForSchedulerUpdate.unlock();
   } // --- End of critical section
   Thread(functionForTaskExecution, args, _threadStackSize);
 }
@@ -1045,14 +1046,13 @@ void Executor::sleepWhileNoEventsFromAnyRunningTask()
 {
   DEBTRACE("Executor::sleepWhileNoEventsFromAnyRunningTask()");
 //   _semForNewTasksToPerform.wait(); //----utiliser pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
-  _mutexForSchedulerUpdate.lock();
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
   if (_numberOfRunningTasks > 0 && _numberOfEndedTasks==0)
     {
       _isWaitingEventsFromRunningTasks = true;
       _condForNewTasksToPerform.wait(_mutexForSchedulerUpdate); // mutex released during wait
     }
   _numberOfEndedTasks=0;
-  _mutexForSchedulerUpdate.unlock();
   DEBTRACE("---");
 }
 
@@ -1086,13 +1086,26 @@ void Executor::wakeUp()
 int Executor::getNbOfThreads()
 {
   int ret;
-  _mutexForNbOfConcurrentThreads.lock();
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForNbOfConcurrentThreads);
   _isRunningunderExternalControl=true;
   ret = _groupOfAllThreadsCreated.size();
-  _mutexForNbOfConcurrentThreads.unlock();
   return ret;
 }
 
+/*!
+ * This thread is NOT supposed to be detached !
+ */
+void *Executor::functionForTaskLoad(void *arg)
+{
+  DEBTRACE("Executor::functionForTaskLoad(void *arg)");
+  struct threadargs *args = (struct threadargs *) arg;
+  Task *task=args->task;
+  Scheduler *sched=args->sched;
+  Executor *execInst=args->execInst;
+  delete args;
+  execInst->loadTask(task);// no throw of this method - all throw are catched !
+  return 0;
+}
 
 //! Function to perform execution of a task in a thread
 /*!
@@ -1116,7 +1129,7 @@ void *Executor::functionForTaskExecution(void *arg)
   Scheduler *sched=args->sched;
   Executor *execInst=args->execInst;
   delete args;
-  execInst->traceExec(task, "state:"+Node::getStateName(task->getState()));
+  execInst->traceExec(task, "state:"+Node::getStateName(task->getState()),ComputePlacement(task));
 
   Thread::detach();
 
@@ -1125,9 +1138,9 @@ void *Executor::functionForTaskExecution(void *arg)
   YACS::Event ev=YACS::FINISH;
   try
     {
-      execInst->traceExec(task, "start execution");
+      execInst->traceExec(task, "start execution",ComputePlacement(task));
       task->execute();
-      execInst->traceExec(task, "end execution OK");
+      execInst->traceExec(task, "end execution OK",ComputePlacement(task));
     }
   catch(Exception& ex)
     {
@@ -1136,14 +1149,14 @@ void *Executor::functionForTaskExecution(void *arg)
       ev=YACS::ABORT;
       string message = "end execution ABORT, ";
       message += ex.what();
-      execInst->traceExec(task, message);
+      execInst->traceExec(task, message,ComputePlacement(task));
     }
   catch(...) 
     {
       // Execution has failed
       std::cerr << "Execution has failed: unknown reason" << std::endl;
       ev=YACS::ABORT;
-      execInst->traceExec(task, "end execution ABORT, unknown reason");
+      execInst->traceExec(task, "end execution ABORT, unknown reason",ComputePlacement(task));
     }
 
   // Disconnect task
@@ -1151,19 +1164,31 @@ void *Executor::functionForTaskExecution(void *arg)
     {
       DEBTRACE("task->disconnectService()");
       task->disconnectService();
-      execInst->traceExec(task, "disconnectService");
+      execInst->traceExec(task, "disconnectService",ComputePlacement(task));
     }
   catch(...) 
     {
       // Disconnect has failed
       std::cerr << "disconnect has failed" << std::endl;
       ev=YACS::ABORT;
-      execInst->traceExec(task, "disconnectService failed, ABORT");
+      execInst->traceExec(task, "disconnectService failed, ABORT",ComputePlacement(task));
+    }
+  //
+
+  std::string placement(ComputePlacement(task));
+
+  // container management for HomogeneousPoolOfContainer
+
+  HomogeneousPoolContainer *contC(dynamic_cast<HomogeneousPoolContainer *>(task->getContainer()));
+  if(contC)
+    {
+      YACS::BASES::AutoLocker<Container> alckCont(contC);
+      contC->release(task);
     }
 
   DEBTRACE("End task->execute()");
   { // --- Critical section
-    execInst->_mutexForSchedulerUpdate.lock();
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&execInst->_mutexForSchedulerUpdate);
     try
       {
         if (ev == YACS::FINISH) task->finished();
@@ -1177,7 +1202,7 @@ void *Executor::functionForTaskExecution(void *arg)
               }
             task->aborted();
           }
-        execInst->traceExec(task, "state:"+Node::getStateName(task->getState()));
+        execInst->traceExec(task, "state:"+Node::getStateName(task->getState()),placement);
         sched->notifyFrom(task,ev);
       }
     catch(Exception& ex)
@@ -1217,7 +1242,6 @@ void *Executor::functionForTaskExecution(void *arg)
     DEBTRACE("after _semForMaxThreads.post " << execInst->_semThreadCnt);
     if (execInst->_executorState != YACS::PAUSED)  execInst->wakeUp();
 
-    execInst->_mutexForSchedulerUpdate.unlock();
   } // --- End of critical section (change state)
 
   //execInst->notifyEndOfThread(0);
@@ -1225,19 +1249,14 @@ void *Executor::functionForTaskExecution(void *arg)
   return 0;
 }
 
-void Executor::traceExec(Task *task, const std::string& message)
+void Executor::traceExec(Task *task, const std::string& message, const std::string& placement)
 {
   string nodeName = _mainSched->getTaskName(task);
   Container *cont = task->getContainer();
   string containerName = "---";
-  string placement = "---";
   if (cont)
-    {
-      containerName = cont->getName();
-      ComponentInstance *compo = task->getComponent();
-      //if (compo)
-      placement = cont->getFullPlacementId(compo);
-    }
+    containerName = cont->getName();
+
 #ifdef WIN32
   DWORD now = timeGetTime();
   double elapse = (now - _start)/1000.0;
@@ -1246,10 +1265,11 @@ void Executor::traceExec(Task *task, const std::string& message)
   gettimeofday(&now, NULL);
   double elapse = (now.tv_sec - _start.tv_sec) + double(now.tv_usec - _start.tv_usec)/1000000.0;
 #endif
-  _mutexForTrace.lock();
-  _trace << elapse << " " << containerName << " " << placement << " " << nodeName << " " << message << endl;
-  _trace << flush;
-  _mutexForTrace.unlock();
+  {
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForTrace);
+    _trace << elapse << " " << containerName << " " << placement << " " << nodeName << " " << message << endl;
+    _trace << flush;
+  }
 }
 
 //! emit notification to all observers registered with  the dispatcher 
@@ -1263,3 +1283,71 @@ void Executor::sendEvent(const std::string& event)
   YASSERT(_root);
   disp->dispatch(_root,event);
 }
+
+/*!
+ * This method takes in input a list of tasks and selects from that lists a part of it considering only the containers.
+ * If tasks have no container instance subclass of HomogeneousPoolContainer this method will let the \a tsks untouched.
+ *
+ * \param [in,out] tsks - list of tasks to be
+ */
+void Executor::FilterTasksConsideringContainers(std::vector<Task *>& tsks)
+{
+  std::map<HomogeneousPoolContainer *, std::vector<Task *> > m;
+  for(std::vector<Task *>::const_iterator it=tsks.begin();it!=tsks.end();it++)
+    {
+      Task *cur(*it);
+      if(!cur)
+        continue;
+      Container *cont(cur->getContainer());
+      if(!cont)
+        {
+          m[(HomogeneousPoolContainer *)NULL].push_back(cur);
+          continue;
+        }
+      HomogeneousPoolContainer *contC(dynamic_cast<HomogeneousPoolContainer *>(cont));
+      if(!contC)
+        {
+          m[(HomogeneousPoolContainer *)NULL].push_back(cur);
+          continue;
+        }
+      m[contC].push_back(cur);
+    }
+  //
+  std::vector<Task *> ret;
+  for(std::map<HomogeneousPoolContainer *, std::vector<Task *> >::const_iterator it=m.begin();it!=m.end();it++)
+    {
+      HomogeneousPoolContainer *curhpc((*it).first);
+      const std::vector<Task *>& curtsks((*it).second);
+      if(!curhpc)
+        {
+          ret.insert(ret.end(),curtsks.begin(),curtsks.end());
+        }
+      else
+        {
+          // start of critical section for container curhpc
+          YACS::BASES::AutoLocker<Container> alckForCont(curhpc);
+          std::vector<const Task *> vecOfTaskSharingSameHPContToBeRunSimutaneously;
+          std::size_t sz(curhpc->getNumberOfFreePlace());
+          std::vector<Task *>::const_iterator it2(curtsks.begin());
+          for(std::size_t i=0;i<sz && it2!=curtsks.end();i++,it2++)
+            {
+              vecOfTaskSharingSameHPContToBeRunSimutaneously.push_back(*it2);
+              ret.push_back(*it2);
+            }
+          curhpc->allocateFor(vecOfTaskSharingSameHPContToBeRunSimutaneously);
+          //end of critical section
+        }
+    }
+  //
+  tsks=ret;
+}
+
+std::string Executor::ComputePlacement(Task *zeTask)
+{
+  std::string placement("---");
+  if(!zeTask)
+    return placement;
+  if(zeTask->getContainer())
+    placement=zeTask->getContainer()->getFullPlacementId(zeTask);
+  return placement;
+}
index 90c25499d34f98e11fbccdb6f5db8bf9035acbe1..bf606ea6e41069b209461811e7cd52074d4d896b 100644 (file)
@@ -118,15 +118,20 @@ namespace YACS
       bool checkBreakPoints();
       void waitResume();
       void loadTask(Task *task);
-      void launchTasks(std::vector<Task*>& tasks);
+      void loadTasks(const std::vector<Task *>& tasks);
+      void loadParallelTasks(const std::vector<Task *>& tasks);
+      void launchTasks(const std::vector<Task*>& tasks);
       void launchTask(Task *task);
       void wakeUp();
       void sleepWhileNoEventsFromAnyRunningTask();
       void notifyEndOfThread(YACS::BASES::Thread *thread);
-      void traceExec(Task *task, const std::string& message);
+      void traceExec(Task *task, const std::string& message, const std::string& placement);
       void _displayDot(Scheduler *graph);
       virtual void sendEvent(const std::string& event);
+      static void FilterTasksConsideringContainers(std::vector<Task *>& tsks);
+      static std::string ComputePlacement(Task *zeTask);
     protected:
+      static void *functionForTaskLoad(void *);
       static void *functionForTaskExecution(void *);
     };
   }
diff --git a/src/engine/HomogeneousPoolContainer.cxx b/src/engine/HomogeneousPoolContainer.cxx
new file mode 100644 (file)
index 0000000..9471e70
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "HomogeneousPoolContainer.hxx"
+#include "Exception.hxx"
+
+using namespace YACS::ENGINE;
+
+const char HomogeneousPoolContainer::SIZE_OF_POOL_KEY[]="SizeOfPool";
+
+const char HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY[]="InitializeScriptKey";
+
+void HomogeneousPoolContainer::attachOnCloning() const
+{
+  _isAttachedOnCloning=true;
+}
+
+void HomogeneousPoolContainer::setAttachOnCloningStatus(bool val) const
+{
+  _isAttachedOnCloning=true;
+  if(val)
+    return ;
+  else
+    throw Exception("An HomogeneousPoolContainer cannot be detached on cloning #2 !");
+}
+
+void HomogeneousPoolContainer::dettachOnCloning() const
+{
+  _isAttachedOnCloning=true;
+  throw Exception("An HomogeneousPoolContainer cannot be detached on cloning !");
+}
+
+/*!
+ * By definition an HomogeneousPoolContainer instance is attached on cloning.
+ */
+bool HomogeneousPoolContainer::isAttachedOnCloning() const
+{
+  return true;
+}
+
+HomogeneousPoolContainer::HomogeneousPoolContainer()
+{
+  _isAttachedOnCloning=true;
+}
+
+HomogeneousPoolContainer::~HomogeneousPoolContainer()
+{
+}
diff --git a/src/engine/HomogeneousPoolContainer.hxx b/src/engine/HomogeneousPoolContainer.hxx
new file mode 100644 (file)
index 0000000..7ac8dec
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __HOMOGENEOUSPOOLCONTAINER_HXX__
+#define __HOMOGENEOUSPOOLCONTAINER_HXX__
+
+#include "YACSlibEngineExport.hxx"
+#include "Exception.hxx"
+#include "Container.hxx"
+
+#include <vector>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    /*!
+     * This is an abstract class, that represents a set of fixed number of worker "kernelcontainers" homegenous in the sense that can be used indifferently each other.
+     * But each of those worker pool can be used once at a time.
+     */
+    class YACSLIBENGINE_EXPORT HomogeneousPoolContainer : public Container
+    {
+    public:
+      void attachOnCloning() const;
+      void dettachOnCloning() const;
+      bool isAttachedOnCloning() const;
+      void setAttachOnCloningStatus(bool val) const;
+      //
+      virtual void setSizeOfPool(int sz) = 0;
+      virtual int getSizeOfPool() const = 0;
+      virtual std::size_t getNumberOfFreePlace() const = 0;
+      virtual void allocateFor(const std::vector<const Task *>& nodes) = 0;
+      virtual void release(const Task *node) = 0;
+      static const char SIZE_OF_POOL_KEY[];
+      static const char INITIALIZE_SCRIPT_KEY[];
+    protected:
+      HomogeneousPoolContainer();
+#ifndef SWIG
+      virtual ~HomogeneousPoolContainer();
+#endif
+    };
+  }
+}
+
+#endif
index 57194ae52763e8e664edc79c646130875e3dd8e9..432d53efb61bae2b474051a2a4da77c49686c127 100644 (file)
@@ -29,7 +29,11 @@ using namespace YACS::ENGINE;
 using namespace std;
 
 
-InlineNode::~InlineNode() { }
+InlineNode::~InlineNode()
+{
+  if(_container)
+    _container->decrRef();
+}
 
 void InlineNode::accept(Visitor *visitor)
 {
@@ -48,9 +52,7 @@ void InlineNode::setScript(const std::string& script)
 
 
 InlineFuncNode::~InlineFuncNode()
-{ 
-  if(_container)
-    _container->decrRef();
+{
 }
 
 void InlineFuncNode::accept(Visitor *visitor)
@@ -58,6 +60,9 @@ void InlineFuncNode::accept(Visitor *visitor)
   visitor->visitInlineFuncNode(this);
 }
 
+/*!
+ * \param fname: name of the function contained in the script to execute
+ */
 void InlineFuncNode::setFname(const std::string& fname)
 {
   _fname=fname;
@@ -112,6 +117,17 @@ void InlineNode::performDuplicationOfPlacement(const Node& other)
     _container=otherC._container->clone();
 }
 
+void InlineNode::performShallowDuplicationOfPlacement(const Node& other)
+{
+  const InlineNode &otherC=*(dynamic_cast<const InlineNode *>(&other));
+  //if other has no container don't clone: this will not have one
+  if(otherC._container)
+    {
+      _container=otherC._container;
+      _container->incrRef();
+    }
+}
+
 bool InlineNode::isDeployable() const
 {
   if(_mode=="remote")
index f6f15c02f269a3fef80a01b40e0c037140a95740..bae4ab31e5e1851f72ae54fd27b8fb0cdebdc73e 100644 (file)
@@ -65,6 +65,7 @@ namespace YACS
       virtual void setContainer(Container* container);
       virtual Container* getContainer();
       void performDuplicationOfPlacement(const Node& other);
+      void performShallowDuplicationOfPlacement(const Node& other);
       bool isDeployable() const;
     protected:
       std::string _script;
@@ -91,15 +92,12 @@ namespace YACS
         :InlineNode(other,father),_fname(other._fname) { }
       InlineFuncNode(const std::string& name):InlineNode(name) { }
     public:
-//! Set the function name to use in node execution
-/*!
- * \param fname: name of the function contained in the script to execute
- */
+      //! Set the function name to use in node execution
       virtual void setFname(const std::string& fname);
       virtual std::string getFname() { return _fname; }
       void accept(Visitor *visitor);
       virtual ~InlineFuncNode();
-      virtual std::string typeName() {return "YACS__ENGINE__InlineFuncNode";}
+      virtual std::string typeName() { return "YACS__ENGINE__InlineFuncNode"; }
       virtual void checkBasicConsistency() const throw(Exception);
     protected:
       std::string _fname;
index bf56f7789275a23effced0fdc1f072547a5f430c..0ea4a1c1c5b779839da5f5f1373c526f4aa7d4fe 100644 (file)
@@ -392,10 +392,6 @@ void Loop::edRemoveChild(Node *node) throw(YACS::Exception)
   modified();
 }
 
-void Loop::selectRunnableTasks(std::vector<Task *>& tasks)
-{
-}
-
 std::list<Node *> Loop::edGetDirectDescendants() const
 {
   list<Node *> ret;
index 395cca0a43fd5c2168ec6b9892a9fc518fd2e77e..f5558552e59a95d109d8879a855c9ac96d54ecee 100644 (file)
@@ -169,7 +169,6 @@ namespace YACS
       void getReadyTasks(std::vector<Task *>& tasks);
       void edRemoveChild(Node *node) throw(Exception);
       bool isRepeatedUnpredictablySeveralTimes() const { return true; }
-      void selectRunnableTasks(std::vector<Task *>& tasks);
       std::list<Node *> edGetDirectDescendants() const;
       std::list<InputPort *> getSetOfInputPort() const;
       int getNumberOfInputPorts() const;
index b8c40da7fb1cf92772c9738ef3a3342791d5d43f..31c2df78e7587272b7d0666d0085c33cd7800ff9 100644 (file)
@@ -107,13 +107,49 @@ void Node::init(bool start)
   setState(YACS::READY);
 }
 
+/*!
+ * This method clones \a this by :
+ *
+ * - deep copying nodes, links, ports, types
+ * - containers are either deep copied or shallow copied depending on _isAttachedOnCloning attribute.
+ * - component are either deep copied or shallow copied depending on _isAttachedOnCloning attribute.
+ *
+ * So \b this \b method \b clone \b is \b dedicated \b for \b DynParaLoop \b class \b or \b subclasses.
+ * It \b should \b not \b be \b used \b elsewhere, because
+ * _isAttachedOnCloning attribute is an attribute in the engine not for GUI/TUI aspects.
+ * For GUI/TUI manipulation cloneWithoutCompAndContDeepCpy method should be used preferably.
+ *
+ * \param [in] father - The new father of the returned clone.
+ * \param [in] editionOnly ignored
+ *
+ * \sa cloneWithoutCompAndContDeepCpy
+ */
 Node *Node::clone(ComposedNode *father, bool editionOnly) const
 {
-  Node *ret=simpleClone(father,editionOnly);
+  Node *ret(simpleClone(father,editionOnly));
   ret->performDuplicationOfPlacement(*this);
   return ret;
 }
 
+/*!
+ * This method clones \a this by :
+ * - deep copying nodes, links, ports, types
+ * - shallow copy containers
+ * - shallow copy components
+ *
+ * So this method simply ignores isAttachedOnCloning attribute for both containers and components.
+ * So this method is dedicated for the GUI/TUI users.
+ *
+ * \param [in] father - The new father of the returned clone.
+ * \param [in] editionOnly ignored
+ */
+Node *Node::cloneWithoutCompAndContDeepCpy(ComposedNode *father, bool editionOnly) const
+{
+  Node *ret(simpleClone(father,editionOnly));
+  ret->performShallowDuplicationOfPlacement(*this);
+  return ret;
+}
+
 //! Change the name of the node
 /*!
  *  raise an exception if the name is already used in the scope of its father 
index caff230d9e2570020ce16e4610754f7497ff9a06..e7c865b6cadee3e0475c5072f5639c278f7949ed 100644 (file)
@@ -91,7 +91,10 @@ namespace YACS
     protected:
       Node(const std::string& name);
       Node(const Node& other, ComposedNode *father);
+      //! performs a duplication of placement using clone method of containers and components. clone behaviour is driven by attachOnCloning attribute.
       virtual void performDuplicationOfPlacement(const Node& other) = 0;
+      //! performs a also duplication of placement but here containers and components are not copied at all whatever the value of attachedOnCloning.
+      virtual void performShallowDuplicationOfPlacement(const Node& other) = 0;
       virtual Node *simpleClone(ComposedNode *father, bool editionOnly=true) const = 0;
     public:
       virtual ~Node();
@@ -100,6 +103,8 @@ namespace YACS
       virtual void resetState(int level);
       //! \b This method \b MUST \b NEVER \b BE \b VIRTUAL
       Node *clone(ComposedNode *father, bool editionOnly=true) const;
+      //! \b This method \b MUST \b NEVER \b BE \b VIRTUAL
+      Node *cloneWithoutCompAndContDeepCpy(ComposedNode *father, bool editionOnly=true) const;
       void setState(YACS::StatesForNode theState); // To centralize state changes
       virtual YACS::StatesForNode getState() const { return _state; }
       virtual YACS::StatesForNode getEffectiveState() const;
@@ -153,7 +158,7 @@ namespace YACS
       virtual void setProperty(const std::string& name,const std::string& value);
       virtual std::string getProperty(const std::string& name);
       std::map<std::string,std::string> getProperties() ;
-      std::map<std::string,std::string> getPropertyMap(){return _propertyMap;} ;
+      std::map<std::string,std::string> getPropertyMap() { return _propertyMap; }
       virtual void setProperties(std::map<std::string,std::string> properties);
       virtual Node *getChildByName(const std::string& name) const throw(Exception) = 0;
       virtual Proc *getProc();
@@ -163,17 +168,17 @@ namespace YACS
       int getNumId();
       virtual void sendEvent(const std::string& event);
       static std::map<int,Node *> idMap;
-      virtual std::string typeName() {return "YACS__ENGINE__Node";}
-      virtual std::string getErrorDetails(){return _errorDetails;};
-      virtual void setErrorDetails(const std::string& error){_errorDetails=error;};
+      virtual std::string typeName() { return "YACS__ENGINE__Node"; }
+      virtual std::string getErrorDetails() const { return _errorDetails; }
+      virtual void setErrorDetails(const std::string& error) { _errorDetails=error; }
       virtual void modified();
-      virtual int isModified(){return _modified;}
+      virtual int isModified() { return _modified; }
       virtual int isValid();
       virtual void edUpdateState();
       virtual std::string getErrorReport();
       virtual std::string getContainerLog();
       virtual void ensureLoading();
-      virtual void getCoupledNodes(std::set<Task*>& coupledNodes){};
+      virtual void getCoupledNodes(std::set<Task*>& coupledNodes) { }
       virtual void cleanNodes();
     protected:
       virtual void exForwardFailed();
index 46185cc7fb883f8652bd35e571037c300856d176..c168305be4f96840b73ed2d2312c5dd5c8050855 100644 (file)
@@ -443,7 +443,7 @@ void Proc::modified()
 /*!
  * \param xmlSchemaFile: the file name
  */
-void Proc::saveSchema(std::string xmlSchemaFile)
+void Proc::saveSchema(const std::string& xmlSchemaFile)
 {
   VisitorSaveSchema vss(this);
   vss.openFileSchema(xmlSchemaFile);
@@ -455,7 +455,7 @@ void Proc::saveSchema(std::string xmlSchemaFile)
 /*!
  * \param xmlStateFile: the file name
  */
-void Proc::saveState(std::string xmlStateFile)
+void Proc::saveState(const std::string& xmlStateFile)
 {
   VisitorSaveState vst(this);
   vst.openFileDump(xmlStateFile);
@@ -469,9 +469,9 @@ void Proc::saveState(std::string xmlStateFile)
  * \param kind: the container kind (depends on runtime)
  * \return the created Container
  */
-Container* Proc::createContainer(const std::string& name,const std::string& kind)
+Container *Proc::createContainer(const std::string& name, const std::string& kind)
 {
-  Container* co=  getRuntime()->createContainer(kind);
+  Container *co(getRuntime()->createContainer(kind));
   co->setName(name);
   if(containerMap.count(name)!=0)
     containerMap[name]->decrRef();
index fe44ed6300b9ed04c6efd965e7534b7b63cec2b7..05a90029b442ddfe8d8c1eca006591d615c6a859 100644 (file)
@@ -40,7 +40,7 @@ namespace YACS
     class ComponentInstance;
     class Logger;
 
-    class YACSLIBENGINE_EXPORT Proc: public Bloc
+    class YACSLIBENGINE_EXPORT Proc : public Bloc
     {
     public:
       Proc(const std::string& name);
@@ -51,10 +51,10 @@ namespace YACS
       virtual TypeCode *createSequenceTc (const std::string& id, const std::string& name, 
                                          TypeCode *content);
       virtual TypeCode *createStructTc (const std::string& id, const std::string& name);
-      virtual TypeCodegetTypeCode(const std::string& name);
+      virtual TypeCode *getTypeCode(const std::string& name);
       virtual void setTypeCode(const std::string& name,TypeCode *t);
-      virtual Container* createContainer(const std::string& name,const std::string& kind="");
-      virtual ComponentInstance* createComponentInstance(const std::string& componame, 
+      virtual Container *createContainer(const std::string& name, const std::string& kind="");
+      virtual ComponentInstance *createComponentInstance(const std::string& componame,
                                                          const std::string& name="",
                                                          const std::string& kind="");
       virtual void addComponentInstance(ComponentInstance* inst, const std::string& name="",bool resetCtr=false);
@@ -62,7 +62,7 @@ namespace YACS
       virtual void removeContainer(Container* cont);
       virtual void accept(Visitor *visitor);
       virtual Proc *getProc();
-      virtual const Proc * getProc() const;
+      virtual const Proc *getProc() const;
 
       YACS::StatesForNode getNodeState(int numId);
       std::string getNodeProgress(int numId);
@@ -95,8 +95,8 @@ namespace YACS
       virtual bool getEdition(){return _edition;}
       virtual void setEdition(bool edition);
       virtual void modified();
-      virtual void saveSchema(std::string xmlSchemaFile);
-      virtual void saveState(std::string xmlStateFile);
+      virtual void saveSchema(const std::string& xmlSchemaFile);
+      virtual void saveState(const std::string& xmlStateFile);
     protected:
       bool _edition;
       int _compoinstctr;
index 7c53eccf04bcc92dc1c48fe02ff09f320973d8c6..1d8e735b00e31750bd261e2bd7cbbcf3d7de5455 100644 (file)
@@ -36,7 +36,7 @@ namespace YACS
 
       virtual void setProperty(const std::string& name,const std::string& value);
       virtual std::string getProperty(const std::string& name);
-      std::map<std::string,std::string> getProperties() { return _propertyMap; };
+      std::map<std::string,std::string> getProperties() const { return _propertyMap; };
       virtual void setProperties(std::map<std::string,std::string> properties);
     protected:
       std::map<std::string,std::string> _propertyMap;
index 93ce8dff0b9db8888f84c189fc85b59158367715..f3b25dc5cab3486d39899b677b36b21b1e93a28c 100644 (file)
@@ -42,7 +42,7 @@ void RefCounter::incrRef() const
   RefCounter::_totalCnt++;
 #endif
   _cnt++;
-  _globalMutexForTS.unlock();
+  _globalMutexForTS.unLock();
 }
 
 bool RefCounter::decrRef()
@@ -52,7 +52,7 @@ bool RefCounter::decrRef()
   RefCounter::_totalCnt--;
 #endif
   bool ret=(--_cnt==0);
-  _globalMutexForTS.unlock();
+  _globalMutexForTS.unLock();
   if(ret)
     delete this;
   return ret;
@@ -65,6 +65,10 @@ RefCounter::RefCounter():_cnt(1)
 #endif
 }
 
+RefCounter::RefCounter(const RefCounter& other):_cnt(1)
+{
+}
+
 RefCounter::~RefCounter()
 {
 #ifdef REFCNT
index c2bb3236ea5cce71eb866e04c617e95e6e5f56cc..b02f59cbb54185618009ae603c224ddcde0298b4 100644 (file)
@@ -35,6 +35,7 @@ namespace YACS
       static unsigned int _totalCnt;
     protected:
       RefCounter();
+      RefCounter(const RefCounter& other);
       virtual ~RefCounter();
     protected:
       mutable unsigned int _cnt;
index 453ca04c5da8b9d68119b8240559c16cce143ed1..9c5feef423ac4c234171a17049fdde3bb2ee793b 100644 (file)
 
 using namespace YACS::ENGINE;
 
-ServerNode::ServerNode(const std::string& name):InlineFuncNode(name),_container(0)
+ServerNode::ServerNode(const std::string& name):InlineFuncNode(name)
 {
 }
 
-ServerNode::ServerNode(const ServerNode& other, ComposedNode *father):InlineFuncNode(other,father),_container(0)
+ServerNode::ServerNode(const ServerNode& other, ComposedNode *father):InlineFuncNode(other,father)
 {
 }
 
-void ServerNode::performDuplicationOfPlacement(const Node& other)
-{
-  const ServerNode &otherC=*(dynamic_cast<const ServerNode *>(&other));
-  //if other has no container don't clone: this will not have one
-  if(otherC._container)
-    _container=otherC._container->clone();
-}
-
 void ServerNode::load()
 {
   if(_container)
     {
-      if(!_container->isAlreadyStarted(0))
+      if(!_container->isAlreadyStarted(this))
         {
           try
             {
-              _container->start(0);
+              _container->start(this);
             }
           catch(Exception& e)
             {
@@ -70,18 +62,6 @@ void ServerNode::accept(Visitor *visitor)
   visitor->visitServerNode(this);
 }
 
-void ServerNode::setContainer(Container *container)
-{
-  if(_container==container)
-    return ;
-  if(_container)
-    _container->decrRef();
-  _container=container;
-  if(_container)
-    _container->incrRef();
-  modified();
-}
-
 //! By definition of ServerNode class.
 bool ServerNode::isDeployable() const
 {
@@ -90,6 +70,5 @@ bool ServerNode::isDeployable() const
 
 ServerNode::~ServerNode()
 {
-  if(_container)
-    _container->decrRef();
 }
+
index 2c33a24dab49736b0c47cba71a3d688b322e8d16..9e871256b4ea43aa831e6ba7cff9f41be732464f 100644 (file)
@@ -37,18 +37,13 @@ namespace YACS
     public:
       ServerNode(const std::string& name);
       ServerNode(const ServerNode& other, ComposedNode *father);
-      void performDuplicationOfPlacement(const Node& other);
       void load();
       void accept(Visitor *visitor);
       virtual ServerNode *createNode(const std::string& name) const = 0;
-      Container *getContainer() const { return _container; }
-      void setContainer(Container *container);
       bool isDeployable() const;
       virtual std::string getEffectiveKindOfServer() const = 0;
       virtual ~ServerNode();
       virtual std::string typeName() { return "YACS__ENGINE__ServerNode"; }
-    protected:
-      Container *_container;
     };
   }
 }
index f150939ade7d036ae9d21d2ade9814ad9e4fd7bf..a0192b979729b1fbd09fe35cd8fc5469ee425958 100644 (file)
@@ -69,6 +69,17 @@ void ServiceNode::performDuplicationOfPlacement(const Node& other)
     _component=otherC._component->clone();
 }
 
+void ServiceNode::performShallowDuplicationOfPlacement(const Node& other)
+{
+  const ServiceNode &otherC=*(dynamic_cast<const ServiceNode *>(&other));
+  //if other has no component don't clone: this will not have one
+  if(otherC._component)
+    {
+      _component=otherC._component;
+      _component->incrRef();
+    }
+}
+
 ServiceNode::~ServiceNode()
 {
   if(_component)
@@ -80,11 +91,11 @@ void ServiceNode::load()
 {
   if(_component)
     {
-      if(!_component->isLoaded())
+      if(!_component->isLoaded(this))
         {
           try
             {
-              _component->load();
+              _component->load(this);
             }
           catch(Exception& e)
             {
@@ -113,6 +124,11 @@ ComponentInstance *ServiceNode::getComponent()
   return _component;
 }
 
+const ComponentInstance *ServiceNode::getComponent() const
+{
+  return _component;
+}
+
 //! Return the associated container
 Container *ServiceNode::getContainer()
 {
@@ -133,7 +149,7 @@ void ServiceNode::setComponent(ComponentInstance* compo) throw(YACS::Exception)
   if(compo)
     {
       DEBTRACE(compo->getInstanceName());
-      if(compo->getKind() != this->getKind())
+      if(compo->getKindForNode() != this->getKind())
         {
           //Not allowed
           std::string what("ServiceNode::setComponent : component instance kind not allowed ");
index 9db9bb68542055b978dfe8ece71c74c71ab37c14..9ca48a8e7a9e1fe6fcfcef4a8fe7ff6b1ba277d7 100644 (file)
@@ -31,30 +31,33 @@ namespace YACS
   {
     class ComponentInstance;
 
-    class YACSLIBENGINE_EXPORT ServiceNode: public ElementaryNode 
+    class YACSLIBENGINE_EXPORT ServiceNode : public ElementaryNode
     {
     protected:
       ServiceNode(const std::string& name);
       ServiceNode(const ServiceNode& other, ComposedNode *father);
       void performDuplicationOfPlacement(const Node& other);
+      void performShallowDuplicationOfPlacement(const Node& other);
     public:
       virtual void load();
       virtual bool isDeployable() const;
       virtual void setComponent(ComponentInstance* compo) throw(Exception);
       virtual ComponentInstance *getComponent();
+      virtual const ComponentInstance *getComponent() const;
       virtual Container *getContainer();
       virtual void setRef(const std::string& ref);
       virtual std::string getRef();
-      virtual void setMethod(const std::string& method){ _method=method; }
+      virtual void setMethod(const std::string& method) { _method=method; }
       virtual std::string getMethod(){return _method;}
       virtual ServiceNode *createNode(const std::string& name) = 0;
       virtual ~ServiceNode();
       virtual void accept(Visitor *visitor);
       virtual std::string getKind() const;
+      virtual std::string typeName() { return "YACS__ENGINE__ServiceNode"; }
+    public:
       static const char KIND[];
-      virtual std::string typeName() {return "YACS__ENGINE__ServiceNode";}
     protected:
-      ComponentInstance_component;
+      ComponentInstance *_component;
       std::string _method;
       std::string _ref;
     };
index b460cfd4e578edee650028210477fad151820108..504b5cd79e0ec5b7808d606c1d58989eeddfd598 100644 (file)
@@ -48,6 +48,10 @@ void StaticDefinedComposedNode::forceMultiplicity(unsigned value)
   //no sense for this class
 }
 
+void StaticDefinedComposedNode::selectRunnableTasks(std::vector<Task *>& tasks)
+{
+}
+
 void StaticDefinedComposedNode::checkControlDependancy(OutPort *start, InPort *end, bool cross,
                                                        std::map < ComposedNode *,  std::list < OutPort * >, SortHierarc >& fw,
                                                        std::vector<OutPort *>& fwCross,
index 03c8ac512dbcaa1034d6ed368777b7e13dc739d8..f1b0100e60a5f869fee08ac5ddcd608289c4076b 100644 (file)
@@ -40,6 +40,7 @@ namespace YACS
       bool isPlacementPredictableB4Run() const;
       bool isMultiplicitySpecified(unsigned& value) const;
       void forceMultiplicity(unsigned value);
+      void selectRunnableTasks(std::vector<Task *>& tasks);
     protected:
       void checkControlDependancy(OutPort *start, InPort *end, bool cross,
                                   std::map < ComposedNode *,  std::list < OutPort * >, SortHierarc >& fw,
index 93323cafddfc802ecc84d4b3bdb08cd47e45260c..947473706575d82b4c3bc363ae891ad37778b119 100644 (file)
@@ -386,10 +386,6 @@ void Switch::getReadyTasks(std::vector<Task *>& tasks)
     }
 }
 
-void Switch::selectRunnableTasks(std::vector<Task *>& tasks)
-{
-}
-
 list<Node *> Switch::edGetDirectDescendants() const
 {
   list<Node *> ret;
index bc4b7460e8b7ccbb69f8704ed5f4ca51998c3149..5d0ccb7175c455644b8939808ca95d279e8fc4b2 100644 (file)
@@ -111,7 +111,6 @@ namespace YACS
       virtual bool edAddChild(Node *DISOWNnode) throw(Exception);
       int getMaxCase();
       void getReadyTasks(std::vector<Task *>& tasks);
-      void selectRunnableTasks(std::vector<Task *>& tasks);
       std::list<Node *> edGetDirectDescendants() const;
       InputPort *edGetConditionPort() { return &_condition; }
       void writeDot(std::ostream &os) const;
index 4f9d0ba54d85e179aafe43631babfed66776d749..65f56b8eece2b94c0e105f404a605c1dcedb29ef 100644 (file)
@@ -46,6 +46,7 @@ namespace YACS
       virtual void getCoupledTasks(std::set<Task*>& coupledSet) = 0;
       virtual bool isDeployable() const = 0;
       virtual ComponentInstance *getComponent() = 0;
+      virtual const ComponentInstance *getComponent() const = 0;
       virtual Container *getContainer() = 0;
       virtual YACS::StatesForNode getState() const = 0;
       virtual void finished() = 0;
index 97821be31bdab1d8c917b909ff7d12c7fd5f7525..fe9d055cd7100c4b0a9459c9556c75df7dfe295e 100644 (file)
@@ -31,17 +31,17 @@ ComponentInstanceTest1::ComponentInstanceTest1(const std::string& name):Componen
 {
 }
 
-void ComponentInstanceTest1::load()
+void ComponentInstanceTest1::load(Task *askingNode)
 {
   _loaded=true;
 }
 
-void ComponentInstanceTest1::unload()
+void ComponentInstanceTest1::unload(Task *askingNode)
 {
   _loaded=false;
 }
 
-bool ComponentInstanceTest1::isLoaded()
+bool ComponentInstanceTest1::isLoaded(Task *askingNode) const
 {
   return _loaded;
 }
@@ -51,6 +51,11 @@ std::string ComponentInstanceTest1::getKind() const
   return ToyNode1S::KIND;
 }
 
+std::string ComponentInstanceTest1::getKindForNode() const
+{
+  return ToyNode1S::KIND;
+}
+
 ServiceNode* ComponentInstanceTest1::createNode(const std::string& name)
 {
   ToyNode1S* node=new ToyNode1S(name);
@@ -69,6 +74,11 @@ ComponentInstance *ComponentInstanceTest1::clone() const
     return new ComponentInstanceTest1(*this);
 }
 
+ComponentInstance *ComponentInstanceTest1::cloneAlways() const
+{
+  return new ComponentInstanceTest1(*this);
+}
+
 ComponentInstanceTest2::ComponentInstanceTest2(const ComponentInstanceTest2& other):ComponentInstance(other),_loaded(false)
 {
 }
@@ -77,17 +87,17 @@ ComponentInstanceTest2::ComponentInstanceTest2(const std::string& name):Componen
 {
 }
 
-void ComponentInstanceTest2::load()
+void ComponentInstanceTest2::load(Task *askingNode)
 {
   _loaded=true;
 }
 
-void ComponentInstanceTest2::unload()
+void ComponentInstanceTest2::unload(Task *askingNode)
 {
   _loaded=false;
 }
 
-bool ComponentInstanceTest2::isLoaded()
+bool ComponentInstanceTest2::isLoaded(Task *askingNode) const
 {
   return _loaded;
 }
@@ -97,6 +107,11 @@ std::string ComponentInstanceTest2::getKind() const
   return ToyNode2S::KIND;
 }
 
+std::string ComponentInstanceTest2::getKindForNode() const
+{
+  return ToyNode2S::KIND;
+}
+
 ServiceNode* ComponentInstanceTest2::createNode(const std::string& name)
 {
   ToyNode2S* node=new ToyNode2S(name);
@@ -114,3 +129,8 @@ ComponentInstance *ComponentInstanceTest2::clone() const
   else
     return new ComponentInstanceTest2(*this);
 }
+
+ComponentInstance *ComponentInstanceTest2::cloneAlways() const
+{
+  return new ComponentInstanceTest2(*this);
+}
index de03d9c1f065325d8a882864f9c35d086477da43..c401a0fdea413640c91ab49dcbd09b674c8de5e0 100644 (file)
@@ -31,12 +31,14 @@ namespace YACS
     public:
       ComponentInstanceTest1(const ComponentInstanceTest1& other);
       ComponentInstanceTest1(const std::string& name);
-      void load();
-      void unload();
-      bool isLoaded();
+      void load(Task *askingNode);
+      void unload(Task *askingNode);
+      bool isLoaded(Task *askingNode) const;
       std::string getKind() const;
+      std::string getKindForNode() const;
       ServiceNode* createNode(const std::string& name);
       ComponentInstance *clone() const;
+      ComponentInstance *cloneAlways() const;
     protected:
       bool _loaded;
     };
@@ -46,12 +48,14 @@ namespace YACS
     public:
       ComponentInstanceTest2(const ComponentInstanceTest2& other);
       ComponentInstanceTest2(const std::string& name);
-      void load();
-      void unload();
-      bool isLoaded();
+      void load(Task *askingNode);
+      void unload(Task *askingNode);
+      bool isLoaded(Task *askingNode) const;
       std::string getKind() const;
+      std::string getKindForNode() const;
       ServiceNode* createNode(const std::string& name);
       ComponentInstance *clone() const;
+      ComponentInstance *cloneAlways() const;
     protected:
       bool _loaded;
     };
index 414e197c850546c54da05843f7598e713d368d0d..638b9055eed5b3419be4777b00fef01fe3c470eb 100644 (file)
@@ -37,6 +37,11 @@ ContainerTest::ContainerTest():_alreadyStarted(false),_myCounter(_counter++)
 {
 }
 
+std::string ContainerTest::getKind() const
+{
+  return std::string();
+}
+
 std::string ContainerTest::getPlacementInfo() const
 {
   ostringstream stream;
@@ -44,12 +49,12 @@ std::string ContainerTest::getPlacementInfo() const
   return stream.str();
 }
 
-bool ContainerTest::isAlreadyStarted(const ComponentInstance *inst) const
+bool ContainerTest::isAlreadyStarted(const Task *askingNode) const
 {
   return _alreadyStarted;
 }
 
-void ContainerTest::start(const ComponentInstance *inst) throw(YACS::Exception)
+void ContainerTest::start(const Task *askingNode) throw(YACS::Exception)
 {
   if(_alreadyStarted)
     throw Exception("ContainerTest already started !!!!");
@@ -67,6 +72,11 @@ Container *ContainerTest::clone() const
     return new ContainerTest;
 }
 
+Container *ContainerTest::cloneAlways() const
+{
+  return new ContainerTest;
+}
+
 void ContainerTest::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception)
 {
   if(inst->getKind()!=SUPPORTED_COMP_KIND)
@@ -82,12 +92,17 @@ ContainerTest2::ContainerTest2():_alreadyStarted(false),_myCounter(_counter++)
 {
 }
 
-bool ContainerTest2::isAlreadyStarted(const ComponentInstance *inst) const
+std::string ContainerTest2::getKind() const
+{
+  return std::string();
+}
+
+bool ContainerTest2::isAlreadyStarted(const Task *askingNode) const
 {
   return _alreadyStarted;
 }
 
-void ContainerTest2::start(const ComponentInstance *inst) throw(YACS::Exception)
+void ContainerTest2::start(const Task *askingNode) throw(YACS::Exception)
 {
   if(_alreadyStarted)
     throw Exception("ContainerTest already started !!!!");
@@ -105,6 +120,11 @@ Container *ContainerTest2::clone() const
     return new ContainerTest2;
 }
 
+Container *ContainerTest2::cloneAlways() const
+{
+  return new ContainerTest2;
+}
+
 void ContainerTest2::initAllContainers()
 {
   _counter=0;
index 4b023e3b65a3385f5024b530718fa150c9958771..405127d60b62a7f38a41ac6e403da343b964471b 100644 (file)
@@ -30,13 +30,26 @@ namespace YACS
     {
     public:
       ContainerTest();
+      std::string getKind() const;
       std::string getPlacementInfo() const;
       // implementation of compulsary methods
-      bool isAlreadyStarted(const ComponentInstance *inst) const;
-      void start(const ComponentInstance *inst) throw(Exception);
+      bool isAlreadyStarted(const Task *askingNode) const;
+      void start(const Task *askingNode) throw(Exception);
       Container *clone() const;
-      std::string getPlacementId(const ComponentInstance *inst) const { return ""; }
-      std::string getFullPlacementId(const ComponentInstance *inst) const { return ""; }
+      Container *cloneAlways() const;
+      //
+      void lock() { }
+      void unLock() { }
+      void clearProperties() { }
+      void addComponentName(const std::string& name) { }
+      void shutdown(int level) { }
+      void setProperty(const std::string& name,const std::string& value) { }
+      std::string getProperty(const std::string& name) const { }
+      std::map<std::string,std::string> getResourceProperties(const std::string& name) const { return std::map<std::string,std::string>(); }
+      std::map<std::string,std::string> getProperties() const { return std::map<std::string,std::string>(); }
+      //
+      std::string getPlacementId(const Task *askingNode) const { return ""; }
+      std::string getFullPlacementId(const Task *askingNode) const { return ""; }
       static void initAllContainers();
     protected:
       void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception);
@@ -51,12 +64,25 @@ namespace YACS
     {
     public:
       ContainerTest2();
+      std::string getKind() const;
       // implementation of compulsary methods
-      bool isAlreadyStarted(const ComponentInstance *inst) const;
-      void start(const ComponentInstance *inst) throw(Exception);
+      bool isAlreadyStarted(const Task *askingNode) const;
+      void start(const Task *askingNode) throw(Exception);
       Container *clone() const;
-      std::string getPlacementId(const ComponentInstance *inst) const { return ""; }
-      std::string getFullPlacementId(const ComponentInstance *inst) const { return ""; }
+      Container *cloneAlways() const;
+      //
+      void lock() { }
+      void unLock() { }
+      void clearProperties() { }
+      void addComponentName(const std::string& name) { }
+      void shutdown(int level) { }
+      void setProperty(const std::string& name,const std::string& value) { }
+      std::string getProperty(const std::string& name) const { }
+      std::map<std::string,std::string> getResourceProperties(const std::string& name) const { return std::map<std::string,std::string>(); }
+      std::map<std::string,std::string> getProperties() const { return std::map<std::string,std::string>(); }
+      //
+      std::string getPlacementId(const Task *askingNode) const { return ""; }
+      std::string getFullPlacementId(const Task *askingNode) const { return ""; }
       static void initAllContainers();
     protected:
       void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(Exception);
index cc6cd1c1a04543d131405d71ea9da4d8845ea1fd..e1bb320ddaa11e5fe91afeca203e0d7e302c1035 100644 (file)
@@ -34,6 +34,7 @@
 #include "Switch.hxx"
 #include "InputPort.hxx"
 #include "TypeCode.hxx"
+#include "HomogeneousPoolContainer.hxx"
 #include "ComponentInstance.hxx"
 #include "InputDataStreamPort.hxx"
 #include "OutputDataStreamPort.hxx"
@@ -699,11 +700,25 @@ void VisitorSaveSchema::writeContainers(Proc *proc)
     {
       string name = it->first;
       _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
+      _out << indent(depth+1) << "<property name=\"" << Container::KIND_ENTRY << "\" value=\"" << it->second->getKind() << "\"/>" << endl;
+      _out << indent(depth+1) << "<property name=\"" << Container::AOC_ENTRY << "\" value=\"" << (int)it->second->isAttachedOnCloning() << "\"/>" << endl;
       map<string, string> properties = (it->second)->getProperties();
       map<string, string>::iterator itm;
       for(itm = properties.begin(); itm != properties.end(); ++itm)
-        _out << indent(depth+1) << "<property name=\"" << (*itm).first
-             << "\" value=\"" << (*itm).second << "\"/>" << endl;
+        {
+          if((*itm).first==Container::KIND_ENTRY)
+            continue;
+          if((*itm).first==Container::AOC_ENTRY)
+            continue;
+          if((*itm).first!=HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY)
+            {
+              _out << indent(depth+1) << "<property name=\"" << (*itm).first << "\" value=\"" << (*itm).second << "\"/>" << endl;
+            }
+          else
+            {
+              _out << indent(depth+1) << "<initializescriptkey><code><![CDATA[" << (*itm).second << "]]></code></initializescriptkey>" << endl;
+            }
+        }
       _out << indent(depth) << "</container>"  << endl;
     }
 }
index cd1197ac595641454500fba42e193b13999e32f4..ca6b594afaa749ec6379e34640debdd63f6194a0 100644 (file)
@@ -72,7 +72,7 @@ VisitorSaveState::~VisitorSaveState()
     }
 }
 
-void VisitorSaveState::openFileDump(std::string xmlDump) throw(YACS::Exception)
+void VisitorSaveState::openFileDump(const std::string& xmlDump) throw(YACS::Exception)
 {
   _out.open(xmlDump.c_str(), ios::out);
   if (!_out)
index b1e10b1871ac63fd1ed57b2b6f79c81e8a3bdee6..13f2431510b355160d3acbd5a834dfc3d05b0cc5 100644 (file)
@@ -37,7 +37,7 @@ namespace YACS
     public:
       VisitorSaveState(ComposedNode *root);
       virtual ~VisitorSaveState();
-      void openFileDump(std::string xmlDump) throw(Exception);
+      void openFileDump(const std::string& xmlDump) throw(Exception);
       void closeFileDump();
       virtual void visitBloc(Bloc *node);
       virtual void visitElementaryNode(ElementaryNode *node);
index bad933f9caff9ed6b47340a1bd56879c773f8c8f..d1a494dddb3f8c50123d15e7dfb3c98f246bd049 100644 (file)
@@ -80,6 +80,7 @@ catch (const CORBA::SystemException& ex) { \
 #include "InputDataStreamPort.hxx"
 #include "OutputDataStreamPort.hxx"
 #include "OptimizerLoop.hxx"
+#include "HomogeneousPoolContainer.hxx"
 
 class InterpreterUnlocker
 {
@@ -205,6 +206,17 @@ static PyObject* convertPort(YACS::ENGINE::Port* port,int owner=0)
   return ob;
 }
 
+static PyObject *convertContainer(YACS::ENGINE::Container *cont, int owner=0)
+{
+  if(!cont)
+    return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
+  if(dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(cont))
+    {
+      return SWIG_NewPointerObj((void*)dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(cont),SWIGTYPE_p_YACS__ENGINE__HomogeneousPoolContainer, owner);
+    }
+  return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
+}
+
 %}
 
 #if SWIG_VERSION >= 0x010329
index 898af99bb64ae0210b90df063995fa84306ae6ec..6262f477304eb9a88bfe601602d70b5252dc25f6 100644 (file)
@@ -53,6 +53,7 @@
 #include "ExecutorSwig.hxx"
 #include "Dispatcher.hxx"
 #include "Container.hxx"
+#include "HomogeneousPoolContainer.hxx"
 #include "Logger.hxx"
 #include "DeploymentTree.hxx"
 #include "ComponentInstance.hxx"
@@ -126,10 +127,20 @@ REFCOUNT_TEMPLATE(CONTAINmap,YACS::ENGINE::Container)
 %template(propmap)       std::map<std::string, std::string>;
 
 REFCOUNT_TEMPLATE(CompoInstmap,YACS::ENGINE::ComponentInstance)
+
 /*
  * End of Template section
  */
 
+%typemap(out) Container *
+{
+  $result=convertContainer($1,$owner);
+}
+
+%typemap(out) YACS::ENGINE::Container *
+{
+  $result=convertContainer($1,$owner);
+}
 
 /*
  * Ownership section
@@ -158,6 +169,8 @@ REFCOUNT_TEMPLATE(CompoInstmap,YACS::ENGINE::ComponentInstance)
 %newobject *::createInputDataStreamPort;
 %newobject *::createOutputDataStreamPort;
 %newobject *::clone;
+%newobject *::cloneAlways;
+%newobject *::cloneWithoutCompAndContDeepCpy;
 %newobject *::New;
 
 //Take ownership : transfer it from C++ (has to be completed)
@@ -246,6 +259,7 @@ EXCEPTION(YACS::ENGINE::ExecutorSwig::waitPause)
 
 %include <ComponentInstance.hxx>
 %include <Container.hxx>
+%include <HomogeneousPoolContainer.hxx>
 %include <InputPort.hxx>
 %extend YACS::ENGINE::InputPort
 {
index 52398d4c1974301355ce844fd08322cb8f70c6f9..3a5da9fbb9922cdc26115e7d3ebf3c3cf045a2c1 100644 (file)
@@ -121,6 +121,7 @@ namespace YACS
 %types(YACS::ENGINE::WhileLoop *,YACS::ENGINE::ForEachLoop *,YACS::ENGINE::ComposedNode *,YACS::ENGINE::InlineNode *);
 %types(YACS::ENGINE::InlineFuncNode *,YACS::ENGINE::ServiceInlineNode *,YACS::ENGINE::ServiceNode *);
 %types(YACS::ENGINE::ElementaryNode *);
+%types(YACS::ENGINE::Container *, YACS::ENGINE::HomogeneousPoolContainer *);
 
 %types(YACS::ENGINE::InputPort *,YACS::ENGINE::OutputPort *,YACS::ENGINE::InPropertyPort *);
 %types(YACS::ENGINE::InputDataStreamPort *,YACS::ENGINE::OutputDataStreamPort *);
index af8f6b07445ad190fd02e513f033a5dc2f248e7f..411231c3bd54b116c87f21b92891f557fb9d1159 100644 (file)
@@ -73,6 +73,9 @@ SET(_link_LIBRARIES
 SET(_uic_files
   FormComponent.ui
   FormContainer.ui
+  FormAdvParamContainer.ui
+  FormParamContainer.ui
+  FormHPContainer.ui
   FormEachLoop.ui
   FormEditItem.ui
   FormEditTree.ui
@@ -118,7 +121,11 @@ SET(_moc_HEADERS
   EditionSwitch.hxx
   EditionWhile.hxx
   FormComponent.hxx
+  FormContainerBase.hxx
   FormContainer.hxx
+  FormHPContainer.hxx
+  FormAdvParamContainer.hxx
+  FormContainerDecorator.hxx
   FormEachLoop.hxx
   FormEditItem.hxx
   FormEditTree.hxx
@@ -174,7 +181,7 @@ SET(GenericGui_SOURCES
   EditionComponent.hxx
   EditionComponent.cxx            
   EditionContainer.hxx            
-  EditionContainer.cxx            
+  EditionContainer.cxx
   EditionControlLink.hxx          
   EditionControlLink.cxx          
   EditionDataLink.hxx             
@@ -218,7 +225,15 @@ SET(GenericGui_SOURCES
   FormComponent.hxx               
   FormComponent.cxx               
   FormContainer.hxx               
-  FormContainer.cxx               
+  FormContainer.cxx
+  FormHPContainer.hxx 
+  FormHPContainer.cxx
+  FormContainerBase.hxx
+  FormContainerBase.cxx
+  FormAdvParamContainer.hxx 
+  FormAdvParamContainer.cxx   
+  FormContainerDecorator.hxx               
+  FormContainerDecorator.cxx        
   FormEachLoop.hxx                
   FormEachLoop.cxx                
   FormEditItem.hxx                
index ea0eea506fd8fb1a02c061b476183795a88842b2..7a14c3b0f7d18afd0b24ad3829fd5267381a0cc2 100644 (file)
@@ -104,7 +104,7 @@ void EditionComponent::changeContainer(int index)
       return;
     }
   Container *newContainer =proc->containerMap[contName];
-  SubjectContainer *scnt = GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer];
+  SubjectContainerBase *scnt = GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer];
   scompo->associateToContainer(scnt);
   scompo->select(true);
 }
index 18d02683466ef1d05b940b222194b40e72262f21..f42585b8860d8312bce17a8bec77b3ab11cc8b1e 100644 (file)
@@ -22,7 +22,7 @@
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
 
-#include "FormContainer.hxx"
+#include "FormContainerDecorator.hxx"
 #include "QtGuiContext.hxx"
 #include "guiObservers.hxx"
 #include "Proc.hxx"
@@ -36,17 +36,12 @@ using namespace YACS;
 using namespace YACS::HMI;
 using namespace YACS::ENGINE;
 
-EditionContainer::EditionContainer(Subject* subject,
-                                   QWidget* parent,
-                                   const char* name)
-  : ItemEdition(subject, parent, name)
+EditionContainer::EditionContainer(Subject* subject, QWidget* parent, const char* name):ItemEdition(subject, parent, name)
 {
-  _wContainer = new FormContainer(this);
+  _wContainer = new FormContainerDecorator(getContainer(),this);
   _wid->gridLayout1->addWidget(_wContainer);
-  connect(_wContainer->cb_resource, SIGNAL(mousePressed()),
-          this, SLOT(fillContainerPanel()));
-  connect(_wContainer->tb_container, SIGNAL(toggled(bool)),
-          this, SLOT(fillContainerPanel())); // --- to update display of current selection
+  connect(_wContainer, SIGNAL(resourceMousePressed()), this, SLOT(fillContainerPanel()));
+  connect(_wContainer->tb_container, SIGNAL(toggled(bool)), this, SLOT(fillContainerPanel())); // --- to update display of current selection
   _wContainer->tb_container->toggle();
 }
 
@@ -62,7 +57,7 @@ void EditionContainer::update(GuiEvent event, int type, Subject* son)
     {
     case RENAME:
     case UPDATE:
-      _wContainer->le_name->setText((son->getName()).c_str());
+      _wContainer->setName(son->getName());
       fillContainerPanel();
       break;
     default:
@@ -73,9 +68,7 @@ void EditionContainer::update(GuiEvent event, int type, Subject* son)
 void EditionContainer::fillContainerPanel()
 {
   DEBTRACE("EditionContainer::fillContainerPanel");
-  SubjectContainer *scont = dynamic_cast<SubjectContainer*>(_subject);
-  YASSERT(scont);
-  _wContainer->FillPanel(scont->getContainer());
+  _wContainer->FillPanel(getContainer());
 }
 
 void EditionContainer::onApply()
@@ -99,3 +92,10 @@ void EditionContainer::onCancel()
   _wContainer->onCancel();
   ItemEdition::onCancel();
 }
+
+YACS::ENGINE::Container *EditionContainer::getContainer()
+{
+  SubjectContainerBase *scont(dynamic_cast<SubjectContainerBase*>(_subject));
+  YASSERT(scont);
+  return scont->getContainer();
+}
index 51f8ccc56fca554843bc8858f676a5d94317a8ff..f9922cbd504445480c671acb8c3260741878234c 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "ItemEdition.hxx"
 
-class FormContainer;
+class FormContainerDecorator;
 
 namespace YACS
 {
@@ -45,8 +45,12 @@ namespace YACS
       virtual void onApply();
       virtual void onCancel();
 
+    private:
+
+      YACS::ENGINE::Container *getContainer();
+
     protected:
-      FormContainer *_wContainer;
+      FormContainerDecorator *_wContainer;
     };
   }
 }
index 00267fda60c35a8516e9783015bf0c626e448b4e..6ea6f0cf95d703b5091c37aa28ea5874b409e29a 100644 (file)
@@ -45,22 +45,23 @@ EditionSalomeNode::EditionSalomeNode(Subject* subject,
                                      const char* name)
   : EditionElementaryNode(subject, parent, name)
 {
-
+  //   SubjectServiceNode *ssn = dynamic_cast<SubjectServiceNode*>(_subject);
+  //   YASSERT(ssn);
+  _servNode = dynamic_cast<YACS::ENGINE::ServiceNode*>(_subElemNode->getNode());
+  YASSERT(_servNode);
   // --- create property editor panel
   _propeditor=new PropertyEditor(_subject);
   _wid->gridLayout1->addWidget(_propeditor);
 
   // --- create container and component panels
 
-  _wContainer = new FormContainer(this);
+  _wContainer = new FormContainerDecorator(_servNode->getContainer(),this);
   _wid->gridLayout1->addWidget(_wContainer);
 
-  connect(_wContainer->cb_resource, SIGNAL(mousePressed()),
-          this, SLOT(fillContainerPanel()));
-  connect(_wContainer->cb_resource, SIGNAL(activated(int)),
-          this, SLOT(changeHost(int)));
-  connect(_wContainer->tb_container, SIGNAL(toggled(bool)),
-          this, SLOT(fillContainerPanel())); // --- to update display of current selection
+  connect(_wContainer, SIGNAL(resourceMousePressed()), this, SLOT(fillContainerPanel()));
+  connect(_wContainer, SIGNAL(resourceActivated(int)), this, SLOT(changeHost(int)));
+  connect(_wContainer, SIGNAL(containerToggled(bool)), this, SLOT(fillContainerPanel()));
+  // --- to update display of current selection
 
   _wComponent = new FormComponent(this);
   _wid->gridLayout1->addWidget(_wComponent);
@@ -89,11 +90,7 @@ EditionSalomeNode::EditionSalomeNode(Subject* subject,
   _hbl_method->addWidget(_le_method);
   _wid->gridLayout1->addLayout(_hbl_method, _wid->gridLayout1->rowCount(), 0, 1, 1);
   _la_method->setText("Method:");
-//   SubjectServiceNode *ssn = dynamic_cast<SubjectServiceNode*>(_subject);
-//   YASSERT(ssn);
-  _servNode =
-    dynamic_cast<YACS::ENGINE::ServiceNode*>(_subElemNode->getNode());
-  YASSERT(_servNode);
+
   _le_method->setText((_servNode->getMethod()).c_str());
   _le_method->setReadOnly(true);
 
@@ -141,7 +138,7 @@ void EditionSalomeNode::update(GuiEvent event, int type, Subject* son)
 void EditionSalomeNode::synchronize()
 {
   EditionElementaryNode::synchronize();
-  _wContainer->tb_container->setChecked(FormContainer::_checked);
+  _wContainer->synchronizeCheckContainer();
   _wComponent->tb_component->setChecked(FormComponent::_checked);
   fillComponentPanel();
   fillContainerPanel();
@@ -235,18 +232,17 @@ void EditionSalomeNode::changeContainer(int index)
       return;
     }
   YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(newContainer));
-  SubjectContainer *scnt = GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer];
+  SubjectContainerBase *scnt(GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer]);
 
-  SubjectServiceNode *ssn = dynamic_cast<SubjectServiceNode*>(_subject);
-  SubjectComponent *sco =
-    dynamic_cast<SubjectComponent*>(ssn->getSubjectReference()->getReference());
+  SubjectServiceNode *ssn(dynamic_cast<SubjectServiceNode*>(_subject));
+  SubjectComponent *sco(dynamic_cast<SubjectComponent*>(ssn->getSubjectReference()->getReference()));
   YASSERT(sco);
   sco->associateToContainer(scnt);
 }
 
 void EditionSalomeNode::changeHost(int index)
 {
-  string hostName = _wContainer->cb_resource->itemText(index).toStdString();
+  string hostName = _wContainer->getHostName(index);
   DEBTRACE(hostName);
 }
 
index 3cae9d6af0fcb8ca10f7d8cc45f96273c437a7ef..ff48edf41ad213b5be86067dce1fa07ef97de545 100644 (file)
@@ -21,6 +21,7 @@
 #define _EDITIONSALOMENODE_HXX_
 
 #include "EditionElementaryNode.hxx"
+#include "FormContainerDecorator.hxx"
 #include <QHBoxLayout>
 #include <QLabel>
 #include <QLineEdit>
@@ -67,7 +68,7 @@ namespace YACS
     protected:
       PropertyEditor* _propeditor;
       FormComponent *_wComponent;
-      FormContainer *_wContainer;
+      FormContainerDecorator *_wContainer;
       QHBoxLayout *_hbl_method;
       QLabel *_la_method;
       QLineEdit *_le_method;
index 0012a4635c0ceb2ce43fed6045fd900b895291ac..41d5968a03c3b5a536ba95b8144a208febaf9432 100644 (file)
@@ -137,9 +137,12 @@ EditionScript::EditionScript(Subject* subject,
   hboxLayout2->addWidget(cb_container);
   _portslayout->addWidget(fr_container);
 
-  formcontainer = new FormContainer(this);
-  formcontainer->on_tb_container_toggled(false);
+  //
+  YACS::ENGINE::InlineNode *pyNode(dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode()));
+  YACS::ENGINE::Container *cont(pyNode->getContainer());
+  formcontainer = new FormContainerDecorator(cont,this);
   _portslayout->addWidget(formcontainer);
+  //_portslayout->addWidget(formcontainer->getWidget());
   //end of insertion of execution mode
 
   createTablePorts(_portslayout);
@@ -327,10 +330,11 @@ void EditionScript::on_tb_options_toggled(bool checked)
   if(_checked)
     {
       fr_options->show();
-      if(_remote) {
-       fr_container->show();
-       formcontainer->show();
-      }
+      if(_remote)
+        {
+          fr_container->show();
+          formcontainer->show();
+        }
     }
   else
     {
@@ -409,7 +413,7 @@ void EditionScript::changeContainer(int index)
       return;
     }
   YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(newContainer));
-  SubjectContainer *scnt = GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer];
+  SubjectContainerBase *scnt(GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer]);
 
   _subInlineNode->setContainer(scnt);
   
index 0055f285ace434005140a9b792027470c460141f..935a7bdf62f6de3e4a8e5a8be06ac0e9e1031333 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "yacsconfig.h"
 #include "EditionElementaryNode.hxx"
+#include "FormContainerDecorator.hxx"
 #include "FormComponent.hxx"
 #include <QRadioButton>
 
@@ -75,7 +76,7 @@ namespace YACS
       ComboBox* cb_container;
       QRadioButton* radiolocal;
       QRadioButton* radioremote;
-      FormContainer* formcontainer;
+      FormContainerDecorator* formcontainer;
     };
   }
 }
diff --git a/src/genericgui/FormAdvParamContainer.cxx b/src/genericgui/FormAdvParamContainer.cxx
new file mode 100644 (file)
index 0000000..4785b8b
--- /dev/null
@@ -0,0 +1,534 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FormAdvParamContainer.hxx"
+#include "FormComponent.hxx"
+#include "QtGuiContext.hxx"
+#include "Container.hxx"
+
+#include <cassert>
+#include <cstdlib>
+#include <climits>
+
+//#define _DEVDEBUG_
+#include "YacsTrace.hxx"
+
+#include <QList>
+#include <sstream>
+
+using namespace std;
+using namespace YACS;
+using namespace YACS::HMI;
+using namespace YACS::ENGINE;
+
+FormAdvParamContainer::FormAdvParamContainer(std::map<std::string, std::string>& prop, QWidget *parent):QWidget(parent),_properties(prop)
+{
+  setupUi(this);
+  sb_mem->setMaximum(INT_MAX);
+  sb_cpu->setMaximum(INT_MAX);
+  sb_nbNodes->setMaximum(INT_MAX);
+  sb_procNode->setMaximum(INT_MAX);
+  sb_nbprocpar->setMaximum(INT_MAX);
+  sb_nbproc->setMaximum(INT_MAX);
+  
+  FillPanel("",0); // --- set widgets before signal connexion to avoid false modif detection
+
+  connect(cb_policy, SIGNAL(activated(const QString&)), this, SLOT(onModifyPolicy(const QString&)));
+  connect(cb_parallel, SIGNAL(activated(const QString&)), this, SLOT(onModifyParLib(const QString&)));
+  connect(le_workdir, SIGNAL(textChanged(const QString&)), this, SLOT(onModifyWorkDir(const QString&)));
+  connect(le_contname, SIGNAL(textChanged(const QString&)), this, SLOT(onModifyContName(const QString&)));
+  connect(le_os, SIGNAL(textChanged(const QString&)), this, SLOT(onModifyOS(const QString&)));
+  connect(le_hostname, SIGNAL(textChanged(const QString&)), this, SLOT(onModifyHostName(const QString&)));
+  connect(le_compolist, SIGNAL(textChanged(const QString&)), this, SLOT(onModifyCompoList(const QString&)));
+  connect(le_resourceList, SIGNAL(textChanged(const QString&)), this, SLOT(onModifyResourceList(const QString&)));
+  connect(ch_mpi, SIGNAL(clicked(bool)), this, SLOT(onModifyIsMPI(bool)));
+  connect(sb_mem, SIGNAL(valueChanged(const QString&)), this, SLOT(onModifyMem(const QString&)));
+  connect(sb_cpu, SIGNAL(valueChanged(const QString&)), this, SLOT(onModifyClock(const QString&)));
+  connect(sb_nbNodes, SIGNAL(valueChanged(const QString&)), this, SLOT(onModifyNodes(const QString&)));
+  connect(sb_procNode, SIGNAL(valueChanged(const QString&)), this, SLOT(onModifyProcs(const QString&)));
+  connect(sb_nbprocpar, SIGNAL(valueChanged(const QString&)), this, SLOT(onModifyProcPar(const QString&)));
+  connect(sb_nbproc, SIGNAL(valueChanged(const QString&)), this, SLOT(onModifyProcRes(const QString&)));
+}
+
+FormAdvParamContainer::~FormAdvParamContainer()
+{
+}
+
+void FormAdvParamContainer::FillPanel(const std::string& resource, YACS::ENGINE::Container *container)
+{
+  DEBTRACE("FormContainer::FillPanel");
+  _container = container;
+  if (_container)
+    {
+      _properties = _container->getProperties();
+    }
+  else
+    {
+      _properties.clear();
+    }
+
+  if(_properties.count("type") && _properties["type"]=="multi")
+    cb_mode->setText("multi");
+  else
+    cb_mode->setText("mono");
+
+  vector<string> parlibs;
+  parlibs.push_back("");
+  parlibs.push_back("Mpi");
+  parlibs.push_back("Dummy");
+  cb_parallel->clear();
+  for(int i=0; i< parlibs.size(); i++)
+    cb_parallel->addItem(parlibs[i].c_str());
+  if(_properties.count("parallelLib"))
+    {
+      int i=0;
+      for(i=0; i< parlibs.size(); i++)
+        if(parlibs[i] == _properties["parallelLib"])
+          {
+            cb_parallel->setCurrentIndex(i);
+            break;
+          }
+    }
+  else
+    cb_parallel->setCurrentIndex(0);
+  
+  if(_properties.count("workingdir"))
+    le_workdir->setText(_properties["workingdir"].c_str());
+  else
+    le_workdir->setText("");
+
+  if(_properties.count("container_name"))
+    le_contname->setText(_properties["container_name"].c_str());
+  else
+    le_contname->setText("");
+
+  if(_properties.count("isMPI"))
+    {
+      DEBTRACE("_properties[isMPI]=" << _properties["isMPI"]);
+      if ((_properties["isMPI"] == "0") || (_properties["isMPI"] == "false"))
+        ch_mpi->setCheckState(Qt::Unchecked);
+      else
+        ch_mpi->setCheckState(Qt::Checked);
+    }
+  else
+    ch_mpi->setCheckState(Qt::Unchecked);
+
+  if(_properties.count("nb_parallel_procs"))
+    sb_nbprocpar->setValue(atoi(_properties["nb_parallel_procs"].c_str()));
+  else
+    sb_nbprocpar->setValue(0);
+  
+  updateResource(resource);
+
+  if (!QtGuiContext::getQtCurrent()->isEdition())
+    {
+      //if the schema is in execution do not allow editing
+      cb_parallel->setEnabled(false);
+      le_workdir->setReadOnly(true);
+      le_contname->setReadOnly(true);
+      ch_mpi->setEnabled(false);
+      sb_nbprocpar->setReadOnly(true);
+      le_hostname->setEnabled(false);
+      le_os->setEnabled(false);
+      sb_nbproc->setEnabled(false);
+      sb_mem->setEnabled(false);
+      sb_cpu->setEnabled(false);
+      sb_nbNodes->setEnabled(false);
+      sb_procNode->setEnabled(false);
+      cb_policy->setEnabled(false);
+      le_compolist->setEnabled(false);
+      le_resourceList->setEnabled(false);
+    }
+}
+
+void FormAdvParamContainer::onModified()
+{
+  DEBTRACE("FormContainer::onModified");
+  Subject *sub = QtGuiContext::getQtCurrent()->getSelectedSubject();
+  if (!sub) return;
+  YASSERT(QtGuiContext::getQtCurrent()->_mapOfEditionItem.count(sub));
+  QWidget *widget = QtGuiContext::getQtCurrent()->_mapOfEditionItem[sub];
+  ItemEdition *item = dynamic_cast<ItemEdition*>(widget);
+  YASSERT(item);
+  item->setEdited(true);
+}
+
+void FormAdvParamContainer::updateResource(const std::string &resource)
+{
+  DEBTRACE("FormContainer::updateResource " << resource);
+  if(resource.empty())
+  {
+    //the resource is not specified: use automatic and allow editing
+    if(_properties.count("hostname"))
+      le_hostname->setText(_properties["hostname"].c_str());
+    else
+      le_hostname->setText("");
+    le_hostname->setEnabled(true);
+
+    if(_properties.count("OS"))
+      le_os->setText(_properties["OS"].c_str());
+    else
+      le_os->setText("");
+    le_os->setEnabled(true);
+
+    if(_properties.count("nb_resource_procs"))
+      sb_nbproc->setValue(atoi(_properties["nb_resource_procs"].c_str()));
+    else
+      sb_nbproc->setValue(0);
+    sb_nbproc->setEnabled(true);
+
+    if(_properties.count("mem_mb"))
+      sb_mem->setValue(atoi(_properties["mem_mb"].c_str()));
+    else
+      sb_mem->setValue(0);
+    sb_mem->setEnabled(true);
+
+    if(_properties.count("cpu_clock"))
+      sb_cpu->setValue(atoi(_properties["cpu_clock"].c_str()));
+    else
+      sb_cpu->setValue(0);
+    sb_cpu->setEnabled(true);
+
+    if(_properties.count("nb_node"))
+      sb_nbNodes->setValue(atoi(_properties["nb_node"].c_str()));
+    else
+      sb_nbNodes->setValue(0);
+    sb_nbNodes->setEnabled(true);
+
+    if(_properties.count("nb_proc_per_node"))
+      sb_procNode->setValue(atoi(_properties["nb_proc_per_node"].c_str()));
+    else
+      sb_procNode->setValue(0);
+    sb_procNode->setEnabled(true);
+
+    std::vector<std::string> policies;
+    policies.push_back("cycl");
+    policies.push_back("altcycl");
+    policies.push_back("best");
+    policies.push_back("first");
+    cb_policy->clear();
+    for(int i=0; i< policies.size(); i++)
+      cb_policy->addItem(policies[i].c_str());
+    if(_properties.count("policy"))
+      {
+        int i=0;
+        for(i=0; i< policies.size(); i++)
+          if(policies[i] == _properties["policy"])
+            {
+              cb_policy->setCurrentIndex(i);
+              break;
+            }
+      }
+    else
+      cb_policy->setCurrentIndex(1);
+    cb_policy->setEnabled(true);
+
+    if(_properties.count("component_list"))
+      le_compolist->setText(_properties["component_list"].c_str());
+    else
+      le_compolist->setText("");
+    le_compolist->setEnabled(true);
+
+    if(_properties.count("resource_list"))
+      le_resourceList->setText(_properties["resource_list"].c_str());
+    else
+      le_resourceList->setText("");
+    le_resourceList->setEnabled(true);
+  }
+  else
+  {
+    //a specific resource has been chosen: properties are those declared in the resources manager
+    //properties can not be edited
+    std::map<std::string,std::string> properties(_container->getResourceProperties(resource));
+    if(properties.count("hostname"))
+      le_hostname->setText(properties["hostname"].c_str());
+    else
+      le_hostname->setText("");
+    le_hostname->setEnabled(false);
+
+    if(properties.count("OS"))
+      le_os->setText(properties["OS"].c_str());
+    else
+      le_os->setText("");
+    le_os->setEnabled(false);
+
+    if(properties.count("nb_resource_procs"))
+      sb_nbproc->setValue(atoi(properties["nb_resource_procs"].c_str()));
+    else
+      sb_nbproc->setValue(0);
+    sb_nbproc->setEnabled(false);
+
+    if(properties.count("mem_mb"))
+      sb_mem->setValue(atoi(properties["mem_mb"].c_str()));
+    else
+      sb_mem->setValue(0);
+    sb_mem->setEnabled(false);
+
+    if(properties.count("cpu_clock"))
+      sb_cpu->setValue(atoi(properties["cpu_clock"].c_str()));
+    else
+      sb_cpu->setValue(0);
+    sb_cpu->setEnabled(false);
+
+    if(properties.count("nb_node"))
+      sb_nbNodes->setValue(atoi(properties["nb_node"].c_str()));
+    else
+      sb_nbNodes->setValue(0);
+    sb_nbNodes->setEnabled(false);
+
+    if(properties.count("nb_proc_per_node"))
+      sb_procNode->setValue(atoi(properties["nb_proc_per_node"].c_str()));
+    else
+      sb_procNode->setValue(0);
+    sb_procNode->setEnabled(false);
+
+    cb_policy->clear();
+    cb_policy->setEnabled(false);
+
+    if(properties.count("component_list"))
+      le_compolist->setText(properties["component_list"].c_str());
+    else
+      le_compolist->setText("");
+    le_compolist->setEnabled(false);
+
+    if(properties.count("resource_list"))
+      le_resourceList->setText(properties["resource_list"].c_str());
+    else
+      le_resourceList->setText("");
+    le_resourceList->setEnabled(false);
+  }
+}
+
+void FormAdvParamContainer::setModeText(const std::string& mode)
+{
+  cb_mode->setText(mode.c_str());
+}
+
+void FormAdvParamContainer::onModifyResource(const QString &text)
+{
+  DEBTRACE("onModifyResource " << text.toStdString());
+  if (!_container) return;
+  std::string resource=text.toStdString();
+  if(resource=="automatic")resource="";
+  map<string,string> properties = _container->getProperties();
+  _properties["name"] = resource;
+  if (properties["name"] != resource)
+    {
+      // reset resource properties
+      _properties.erase("hostname");
+      _properties.erase("OS");
+      _properties.erase("nb_resource_procs");
+      _properties.erase("mem_mb");
+      _properties.erase("cpu_clock");
+      _properties.erase("nb_node");
+      _properties.erase("nb_proc_per_node");
+      _properties.erase("policy");
+      onModified();
+      updateResource(resource);
+    }
+}
+
+void FormAdvParamContainer::onModifyPolicy(const QString &text)
+{
+  DEBTRACE("onModifyPolicy " << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  _properties["policy"] = text.toStdString();
+  if (properties["policy"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyWorkDir(const QString &text)
+{
+  DEBTRACE("onModifyWorkDir " << text.toStdString());
+  if (!_container) return;
+  map<string,string> properties = _container->getProperties();
+  _properties["workingdir"] = text.toStdString();
+  if (properties["workingdir"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyContName(const QString &text)
+{
+  DEBTRACE("onModifyContName " << text.toStdString());
+  if (!_container) return;
+  map<string,string> properties = _container->getProperties();
+  _properties["container_name"] = text.toStdString();
+  if (properties["container_name"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyOS(const QString &text)
+{
+  DEBTRACE("onModifyOS " << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  _properties["OS"] = text.toStdString();
+  if (properties["OS"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyParLib(const QString &text)
+{
+  DEBTRACE("onModifyParLib " << text.toStdString());
+  if (!_container) return;
+  map<string,string> properties = _container->getProperties();
+  _properties["parallelLib"] = text.toStdString();
+  if (properties["parallelLib"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyIsMPI(bool isMpi)
+{
+  DEBTRACE("onModifyIsMPI " << isMpi);
+  if (!_container) return;
+  string text = "false";
+  if (isMpi) text = "true";
+  DEBTRACE(text);
+  map<string,string> properties = _container->getProperties();
+  _properties["isMPI"] = text;
+  if (properties["isMPI"] != text)
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyMem(const QString &text)
+{
+  DEBTRACE("onModifyMem " << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  if(properties.count("mem_mb")==0 )properties["mem_mb"]="0"; //default value
+  _properties["mem_mb"] = text.toStdString();
+  if (properties["mem_mb"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyClock(const QString &text)
+{
+  DEBTRACE("onModifyClock " << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  if(properties.count("cpu_clock")==0 )properties["cpu_clock"]="0"; //default value
+  _properties["cpu_clock"] = text.toStdString();
+  if (properties["cpu_clock"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyNodes(const QString &text)
+{
+  DEBTRACE("onModifyNodes " << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  if(properties.count("nb_node")==0 )properties["nb_node"]="0"; //default value
+  _properties["nb_node"] = text.toStdString();
+  if (properties["nb_node"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyProcs(const QString &text)
+{
+  DEBTRACE("onModifyProcs " << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  if(properties.count("nb_proc_per_node")==0 )properties["nb_proc_per_node"]="0"; //default value
+  _properties["nb_proc_per_node"] = text.toStdString();
+  if (properties["nb_proc_per_node"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyCompos(const QString &text)
+{
+  DEBTRACE("onModifyCompo " << text.toStdString());
+  if (!_container) return;
+  map<string,string> properties = _container->getProperties();
+  _properties["nb_component_nodes"] = text.toStdString();
+  if (properties["nb_component_nodes"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyProcPar(const QString &text)
+{
+  DEBTRACE("onModifyProcPar "  << text.toStdString());
+  if (!_container) return;
+  map<string,string> properties = _container->getProperties();
+  _properties["nb_parallel_procs"] = text.toStdString();
+  if (properties["nb_parallel_procs"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyResourceName(const QString &text)
+{
+  DEBTRACE("onModifyResourceName "  << text.toStdString());
+  if (!_container) return;
+  map<string,string> properties = _container->getProperties();
+  _properties["resource_name"] = text.toStdString();
+  if (properties["resource_name"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyHostName(const QString &text)
+{
+  DEBTRACE("onModifyHostName "  << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+
+  map<string,string> properties = _container->getProperties();
+  _properties["hostname"] = text.toStdString();
+  if (properties["hostname"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyProcRes(const QString &text)
+{
+  DEBTRACE("onModifyProcRes "  << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  if(properties.count("nb_resource_procs")==0 )properties["nb_resource_procs"]="0"; //default value
+  _properties["nb_resource_procs"] = text.toStdString();
+  if (properties["nb_resource_procs"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyCompoList(const QString &text)
+{
+  DEBTRACE("onModifyCompoList "  << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  _properties["component_list"] = text.toStdString();
+  if (properties["component_list"] != text.toStdString())
+    onModified();
+}
+
+void FormAdvParamContainer::onModifyResourceList(const QString &text)
+{
+  DEBTRACE("onModifyResourceList "  << text.toStdString());
+  if (!_container) return;
+  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
+  map<string,string> properties = _container->getProperties();
+  _properties["resource_list"] = text.toStdString();
+  if (properties["resource_list"] != text.toStdString())
+    onModified();
+}
diff --git a/src/genericgui/FormAdvParamContainer.hxx b/src/genericgui/FormAdvParamContainer.hxx
new file mode 100644 (file)
index 0000000..7e55cee
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _FORMADVPARAMCONTAINER_HXX_
+#define _FORMADVPARAMCONTAINER_HXX_
+
+#include "ui_FormAdvParamContainer.h"
+
+#include <QIcon>
+#include <map>
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Container;
+  }
+}
+
+class FormAdvParamContainer : public QWidget, public Ui::fm_advparamcontainer
+{
+  Q_OBJECT
+
+public:
+  FormAdvParamContainer(std::map<std::string, std::string>& prop, QWidget *parent = 0);
+  virtual ~FormAdvParamContainer();
+
+  void FillPanel(const std::string& resource, YACS::ENGINE::Container *container);
+  virtual void onModified();
+  void updateResource(const std::string &resource);
+  void setModeText(const std::string& mode);
+
+public slots:
+  void onModifyName(const QString &text);
+  void onModifyResource(const QString &text);
+  void onModifyPolicy(const QString &text);
+  void onModifyWorkDir(const QString &text);
+  void onModifyContName(const QString &text);
+  void onModifyOS(const QString &text);
+  void onModifyParLib(const QString &text);
+  void onModifyIsMPI(bool isMpi);
+  void onModifyMem(const QString &text);
+  void onModifyClock(const QString &text);
+  void onModifyNodes(const QString &text);
+  void onModifyProcs(const QString &text);
+  void onModifyCompos(const QString &text);
+  void onModifyProcPar(const QString &text);
+  void onModifyResourceName(const QString &text);
+  void onModifyHostName(const QString &text);
+  void onModifyProcRes(const QString &text);
+  void onModifyCompoList(const QString &text);
+  void onModifyResourceList(const QString &text);
+
+
+protected:
+  bool _advanced;
+  YACS::ENGINE::Container *_container;
+  std::map<std::string, std::string>& _properties;
+
+private:
+};
+
+#endif
diff --git a/src/genericgui/FormAdvParamContainer.ui b/src/genericgui/FormAdvParamContainer.ui
new file mode 100644 (file)
index 0000000..ac82257
--- /dev/null
@@ -0,0 +1,419 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>fm_advparamcontainer</class>
+ <widget class="QWidget" name="fm_advparamcontainer">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>393</width>
+    <height>565</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_1">
+   <property name="margin">
+    <number>2</number>
+   </property>
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="gb_basic">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Parameters</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <property name="margin">
+       <number>2</number>
+      </property>
+      <item row="0" column="0" colspan="2">
+       <widget class="QTabWidget" name="tw_advance">
+        <property name="currentIndex">
+         <number>1</number>
+        </property>
+        <widget class="QWidget" name="tab">
+         <attribute name="title">
+          <string>Container</string>
+         </attribute>
+         <layout class="QGridLayout" name="gridLayout_3">
+          <item row="0" column="0" colspan="2">
+           <widget class="QLabel" name="label_3">
+            <property name="text">
+             <string>container name:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="2">
+           <widget class="QLineEdit" name="le_contname">
+            <property name="toolTip">
+             <string>name of the container when instanciated at runtime</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="label_9">
+            <property name="text">
+             <string>mode:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0" colspan="2">
+           <widget class="QLabel" name="label_12">
+            <property name="text">
+             <string>working dir:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="2">
+           <widget class="QLineEdit" name="le_workdir"/>
+          </item>
+          <item row="3" column="0" colspan="3">
+           <widget class="QGroupBox" name="groupBox_2">
+            <property name="title">
+             <string>Parallel parameters</string>
+            </property>
+            <layout class="QGridLayout" name="gridLayout_4">
+             <item row="0" column="0">
+              <widget class="QLabel" name="label_16">
+               <property name="text">
+                <string>nb procs:</string>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="3">
+              <widget class="QSpinBox" name="sb_nbprocpar">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="0" colspan="4">
+              <widget class="QCheckBox" name="ch_mpi">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+               <property name="layoutDirection">
+                <enum>Qt::RightToLeft</enum>
+               </property>
+               <property name="autoFillBackground">
+                <bool>false</bool>
+               </property>
+               <property name="text">
+                <string>MPI container</string>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="0" colspan="2">
+              <widget class="QLabel" name="label_17">
+               <property name="text">
+                <string>PaCO++ lib:</string>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="2" colspan="2">
+              <widget class="QComboBox" name="cb_parallel">
+               <property name="editable">
+                <bool>false</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="2">
+              <spacer name="horizontalSpacer">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>50</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item row="4" column="1">
+           <spacer name="verticalSpacer">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>168</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="1" column="2">
+           <widget class="QLineEdit" name="cb_mode">
+            <property name="readOnly">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+        <widget class="QWidget" name="tab_2">
+         <attribute name="title">
+          <string>Resource</string>
+         </attribute>
+         <layout class="QGridLayout" name="gridLayout_5">
+          <item row="0" column="0">
+           <widget class="QLabel" name="label_19">
+            <property name="text">
+             <string>hostname:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1" colspan="2">
+           <widget class="QLineEdit" name="le_hostname"/>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="label_13">
+            <property name="text">
+             <string>O.S.:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1" colspan="2">
+           <widget class="QLineEdit" name="le_os"/>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="label_20">
+            <property name="text">
+             <string>nb procs:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <spacer name="horizontalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="2" column="2">
+           <widget class="QSpinBox" name="sb_nbproc">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="0">
+           <widget class="QLabel" name="label_5">
+            <property name="text">
+             <string>mem mb:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1">
+           <spacer name="horizontalSpacer_3">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="3" column="2">
+           <widget class="QSpinBox" name="sb_mem">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="toolTip">
+             <string>required memory (megaBytes)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="0">
+           <widget class="QLabel" name="label_6">
+            <property name="text">
+             <string>cpu clock:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="1">
+           <spacer name="horizontalSpacer_4">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="4" column="2">
+           <widget class="QSpinBox" name="sb_cpu">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="toolTip">
+             <string>required cpu clock frequency (MHz)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="0">
+           <widget class="QLabel" name="label_8">
+            <property name="text">
+             <string>nb nodes:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="1">
+           <spacer name="horizontalSpacer_5">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="5" column="2">
+           <widget class="QSpinBox" name="sb_nbNodes">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item row="6" column="0">
+           <widget class="QLabel" name="label_7">
+            <property name="text">
+             <string>nb proc / node:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="6" column="1">
+           <spacer name="horizontalSpacer_6">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="6" column="2">
+           <widget class="QSpinBox" name="sb_procNode">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item row="7" column="0">
+           <widget class="QLabel" name="label_14">
+            <property name="text">
+             <string>policy:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="8" column="0">
+           <widget class="QLabel" name="label_10">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Component list:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="9" column="0" colspan="3">
+           <widget class="QLineEdit" name="le_compolist">
+            <property name="toolTip">
+             <string>example: GEOM, SMESH</string>
+            </property>
+           </widget>
+          </item>
+          <item row="10" column="0" colspan="2">
+           <widget class="QLabel" name="label_21">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Restricted resource list:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="11" column="0" colspan="3">
+           <widget class="QLineEdit" name="le_resourceList">
+            <property name="toolTip">
+             <string>example: machine1, machine2</string>
+            </property>
+           </widget>
+          </item>
+          <item row="7" column="1" colspan="2">
+           <widget class="QComboBox" name="cb_policy">
+            <property name="editable">
+             <bool>false</bool>
+            </property>
+            <property name="maxVisibleItems">
+             <number>3</number>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index 07598f87e94ca532d9e0dc06ed19e37d1da5aec1..7e43deee49eb115ad29abbe773aaef56b88e38cc 100644 (file)
 //
 
 #include "FormContainer.hxx"
-#include "FormComponent.hxx"
-#include "QtGuiContext.hxx"
+#include "FormAdvParamContainer.hxx"
 #include "Container.hxx"
-
-#include <cassert>
-#include <cstdlib>
-#include <climits>
-
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
 
+#include <QComboBox>
 #include <QList>
+
 #include <sstream>
 
 using namespace std;
-using namespace YACS;
-using namespace YACS::HMI;
-using namespace YACS::ENGINE;
-
-bool FormContainer::_checked = false;
-
-FormContainer::FormContainer(QWidget *parent)
-{
-  setupUi(this);
-  _advanced = false;
-  _properties.clear();
-
-  QIcon icon;
-  icon.addFile("icons:icon_down.png");
-  icon.addFile("icons:icon_up.png",
-                QSize(), QIcon::Normal, QIcon::On);
-  tb_container->setIcon(icon);
-  on_tb_container_toggled(FormContainer::_checked);
-  on_ch_advance_stateChanged(0);
-
-  sb_mem->setMaximum(INT_MAX);
-  sb_cpu->setMaximum(INT_MAX);
-  sb_nbNodes->setMaximum(INT_MAX);
-  sb_procNode->setMaximum(INT_MAX);
-  sb_nbprocpar->setMaximum(INT_MAX);
-  sb_nbproc->setMaximum(INT_MAX);
-  
-
-  FillPanel(0); // --- set widgets before signal connexion to avoid false modif detection
-
-  connect(le_name, SIGNAL(textChanged(const QString&)),
-          this, SLOT(onModifyName(const QString&)));
-
-  connect(cb_resource, SIGNAL(activated(const QString&)),
-          this, SLOT(onModifyResource(const QString&)));
-
-  connect(cb_policy, SIGNAL(activated(const QString&)),
-          this, SLOT(onModifyPolicy(const QString&)));
-
-  connect(cb_type, SIGNAL(activated(const QString&)),
-          this, SLOT(onModifyType(const QString&)));
-
-  connect(cb_parallel, SIGNAL(activated(const QString&)),
-          this, SLOT(onModifyParLib(const QString&)));
-
-  connect(le_workdir, SIGNAL(textChanged(const QString&)),
-          this, SLOT(onModifyWorkDir(const QString&)));
-
-  connect(le_contname, SIGNAL(textChanged(const QString&)),
-          this, SLOT(onModifyContName(const QString&)));
-
-  connect(le_os, SIGNAL(textChanged(const QString&)),
-          this, SLOT(onModifyOS(const QString&)));
-
-  connect(le_hostname, SIGNAL(textChanged(const QString&)),
-          this, SLOT(onModifyHostName(const QString&)));
 
-  connect(le_compolist, SIGNAL(textChanged(const QString&)),
-          this, SLOT(onModifyCompoList(const QString&)));
-
-  connect(le_resourceList, SIGNAL(textChanged(const QString&)),
-          this, SLOT(onModifyResourceList(const QString&)));
-
-  connect(ch_mpi, SIGNAL(clicked(bool)),
-          this, SLOT(onModifyIsMPI(bool)));
-
-  connect(sb_mem, SIGNAL(valueChanged(const QString&)),
-          this, SLOT(onModifyMem(const QString&)));
-
-  connect(sb_cpu, SIGNAL(valueChanged(const QString&)),
-          this, SLOT(onModifyClock(const QString&)));
-
-  connect(sb_nbNodes, SIGNAL(valueChanged(const QString&)),
-          this, SLOT(onModifyNodes(const QString&)));
-
-  connect(sb_procNode, SIGNAL(valueChanged(const QString&)),
-          this, SLOT(onModifyProcs(const QString&)));
-
-  connect(sb_nbprocpar, SIGNAL(valueChanged(const QString&)),
-          this, SLOT(onModifyProcPar(const QString&)));
-
-  connect(sb_nbproc, SIGNAL(valueChanged(const QString&)),
-          this, SLOT(onModifyProcRes(const QString&)));
+FormContainer::FormContainer(QWidget *parent):FormContainerBase(parent),cb_type(new QComboBox(this))
+{ 
+  gridLayout_2_2->addWidget(cb_type);
+  FormContainer::FillPanel(0); // --- set widgets before signal connexion to avoid false modif detection
+  connect(cb_type, SIGNAL(activated(const QString&)),this, SLOT(onModifyType(const QString&)));
+  connect(ch_aoc,SIGNAL(stateChanged(int)),this,SLOT(onModifyAOC(int)));
 }
 
 FormContainer::~FormContainer()
@@ -125,596 +45,50 @@ FormContainer::~FormContainer()
 void FormContainer::FillPanel(YACS::ENGINE::Container *container)
 {
   DEBTRACE("FormContainer::FillPanel");
-  _container = container;
-  if (_container)
-    {
-      _properties = _container->getProperties();
-      le_name->setText(_container->getName().c_str());
-    }
-  else
-    {
-      _properties.clear();
-      le_name->setText("not defined");
-    }
-
+  FormContainerBase::FillPanel(container);
+  if(container)
+    ch_aoc->setCheckState(container->isAttachedOnCloning()?Qt::Checked:Qt::Unchecked);
   cb_type->clear();
   cb_type->addItem("mono");
   cb_type->addItem("multi");
   if(_properties.count("type") && _properties["type"]=="multi")
-  {
     cb_type->setCurrentIndex(1);
-    cb_mode->setText("multi");
-  }
-  else
-    cb_mode->setText("mono");
-
-
-  vector<string> parlibs;
-  parlibs.push_back("");
-  parlibs.push_back("Mpi");
-  parlibs.push_back("Dummy");
-  cb_parallel->clear();
-  for(int i=0; i< parlibs.size(); i++)
-    cb_parallel->addItem(parlibs[i].c_str());
-  if(_properties.count("parallelLib"))
-    {
-      int i=0;
-      for(i=0; i< parlibs.size(); i++)
-        if(parlibs[i] == _properties["parallelLib"])
-          {
-            cb_parallel->setCurrentIndex(i);
-            break;
-          }
-    }
-  else
-    cb_parallel->setCurrentIndex(0);
-  
-  if(_properties.count("workingdir"))
-    le_workdir->setText(_properties["workingdir"].c_str());
-  else
-    le_workdir->setText("");
-
-  if(_properties.count("container_name"))
-    le_contname->setText(_properties["container_name"].c_str());
-  else
-    le_contname->setText("");
-
-  if(_properties.count("isMPI"))
-    {
-      DEBTRACE("_properties[isMPI]=" << _properties["isMPI"]);
-      if ((_properties["isMPI"] == "0") || (_properties["isMPI"] == "false"))
-        ch_mpi->setCheckState(Qt::Unchecked);
-      else
-        ch_mpi->setCheckState(Qt::Checked);
-    }
-  else
-    ch_mpi->setCheckState(Qt::Unchecked);
-
-  if(_properties.count("nb_parallel_procs"))
-    sb_nbprocpar->setValue(atoi(_properties["nb_parallel_procs"].c_str()));
-  else
-    sb_nbprocpar->setValue(0);
-
-  //Resources
-  cb_resource->clear();
-  cb_resource->addItem("automatic"); // --- when no resource is selected
-
-  //add available resources
-  list<string> machines = QtGuiContext::getQtCurrent()->getGMain()->getMachineList();
-  list<string>::iterator itm = machines.begin();
-  for( ; itm != machines.end(); ++itm)
-    {
-      cb_resource->addItem(QString((*itm).c_str()));
-    }
-
-  std::string resource="";
-  if(_properties.count("name") && _properties["name"] != "")
-    {
-      //a resource has been specified
-      int index = cb_resource->findText(_properties["name"].c_str());
-      if (index > 0)
-        {
-          //the resource is found: use it
-          cb_resource->setCurrentIndex(index);
-          resource=_properties["name"];
-        }
-      else
-        {
-          //the resource has not been found: add a false item
-          std::string item="Unknown resource ("+_properties["name"]+")";
-          cb_resource->addItem(item.c_str());
-          cb_resource->setCurrentIndex(cb_resource->count()-1);
-        }
-    }
-  else
-    cb_resource->setCurrentIndex(0);
-  updateResource(resource);
-
-  if (!QtGuiContext::getQtCurrent()->isEdition())
-    {
-      //if the schema is in execution do not allow editing
-      le_name->setReadOnly(true);
-      cb_type->setEnabled(false);
-      cb_parallel->setEnabled(false);
-      le_workdir->setReadOnly(true);
-      le_contname->setReadOnly(true);
-      ch_mpi->setEnabled(false);
-      sb_nbprocpar->setReadOnly(true);
-      cb_resource->setEnabled(false);
-      le_hostname->setEnabled(false);
-      le_os->setEnabled(false);
-      sb_nbproc->setEnabled(false);
-      sb_mem->setEnabled(false);
-      sb_cpu->setEnabled(false);
-      sb_nbNodes->setEnabled(false);
-      sb_procNode->setEnabled(false);
-      cb_policy->setEnabled(false);
-      le_compolist->setEnabled(false);
-      le_resourceList->setEnabled(false);
-    }
-}
-
-void FormContainer::onModified()
-{
-  DEBTRACE("FormContainer::onModified");
-  Subject *sub = QtGuiContext::getQtCurrent()->getSelectedSubject();
-  if (!sub) return;
-  YASSERT(QtGuiContext::getQtCurrent()->_mapOfEditionItem.count(sub));
-  QWidget *widget = QtGuiContext::getQtCurrent()->_mapOfEditionItem[sub];
-  ItemEdition *item = dynamic_cast<ItemEdition*>(widget);
-  YASSERT(item);
-  item->setEdited(true);
-}
-
-void FormContainer::on_tb_container_toggled(bool checked)
-{
-  DEBTRACE("FormContainer::on_tb_container_toggled " << checked);
-  _checked = checked;
-  if (_checked) gb_basic->show();
-  else gb_basic->hide();
-}
-
-void FormContainer::on_ch_advance_stateChanged(int state)
-{
-  DEBTRACE("FormContainer::on_ch_advance_stateChanged " << state);
-  if (state) tw_advance->show();
-  else tw_advance->hide();
 }
 
-void FormContainer::onModifyName(const QString &text)
+QString FormContainer::getTypeStr() const
 {
-  DEBTRACE("onModifyName " << text.toStdString());
-  SubjectContainer *scont =
-    QtGuiContext::getQtCurrent()->_mapOfSubjectContainer[_container];
-  YASSERT(scont);
-  string name = scont->getName();
-  if (name != text.toStdString())
-    onModified();
-}
-
-void FormContainer::updateResource(const std::string &resource)
-{
-  DEBTRACE("FormContainer::updateResource " << resource);
-  if (resource=="")
-  {
-    //the resource is not specified: use automatic and allow editing
-    if(_properties.count("hostname"))
-      le_hostname->setText(_properties["hostname"].c_str());
-    else
-      le_hostname->setText("");
-    le_hostname->setEnabled(true);
-
-    if(_properties.count("OS"))
-      le_os->setText(_properties["OS"].c_str());
-    else
-      le_os->setText("");
-    le_os->setEnabled(true);
-
-    if(_properties.count("nb_resource_procs"))
-      sb_nbproc->setValue(atoi(_properties["nb_resource_procs"].c_str()));
-    else
-      sb_nbproc->setValue(0);
-    sb_nbproc->setEnabled(true);
-
-    if(_properties.count("mem_mb"))
-      sb_mem->setValue(atoi(_properties["mem_mb"].c_str()));
-    else
-      sb_mem->setValue(0);
-    sb_mem->setEnabled(true);
-
-    if(_properties.count("cpu_clock"))
-      sb_cpu->setValue(atoi(_properties["cpu_clock"].c_str()));
-    else
-      sb_cpu->setValue(0);
-    sb_cpu->setEnabled(true);
-
-    if(_properties.count("nb_node"))
-      sb_nbNodes->setValue(atoi(_properties["nb_node"].c_str()));
-    else
-      sb_nbNodes->setValue(0);
-    sb_nbNodes->setEnabled(true);
-
-    if(_properties.count("nb_proc_per_node"))
-      sb_procNode->setValue(atoi(_properties["nb_proc_per_node"].c_str()));
-    else
-      sb_procNode->setValue(0);
-    sb_procNode->setEnabled(true);
-
-    std::vector<std::string> policies;
-    policies.push_back("cycl");
-    policies.push_back("altcycl");
-    policies.push_back("best");
-    policies.push_back("first");
-    cb_policy->clear();
-    for(int i=0; i< policies.size(); i++)
-      cb_policy->addItem(policies[i].c_str());
-    if(_properties.count("policy"))
-      {
-        int i=0;
-        for(i=0; i< policies.size(); i++)
-          if(policies[i] == _properties["policy"])
-            {
-              cb_policy->setCurrentIndex(i);
-              break;
-            }
-      }
-    else
-      cb_policy->setCurrentIndex(1);
-    cb_policy->setEnabled(true);
-
-    if(_properties.count("component_list"))
-      le_compolist->setText(_properties["component_list"].c_str());
-    else
-      le_compolist->setText("");
-    le_compolist->setEnabled(true);
-
-    if(_properties.count("resource_list"))
-      le_resourceList->setText(_properties["resource_list"].c_str());
-    else
-      le_resourceList->setText("");
-    le_resourceList->setEnabled(true);
-  }
-  else
-  {
-    //a specific resource has been chosen: properties are those declared in the resources manager
-    //properties can not be edited
-    std::map<std::string,std::string> properties= _container->getResourceProperties(resource);
-    if(properties.count("hostname"))
-      le_hostname->setText(properties["hostname"].c_str());
-    else
-      le_hostname->setText("");
-    le_hostname->setEnabled(false);
-
-    if(properties.count("OS"))
-      le_os->setText(properties["OS"].c_str());
-    else
-      le_os->setText("");
-    le_os->setEnabled(false);
-
-    if(properties.count("nb_resource_procs"))
-      sb_nbproc->setValue(atoi(properties["nb_resource_procs"].c_str()));
-    else
-      sb_nbproc->setValue(0);
-    sb_nbproc->setEnabled(false);
-
-    if(properties.count("mem_mb"))
-      sb_mem->setValue(atoi(properties["mem_mb"].c_str()));
-    else
-      sb_mem->setValue(0);
-    sb_mem->setEnabled(false);
-
-    if(properties.count("cpu_clock"))
-      sb_cpu->setValue(atoi(properties["cpu_clock"].c_str()));
-    else
-      sb_cpu->setValue(0);
-    sb_cpu->setEnabled(false);
-
-    if(properties.count("nb_node"))
-      sb_nbNodes->setValue(atoi(properties["nb_node"].c_str()));
-    else
-      sb_nbNodes->setValue(0);
-    sb_nbNodes->setEnabled(false);
-
-    if(properties.count("nb_proc_per_node"))
-      sb_procNode->setValue(atoi(properties["nb_proc_per_node"].c_str()));
-    else
-      sb_procNode->setValue(0);
-    sb_procNode->setEnabled(false);
-
-    cb_policy->clear();
-    cb_policy->setEnabled(false);
-
-    if(properties.count("component_list"))
-      le_compolist->setText(properties["component_list"].c_str());
-    else
-      le_compolist->setText("");
-    le_compolist->setEnabled(false);
-
-    if(properties.count("resource_list"))
-      le_resourceList->setText(properties["resource_list"].c_str());
-    else
-      le_resourceList->setText("");
-    le_resourceList->setEnabled(false);
-  }
-}
-
-void FormContainer::onModifyResource(const QString &text)
-{
-  DEBTRACE("onModifyResource " << text.toStdString());
-  if (!_container) return;
-  std::string resource=text.toStdString();
-  if(resource=="automatic")resource="";
-  map<string,string> properties = _container->getProperties();
-  _properties["name"] = resource;
-  if (properties["name"] != resource)
-    {
-      // reset resource properties
-      _properties.erase("hostname");
-      _properties.erase("OS");
-      _properties.erase("nb_resource_procs");
-      _properties.erase("mem_mb");
-      _properties.erase("cpu_clock");
-      _properties.erase("nb_node");
-      _properties.erase("nb_proc_per_node");
-      _properties.erase("policy");
-      onModified();
-      updateResource(resource);
-    }
+  return QString("Container");
 }
 
 void FormContainer::onModifyType(const QString &text)
 {
   DEBTRACE("onModifyType " << text.toStdString());
-  if (!_container) return;
+  if (!_container)
+    return;
   std::string prop=_container->getProperty("type");
   _properties["type"] = text.toStdString();
   if (_properties["type"] == "mono")
-    cb_mode->setText("mono");
+    _advancedParams->setModeText("mono");
   else
-    cb_mode->setText("multi");
+    _advancedParams->setModeText("multi");
   if (prop != text.toStdString())
     onModified();
 }
 
-void FormContainer::onModifyPolicy(const QString &text)
-{
-  DEBTRACE("onModifyPolicy " << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  _properties["policy"] = text.toStdString();
-  if (properties["policy"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyWorkDir(const QString &text)
-{
-  DEBTRACE("onModifyWorkDir " << text.toStdString());
-  if (!_container) return;
-  map<string,string> properties = _container->getProperties();
-  _properties["workingdir"] = text.toStdString();
-  if (properties["workingdir"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyContName(const QString &text)
-{
-  DEBTRACE("onModifyContName " << text.toStdString());
-  if (!_container) return;
-  map<string,string> properties = _container->getProperties();
-  _properties["container_name"] = text.toStdString();
-  if (properties["container_name"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyOS(const QString &text)
-{
-  DEBTRACE("onModifyOS " << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  _properties["OS"] = text.toStdString();
-  if (properties["OS"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyParLib(const QString &text)
-{
-  DEBTRACE("onModifyParLib " << text.toStdString());
-  if (!_container) return;
-  map<string,string> properties = _container->getProperties();
-  _properties["parallelLib"] = text.toStdString();
-  if (properties["parallelLib"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyIsMPI(bool isMpi)
-{
-  DEBTRACE("onModifyIsMPI " << isMpi);
-  if (!_container) return;
-  string text = "false";
-  if (isMpi) text = "true";
-  DEBTRACE(text);
-  map<string,string> properties = _container->getProperties();
-  _properties["isMPI"] = text;
-  if (properties["isMPI"] != text)
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyMem(const QString &text)
-{
-  DEBTRACE("onModifyMem " << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  if(properties.count("mem_mb")==0 )properties["mem_mb"]="0"; //default value
-  _properties["mem_mb"] = text.toStdString();
-  if (properties["mem_mb"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyClock(const QString &text)
-{
-  DEBTRACE("onModifyClock " << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  if(properties.count("cpu_clock")==0 )properties["cpu_clock"]="0"; //default value
-  _properties["cpu_clock"] = text.toStdString();
-  if (properties["cpu_clock"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyNodes(const QString &text)
-{
-  DEBTRACE("onModifyNodes " << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  if(properties.count("nb_node")==0 )properties["nb_node"]="0"; //default value
-  _properties["nb_node"] = text.toStdString();
-  if (properties["nb_node"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyProcs(const QString &text)
-{
-  DEBTRACE("onModifyProcs " << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  if(properties.count("nb_proc_per_node")==0 )properties["nb_proc_per_node"]="0"; //default value
-  _properties["nb_proc_per_node"] = text.toStdString();
-  if (properties["nb_proc_per_node"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyCompos(const QString &text)
-{
-  DEBTRACE("onModifyCompo " << text.toStdString());
-  if (!_container) return;
-  map<string,string> properties = _container->getProperties();
-  _properties["nb_component_nodes"] = text.toStdString();
-  if (properties["nb_component_nodes"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyProcPar(const QString &text)
-{
-  DEBTRACE("onModifyProcPar "  << text.toStdString());
-  if (!_container) return;
-  map<string,string> properties = _container->getProperties();
-  _properties["nb_parallel_procs"] = text.toStdString();
-  if (properties["nb_parallel_procs"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyResourceName(const QString &text)
-{
-  DEBTRACE("onModifyResourceName "  << text.toStdString());
-  if (!_container) return;
-  map<string,string> properties = _container->getProperties();
-  _properties["resource_name"] = text.toStdString();
-  if (properties["resource_name"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyHostName(const QString &text)
-{
-  DEBTRACE("onModifyHostName "  << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-
-  map<string,string> properties = _container->getProperties();
-  _properties["hostname"] = text.toStdString();
-  if (properties["hostname"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyProcRes(const QString &text)
-{
-  DEBTRACE("onModifyProcRes "  << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  if(properties.count("nb_resource_procs")==0 )properties["nb_resource_procs"]="0"; //default value
-  _properties["nb_resource_procs"] = text.toStdString();
-  if (properties["nb_resource_procs"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyCompoList(const QString &text)
-{
-  DEBTRACE("onModifyCompoList "  << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  _properties["component_list"] = text.toStdString();
-  if (properties["component_list"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-void FormContainer::onModifyResourceList(const QString &text)
-{
-  DEBTRACE("onModifyResourceList "  << text.toStdString());
-  if (!_container) return;
-  if(_properties.count("name") && _properties["name"] != "")return; //do not modify resource parameter when specific resource is set
-  map<string,string> properties = _container->getProperties();
-  _properties["resource_list"] = text.toStdString();
-  if (properties["resource_list"] != text.toStdString())
-    {
-      onModified();
-    }
-}
-
-
-bool FormContainer::onApply()
-{
-  SubjectContainer *scont =
-    QtGuiContext::getQtCurrent()->_mapOfSubjectContainer[_container];
-  YASSERT(scont);
-  bool ret = scont->setName(le_name->text().toStdString());
-  DEBTRACE(ret);
-  if (ret) ret = scont->setProperties(_properties);
-  return ret;
-}
-
-void FormContainer::onCancel()
-{
-  SubjectContainer *scont =
-    QtGuiContext::getQtCurrent()->_mapOfSubjectContainer[_container];
-  YASSERT(scont);
-  FillPanel(scont->getContainer());
+void FormContainer::onModifyAOC(int val)
+{
+  if (!_container)
+    return;
+  bool val2(false);
+  if(val==Qt::Unchecked)
+    val2=false;
+  if(val==Qt::Checked)
+    val2=true;
+  bool prop(_container->isAttachedOnCloning());
+  int prop2((int)val2);
+  std::ostringstream oss; oss << prop2;
+  _properties[YACS::ENGINE::Container::AOC_ENTRY]=oss.str();
+  _container->setAttachOnCloningStatus(val2);
+  if(prop!=val2)
+    onModified();
 }
index 6ca4d114e735df3848ffb7b12a92b9bc6cabb07c..08f464ff2238a35f2d33cda854a817e79db8445f 100644 (file)
 #ifndef _FORMCONTAINER_HXX_
 #define _FORMCONTAINER_HXX_
 
-#include "ui_FormContainer.h"
-
-#include <QIcon>
-#include <map>
-#include <string>
+#include "FormContainerBase.hxx"
 
 namespace YACS
 {
@@ -34,54 +30,21 @@ namespace YACS
   }
 }
 
-class FormContainer: public QWidget, public Ui::fm_container
+class QComboBox;
+
+class FormContainer : public FormContainerBase
 {
   Q_OBJECT
-
 public:
   FormContainer(QWidget *parent = 0);
   virtual ~FormContainer();
-
-  void FillPanel(YACS::ENGINE::Container *container);
-  virtual void onModified();
-  virtual bool onApply();
-  virtual void onCancel();
-  void updateResource(const std::string &resource);
-
-public:
-  static bool _checked;
-
+  virtual void FillPanel(YACS::ENGINE::Container *container);
+  QString getTypeStr() const;
 public slots:
-  void on_tb_container_toggled(bool checked);
-  void on_ch_advance_stateChanged(int state);
-  void onModifyName(const QString &text);
-  void onModifyResource(const QString &text);
-  void onModifyPolicy(const QString &text);
   void onModifyType(const QString &text);
-  void onModifyWorkDir(const QString &text);
-  void onModifyContName(const QString &text);
-  void onModifyOS(const QString &text);
-  void onModifyParLib(const QString &text);
-  void onModifyIsMPI(bool isMpi);
-  void onModifyMem(const QString &text);
-  void onModifyClock(const QString &text);
-  void onModifyNodes(const QString &text);
-  void onModifyProcs(const QString &text);
-  void onModifyCompos(const QString &text);
-  void onModifyProcPar(const QString &text);
-  void onModifyResourceName(const QString &text);
-  void onModifyHostName(const QString &text);
-  void onModifyProcRes(const QString &text);
-  void onModifyCompoList(const QString &text);
-  void onModifyResourceList(const QString &text);
-
-
-protected:
-  bool _advanced;
-  YACS::ENGINE::Container *_container;
-  std::map<std::string, std::string> _properties;
-
+  void onModifyAOC(int val);
 private:
+  QComboBox *cb_type;
 };
 
 #endif
index bdc2b372cc96bb191ffefdc5a872796ba447b915..bdfd15d3f83edbec80cdb78000a4ec74b2116cbc 100644 (file)
@@ -13,7 +13,7 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout_5">
+  <layout class="QGridLayout" name="gridLayout_1">
    <property name="margin">
     <number>2</number>
    </property>
      </item>
     </layout>
    </item>
-   <item row="1" column="0">
-    <widget class="QGroupBox" name="gb_basic">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="title">
-      <string>Parameters</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_4">
-      <property name="margin">
-       <number>2</number>
-      </property>
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>Name:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLineEdit" name="le_name">
-        <property name="toolTip">
-         <string>identification of the container in schema</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_4">
-        <property name="text">
-         <string>Resource:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="ComboBox" name="cb_resource">
-        <property name="toolTip">
-         <string>name of the resource hosting container when manually set</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QLabel" name="label_15">
-        <property name="text">
-         <string>type:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="ComboBox" name="cb_type">
-        <property name="toolTip">
-         <string>container type</string>
-        </property>
-        <property name="maxVisibleItems">
-         <number>2</number>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0" colspan="2">
-       <widget class="QCheckBox" name="ch_advance">
-        <property name="text">
-         <string>Show Advanced parameters</string>
-        </property>
-       </widget>
-      </item>
-      <item row="4" column="0" colspan="2">
-       <widget class="QTabWidget" name="tw_advance">
-        <property name="currentIndex">
-         <number>1</number>
-        </property>
-        <widget class="QWidget" name="tab">
-         <attribute name="title">
-          <string>Container</string>
-         </attribute>
-         <layout class="QGridLayout" name="gridLayout_2">
-          <item row="0" column="0" colspan="2">
-           <widget class="QLabel" name="label_3">
-            <property name="text">
-             <string>container name:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="0" column="2">
-           <widget class="QLineEdit" name="le_contname">
-            <property name="toolTip">
-             <string>name of the container when instanciated at runtime</string>
-            </property>
-           </widget>
-          </item>
-          <item row="1" column="0">
-           <widget class="QLabel" name="label_9">
-            <property name="text">
-             <string>mode:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="0" colspan="2">
-           <widget class="QLabel" name="label_12">
-            <property name="text">
-             <string>working dir:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="2">
-           <widget class="QLineEdit" name="le_workdir"/>
-          </item>
-          <item row="3" column="0" colspan="3">
-           <widget class="QGroupBox" name="groupBox_2">
-            <property name="title">
-             <string>Parallel parameters</string>
-            </property>
-            <layout class="QGridLayout" name="gridLayout">
-             <item row="0" column="0">
-              <widget class="QLabel" name="label_16">
-               <property name="text">
-                <string>nb procs:</string>
-               </property>
-              </widget>
-             </item>
-             <item row="0" column="3">
-              <widget class="QSpinBox" name="sb_nbprocpar">
-               <property name="sizePolicy">
-                <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-                 <horstretch>0</horstretch>
-                 <verstretch>0</verstretch>
-                </sizepolicy>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="0" colspan="4">
-              <widget class="QCheckBox" name="ch_mpi">
-               <property name="sizePolicy">
-                <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-                 <horstretch>0</horstretch>
-                 <verstretch>0</verstretch>
-                </sizepolicy>
-               </property>
-               <property name="layoutDirection">
-                <enum>Qt::RightToLeft</enum>
-               </property>
-               <property name="autoFillBackground">
-                <bool>false</bool>
-               </property>
-               <property name="text">
-                <string>MPI container</string>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="0" colspan="2">
-              <widget class="QLabel" name="label_17">
-               <property name="text">
-                <string>PaCO++ lib:</string>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="2" colspan="2">
-              <widget class="ComboBox" name="cb_parallel">
-               <property name="editable">
-                <bool>false</bool>
-               </property>
-              </widget>
-             </item>
-             <item row="0" column="2">
-              <spacer name="horizontalSpacer">
-               <property name="orientation">
-                <enum>Qt::Horizontal</enum>
-               </property>
-               <property name="sizeHint" stdset="0">
-                <size>
-                 <width>50</width>
-                 <height>20</height>
-                </size>
-               </property>
-              </spacer>
-             </item>
-            </layout>
-           </widget>
-          </item>
-          <item row="4" column="1">
-           <spacer name="verticalSpacer">
-            <property name="orientation">
-             <enum>Qt::Vertical</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>20</width>
-              <height>168</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item row="1" column="2">
-           <widget class="QLineEdit" name="cb_mode">
-            <property name="readOnly">
-             <bool>true</bool>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-        <widget class="QWidget" name="tab_2">
-         <attribute name="title">
-          <string>Resource</string>
-         </attribute>
-         <layout class="QGridLayout" name="gridLayout_3">
-          <item row="0" column="0">
-           <widget class="QLabel" name="label_19">
-            <property name="text">
-             <string>hostname:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="0" column="1" colspan="2">
-           <widget class="QLineEdit" name="le_hostname"/>
-          </item>
-          <item row="1" column="0">
-           <widget class="QLabel" name="label_13">
-            <property name="text">
-             <string>O.S.:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="1" column="1" colspan="2">
-           <widget class="QLineEdit" name="le_os"/>
-          </item>
-          <item row="2" column="0">
-           <widget class="QLabel" name="label_20">
-            <property name="text">
-             <string>nb procs:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="1">
-           <spacer name="horizontalSpacer_2">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>20</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item row="2" column="2">
-           <widget class="QSpinBox" name="sb_nbproc">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-           </widget>
-          </item>
-          <item row="3" column="0">
-           <widget class="QLabel" name="label_5">
-            <property name="text">
-             <string>mem mb:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="3" column="1">
-           <spacer name="horizontalSpacer_3">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>20</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item row="3" column="2">
-           <widget class="QSpinBox" name="sb_mem">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="toolTip">
-             <string>required memory (megaBytes)</string>
-            </property>
-           </widget>
-          </item>
-          <item row="4" column="0">
-           <widget class="QLabel" name="label_6">
-            <property name="text">
-             <string>cpu clock:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="4" column="1">
-           <spacer name="horizontalSpacer_4">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>20</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item row="4" column="2">
-           <widget class="QSpinBox" name="sb_cpu">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="toolTip">
-             <string>required cpu clock frequency (MHz)</string>
-            </property>
-           </widget>
-          </item>
-          <item row="5" column="0">
-           <widget class="QLabel" name="label_8">
-            <property name="text">
-             <string>nb nodes:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="5" column="1">
-           <spacer name="horizontalSpacer_5">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>20</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item row="5" column="2">
-           <widget class="QSpinBox" name="sb_nbNodes">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-           </widget>
-          </item>
-          <item row="6" column="0">
-           <widget class="QLabel" name="label_7">
-            <property name="text">
-             <string>nb proc / node:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="6" column="1">
-           <spacer name="horizontalSpacer_6">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>20</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item row="6" column="2">
-           <widget class="QSpinBox" name="sb_procNode">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-           </widget>
-          </item>
-          <item row="7" column="0">
-           <widget class="QLabel" name="label_14">
-            <property name="text">
-             <string>policy:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="8" column="0">
-           <widget class="QLabel" name="label_10">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="text">
-             <string>Component list:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="9" column="0" colspan="3">
-           <widget class="QLineEdit" name="le_compolist">
-            <property name="toolTip">
-             <string>example: GEOM, SMESH</string>
-            </property>
-           </widget>
-          </item>
-          <item row="10" column="0" colspan="2">
-           <widget class="QLabel" name="label_21">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="text">
-             <string>Restricted resource list:</string>
-            </property>
-           </widget>
-          </item>
-          <item row="11" column="0" colspan="3">
-           <widget class="QLineEdit" name="le_resourceList">
-            <property name="toolTip">
-             <string>example: machine1, machine2</string>
-            </property>
-           </widget>
-          </item>
-          <item row="7" column="1" colspan="2">
-           <widget class="ComboBox" name="cb_policy">
-            <property name="editable">
-             <bool>false</bool>
-            </property>
-            <property name="maxVisibleItems">
-             <number>3</number>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
   </layout>
  </widget>
- <customwidgets>
-  <customwidget>
-   <class>ComboBox</class>
-   <extends>QComboBox</extends>
-   <header>FormComponent.hxx</header>
-  </customwidget>
- </customwidgets>
  <resources/>
- <connections>
-  <connection>
-   <sender>ch_advance</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>tw_advance</receiver>
-   <slot>setShown(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>140</x>
-     <y>171</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>135</x>
-     <y>202</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
+ <connections/>
 </ui>
diff --git a/src/genericgui/FormContainerBase.cxx b/src/genericgui/FormContainerBase.cxx
new file mode 100644 (file)
index 0000000..96601a8
--- /dev/null
@@ -0,0 +1,164 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FormContainerBase.hxx"
+#include "FormAdvParamContainer.hxx"
+#include "FormComponent.hxx"
+#include "QtGuiContext.hxx"
+#include "Container.hxx"
+
+#include <cassert>
+#include <cstdlib>
+#include <climits>
+
+//#define _DEVDEBUG_
+#include "YacsTrace.hxx"
+
+#include <QList>
+#include <sstream>
+
+using namespace std;
+using namespace YACS;
+using namespace YACS::HMI;
+using namespace YACS::ENGINE;
+
+FormContainerBase::FormContainerBase(QWidget *parent):QWidget(parent),_advancedParams(new FormAdvParamContainer(_properties,this))
+{
+  setupUi(this);
+  _advanced = false;
+  gridLayout_2->addWidget(_advancedParams);
+  on_ch_advance_stateChanged(0);
+  
+  FillPanel(0); // --- set widgets before signal connexion to avoid false modif detection
+  connect(le_name, SIGNAL(textChanged(const QString&)), this, SLOT(onModifyName(const QString&)));
+  connect(cb_resource, SIGNAL(activated(const QString&)), _advancedParams, SLOT(onModifyResource(const QString&)));
+}
+
+FormContainerBase::~FormContainerBase()
+{
+  delete _advancedParams;
+}
+
+void FormContainerBase::FillPanel(YACS::ENGINE::Container *container)
+{
+  DEBTRACE("FormContainer::FillPanel");
+  _container = container;
+  if (_container)
+    {
+      _properties = _container->getProperties();
+      le_name->setText(_container->getName().c_str());
+    }
+  else
+    {
+      _properties.clear();
+      le_name->setText("not defined");
+    }
+
+  //Resources
+  cb_resource->clear();
+  cb_resource->addItem("automatic"); // --- when no resource is selected
+
+  //add available resources
+  list<string> machines = QtGuiContext::getQtCurrent()->getGMain()->getMachineList();
+  list<string>::iterator itm = machines.begin();
+  for( ; itm != machines.end(); ++itm)
+    {
+      cb_resource->addItem(QString((*itm).c_str()));
+    }
+
+  std::string resource;
+  if(_properties.count("name") && _properties["name"] != "")
+    {
+      //a resource has been specified
+      int index = cb_resource->findText(_properties["name"].c_str());
+      if (index > 0)
+        {
+          //the resource is found: use it
+          cb_resource->setCurrentIndex(index);
+          resource=_properties["name"];
+        }
+      else
+        {
+          //the resource has not been found: add a false item
+          std::string item="Unknown resource ("+_properties["name"]+")";
+          cb_resource->addItem(item.c_str());
+          cb_resource->setCurrentIndex(cb_resource->count()-1);
+        }
+    }
+  else
+    cb_resource->setCurrentIndex(0);
+  _advancedParams->FillPanel(resource,container);
+
+  if (!QtGuiContext::getQtCurrent()->isEdition())
+    {
+      //if the schema is in execution do not allow editing
+      le_name->setReadOnly(true);
+      cb_resource->setEnabled(false);
+    }
+}
+
+void FormContainerBase::onModified()
+{
+  DEBTRACE("FormContainerBase::onModified");
+  Subject *sub(QtGuiContext::getQtCurrent()->getSelectedSubject());
+  if (!sub)
+    return;
+  YASSERT(QtGuiContext::getQtCurrent()->_mapOfEditionItem.count(sub));
+  QWidget *widget(QtGuiContext::getQtCurrent()->_mapOfEditionItem[sub]);
+  ItemEdition *item(dynamic_cast<ItemEdition*>(widget));
+  YASSERT(item);
+  item->setEdited(true);
+}
+
+void FormContainerBase::on_ch_advance_stateChanged(int state)
+{
+  DEBTRACE("FormContainer::on_ch_advance_stateChanged " << state);
+  if (state)
+    _advancedParams->show();
+  else
+    _advancedParams->hide();
+}
+
+void FormContainerBase::onModifyName(const QString &text)
+{
+  DEBTRACE("onModifyName " << text.toStdString());
+  SubjectContainerBase *scont(QtGuiContext::getQtCurrent()->_mapOfSubjectContainer[_container]);
+  YASSERT(scont);
+  string name = scont->getName();
+  if (name != text.toStdString())
+    onModified();
+}
+
+bool FormContainerBase::onApply()
+{
+  SubjectContainerBase *scont(QtGuiContext::getQtCurrent()->_mapOfSubjectContainer[_container]);
+  YASSERT(scont);
+  bool ret(scont->setName(le_name->text().toStdString()));
+  DEBTRACE(ret);
+  if (ret)
+    ret = scont->setProperties(_properties);
+  return ret;
+}
+
+void FormContainerBase::onCancel()
+{
+  SubjectContainerBase *scont(QtGuiContext::getQtCurrent()->_mapOfSubjectContainer[_container]);
+  YASSERT(scont);
+  FillPanel(scont->getContainer());
+}
diff --git a/src/genericgui/FormContainerBase.hxx b/src/genericgui/FormContainerBase.hxx
new file mode 100644 (file)
index 0000000..43cf6d6
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _FORMCONTAINERBASE_HXX_
+#define _FORMCONTAINERBASE_HXX_
+
+#include "ui_FormParamContainer.h"
+
+#include <QString>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Container;
+  }
+}
+
+class FormAdvParamContainer;
+
+class FormContainerBase : public QWidget, public Ui::fm_paramcontainer
+{
+  Q_OBJECT
+
+public:
+  FormContainerBase(QWidget *parent = 0);
+  virtual ~FormContainerBase();
+  virtual void FillPanel(YACS::ENGINE::Container *container);
+  virtual void onModified();
+  virtual bool onApply();
+  virtual void onCancel();
+  virtual QString getTypeStr() const = 0;
+public slots:
+  void on_ch_advance_stateChanged(int state);
+  void onModifyName(const QString &text);
+
+protected:
+  bool _advanced;
+  YACS::ENGINE::Container *_container;
+  std::map<std::string, std::string> _properties;
+  FormAdvParamContainer *_advancedParams;
+};
+
+#endif
diff --git a/src/genericgui/FormContainerDecorator.cxx b/src/genericgui/FormContainerDecorator.cxx
new file mode 100644 (file)
index 0000000..f6d2405
--- /dev/null
@@ -0,0 +1,184 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FormContainerDecorator.hxx"
+#include "FormContainer.hxx"
+#include "FormHPContainer.hxx"
+
+#include "HomogeneousPoolContainer.hxx"
+#include "Exception.hxx"
+
+//#define _DEVDEBUG_
+#include "YacsTrace.hxx"
+
+using namespace YACS::ENGINE;
+
+bool FormContainerDecorator::CHECKED = false;
+
+FormContainerDecorator::FormContainerDecorator(YACS::ENGINE::Container *cont, QWidget *parent):QWidget(parent),_typ(0)
+{
+  setupUi(this);
+  _icon.addFile("icons:icon_down.png");
+  _icon.addFile("icons:icon_up.png",QSize(), QIcon::Normal, QIcon::On);
+  tb_container->setIcon(_icon);
+  connect(this,SIGNAL(typeOfContainerIsKnown(const QString&)),label,SLOT(setText(const QString &)));
+  if(!cont)
+    return ;
+  HomogeneousPoolContainer *hpc(dynamic_cast<HomogeneousPoolContainer *>(cont));
+  if(!hpc)
+    _typ=new FormContainer(this);
+  else
+    _typ=new FormHPContainer(this);
+  emit typeOfContainerIsKnown(_typ->getTypeStr());
+  _typ->FillPanel(cont);
+  gridLayout_1->addWidget(_typ);
+  connectForTyp();
+  tb_container->setChecked(CHECKED);
+  on_tb_container_toggled(CHECKED);
+}
+
+FormContainerDecorator::~FormContainerDecorator()
+{
+  delete _typ;
+}
+
+void FormContainerDecorator::FillPanel(YACS::ENGINE::Container *container)
+{
+  checkAndRepareTypeIfNecessary(container);
+  _typ->FillPanel(container);
+}
+
+QWidget *FormContainerDecorator::getWidget()
+{
+  return _typ;
+}
+
+bool FormContainerDecorator::onApply()
+{
+  if(!checkOK())
+    return false;
+  return _typ->onApply();
+}
+
+void FormContainerDecorator::onCancel()
+{
+  if(!checkOK())
+    return ;
+  _typ->onCancel();
+}
+
+void FormContainerDecorator::show()
+{
+  QWidget::show();
+  if(!checkOK())
+    return ;
+  _typ->show();
+  tb_container->setChecked(CHECKED);
+  on_tb_container_toggled(CHECKED);
+}
+
+void FormContainerDecorator::hide()
+{
+  QWidget::hide();
+  if(!checkOK())
+    return ;
+  _typ->hide();
+}
+
+void FormContainerDecorator::on_tb_container_toggled(bool checked)
+{
+  DEBTRACE("FormContainer::on_tb_container_toggled " << checked);
+  CHECKED = checked;
+  if (CHECKED)
+    {
+      getWidget()->show();
+    }
+  else
+    {
+      getWidget()->hide();
+    }
+}
+
+void FormContainerDecorator::synchronizeCheckContainer()
+{
+  tb_container->setChecked(CHECKED);
+}
+
+std::string FormContainerDecorator::getHostName(int index) const
+{
+  if(!checkOK())
+    return std::string();
+  return _typ->cb_resource->itemText(index).toStdString();
+}
+
+void FormContainerDecorator::setName(const std::string& name)
+{
+  if(!checkOK())
+    return ;
+  _typ->le_name->setText(name.c_str());
+}
+
+void FormContainerDecorator::onResMousePressed()
+{
+  emit(resourceMousePressed());
+}
+
+void FormContainerDecorator::onResActivated(int v)
+{
+  emit(resourceActivated(v));
+}
+
+void FormContainerDecorator::onContToggled(bool v)
+{
+  emit(containerToggled(v));
+}
+
+bool FormContainerDecorator::checkOK() const
+{
+  return _typ;
+}
+
+void FormContainerDecorator::checkAndRepareTypeIfNecessary(YACS::ENGINE::Container *container)
+{
+  if(!container)
+    return ;
+  YACS::ENGINE::HomogeneousPoolContainer *cont1(dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(container));
+  if(_typ)
+    {
+      bool isTyp1(dynamic_cast<FormHPContainer *>(_typ)!=0);
+      if((!cont1 && !isTyp1) || (cont1 && isTyp1))
+        return ;
+      delete _typ; _typ=0;
+    }
+  if(!cont1)
+    _typ=new FormContainer(this);
+  else
+    _typ=new FormHPContainer(this);
+  gridLayout_1->addWidget(_typ);
+  emit typeOfContainerIsKnown(_typ->getTypeStr());
+  connectForTyp();
+  _typ->FillPanel(container);
+}
+
+void FormContainerDecorator::connectForTyp()
+{
+  connect(_typ->cb_resource,SIGNAL(mousePressed()),this,SLOT(onResMousePressed()));
+  connect(_typ->cb_resource,SIGNAL(activated(int)),this,SLOT(onResActivated));
+  connect(tb_container,SIGNAL(toggled(bool)),this,SLOT(onContToggled()));
+}
diff --git a/src/genericgui/FormContainerDecorator.hxx b/src/genericgui/FormContainerDecorator.hxx
new file mode 100644 (file)
index 0000000..4dc8f06
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _FORMCONTAINERDECORATOR_HXX_
+#define _FORMCONTAINERDECORATOR_HXX_
+
+#include <QWidget>
+#include <QIcon>
+
+#include "ui_FormContainer.h"
+
+class FormContainerBase;
+
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Container;
+  }
+}
+
+class FormContainerDecorator : public QWidget, public Ui::fm_container
+{
+  Q_OBJECT
+public:
+  FormContainerDecorator(YACS::ENGINE::Container *cont, QWidget *parent = 0);
+  ~FormContainerDecorator();
+  void FillPanel(YACS::ENGINE::Container *container);
+  QWidget *getWidget();
+  bool onApply();
+  void onCancel();
+  void show();
+  void hide();
+  void synchronizeCheckContainer();
+  std::string getHostName(int index) const;
+  void setName(const std::string& name);
+public:
+  static bool CHECKED;
+public slots:
+  void on_tb_container_toggled(bool checked);
+  void onResMousePressed();
+  void onResActivated(int);
+  void onContToggled(bool);
+signals:
+  void typeOfContainerIsKnown(const QString& typeOfCont);
+  void resourceMousePressed();
+  void resourceActivated(int);
+  void containerToggled(bool);//connect(_wContainer->tb_container, SIGNAL(toggled(bool)), this, SLOT(fillContainerPanel())); // --- to update display of current selection
+private:
+  bool checkOK() const;
+  void checkAndRepareTypeIfNecessary(YACS::ENGINE::Container *container);
+  void connectForTyp();
+private:
+  FormContainerBase *_typ;
+  QIcon _icon;
+};
+
+#endif
diff --git a/src/genericgui/FormHPContainer.cxx b/src/genericgui/FormHPContainer.cxx
new file mode 100644 (file)
index 0000000..9653e5c
--- /dev/null
@@ -0,0 +1,161 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FormHPContainer.hxx"
+#include "FormAdvParamContainer.hxx"
+#include "HomogeneousPoolContainer.hxx"
+#include "QtGuiContext.hxx"
+#include "guiObservers.hxx"
+//#define _DEVDEBUG_
+#include "Resource.hxx"
+#include "YacsTrace.hxx"
+
+#include <QIntValidator>
+#include <QLineEdit>
+
+#if HAS_QSCI4>0
+#include <qsciscintilla.h>
+#include <qscilexerpython.h>
+#endif
+
+#include <sstream>
+#include <limits>
+
+using namespace std;
+
+FormHPContainer::FormHPContainer(QWidget *parent):FormContainerBase(parent),_poolSz(new QLineEdit(this)),_initScriptModified(false)
+{
+  QIntValidator *iv(new QIntValidator(_poolSz)); iv->setRange(1,std::numeric_limits<int>::max());
+  _poolSz->setValidator(iv);
+  label_15->setText("Size of pool :");
+  gridLayout_2_2->addWidget(_poolSz);
+  FormHPContainer::FillPanel(0); // --- set widgets before signal connexion to avoid false modif detection
+  connect(_poolSz, SIGNAL(textChanged(const QString&)),this, SLOT(onModifySzOfPool(const QString&)));
+  ch_aoc->setEnabled(false);
+  ch_aoc->setCheckState(Qt::Checked);
+  //
+#if HAS_QSCI4>0
+  _initScript=new QsciScintilla(_advancedParams->tw_advance);
+  QsciLexerPython *lex(new QsciLexerPython(_initScript));
+  lex->setFont(YACS::HMI::Resource::pythonfont);
+  _initScript->setLexer(lex);
+  _initScript->setBraceMatching(QsciScintilla::SloppyBraceMatch);
+  _initScript->setAutoIndent(1);
+  _initScript->setIndentationWidth(4);
+  _initScript->setIndentationGuides(1);
+  _initScript->setIndentationsUseTabs(0);
+  _initScript->setAutoCompletionThreshold(2);
+  _initScript->setMarginWidth(1,0);
+  _initScript->setFolding(QsciScintilla::PlainFoldStyle);
+#else
+  _initScript=new QTextEdit(this);
+#endif
+  connect(_initScript,SIGNAL(textChanged()),this,SLOT(initSciptChanged()));
+  QGridLayout *gridLayout(new QGridLayout(_initScript));
+  _advancedParams->tw_advance->addTab(_initScript,"Init Script");
+}
+
+FormHPContainer::~FormHPContainer()
+{
+}
+
+void FormHPContainer::FillPanel(YACS::ENGINE::Container *container)
+{
+  DEBTRACE("FormHPContainer::FillPanel");
+  FormContainerBase::FillPanel(container);
+  if(!container)
+    return ;
+  YACS::ENGINE::HomogeneousPoolContainer *hpc(dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(container));
+  if(!hpc)
+    throw YACS::Exception("FormHPContainer::FillPanel : not a HP Container !");
+  _poolSz->setText(QString("%1").arg(hpc->getSizeOfPool()));
+  std::string initScript;
+  if(_properties.count(YACS::ENGINE::HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY))
+    initScript=_properties[YACS::ENGINE::HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY];
+  std::string initScript2(BuildWithFinalEndLine(initScript));
+  _initScript->blockSignals(true);
+  _initScript->setText(initScript2.c_str());
+  _initScript->blockSignals(false);
+  if (!YACS::HMI::QtGuiContext::getQtCurrent()->isEdition())
+    {
+      //if the schema is in execution do not allow editing
+      _poolSz->setEnabled(false);
+      _initScript->setEnabled(false);
+    }
+}
+
+QString FormHPContainer::getTypeStr() const
+{
+  return QString("Container (HP)");
+}
+
+void FormHPContainer::onModifySzOfPool(const QString& newSz)
+{
+  if (!_container)
+    return;
+  map<string,string> properties(_container->getProperties());
+  uint sz;
+  bool isOK;
+  sz=newSz.toUInt(&isOK);
+  if(!isOK)
+    return ;
+  _properties[YACS::ENGINE::HomogeneousPoolContainer::SIZE_OF_POOL_KEY] = newSz.toStdString();
+  if(properties[YACS::ENGINE::HomogeneousPoolContainer::SIZE_OF_POOL_KEY] != newSz.toStdString())
+    onModified();
+}
+
+bool FormHPContainer::onApply()
+{
+  YACS::HMI::SubjectContainerBase *scont(YACS::HMI::QtGuiContext::getQtCurrent()->_mapOfSubjectContainer[_container]);
+  YASSERT(scont);
+  bool ret(scont->setName(le_name->text().toStdString()));
+  std::map<std::string,std::string> properties(_properties);
+  if(_initScriptModified)
+    {
+      std::string text(_initScript->text().toStdString());
+      std::string text2(BuildWithFinalEndLine(text));
+      properties[YACS::ENGINE::HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY]=text2;
+    }
+  _initScriptModified=false;
+  DEBTRACE(ret);
+  if(ret)
+    ret = scont->setProperties(properties);
+  return ret;
+}
+
+void FormHPContainer::initSciptChanged()
+{
+  _initScriptModified=true;
+  onModified();
+}
+
+std::string FormHPContainer::BuildWithFinalEndLine(const std::string& script)
+{
+  if(script.empty())
+    return std::string("\n");
+  std::size_t sz(script.length());
+  if(script[sz-1]!='\n')
+    {
+      std::string ret(script);
+      ret+="\n";
+      return ret;
+    }
+  else
+    return script;
+}
diff --git a/src/genericgui/FormHPContainer.hxx b/src/genericgui/FormHPContainer.hxx
new file mode 100644 (file)
index 0000000..2f93f1d
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _FORMHPCONTAINER_HXX_
+#define _FORMHPCONTAINER_HXX_
+
+#include "FormContainerBase.hxx"
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Container;
+  }
+}
+
+#if HAS_QSCI4>0
+class QsciScintilla;
+#endif
+
+class QTextEdit;
+class QLineEdit;
+
+class FormHPContainer : public FormContainerBase
+{
+  Q_OBJECT
+
+public:
+  FormHPContainer(QWidget *parent = 0);
+  virtual ~FormHPContainer();
+  void FillPanel(YACS::ENGINE::Container *container);
+  QString getTypeStr() const;
+  bool onApply();
+public slots:
+  void onModifySzOfPool(const QString& newSz);
+  void initSciptChanged();
+public:
+  static std::string BuildWithFinalEndLine(const std::string& script);
+private:
+  QLineEdit *_poolSz;
+#if HAS_QSCI4>0
+  QsciScintilla* _initScript;
+#else
+  QTextEdit* _initScript;
+#endif
+  bool _initScriptModified;
+  bool _initScriptLoaded;
+};
+
+#endif
diff --git a/src/genericgui/FormHPContainer.ui b/src/genericgui/FormHPContainer.ui
new file mode 100644 (file)
index 0000000..4cd409f
--- /dev/null
@@ -0,0 +1,554 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>fm_hpcontainer</class>
+ <widget class="QWidget" name="fm_hpcontainer">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>424</width>
+    <height>658</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <property name="margin">
+    <number>2</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QToolButton" name="tb_container">
+       <property name="text">
+        <string>...</string>
+       </property>
+       <property name="checkable">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="font">
+        <font>
+         <weight>75</weight>
+         <bold>true</bold>
+        </font>
+       </property>
+       <property name="text">
+        <string>Container</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_7">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="gb_basic">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Parameters</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_4">
+      <property name="margin">
+       <number>2</number>
+      </property>
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Name:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="le_name">
+        <property name="toolTip">
+         <string>identification of the container in schema</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_4">
+        <property name="text">
+         <string>Resource:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="ComboBox" name="cb_resource">
+        <property name="toolTip">
+         <string>name of the resource hosting container when manually set</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_15">
+        <property name="text">
+         <string>Size of Pool :</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0" colspan="2">
+       <widget class="QCheckBox" name="ch_advance">
+        <property name="text">
+         <string>Show Advanced parameters</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="2">
+       <widget class="QTabWidget" name="tw_advance">
+        <property name="currentIndex">
+         <number>1</number>
+        </property>
+        <widget class="QWidget" name="tab">
+         <attribute name="title">
+          <string>Container</string>
+         </attribute>
+         <layout class="QGridLayout" name="gridLayout_2">
+          <item row="0" column="0" colspan="2">
+           <widget class="QLabel" name="label_3">
+            <property name="text">
+             <string>container name:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="2">
+           <widget class="QLineEdit" name="le_contname">
+            <property name="toolTip">
+             <string>name of the container when instanciated at runtime</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="label_9">
+            <property name="text">
+             <string>mode:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0" colspan="2">
+           <widget class="QLabel" name="label_12">
+            <property name="text">
+             <string>working dir:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="2">
+           <widget class="QLineEdit" name="le_workdir"/>
+          </item>
+          <item row="3" column="0" colspan="3">
+           <widget class="QGroupBox" name="groupBox_2">
+            <property name="title">
+             <string>Parallel parameters</string>
+            </property>
+            <layout class="QGridLayout" name="gridLayout">
+             <item row="0" column="0">
+              <widget class="QLabel" name="label_16">
+               <property name="text">
+                <string>nb procs:</string>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="3">
+              <widget class="QSpinBox" name="sb_nbprocpar">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="0" colspan="4">
+              <widget class="QCheckBox" name="ch_mpi">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+               <property name="layoutDirection">
+                <enum>Qt::RightToLeft</enum>
+               </property>
+               <property name="autoFillBackground">
+                <bool>false</bool>
+               </property>
+               <property name="text">
+                <string>MPI container</string>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="0" colspan="2">
+              <widget class="QLabel" name="label_17">
+               <property name="text">
+                <string>PaCO++ lib:</string>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="2" colspan="2">
+              <widget class="ComboBox" name="cb_parallel">
+               <property name="editable">
+                <bool>false</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="2">
+              <spacer name="horizontalSpacer">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>50</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item row="4" column="1">
+           <spacer name="verticalSpacer">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>168</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="1" column="2">
+           <widget class="QLineEdit" name="cb_mode">
+            <property name="readOnly">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+        <widget class="QWidget" name="tab_2">
+         <attribute name="title">
+          <string>Resource</string>
+         </attribute>
+         <layout class="QGridLayout" name="gridLayout_3">
+          <item row="0" column="0">
+           <widget class="QLabel" name="label_19">
+            <property name="text">
+             <string>hostname:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1" colspan="2">
+           <widget class="QLineEdit" name="le_hostname"/>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="label_13">
+            <property name="text">
+             <string>O.S.:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1" colspan="2">
+           <widget class="QLineEdit" name="le_os"/>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="label_20">
+            <property name="text">
+             <string>nb procs:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <spacer name="horizontalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="2" column="2">
+           <widget class="QSpinBox" name="sb_nbproc">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="0">
+           <widget class="QLabel" name="label_5">
+            <property name="text">
+             <string>mem mb:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1">
+           <spacer name="horizontalSpacer_3">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="3" column="2">
+           <widget class="QSpinBox" name="sb_mem">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="toolTip">
+             <string>required memory (megaBytes)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="0">
+           <widget class="QLabel" name="label_6">
+            <property name="text">
+             <string>cpu clock:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="1">
+           <spacer name="horizontalSpacer_4">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="4" column="2">
+           <widget class="QSpinBox" name="sb_cpu">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="toolTip">
+             <string>required cpu clock frequency (MHz)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="0">
+           <widget class="QLabel" name="label_8">
+            <property name="text">
+             <string>nb nodes:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="1">
+           <spacer name="horizontalSpacer_5">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="5" column="2">
+           <widget class="QSpinBox" name="sb_nbNodes">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item row="6" column="0">
+           <widget class="QLabel" name="label_7">
+            <property name="text">
+             <string>nb proc / node:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="6" column="1">
+           <spacer name="horizontalSpacer_6">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="6" column="2">
+           <widget class="QSpinBox" name="sb_procNode">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item row="7" column="0">
+           <widget class="QLabel" name="label_14">
+            <property name="text">
+             <string>policy:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="8" column="0">
+           <widget class="QLabel" name="label_10">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Component list:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="9" column="0" colspan="3">
+           <widget class="QLineEdit" name="le_compolist">
+            <property name="toolTip">
+             <string>example: GEOM, SMESH</string>
+            </property>
+           </widget>
+          </item>
+          <item row="10" column="0" colspan="2">
+           <widget class="QLabel" name="label_21">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Restricted resource list:</string>
+            </property>
+           </widget>
+          </item>
+          <item row="11" column="0" colspan="3">
+           <widget class="QLineEdit" name="le_resourceList">
+            <property name="toolTip">
+             <string>example: machine1, machine2</string>
+            </property>
+           </widget>
+          </item>
+          <item row="7" column="1" colspan="2">
+           <widget class="ComboBox" name="cb_policy">
+            <property name="editable">
+             <bool>false</bool>
+            </property>
+            <property name="maxVisibleItems">
+             <number>3</number>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+        <widget class="QWidget" name="Initialize">
+         <property name="maximumSize">
+          <size>
+           <width>16777215</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <attribute name="title">
+          <string>Init Script</string>
+         </attribute>
+         <layout class="QGridLayout" name="gridLayout_5">
+          <item row="0" column="0">
+           <layout class="QVBoxLayout" name="verticalLayout_3">
+            <item>
+             <widget class="QTextEdit" name="textEdit"/>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="cb_poolsize"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ComboBox</class>
+   <extends>QComboBox</extends>
+   <header>FormComponent.hxx</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>ch_advance</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>tw_advance</receiver>
+   <slot>setShown(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>140</x>
+     <y>171</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>135</x>
+     <y>202</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/genericgui/FormParamContainer.ui b/src/genericgui/FormParamContainer.ui
new file mode 100644 (file)
index 0000000..41c36c1
--- /dev/null
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>fm_paramcontainer</class>
+ <widget class="QWidget" name="fm_paramcontainer">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>420</width>
+    <height>602</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>350</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_1">
+   <property name="margin">
+    <number>2</number>
+   </property>
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="gb_basic">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Parameters</string>
+     </property>
+     <layout class="QVBoxLayout" name="gridLayout_2">
+      <property name="margin">
+       <number>2</number>
+      </property>
+      <item>
+       <layout class="QHBoxLayout" name="gridLayout_2_0">
+        <property name="margin">
+         <number>2</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="label_2">
+          <property name="text">
+           <string>Name:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLineEdit" name="le_name">
+          <property name="toolTip">
+           <string>identification of the container in schema</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="gridLayout_2_1">
+        <property name="margin">
+         <number>2</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="label_4">
+          <property name="text">
+           <string>Resource:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="cb_resource">
+          <property name="toolTip">
+           <string>name of the resource hosting container when manually set</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="gridLayout_2_2">
+        <property name="margin">
+         <number>2</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="label_15">
+          <property name="text">
+           <string>type:</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="gridLayout_2_3">
+        <property name="margin">
+         <number>2</number>
+        </property>
+        <item>
+         <widget class="QCheckBox" name="ch_advance">
+          <property name="text">
+           <string>Show Advanced parameters</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="ch_aoc">
+          <property name="text">
+           <string>Attached on cloning</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index 16d08646d96d66c6e6430e8d03481e9cdbd2f323..845ee4b77be3f2b3ea3c46cde71820624e55d5e1 100644 (file)
@@ -307,6 +307,10 @@ void GenericGui::createActions()
                                             tr("Create Container"), tr("Create a New Container"),
                                             0, _parent, false, this,  SLOT(onNewContainer()));
 
+  _newHPContainerAct = _wrapper->createAction(getMenuId(), tr("Create a New HP Container"), QIcon("icons:container.png"),
+                                              tr("Create HP Container"), tr("Create a New Homogeneous Pool Container."),
+                                              0, _parent, false, this,  SLOT(onNewHPContainer()));
+
   _selectComponentInstanceAct = _wrapper->createAction(getMenuId(), tr("Select a Component Instance"), QIcon("icons:icon_select.png"),
                                                        tr("Select a Component Instance"), tr("Select a Component Instance"),
                                                        0, _parent, false, this,  SLOT(onSelectComponentInstance()));
@@ -1959,6 +1963,12 @@ void GenericGui::onNewContainer()
   _guiEditor->CreateContainer();
 }
 
+void GenericGui::onNewHPContainer()
+{
+  DEBTRACE("GenericGui::onNewHPContainer");
+  _guiEditor->CreateHPContainer();
+}
+
 void GenericGui::onNewSalomeComponent()
 {
   DEBTRACE("GenericGui::onNewSalomeComponent");
index 92767e1c24c3526db6d2f890f37e2f3bc6cc317a..2c9c6179cd9a1bdeda8fdad4bd38951beb2ca632 100644 (file)
@@ -123,6 +123,7 @@ namespace YACS
       QAction *_createDataTypeAct;
       QAction *_importDataTypeAct;
       QAction *_newContainerAct;
+      QAction *_newHPContainerAct;
       QAction *_selectComponentInstanceAct;
       QAction *_newSalomeComponentAct;
       QAction *_newSalomePythonComponentAct;
@@ -262,6 +263,7 @@ namespace YACS
       void onImportDataType();
 
       void onNewContainer();
+      void onNewHPContainer();
       void onSelectComponentInstance();
       void onNewSalomeComponent();
       void onNewSalomePythonComponent();
index c50a41dda7e654fa9519e829a813650acd5e2086..da2237e89ceccaa4ae3984c7be246b0743c26a04 100644 (file)
@@ -269,7 +269,7 @@ void GuiEditor::CreateContainer()
   DEBTRACE("GuiEditor::CreateContainer");
   SubjectProc *sproc = QtGuiContext::getQtCurrent()->getSubjectProc();
   YASSERT(sproc);
-  SubjectContainer *scont = 0;
+  SubjectContainerBase *scont = 0;
   while (!scont)
     {
       std::stringstream name;
@@ -281,6 +281,23 @@ void GuiEditor::CreateContainer()
     }
 }
 
+void GuiEditor::CreateHPContainer()
+{
+  DEBTRACE("GuiEditor::CreateHPContainer");
+  SubjectProc *sproc = QtGuiContext::getQtCurrent()->getSubjectProc();
+  YASSERT(sproc);
+  SubjectContainerBase *scont = 0;
+  while (!scont)
+    {
+      std::stringstream name;
+      long newid = GuiContext::getCurrent()->getNewId();
+      if (newid > 100000) break;
+      name.str("");
+      name << "container" << newid;
+      scont = sproc->addHPContainer(name.str());
+    }
+}
+
 void GuiEditor::CreateComponentInstance()
 {
   DEBTRACE("GuiEditor::CreateComponentInstance");
index 7940b744320c491ebc22abc17d45a7f4d87908df..0e791a57c0093178acd8c2d589e72fe8f5e2b5af 100644 (file)
@@ -59,6 +59,7 @@ namespace YACS
       void CreateSwitch();
       void CreateOptimizerLoop();
       void CreateContainer();
+      void CreateHPContainer();
       void CreateComponentInstance();
 
       SubjectDataPort* CreateInputPort(SubjectElementaryNode* seNode,
index 9ca26fe400878065f1e0f62bcaeef6dcc494885f..2fd7ae1e1f07f2365453ca3927fc4178bffff27d 100644 (file)
@@ -115,10 +115,10 @@ ItemEditionBase::ItemEditionBase(Subject* subject)
       _category = "Component";
       _type = "Salome Component";
     }
-  else if (SubjectContainer * sub = dynamic_cast<SubjectContainer*>(_subject))
+  else if (SubjectContainerBase * sub = dynamic_cast<SubjectContainerBase*>(_subject))
     {
       _category = "Container";
-      _type = "Salome Container";
+      _type = sub->getLabelForHuman();
     }
 }
 
@@ -402,9 +402,7 @@ void ItemEdition::update(GuiEvent event, int type, Subject* son)
                                         son->getName().c_str());
           break;
         case YACS::HMI::CONTAINER:
-          item =  new EditionContainer(son,
-                                       QtGuiContext::getQtCurrent()->getStackedWidget(),
-                                       son->getName().c_str());
+          item =  new EditionContainer(son,QtGuiContext::getQtCurrent()->getStackedWidget(),son->getName().c_str());
           break;
         case YACS::HMI::COMPONENT:
           item =  new EditionComponent(son,
index 8cbc6bc0d19fea60eb14787f096515dbb49b6e22..1a43e83103aa154cc45705b7b1188f55f308b709 100644 (file)
@@ -227,6 +227,7 @@ void ProcMenu::popupMenu(QWidget *caller, const QPoint &globalPos, const QString
       menu.addSeparator();
       menu.addAction(gmain->_importDataTypeAct);
       menu.addAction(gmain->_newContainerAct);
+      menu.addAction(gmain->_newHPContainerAct);
       QMenu *CNmenu = menu.addMenu(tr("Create Node"));
       CNmenu->addAction(gmain->_nodeFromCatalogAct);
       //   CNmenu->addSeparator();
@@ -607,6 +608,7 @@ void ContainerDirMenu::popupMenu(QWidget *caller, const QPoint &globalPos, const
   if (isEdition)
     {
       menu.addAction(gmain->_newContainerAct);
+      menu.addAction(gmain->_newHPContainerAct);
     }
   menu.exec(globalPos);
 }
index 74b0c2bb15e651ae89bda7bc9f9ccbea18233101..a10774b48b3858288d23b0738d5aef5d64f30ade 100644 (file)
@@ -49,6 +49,7 @@
 #include "PresetPorts.hxx"
 #include "ComponentDefinition.hxx"
 #include "SalomeContainer.hxx"
+#include "SalomeHPContainer.hxx"
 #include "SalomeComponent.hxx"
 #include "TypeCode.hxx"
 #include "RuntimeSALOME.hxx"
@@ -241,7 +242,7 @@ bool CommandAddNodeFromCatalog::localExecute()
       ComposedNode* father =dynamic_cast<ComposedNode*> (node);
       if (father && nodeToClone)
         {
-          son = nodeToClone->clone(0);
+          son = nodeToClone->cloneWithoutCompAndContDeepCpy(0);
           son->setName(_name);
           service = dynamic_cast<ServiceNode*>(son);
         }
@@ -573,7 +574,7 @@ bool CommandPutInComposedNode::localExecute()
          //create a ComposedNode (type _type) with name _newParent
          YACS::ENGINE::Catalog *catalog = YACS::ENGINE::getSALOMERuntime()->getBuiltinCatalog();
          Node* nodeToClone = catalog->_composednodeMap[_type];
-         composednode = nodeToClone->clone(0);
+         composednode = nodeToClone->cloneWithoutCompAndContDeepCpy(0);
          composednode->setName(_newParent);
          //add the new composednode as child of oldfather
          oldFather->edAddChild(composednode);
@@ -707,8 +708,8 @@ bool CommandCopyNode::localExecute()
       if (Loop *loop = dynamic_cast<Loop*>(newFather))
         if (!loop->edGetDirectDescendants().empty())
           throw YACS::Exception("Already a node in a new parent of Loop type");
-      //_clone = node->clone(newFather);
-      _clone = node->clone(0);
+      //_clone = node->cloneWithoutCompAndContDeepCpy(newFather);
+      _clone = node->cloneWithoutCompAndContDeepCpy(0);
       if (!_clone)
         throw YACS::Exception("Node cannot be cloned");
       int nodeSuffix = -1;
@@ -899,7 +900,7 @@ bool CommandRenameContainer::localExecute()
       container->setName(_newName);
       proc->containerMap[_newName] = container;
       YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(container));
-      SubjectContainer *scont = GuiContext::getCurrent()->_mapOfSubjectContainer[container]; 
+      SubjectContainerBase *scont(GuiContext::getCurrent()->_mapOfSubjectContainer[container]);
       scont-> update(RENAME, 0, scont);
       scont->notifyComponentsChange(ASSOCIATE, CONTAINER, scont);
     }
@@ -925,7 +926,7 @@ bool CommandRenameContainer::localReverse()
       container->setName(_oldName);
       proc->containerMap[_oldName] = container;
       YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(container));
-      SubjectContainer *scont = GuiContext::getCurrent()->_mapOfSubjectContainer[container]; 
+      SubjectContainerBase *scont(GuiContext::getCurrent()->_mapOfSubjectContainer[container]);
       scont-> update(RENAME, 0, scont);
       scont->notifyComponentsChange(ASSOCIATE, CONTAINER, scont);
     }
@@ -3108,22 +3109,19 @@ bool CommandAddControlLink::localReverse()
 
 // ----------------------------------------------------------------------------
 
-CommandAddContainer::CommandAddContainer(std::string name,
-                                         std::string refContainer)
+CommandAddContainerBase::CommandAddContainerBase(std::string name, std::string refContainer)
   : Command(), _name(name), _containerToClone(refContainer), _subcont(0)
 {
-  DEBTRACE("CommandAddContainer::CommandAddContainer " << name << " " << refContainer);
+  DEBTRACE("CommandAddContainerBase::CommandAddContainerBase " << name << " " << refContainer);
 }
 
-std::string CommandAddContainer::dump()
+CommandAddContainerBase::~CommandAddContainerBase()
 {
-  string ret ="CommandAddContainer " + _name + " " + _containerToClone;
-  return ret;
 }
 
-bool CommandAddContainer::localExecute()
+bool CommandAddContainerBase::localExecute()
 {
-  DEBTRACE("CommandAddContainer::localExecute");
+  DEBTRACE("CommandAddContainerBase::localExecute");
   try
     {
       Proc* proc = GuiContext::getCurrent()->getProc();
@@ -3132,7 +3130,7 @@ bool CommandAddContainer::localExecute()
           GuiContext::getCurrent()->_lastErrorMessage = "There is already a container with that name";
           return false;
         }
-      Container *container = new SalomeContainer();
+      Container *container(createNewInstance());
       if (! _containerToClone.empty())
         {
           if (proc->containerMap.count(_containerToClone))
@@ -3157,15 +3155,15 @@ bool CommandAddContainer::localExecute()
     }
   catch (Exception& ex)
     {
-      DEBTRACE("CommandAddContainer::localExecute() : " << ex.what());
+      DEBTRACE("CommandAddContainerBase::localExecute() : " << ex.what());
       setErrorMsg(ex);
       return false;
     }
 }
 
-bool CommandAddContainer::localReverse()
+bool CommandAddContainerBase::localReverse()
 {
-  DEBTRACE("CommandAddContainer::localReverse");
+  DEBTRACE("CommandAddContainerBase::localReverse");
   try
     {
       Proc* proc = GuiContext::getCurrent()->getProc();
@@ -3188,6 +3186,40 @@ bool CommandAddContainer::localReverse()
 
 // ----------------------------------------------------------------------------
 
+CommandAddContainer::CommandAddContainer(std::string name, std::string refContainer):CommandAddContainerBase(name,refContainer)
+{
+}
+
+std::string CommandAddContainer::dump()
+{
+  string ret ="CommandAddContainer " + _name + " " + _containerToClone;
+  return ret;
+}
+
+Container *CommandAddContainer::createNewInstance() const
+{
+  return new SalomeContainer;
+}
+
+// ----------------------------------------------------------------------------
+
+CommandAddHPContainer::CommandAddHPContainer(std::string name, std::string refContainer):CommandAddContainerBase(name,refContainer)
+{
+}
+
+std::string CommandAddHPContainer::dump()
+{
+  string ret ="CommandAddHPContainer " + _name + " " + _containerToClone;
+  return ret;
+}
+
+Container *CommandAddHPContainer::createNewInstance() const
+{
+  return new SalomeHPContainer;
+}
+
+// ----------------------------------------------------------------------------
+
 CommandSetNodeProperties::CommandSetNodeProperties(std::string position, std::map<std::string,std::string> properties)
   : Command(), _position(position), _properties(properties)
 {
@@ -3354,11 +3386,11 @@ bool CommandSetContainerProperties::localExecute()
       Proc* proc = GuiContext::getCurrent()->getProc();
       if (proc->containerMap.count(_container))
         {
-          Container *ref = proc->containerMap[_container];
+          Container *ref(proc->containerMap[_container]);
           YASSERT(ref);
           _oldProp = ref->getProperties();
           ref->setProperties(_properties);
-          SubjectContainer *scont = GuiContext::getCurrent()->_mapOfSubjectContainer[ref]; 
+          SubjectContainerBase *scont(GuiContext::getCurrent()->_mapOfSubjectContainer[ref]);
           scont->update(UPDATE, 0, scont);
           scont->notifyComponentsChange(ASSOCIATE, CONTAINER, scont);
           return true;
@@ -3752,7 +3784,7 @@ bool CommandAddComponentInstance::localReverse()
       YASSERT(!_subcompo->hasServices());
       Container *cont = compo->getContainer();
       YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(cont));
-      SubjectContainer *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
+      SubjectContainerBase *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
       subcont->detachComponent(_subcompo);
       GuiContext::getCurrent()->_mapOfSubjectComponent.erase(compo);
       proc->removeComponentInstance(compo);
@@ -3872,7 +3904,7 @@ bool CommandSetContainer::localExecute()
                 _oldcont = pyNode->getContainer()->getName();
               pyNode->setContainer(cont);
               SubjectNode* snode = GuiContext::getCurrent()->_mapOfSubjectNode[pyNode];
-              SubjectContainer *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
+              SubjectContainerBase *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
               snode->update(ASSOCIATE, 0, subcont);
               return true;
             }
@@ -3909,7 +3941,7 @@ bool CommandSetContainer::localReverse()
             {
               pyNode->setContainer(cont);
               SubjectNode* snode = GuiContext::getCurrent()->_mapOfSubjectNode[pyNode];
-              SubjectContainer *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
+              SubjectContainerBase *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
               snode->update(ASSOCIATE, 0, subcont);
               return true;
             }
@@ -3970,7 +4002,7 @@ bool CommandAssociateComponentToContainer::localExecute()
               YASSERT(GuiContext::getCurrent()->_mapOfSubjectComponent.count(compo));
               SubjectComponent *scomp =  GuiContext::getCurrent()->_mapOfSubjectComponent[compo];
               YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(cont));
-              SubjectContainer *subcont =  GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
+              SubjectContainerBase *subcont =  GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
               scomp->addSubjectReference(subcont);
               if (scomp->_subRefContainer)
                 subcont->moveComponent(scomp->_subRefContainer);
@@ -4013,7 +4045,7 @@ bool CommandAssociateComponentToContainer::localReverse()
               YASSERT(GuiContext::getCurrent()->_mapOfSubjectComponent.count(compo));
               SubjectComponent *scomp =  GuiContext::getCurrent()->_mapOfSubjectComponent[compo];
               YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(cont));
-              SubjectContainer *subcont =  GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
+              SubjectContainerBase *subcont =  GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
               scomp->addSubjectReference(subcont);
               if (scomp->_subRefContainer)
                 subcont->moveComponent(scomp->_subRefContainer);
@@ -4120,7 +4152,7 @@ bool CommandAssociateServiceToComponent::localReverse()
             {
               //component instance does not exist anymore recreate it
               ComponentInstance *oldcompo = service->getComponent();
-              compo = oldcompo->clone();
+              compo = oldcompo->cloneAlways();
               compo->setName(_oldInstance);
               proc->addComponentInstance(compo, _oldInstance);
               Container *cont = proc->containerMap[_oldcont];
@@ -4256,7 +4288,7 @@ bool CommandAddComponentFromCatalog::localReverse()
         throw YACS::Exception("Component instance with services attached, not removed");
       Container *cont = compo->getContainer();
       YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(cont));
-      SubjectContainer *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
+      SubjectContainerBase *subcont = GuiContext::getCurrent()->_mapOfSubjectContainer[cont];
       subcont->detachComponent(subCompo);
       //remove componentInstance from proc, from context
       if (_createdInstance)
index 77ca2c1c6df39388b00bc24b36e772196ad3a3da..4f203d54b69c6578acfcc1fa601fcedbb7b6f4ea 100644 (file)
@@ -54,7 +54,7 @@ namespace YACS
     class SubjectOutputDataStreamPort;
     class SubjectLink;
     class SubjectControlLink;
-    class SubjectContainer;
+    class SubjectContainerBase;
     class SubjectComponent;
 
     typedef enum
@@ -527,19 +527,37 @@ namespace YACS
       std::string _inNode;
     };
 
-    class CommandAddContainer: public Command
+    class CommandAddContainerBase : public Command
     {
     public:
-      CommandAddContainer(std::string name,
-                          std::string refContainer ="");
-      SubjectContainer* getSubjectContainer() { return _subcont; };
+      CommandAddContainerBase(std::string name, std::string refContainer);
+      virtual ~CommandAddContainerBase();
+      SubjectContainerBase* getSubjectContainer() { return _subcont; }
     protected:
       virtual bool localExecute();
       virtual bool localReverse();
-      virtual std::string dump();
+      virtual YACS::ENGINE::Container *createNewInstance() const = 0;
       std::string _name;
       std::string _containerToClone;
-      SubjectContainer *_subcont;
+      SubjectContainerBase *_subcont;
+    };
+
+    class CommandAddContainer : public CommandAddContainerBase
+    {
+    public:
+      CommandAddContainer(std::string name, std::string refContainer ="");
+    protected:
+      std::string dump();
+      YACS::ENGINE::Container *createNewInstance() const;
+    };
+
+    class CommandAddHPContainer : public CommandAddContainerBase
+    {
+    public:
+      CommandAddHPContainer(std::string name, std::string refContainer ="");
+    protected:
+      std::string dump();
+      YACS::ENGINE::Container *createNewInstance() const;
     };
 
     class CommandSetContainerProperties: public Command
index 874b41b202050ee05c0f3339fceb9e17ceb00161..4c9a065b32211be3d660ebe29c606f6c8caed034 100644 (file)
@@ -72,7 +72,7 @@ namespace YACS
       std::map<std::pair<YACS::ENGINE::OutPort*, YACS::ENGINE::InPort*>,YACS::HMI::SubjectLink*>   _mapOfSubjectLink;
       std::map<std::pair<YACS::ENGINE::Node*, YACS::ENGINE::Node*>,YACS::HMI::SubjectControlLink*> _mapOfSubjectControlLink;
       std::map<YACS::ENGINE::ComponentInstance*, YACS::HMI::SubjectComponent*>                     _mapOfSubjectComponent;
-      std::map<YACS::ENGINE::Container*, YACS::HMI::SubjectContainer*>                             _mapOfSubjectContainer;
+      std::map<YACS::ENGINE::Container*, YACS::HMI::SubjectContainerBase*>                         _mapOfSubjectContainer;
       std::map<std::string, YACS::HMI::SubjectDataType*>                                           _mapOfSubjectDataType;
       std::map<int,YACS::HMI::SubjectNode*>                                                        _mapOfExecSubjectNode;
       std::map<std::string, YACS::ENGINE::ComponentInstance*>                                      _mapOfLastComponentInstance;
index 1720f5d9185db7e9d14bbb742956f73b324c2a03..57d53d1b7cd3ffbee16ed4349644ce54531a9225 100644 (file)
@@ -45,6 +45,7 @@
 #include "OutputPort.hxx"
 #include "InputDataStreamPort.hxx"
 #include "OutputDataStreamPort.hxx"
+#include "SalomeHPContainer.hxx"
 #include "SalomeContainer.hxx"
 #include "SalomeComponent.hxx"
 #include "ComponentDefinition.hxx"
@@ -276,7 +277,7 @@ bool Subject::destroy(Subject *son)
           startnode = proc->getChildName(sclink->getSubjectOutNode()->getNode());
           endnode = proc->getChildName(sclink->getSubjectInNode()->getNode());
         }
-      else if (SubjectContainer* scont = dynamic_cast<SubjectContainer*>(son))
+      else if (SubjectContainerBase* scont = dynamic_cast<SubjectContainerBase*>(son))
         {
           if(scont->getName() == "DefaultContainer")
             {
@@ -621,7 +622,7 @@ void SubjectNode::registerUndoDestroy()
   Bloc *undoBloc = new Bloc(blocName.str());
   undoProc->edAddChild(undoBloc);
   ComposedNode *newFather = undoBloc;
-  Node *clone = _node->clone(0);
+  Node *clone = _node->cloneWithoutCompAndContDeepCpy(0);
   newFather->edAddChild(clone);
 
   // --- register a CommandCopyNode from undoProc
@@ -1890,13 +1891,10 @@ void SubjectProc::loadComponents()
 void SubjectProc::loadContainers()
 {
   Proc* aProc = GuiContext::getCurrent()->getProc();
-  for (map<string, Container*>::const_iterator itCont = aProc->containerMap.begin();
-       itCont != aProc->containerMap.end(); ++itCont)
-    if ( GuiContext::getCurrent()->_mapOfSubjectContainer.find((*itCont).second)
-         ==
-         GuiContext::getCurrent()->_mapOfSubjectContainer.end() )
+  for (map<string, Container*>::const_iterator itCont = aProc->containerMap.begin(); itCont != aProc->containerMap.end(); ++itCont)
+    if ( GuiContext::getCurrent()->_mapOfSubjectContainer.find((*itCont).second) == GuiContext::getCurrent()->_mapOfSubjectContainer.end() )
       // engine object for container already exists => add only a subject for it
-      addSubjectContainer((*itCont).second, (*itCont).second->getName());
+      addSubjectContainer((*itCont).second,(*itCont).second->getName());
 }
 
 SubjectComponent* SubjectProc::addComponent(std::string compoName, std::string containerName)
@@ -1912,12 +1910,12 @@ SubjectComponent* SubjectProc::addComponent(std::string compoName, std::string c
   return 0;
 }
 
-SubjectContainerSubjectProc::addContainer(std::string name, std::string ref)
+SubjectContainerBase *SubjectProc::addContainer(std::string name, std::string ref)
 {
   DEBTRACE("SubjectProc::addContainer " << name << " " << ref);
   if (! GuiContext::getCurrent()->getProc()->containerMap.count(name))
     {
-      CommandAddContainer *command = new CommandAddContainer(name,ref);
+      CommandAddContainer *command(new CommandAddContainer(name,ref));
       if (command->execute())
         {
           GuiContext::getCurrent()->getInvoc()->add(command);
@@ -1930,6 +1928,24 @@ SubjectContainer* SubjectProc::addContainer(std::string name, std::string ref)
   return 0;
 }
 
+SubjectContainerBase* SubjectProc::addHPContainer(std::string name, std::string ref)
+{
+  DEBTRACE("SubjectProc::addContainer " << name << " " << ref);
+  if (! GuiContext::getCurrent()->getProc()->containerMap.count(name))
+    {
+      CommandAddHPContainer *command(new CommandAddHPContainer(name,ref));
+      if (command->execute())
+        {
+          GuiContext::getCurrent()->getInvoc()->add(command);
+          return command->getSubjectContainer();
+        }
+      else
+        delete command;
+    }
+  else GuiContext::getCurrent()->_lastErrorMessage = "There is already a container with that name";
+  return 0;
+}
+
 bool SubjectProc::addDataType(YACS::ENGINE::Catalog* catalog, std::string typeName)
 {
   DEBTRACE("SubjectProc::addDataType " << typeName);
@@ -1954,13 +1970,12 @@ SubjectComponent* SubjectProc::addSubjectComponent(YACS::ENGINE::ComponentInstan
   return son;
 }
 
-SubjectContainer* SubjectProc::addSubjectContainer(YACS::ENGINE::Container* cont,
-                                                   std::string name)
+SubjectContainerBase *SubjectProc::addSubjectContainer(YACS::ENGINE::Container *cont, std::string name)
 {
   DEBTRACE("SubjectProc::addSubjectContainer " << name);
-  SubjectContainer *son = new SubjectContainer(cont, this);
+  SubjectContainerBase *son(SubjectContainerBase::New(cont,this));
   // In edition mode do not clone containers
-  cont->attachOnCloning();
+  // cont->attachOnCloning(); // agy : do not use _attachOnCloning attribute in edition mode. This attribute should be used now at runtime.
   GuiContext::getCurrent()->_mapOfSubjectContainer[cont] = son;
   update(ADD, CONTAINER, son);
   return son;
@@ -2025,7 +2040,7 @@ void SubjectProc::removeSubjectDataType(std::string typeName)
   aTypeCode->decrRef();
 }
 
-void SubjectProc::removeSubjectContainer(SubjectContainer* scont)
+void SubjectProc::removeSubjectContainer(SubjectContainerBase* scont)
 {
   YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(scont->getContainer()));
   erase(scont); // do all the necessary updates
@@ -2302,7 +2317,7 @@ bool SubjectInlineNode::setExecutionMode(const std::string& mode)
   return false;
 }
 
-bool SubjectInlineNode::setContainer(SubjectContainerscont)
+bool SubjectInlineNode::setContainer(SubjectContainerBase *scont)
 {
   DEBTRACE("SubjectInlineNode::setContainer ");
   Proc *proc = GuiContext::getCurrent()->getProc();
@@ -2425,17 +2440,7 @@ void SubjectServiceNode::setComponent()
                 if (proc->containerMap.count(cont->getName()) == 0)
                   {
                     //container exists but is not in containerMap. Clone it, it's probably the result of copy paste from outside the proc
-                    Container* newcont;
-                    if(cont->isAttachedOnCloning())
-                      {
-                        cont->dettachOnCloning();
-                        newcont=cont->clone();
-                        cont->attachOnCloning();
-                        newcont->attachOnCloning();
-                      }
-                    else
-                      newcont=cont->clone();
-
+                    Container* newcont(cont->cloneAlways());
                     proc->containerMap[cont->getName()]=newcont;
                     instance->setContainer(newcont);
                     GuiContext::getCurrent()->getSubjectProc()->addSubjectContainer(newcont, newcont->getName());
@@ -4246,7 +4251,7 @@ void SubjectComponent::localclean(Command *command)
       
     Container* container = _compoInst->getContainer();
     if (!container) return;
-    SubjectContainer *subContainer;
+    SubjectContainerBase *subContainer(0);
     YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(container));
     subContainer = GuiContext::getCurrent()->_mapOfSubjectContainer[container];
     subContainer->removeSubComponentFromSet(this);
@@ -4279,7 +4284,7 @@ void SubjectComponent::setContainer()
   Container* container = _compoInst->getContainer();
   if (container)
     {
-      SubjectContainer *subContainer;
+      SubjectContainerBase *subContainer;
       if (GuiContext::getCurrent()->_mapOfSubjectContainer.count(container))
         subContainer = GuiContext::getCurrent()->_mapOfSubjectContainer[container];
       else
@@ -4294,7 +4299,7 @@ void SubjectComponent::setContainer()
     }
 }
 
-bool SubjectComponent::associateToContainer(SubjectContainersubcont)
+bool SubjectComponent::associateToContainer(SubjectContainerBase *subcont)
 {
   DEBTRACE("SubjectComponent::associateToContainer " << getName() << " " << subcont->getName());
   CommandAssociateComponentToContainer *command =
@@ -4385,16 +4390,25 @@ std::map<std::string, std::string> SubjectComponent::getProperties()
 
 // ----------------------------------------------------------------------------
 
-SubjectContainer::SubjectContainer(YACS::ENGINE::Container* container, Subject *parent)
-  : Subject(parent), _container(container)
+SubjectContainerBase *SubjectContainerBase::New(YACS::ENGINE::Container* container, Subject *parent)
+{
+  if(!container)
+    return 0;
+  if(!dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(container))
+    return new SubjectContainer(container,parent);
+  else
+    return new SubjectHPContainer(dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(container),parent);
+}
+
+SubjectContainerBase::SubjectContainerBase(YACS::ENGINE::Container* container, Subject *parent):Subject(parent), _container(container)
 {
   _subComponentSet.clear();
   _subReferenceMap.clear();
 }
 
-SubjectContainer::~SubjectContainer()
+SubjectContainerBase::~SubjectContainerBase()
 {
-  DEBTRACE("SubjectContainer::~SubjectContainer");
+  DEBTRACE("SubjectContainerBase::~SubjectContainerBase");
   Proc* aProc = GuiContext::getCurrent()->getProc();
   if ( aProc )
   {
@@ -4413,24 +4427,25 @@ SubjectContainer::~SubjectContainer()
   }
 }
 
-std::map<std::string, std::string> SubjectContainer::getProperties()
+std::map<std::string, std::string> SubjectContainerBase::getProperties()
 {
   return _container->getProperties();
 }
 
-bool SubjectContainer::setProperties(std::map<std::string, std::string> properties)
+bool SubjectContainerBase::setProperties(std::map<std::string, std::string> properties)
 {
-  CommandSetContainerProperties *command = new CommandSetContainerProperties(getName(), properties);
+  CommandSetContainerProperties *command(new CommandSetContainerProperties(getName(), properties));
   if (command->execute())
     {
       GuiContext::getCurrent()->getInvoc()->add(command);
       return true;
     }
-  else delete command;
+  else
+    delete command;
   return false;
 }
 
-bool SubjectContainer::setName(std::string name)
+bool SubjectContainerBase::setName(std::string name)
 {
   DEBTRACE("SubjectContainer::setName " << name);
   if (name == getName())
@@ -4445,7 +4460,7 @@ bool SubjectContainer::setName(std::string name)
   return false;
 }
 
-SubjectReference* SubjectContainer::attachComponent(SubjectComponent* component)
+SubjectReference* SubjectContainerBase::attachComponent(SubjectComponent* component)
 {
   DEBTRACE("SubjectContainer::attachComponent");
   SubjectReference *son = new SubjectReference(component, this);
@@ -4455,18 +4470,18 @@ SubjectReference* SubjectContainer::attachComponent(SubjectComponent* component)
   return son;
 }
 
-void SubjectContainer::detachComponent(SubjectComponent* component)
+void SubjectContainerBase::detachComponent(SubjectComponent* component)
 {
   DEBTRACE("SubjectContainer::detachComponent");
   YASSERT(_subReferenceMap.count(component));
   SubjectReference *reference = _subReferenceMap[component];
-  update(REMOVECHILDREF, COMPONENT, reference);
+  update(REMOVECHILDREF, PYTHONNODE, reference);
   _subComponentSet.erase(component);
   _subReferenceMap.erase(component);
   erase(reference);
 }
 
-void SubjectContainer::moveComponent(SubjectReference* reference)
+void SubjectContainerBase::moveComponent(SubjectReference* reference)
 {
   DEBTRACE("SubjectContainer::moveComponent");
   SubjectContainer* oldcont = dynamic_cast<SubjectContainer*>(reference->getParent());
@@ -4480,14 +4495,14 @@ void SubjectContainer::moveComponent(SubjectReference* reference)
   update(PASTE, COMPONENT, reference);
 }
 
-void SubjectContainer::removeSubComponentFromSet(SubjectComponent *component)
+void SubjectContainerBase::removeSubComponentFromSet(SubjectComponent *component)
 {
   DEBTRACE("SubjectContainer::removeSubComponentFromSet");
   _subComponentSet.erase(component);
   _subReferenceMap.erase(component);
 }
 
-void SubjectContainer::notifyComponentsChange(GuiEvent event, int type, Subject* son)
+void SubjectContainerBase::notifyComponentsChange(GuiEvent event, int type, Subject* son)
 {
   DEBTRACE("SubjectContainer::notifyComponentsChange");
   set<SubjectComponent*>::iterator it = _subComponentSet.begin();
@@ -4498,8 +4513,7 @@ void SubjectContainer::notifyComponentsChange(GuiEvent event, int type, Subject*
     }
 }
 
-
-void SubjectContainer::clean(Command *command)
+void SubjectContainerBase::clean(Command *command)
 {
   if (_askRegisterUndo)
     {
@@ -4510,9 +4524,9 @@ void SubjectContainer::clean(Command *command)
   Subject::clean(command);
 }
 
-void SubjectContainer::localclean(Command *command)
+void SubjectContainerBase::localclean(Command *command)
 {
-  DEBTRACE("SubjectContainer::localClean ");
+  DEBTRACE("SubjectContainerBase::localClean ");
   Proc* aProc = GuiContext::getCurrent()->getProc();
   if ( aProc )
   {
@@ -4536,14 +4550,15 @@ void SubjectContainer::localclean(Command *command)
   }
 }
 
-std::string SubjectContainer::getName()
+std::string SubjectContainerBase::getName()
 {
   return _container->getName();
 }
 
-YACS::ENGINE::Container* SubjectContainer::getContainer() const
+// ----------------------------------------------------------------------------
+
+SubjectContainer::SubjectContainer(YACS::ENGINE::Container *container, Subject *parent):SubjectContainerBase(container,parent)
 {
-  return _container;
 }
 
 void SubjectContainer::registerUndoDestroy()
@@ -4555,6 +4570,32 @@ void SubjectContainer::registerUndoDestroy()
 
 // ----------------------------------------------------------------------------
 
+SubjectHPContainer::SubjectHPContainer(YACS::ENGINE::HomogeneousPoolContainer *container, Subject *parent):SubjectContainerBase(container,parent)
+{
+}
+
+YACS::ENGINE::Container *SubjectHPContainer::getContainer() const
+{
+  if(!_container)
+    return 0;
+  else
+    {
+      YACS::ENGINE::HomogeneousPoolContainer *ret(dynamic_cast<YACS::ENGINE::HomogeneousPoolContainer *>(_container));
+      if(!ret)
+        throw Exception("Invalid container type in SubjectHPContainer !");
+      return ret;
+    }
+}
+
+void SubjectHPContainer::registerUndoDestroy()
+{
+  DEBTRACE("SubjectHPContainer::registerUndoDestroy");
+  Command *command = new CommandAddHPContainer(getName(),"");
+  GuiContext::getCurrent()->getInvoc()->add(command);
+}
+
+// ----------------------------------------------------------------------------
+
 SubjectDataType::SubjectDataType(YACS::ENGINE::TypeCode *typeCode, Subject *parent, std::string alias)
   : Subject(parent), _typeCode(typeCode), _alias(alias)
 {
index 96916aa404b7e3aa74be84bd17f55042b5e1637a..697bab2511019c7f91b7453584bfa7a04b0eabf3 100644 (file)
@@ -69,6 +69,7 @@ namespace YACS
     class Catalog;
     class ComponentInstance;
     class Container;
+    class HomogeneousPoolContainer;
     class TypeCode;
     class OutGate;
     class InGate;
@@ -411,13 +412,16 @@ namespace YACS
     };
 
     class SubjectComponent;
-    class HMI_EXPORT SubjectContainer: public Subject
+    class HMI_EXPORT SubjectContainerBase : public Subject
     {
     public:
-      SubjectContainer(YACS::ENGINE::Container* container, Subject *parent);
-      virtual ~SubjectContainer();
+      static SubjectContainerBase *New(YACS::ENGINE::Container* container, Subject *parent);
+      SubjectContainerBase(YACS::ENGINE::Container* container, Subject *parent);
+      virtual ~SubjectContainerBase();
       virtual std::string getName();
+      virtual std::string getLabelForHuman() const = 0;
       virtual bool setName(std::string name);
+      virtual YACS::ENGINE::Container *getContainer() const { return _container; }
       virtual std::map<std::string, std::string> getProperties();
       virtual bool setProperties(std::map<std::string, std::string> properties);
       virtual SubjectReference* attachComponent(SubjectComponent* component);
@@ -427,18 +431,33 @@ namespace YACS
       virtual void notifyComponentsChange(GuiEvent event, int type, Subject* son);
       virtual void clean(Command *command=0);
       void localclean(Command *command=0);
-      YACS::ENGINE::Container* getContainer() const;
-      bool isUsed() {return !_subComponentSet.empty(); };
-      virtual TypeOfElem getType(){return CONTAINER;}
-      void registerUndoDestroy();
+      bool isUsed() { return !_subComponentSet.empty(); }
+      TypeOfElem getType() { return CONTAINER; }
     protected:
       YACS::ENGINE::Container* _container;
       std::set<SubjectComponent*> _subComponentSet;
       std::map<SubjectComponent*,SubjectReference*> _subReferenceMap;
     };
 
+    class HMI_EXPORT SubjectContainer: public SubjectContainerBase
+    {
+    public:
+      SubjectContainer(YACS::ENGINE::Container *container, Subject *parent);
+      void registerUndoDestroy();
+      std::string getLabelForHuman() const { return std::string("Salome Container"); }
+    };
+
+    class HMI_EXPORT SubjectHPContainer : public SubjectContainerBase
+    {
+    public:
+      SubjectHPContainer(YACS::ENGINE::HomogeneousPoolContainer* container, Subject *parent);
+      void registerUndoDestroy();
+      YACS::ENGINE::Container *getContainer() const;
+      std::string getLabelForHuman() const { return std::string("Salome Homogeneous Pool Container"); }
+    };
+
     class SubjectServiceNode;
-    class HMI_EXPORT SubjectComponent: public Subject
+    class HMI_EXPORT SubjectComponent : public Subject
     {
     public:
       friend class SubjectNode;
@@ -446,7 +465,7 @@ namespace YACS
       virtual ~SubjectComponent();
       virtual std::string getName();
       virtual void setContainer();
-      virtual bool associateToContainer(SubjectContainersubcont);
+      virtual bool associateToContainer(SubjectContainerBase *subcont);
       virtual SubjectReference* attachService(SubjectServiceNode* service);
       virtual void detachService(SubjectServiceNode* service);
       virtual void moveService(SubjectReference* reference);
@@ -494,15 +513,15 @@ namespace YACS
       void loadContainers();
       void loadTypes();
       virtual SubjectComponent* addComponent(std::string compoName, std::string containerName="");
-      virtual SubjectContainer* addContainer(std::string name, std::string ref="");
+      virtual SubjectContainerBase* addContainer(std::string name, std::string ref="");
+      virtual SubjectContainerBase* addHPContainer(std::string name, std::string ref="");
       virtual bool addDataType(YACS::ENGINE::Catalog* catalog, std::string typeName);
       SubjectComponent* addSubjectComponent(YACS::ENGINE::ComponentInstance* compo);
-      SubjectContainer* addSubjectContainer(YACS::ENGINE::Container* cont,
-                                            std::string name = "");
+      SubjectContainerBase* addSubjectContainer(YACS::ENGINE::Container* cont, std::string name = "");
       SubjectDataType* addComSubjectDataType(YACS::ENGINE::TypeCode *type, std::string alias);
       SubjectDataType* addSubjectDataType(YACS::ENGINE::TypeCode *type, std::string alias);
       void removeSubjectDataType(std::string typeName);
-      void removeSubjectContainer(SubjectContainer* scont);
+      void removeSubjectContainer(SubjectContainerBase* scont);
       virtual void clean(Command *command=0);
       void localclean(Command *command=0);
       void addPostErase(Subject* sub) {_postEraseList.push_back(sub); };
@@ -678,7 +697,7 @@ namespace YACS
       virtual std::string getScript();
       virtual void clean(Command *command=0);
       void localclean(Command *command=0);
-      virtual bool setContainer(SubjectContainerscont);
+      virtual bool setContainer(SubjectContainerBase *scont);
       virtual bool setExecutionMode(const std::string& mode);
     protected:
       YACS::ENGINE::InlineNode *_inlineNode;
diff --git a/src/runtime/AutoGIL.hxx b/src/runtime/AutoGIL.hxx
new file mode 100644 (file)
index 0000000..c10df18
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __AUTOGIL_HXX__
+#define __AUTOGIL_HXX__
+
+#include "Exception.hxx"
+#include <Python.h>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class AutoGIL
+    {
+    public:
+      AutoGIL():_gstate(PyGILState_Ensure()) { }
+      ~AutoGIL() { PyGILState_Release(_gstate); }
+    private:
+      PyGILState_STATE _gstate;
+    };
+  }
+}
+
+#endif
index 451934b0512aecdac6a4a10bd753934f9fd199da..1e3048d3ee335e067c0a6205cdcc99bb732de3e1 100644 (file)
@@ -82,6 +82,7 @@ SET(_link_LIBRARIES
 
 SET(YACSRuntimeSALOME_HEADERS
   YACSRuntimeSALOMEExport.hxx 
+  AutoGIL.hxx
   CalStreamPort.hxx
   CORBAComponent.hxx
   CORBACORBAConv.hxx
@@ -116,7 +117,13 @@ SET(YACSRuntimeSALOME_HEADERS
   PythonXMLConv.hxx 
   RuntimeSALOME.hxx
   SalomeComponent.hxx
-  SalomeContainer.hxx 
+  SalomeHPComponent.hxx
+  SalomeContainer.hxx
+  SalomeContainerTools.hxx
+  SalomeContainerHelper.hxx
+  SalomeContainerTmpForHP.hxx
+  SalomeHPContainer.hxx
+  SalomeHPContainerTools.hxx
   SALOMEDispatcher.hxx
   SalomeProc.hxx
   SalomePythonComponent.hxx
@@ -167,6 +174,11 @@ SET(YACSRuntimeSALOME_SOURCES
   DistributedPythonNode.cxx      
   SalomePythonComponent.cxx      
   SalomeContainer.cxx            
+  SalomeContainerTools.cxx
+  SalomeHPContainer.cxx
+  SalomeHPContainerTools.cxx
+  SalomeContainerHelper.cxx
+  SalomeContainerTmpForHP.cxx
   PythonPorts.cxx                
   XMLNode.cxx                    
   XMLPorts.cxx                   
@@ -175,7 +187,8 @@ SET(YACSRuntimeSALOME_SOURCES
   SalomeProc.cxx                 
   CalStreamPort.cxx              
   CORBAComponent.cxx             
-  SalomeComponent.cxx            
+  SalomeComponent.cxx   
+  SalomeHPComponent.cxx         
   CppComponent.cxx               
   CppContainer.cxx               
   CppCORBAConv.cxx               
index 93c265121fbafd0cc92136b4c7ed025b22d70eb4..7ff71f69b721ba7548b4c99578f6641a19320cdc 100644 (file)
@@ -68,8 +68,13 @@ std::string CORBAComponent::getKind() const
   return KIND;
 }
 
+std::string CORBAComponent::getKindForNode() const
+{
+  return KIND;
+}
+
 //! Unload the component 
-void CORBAComponent::unload()
+void CORBAComponent::unload(Task *askingNode)
 {
   //Not implemented
   std::cerr << "CORBAComponent::unload : not implemented " << std::endl;
@@ -84,7 +89,7 @@ CORBA::Object_ptr CORBAComponent::getCompoPtr()
 }
 
 //! Is the component instance already loaded ?
-bool CORBAComponent::isLoaded()
+bool CORBAComponent::isLoaded(Task *askingNode) const
 {
   if(CORBA::is_nil(_objComponent))
     return false;
@@ -93,7 +98,7 @@ bool CORBAComponent::isLoaded()
 }
 
 //! Load the component 
-void CORBAComponent::load()
+void CORBAComponent::load(Task *askingNode)
 {
   DEBTRACE( "CORBAComponent::load" );
   CORBA::ORB_ptr orb;
@@ -182,6 +187,11 @@ ComponentInstance* CORBAComponent::clone() const
   //return new CORBAComponent(*this);
 }
 
+ComponentInstance* CORBAComponent::cloneAlways() const
+{
+  return new CORBAComponent(*this);
+}
+
 std::string CORBAComponent::getFileRepr() const
 {
   ostringstream stream;
index 869202e0e02fdbb06fcd9a5d68384a6e12a544f4..1a2159add26818e709ecfb44353956eae22b2574 100644 (file)
@@ -39,16 +39,18 @@ namespace YACS
       CORBAComponent(const std::string& name);
       CORBAComponent(const CORBAComponent& other);
       virtual ~CORBAComponent();
-      virtual void load();
-      virtual void unload();
-      virtual bool isLoaded();
+      virtual void load(Task *askingNode);
+      virtual void unload(Task *askingNode);
+      virtual bool isLoaded(Task *askingNode) const;
       virtual ServiceNode* createNode(const std::string& name);
       virtual ComponentInstance* clone() const;
+      virtual ComponentInstance* cloneAlways() const;
       virtual std::string getFileRepr() const;
       virtual CORBA::Object_ptr getCompoPtr();
     public:
       static const char KIND[];
       virtual std::string getKind() const;
+      virtual std::string getKindForNode() const;
     protected:
       CORBA::Object_var _objComponent;
     };
index f38696f23b0d6357880544cbf70d8f5230fd7dc4..dc4f665280c9d35a05b7b6e9e57d2b3588e2513e 100644 (file)
@@ -35,6 +35,7 @@
 #include "CalStreamPort.hxx"
 #include "InPort.hxx"
 #include "TypeCode.hxx"
+#include "AutoLocker.hxx"
 
 #ifdef SALOME_KERNEL
 #include "SALOME_NamingService.hxx"
@@ -467,7 +468,7 @@ void SalomeNode::disconnectService()
 {
   DEBTRACE( "SalomeNode::disconnectService: "<<getName());
   // in some rare cases, disconnectService can be called from 2 different threads
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
 
   if(ids.size() == 0)
     return;
index ee14bd161c9dc31df52ebd6a83d4e89db2a1c26a..a4520775711894be07bebf95e4bcadbfccfaf2f5 100644 (file)
@@ -29,6 +29,7 @@
 #include "RuntimeSALOME.hxx"
 #include "TypeConversions.hxx"
 #include "TypeCode.hxx"
+#include "AutoLocker.hxx"
 #include "CORBAPorts.hxx"
 #include "PythonPorts.hxx"
 #include "ServiceNode.hxx"
@@ -165,7 +166,7 @@ void InputCorbaPort::put(CORBA::Any *data) throw (ConversionException)
 #ifdef REFCNT
   DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
 #endif
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
 #ifdef _DEVDEBUG_
   display(data);
 #endif
@@ -207,7 +208,7 @@ CORBA::Any * InputCorbaPort::getAny()
 
 PyObject * InputCorbaPort::getPyObj()
 {
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
   CORBA::TypeCode_var tc=getAny()->type();
   if (!tc->equivalent(CORBA::_tc_null))
     return convertCorbaPyObject(edGetType(),getAny());
@@ -318,7 +319,7 @@ void OutputCorbaPort::put(CORBA::Any *data) throw (ConversionException)
   InputPort *p;
 
   {  
-    YACS::BASES::Lock lock(&_mutex);
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
 #ifdef REFCNT
     DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count);
 #endif
@@ -422,7 +423,7 @@ CORBA::Any * OutputCorbaPort::getAnyOut()
 
 PyObject * OutputCorbaPort::getPyObj()
 {
-  YACS::BASES::Lock lock(&_mutex);
+  YACS::BASES::AutoLocker<YACS::BASES::Mutex> lock(&_mutex);
   CORBA::TypeCode_var tc=getAny()->type();
   if (!tc->equivalent(CORBA::_tc_null))
     return convertCorbaPyObject(edGetType(),getAny());
index 42e2878294981eab7e97780710269584241639f1..abc73ae621c9eeb64d79567fbc4bdd3df8ebde47 100644 (file)
@@ -74,38 +74,42 @@ static std::ostream & operator<<(std::ostream & f, const Any & A)
 
 std::string CppComponent::getKind() const
 {
-   return CppComponent::KIND;
+  return CppComponent::KIND;
+}
+
+std::string CppComponent::getKindForNode() const
+{
+  return CppComponent::KIND;
 }
 
 //! CppComponent constructor
-CppComponent::CppComponent(const std::string &name) : ComponentInstance(name)
+CppComponent::CppComponent(const std::string &name) : ComponentInstance(name), __obj(0), __run(0),__terminate(0)
 {
   _container = getRuntime()->createContainer(CppNode::KIND);
-  if (!_container->isAlreadyStarted(this))
-    _container->start(this);
-  
+  /* This part of code has been commented because the load part is supposed to do that !
+  if (!_container->isAlreadyStarted(0))
+    _container->start(0);
   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);
-  _containerC->createInternalInstance(name, __obj, __run, __terminate);
+  _containerC->createInternalInstance(name, __obj, __run, __terminate);*/
 }
 
 //! CppComponent copy constructor
-CppComponent::CppComponent(const CppComponent& other) : ComponentInstance(other._compoName), __run(other.__run),
-                                                        __terminate(other.__terminate), __obj(0)
+CppComponent::CppComponent(const CppComponent& other) : ComponentInstance(other._compoName), __obj(0), __run(0),__terminate(0)
 {
   _container = getRuntime()->createContainer(CppNode::KIND);
-  if (!_container->isAlreadyStarted(this))
-    _container->start(this);
-
+  /* This part of code has been commented because the load part is supposed to do that !
+  if (!_container->isAlreadyStarted(0))
+    _container->start(0);
   CppContainer * _containerC = dynamic_cast<CppContainer *> (_container);  
-   _containerC->createInternalInstance(_compoName, __obj, __run, __terminate);
+   _containerC->createInternalInstance(_compoName, __obj, __run, __terminate);*/
 }
 
 CppComponent::~CppComponent()
 {
-    DEBTRACE("CppComponent::~CppComponent()");
-    if (__terminate) __terminate(&__obj);
-    if (_container)
-      ((CppContainer *) _container)->unregisterComponentInstance(this);
+  DEBTRACE("CppComponent::~CppComponent()");
+  if (__terminate) __terminate(&__obj);
+  if (_container)
+    ((CppContainer *) _container)->unregisterComponentInstance(this);
 }
 
 void CppComponent::run (const char * service, int nbIn, int nbOut,
@@ -146,48 +150,50 @@ void CppComponent::run (const char * service, int nbIn, int nbOut,
 }
 
 //! Unload the component 
-void CppComponent::unload()
+void CppComponent::unload(Task *askingNode)
 {
   //Not implemented
   DEBTRACE("CppComponent::unload : not implemented ");
 }
 
 //! Is the component instance already loaded ?
-bool CppComponent::isLoaded()
+bool CppComponent::isLoaded(Task *askingNode) const
 {
   return NULL != __obj;
 }
  
-void CppComponent::load()
+void CppComponent::load(Task *askingNode)
 {
-   if (!_container) {
-     _container = getRuntime()->createContainer(CppNode::KIND);
-   }
-   
-   if(_container) {
-
-      CppContainer * containerC= dynamic_cast< CppContainer *> (_container);
-      
+  if (!_container)
+    {
+      _container = getRuntime()->createContainer(CppNode::KIND);
+    }
+
+  if(_container)
+    {
+      CppContainer *containerC(dynamic_cast< CppContainer *> (_container));
+      if(!containerC)
+        throw Exception("The type of container should be CPP for component CPP !");
       containerC->lock();//To be sure
-      if(!_container->isAlreadyStarted(this))
+      if(!_container->isAlreadyStarted(askingNode))
         {
           try
-            {
-              _container->start(this);
-            }
+          {
+              _container->start(askingNode);
+          }
           catch(Exception& e)
-            {
+          {
               containerC->unLock();
               throw e;
-            }
+          }
         }
       containerC->unLock();
       containerC->lock();//To be sure
-      
-      bool isLoadable = containerC->loadComponentLibrary(_compoName);
+
+      bool isLoadable(containerC->loadComponentLibrary(_compoName));
       if (isLoadable) 
         containerC->createInternalInstance(_compoName, __obj, __run, __terminate);
-        
+
       if(NULL == __obj)
         {
           containerC->unLock();
@@ -196,7 +202,6 @@ void CppComponent::load()
       containerC->unLock();
       return;
     }
-
 }
 
 ServiceNode* CppComponent::createNode(const std::string& name)
@@ -218,3 +223,7 @@ ComponentInstance* CppComponent::clone() const
     return new CppComponent(*this);
 }
 
+YACS::ENGINE::ComponentInstance *CppComponent::cloneAlways() const
+{
+  return new CppComponent(*this);
+}
index 56cfa1ff691ca5f94ccb7120ff25adbad80e85d7..d10865669996eb46fdd370b48b6f97c2da896a57 100644 (file)
@@ -56,11 +56,13 @@ namespace YACS
 
         static const char KIND[];
         virtual std::string getKind() const;
-        virtual void load();
-        virtual void unload();
-        virtual bool isLoaded();
+        virtual std::string getKindForNode() const;
+        virtual void load(Task *askingNode);
+        virtual void unload(Task *askingNode);
+        virtual bool isLoaded(Task *askingNode) const;
         virtual ServiceNode* createNode(const std::string& name);
         virtual YACS::ENGINE::ComponentInstance* clone() const;
+        virtual YACS::ENGINE::ComponentInstance* cloneAlways() const;
         
       protected:
   
index c2d151e85cbbc2273bcad1d4d332b82fd56773ad..4366724d2a0e0eeca46f6fc8f549d102540d50ec 100644 (file)
@@ -37,6 +37,8 @@
 
 using namespace YACS::ENGINE;
 
+char CppContainer::KIND[]="Cpp";
+
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
 
@@ -70,19 +72,29 @@ void CppContainer::lock()
 
 void CppContainer::unLock()
 {
-  _mutex.unlock();
+  _mutex.unLock();
+}
+
+std::string CppContainer::getKind() const
+{
+  return KIND;
 }
 
-bool CppContainer::isAlreadyStarted(const ComponentInstance *inst) const
+bool CppContainer::isAlreadyStarted(const Task *askingNode) const
 {
   return NULL != _trueCont;
 }
 
-void CppContainer::start(const ComponentInstance *inst) throw (YACS::Exception)
+void CppContainer::start(const Task *askingNode) throw (YACS::Exception)
 {
   _trueCont = LocalContainer::get();
 }
 
+void CppContainer::shutdown(int level)
+{
+
+}
+
 Container *CppContainer::clone() const
 {
   if(_isAttachedOnCloning)
@@ -94,61 +106,64 @@ Container *CppContainer::clone() const
     return new CppContainer(*this);
 }
 
-bool CppContainer::loadComponentLibrary(const std::string & componentName) throw (YACS::Exception)
+Container *CppContainer::cloneAlways() const
 {
-    if (_trueCont) 
+  return new CppContainer(*this);
+}
+
+bool CppContainer::loadComponentLibrary(const std::string & componentName) throw (YACS::Exception)
+    {
+  if (_trueCont)
     {
-       LocalLibrary L = _trueCont->loadComponentLibrary(componentName);
-       return L.good();
+      LocalLibrary L = _trueCont->loadComponentLibrary(componentName);
+      return L.good();
     }
-    else 
+  else
     {
-       std::string mesg = "CppContainer not started";
-       throw YACS::Exception(mesg);
+      std::string mesg = "CppContainer not started";
+      throw YACS::Exception(mesg);
+    }
+  return false;
     }
-    return false;
-}
 
 CppComponent * CppContainer::createComponentInstance(const std::string & componentName, int /* studyID */)
 {
-    DEBTRACE("CppContainer::createComponentInstance");
-    if (_trueCont)
-       return _trueCont->createComponentInstance(componentName.c_str());
-    else 
+  DEBTRACE("CppContainer::createComponentInstance");
+  if (_trueCont)
+    return _trueCont->createComponentInstance(componentName.c_str());
+  else
     {
-       std::string mesg = "CppContainer not started";
-       throw YACS::Exception(mesg);
+      std::string mesg = "CppContainer not started";
+      throw YACS::Exception(mesg);
     }
 }
 
 void CppContainer::createInternalInstance(const std::string & name, void *&obj, 
                                           RunFunction &r, TerminateFunction &t)
 {
-   DEBTRACE("CppContainer::createInternalInstance");
-   if (_trueCont)
-      _trueCont->createInternalInstance(name.c_str(), obj, r, t);
-   else 
-   {
-     std::string mesg = "CppContainer not started";
-     throw YACS::Exception(mesg);
-   }
+  DEBTRACE("CppContainer::createInternalInstance");
+  if (_trueCont)
+    _trueCont->createInternalInstance(name.c_str(), obj, r, t);
+  else
+    {
+      std::string mesg = "CppContainer not started";
+      throw YACS::Exception(mesg);
+    }
 }
 
-void CppContainer::unregisterComponentInstance(CppComponent * C)
+void CppContainer::unregisterComponentInstance(CppComponent *compo)
 {
-    if (_trueCont) 
-    {
-       _trueCont->unregisterComponentInstance(C);
-    }
+  if (_trueCont)
+    _trueCont->unregisterComponentInstance(compo);
 }
 
 
-std::string CppContainer::getPlacementId(const ComponentInstance *inst) const
+std::string CppContainer::getPlacementId(const Task *askingNode) const
 {
   return "/";
 }
 
-std::string CppContainer::getFullPlacementId(const ComponentInstance *inst) const
+std::string CppContainer::getFullPlacementId(const Task *askingNode) const
 {
   return "/";
 }
@@ -184,31 +199,31 @@ LocalContainer * LocalContainer::get()
 
 void LocalContainer::destroy()
 {
-    if (NULL == _singleton)
-      return;
-    
-    // destroy all component instances
-    _instance_mapMutex.lock(); // lock
-    std::multimap<std::string, CppComponent *>::iterator iI, iJ;
-    for (iI=_instance_map.begin(); iI != _instance_map.end(); iI = iJ)
+  if (NULL == _singleton)
+    return;
+
+  // destroy all component instances
+  _instance_mapMutex.lock(); // lock
+  std::multimap<std::string, CppComponent *>::iterator iI, iJ;
+  for (iI=_instance_map.begin(); iI != _instance_map.end(); iI = iJ)
     {
       iJ = iI++;
       iI->second->setContainer(NULL);
       delete iI->second;
     }
-    _instance_map.clear();
-    _instance_mapMutex.unlock(); // unlock
-    
-    // unload all dynamic libraries
-    _library_mapMutex.lock();
-    std::map<std::string, LocalLibrary>::iterator iL;
-    for (iL=_library_map.begin(); iL != _library_map.end(); iL++)
-        dlclose(iL->second.handle);
-    _library_map.clear();
-    _library_mapMutex.unlock();
-    
-    delete _singleton;
-    _singleton = NULL;
+  _instance_map.clear();
+  _instance_mapMutex.unLock(); // unlock
+
+  // unload all dynamic libraries
+  _library_mapMutex.lock();
+  std::map<std::string, LocalLibrary>::iterator iL;
+  for (iL=_library_map.begin(); iL != _library_map.end(); iL++)
+    dlclose(iL->second.handle);
+  _library_map.clear();
+  _library_mapMutex.unLock();
+
+  delete _singleton;
+  _singleton = NULL;
 }
 
 
@@ -237,7 +252,7 @@ CppComponent * LocalContainer::createComponentInstance(const char * name)
   C = new CppComponent(o, r, t, name);
   _instance_mapMutex.lock(); // lock to be alone 
   _instance_map.insert(std::pair<std::string, CppComponent *>(name, C));
-  _instance_mapMutex.unlock(); // unlock
+  _instance_mapMutex.unLock(); // unlock
   return C;
 }
 
@@ -265,14 +280,14 @@ void LocalContainer::createInternalInstance(const char *name, void *&obj,
 
 void LocalContainer::unregisterComponentInstance(CppComponent * C)
 {
-    _instance_mapMutex.lock(); // lock to be alone 
-    _instance_map.erase(C->getCompoName());
-    _instance_mapMutex.unlock(); // unlock
+  _instance_mapMutex.lock(); // lock to be alone
+  _instance_map.erase(C->getCompoName());
+  _instance_mapMutex.unLock(); // unlock
 }
 
 inline void toupper (std::string & s)
 {
-   transform (s.begin (), s.end (), s.begin (), (int(*)(int)) toupper);
+  transform (s.begin (), s.end (), s.begin (), (int(*)(int)) toupper);
 }
 
 LocalLibrary  LocalContainer::loadComponentLibrary(const std::string & aCompName, const char * prefix, bool forcedLoad)
index 2eb24659224b8f4b6bb5d630e83dfa754299ab26..3a75d6396670628aa0c3323fd033c18f591cfa36 100644 (file)
@@ -100,36 +100,45 @@ namespace YACS
 
     };
 
-    class CppContainer : public Container {
-
+    class CppContainer : public Container
+    {
       friend class CppComponent;
       friend class LocalContainer;
-      
     public:
       CppContainer();
       virtual ~CppContainer();
-      bool isAlreadyStarted(const ComponentInstance *inst) const;
-      void start(const ComponentInstance *inst) throw (YACS::Exception);
-      std::string getPlacementId(const ComponentInstance *inst) const;
-      std::string getFullPlacementId(const ComponentInstance *inst) const;
+      std::string getKind() const;
+      bool isAlreadyStarted(const Task *askingNode) const;
+      void start(const Task *askingNode) throw (YACS::Exception);
+      void shutdown(int level);
+      std::string getPlacementId(const Task *askingNode) const;
+      std::string getFullPlacementId(const Task *askingNode) const;
       YACS::ENGINE::Container *clone() const;
-
+      Container *cloneAlways() const;
       void lock();
       void unLock();
-       
+
       void checkCapabilityToDealWith(const ComponentInstance *inst) const throw (YACS::Exception);
       bool loadComponentLibrary(const std::string & componentName) throw (YACS::Exception);
       CppComponent * createComponentInstance(const std::string & componentName, int studyID = 0);
       void createInternalInstance(const std::string & componentName, 
                                   void *& obj, RunFunction &r, TerminateFunction &t);
       void unregisterComponentInstance(CppComponent * C);
-      
-     protected:
-       YACS::BASES::Mutex _mutex;
-       LocalContainer * _trueCont;
+      //
+      void setProperty(const std::string& name,const std::string& value) { }
+      std::string getProperty(const std::string& name) const { return std::string(); }
+      void clearProperties() { }
+      void addComponentName(const std::string& name) { }
+      std::map<std::string,std::string> getProperties() const { return std::map<std::string,std::string>(); }
+      std::map<std::string,std::string> getResourceProperties(const std::string& name) const { return std::map<std::string,std::string>(); }
+      //
+    public:
+      static char KIND[];
+    protected:
+      YACS::BASES::Mutex _mutex;
+      LocalContainer * _trueCont;
 
-     };
+    };
   };
 };
 
index 7150a6bd98d728b4b32fd3d230ec54525bbb7926..7eab4dcac406922c71586b2468589554345c78a9 100644 (file)
@@ -21,6 +21,9 @@
 #include "RuntimeSALOME.hxx"
 #include "SalomeContainer.hxx"
 #include "PythonNode.hxx"
+#include "SalomeHPContainer.hxx"
+#include "SalomeContainerTmpForHP.hxx"
+#include "AutoGIL.hxx"
 
 #include "PythonPorts.hxx"
 #include "YacsTrace.hxx"
@@ -50,122 +53,165 @@ DistributedPythonNode::DistributedPythonNode(const DistributedPythonNode& other,
 
 DistributedPythonNode::~DistributedPythonNode()
 {
-  PyGILState_STATE gstate = PyGILState_Ensure();
+  AutoGIL agil;
   Py_DECREF(_context);
-  PyGILState_Release(gstate);
 }
 
 void DistributedPythonNode::load()
 {
+  bool isContAlreadyStarted(false);
+  if(_container)
+    isContAlreadyStarted=_container->isAlreadyStarted(this);
   ServerNode::load();
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+  {
+    AutoGIL agil;
+    if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+      {
+        stringstream msg;
+        msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
+        _errorDetails=msg.str();
+        throw Exception(msg.str());
+      }
+    const char picklizeScript[]="import cPickle\ndef pickleForDistPyth2009(*args,**kws):\n  return cPickle.dumps((args,kws),-1)\n\ndef unPickleForDistPyth2009(st):\n  args=cPickle.loads(st)\n  return args\n";
+    PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
+    if(res == NULL)
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+        return;
+      }
+    Py_DECREF(res);
+    _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
+    _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
+    if(_pyfuncSer == NULL)
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+      }
+    if(_pyfuncUnser == NULL)
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+      }
+
+    Engines::Container_var objContainer=Engines::Container::_nil();
+    if(!_container)
+      throw Exception("No container specified !");
+    SalomeContainer *containerCast0(dynamic_cast<SalomeContainer *>(_container));
+    SalomeHPContainer *containerCast1(dynamic_cast<SalomeHPContainer *>(_container));
+    if(containerCast0)
+      objContainer=containerCast0->getContainerPtr(this);
+    else if(containerCast1)
+      {
+        YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,this));
+        objContainer=tmpCont->getContainerPtr(this);
+      }
+    else
+      throw Exception("Unrecognized type of container ! Salome one is expected !");
+    if(CORBA::is_nil(objContainer))
+      throw Exception("Container corba pointer is NULL !");
+
+    try
     {
-      stringstream msg;
-      msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
-      PyGILState_Release(gstate);
-      _errorDetails=msg.str();
-      throw Exception(msg.str());
+        if(containerCast0 || !isContAlreadyStarted)
+          {
+            _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
+          }
+        else
+          {
+            Engines::PyNode_var dftPyScript(objContainer->getDefaultPyNode());
+            if(CORBA::is_nil(dftPyScript))
+              _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
+            else
+              _pynode = dftPyScript;
+          }
     }
-  const char picklizeScript[]="import cPickle\ndef pickleForDistPyth2009(*args,**kws):\n  return cPickle.dumps((args,kws),-1)\n\ndef unPickleForDistPyth2009(st):\n  args=cPickle.loads(st)\n  return args\n";
-  PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
-  if(res == NULL)
+    catch( const SALOME::SALOME_Exception& ex )
     {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-      return;
+        std::string msg="Exception on remote python node creation ";
+        msg += '\n';
+        msg += ex.details.text.in();
+        _errorDetails=msg;
+        throw Exception(msg);
     }
-  Py_DECREF(res);
-  _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
-  _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
-  if(_pyfuncSer == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
 
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-    }
-  if(_pyfuncUnser == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
+    if(CORBA::is_nil(_pynode))
+      throw Exception("In DistributedPythonNode the ref in NULL ! ");
 
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-    }
-  DEBTRACE( "---------------End PyfuncSerNode::load function---------------" );
-  PyGILState_Release(gstate);
+
+    DEBTRACE( "---------------End PyfuncSerNode::load function---------------" );
+  }
 }
 
 void DistributedPythonNode::execute()
 {
   YACSTRACE(1,"+++++++++++++++++ DistributedPythonNode::execute: " << getName() << " " << getFname() << " +++++++++++++++++" );
+  //////
+  PyObject* ob;
+  if(!_pyfuncSer)
+    throw Exception("DistributedPythonNode badly loaded");
+  Engines::pickledArgs *serializationInputCorba(0);
+  PyObject *args(0);
   {
-    Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
-    Engines::PyNode_var pn=objContainer->createPyNode(getName().c_str(),getScript().c_str());
-    //////
-    int pos=0;
-    PyObject* ob;
-    if(!_pyfuncSer)
-      throw Exception("DistributedPythonNode badly loaded");
-    PyGILState_STATE gstate = PyGILState_Ensure();
-    
+    AutoGIL agil;
+
     DEBTRACE( "---------------DistributedPythonNode::inputs---------------" );
-    PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
-    list<InputPort *>::iterator iter2;
-    for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
+    args = PyTuple_New(getNumberOfInputPorts()) ;
+    int pos=0;
+    for(list<InputPort *>::iterator iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++,pos++)
       {
         InputPyPort *p=(InputPyPort *)*iter2;
         ob=p->getPyObj();
         Py_INCREF(ob);
         PyTuple_SetItem(args,pos,ob);
-        pos++;
       }
     PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
     std::string serializationInputC=PyString_AsString(serializationInput);
-    Engines::pickledArgs *serializationInputCorba=new Engines::pickledArgs;
+    serializationInputCorba=new Engines::pickledArgs;
     int len=serializationInputC.length();
     serializationInputCorba->length(serializationInputC.length());
     for(int i=0;i<serializationInputC.length();i++)
       (*serializationInputCorba)[i]=serializationInputC[i];
-    //serializationInputCorba[serializationInputC.length()]='\0';
-    DEBTRACE( "-----------------DistributedPythonNode starting remote python invocation-----------------" );
-    Engines::pickledArgs *resultCorba;
-    try
-      {
-        resultCorba=pn->execute(getFname().c_str(),*serializationInputCorba);
-      }
-    catch(...)
-      {
-        std::string msg="Exception on remote python invocation";
-        PyGILState_Release(gstate);
-        _errorDetails=msg;
-        throw Exception(msg);
-      }
-    DEBTRACE( "-----------------DistributedPythonNode end of remote python invocation-----------------" );
-    //
-    delete serializationInputCorba;
-    char *resultCorbaC=new char[resultCorba->length()+1];
-    resultCorbaC[resultCorba->length()]='\0';
-    for(int i=0;i<resultCorba->length();i++)
-      resultCorbaC[i]=(*resultCorba)[i];
-    delete resultCorba;
+    Py_DECREF(serializationInput);
+  }
+  //serializationInputCorba[serializationInputC.length()]='\0';
+  DEBTRACE( "-----------------DistributedPythonNode starting remote python invocation-----------------" );
+  Engines::pickledArgs *resultCorba;
+  try
+  {
+      resultCorba=_pynode->execute(getFname().c_str(),*serializationInputCorba);
+  }
+  catch(...)
+  {
+      std::string msg="Exception on remote python invocation";
+      _errorDetails=msg;
+      throw Exception(msg);
+  }
+  DEBTRACE( "-----------------DistributedPythonNode end of remote python invocation-----------------" );
+  //
+  delete serializationInputCorba;
+  char *resultCorbaC=new char[resultCorba->length()+1];
+  resultCorbaC[resultCorba->length()]='\0';
+  for(int i=0;i<resultCorba->length();i++)
+    resultCorbaC[i]=(*resultCorba)[i];
+  delete resultCorba;
+  {
+    AutoGIL agil;
     args = PyTuple_New(1);
     PyObject* resultPython=PyString_FromString(resultCorbaC);
     delete [] resultCorbaC;
@@ -177,21 +223,18 @@ void DistributedPythonNode::execute()
       nres=0;
     else if(PyTuple_Check(finalResult))
       nres=PyTuple_Size(finalResult);
-    
+
     if(getNumberOfOutputPorts() != nres)
       {
         std::string msg="Number of output arguments : Mismatch between definition and execution";
         Py_DECREF(finalResult);
-        PyGILState_Release(gstate);
         _errorDetails=msg;
         throw Exception(msg);
       }
-    
-    pos=0;
-    list<OutputPort *>::iterator iter;
     try
-      {
-        for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
+    {
+        int pos(0);
+        for(list<OutputPort *>::iterator iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++, pos++)
           {
             OutputPyPort *p=(OutputPyPort *)*iter;
             DEBTRACE( "port name: " << p->getName() );
@@ -201,17 +244,14 @@ void DistributedPythonNode::execute()
             else ob=finalResult;
             DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
             p->put(ob);
-            pos++;
           }
-      }
+    }
     catch(ConversionException& ex)
-      {
+    {
         Py_DECREF(finalResult);
-        PyGILState_Release(gstate);
         _errorDetails=ex.what();
         throw;
-      }
-    PyGILState_Release(gstate);
+    }
   }
   DEBTRACE( "++++++++++++++ End DistributedPythonNode::execute: " << getName() << " ++++++++++++++++++++" );
 }
@@ -237,9 +277,8 @@ ServerNode *DistributedPythonNode::createNode(const std::string& name) const
 void DistributedPythonNode::initMySelf()
 {
   _implementation = DistributedPythonNode::IMPL_NAME;
-  PyGILState_STATE gstate=PyGILState_Ensure();
+  AutoGIL agil;
   _context=PyDict_New();
-  PyGILState_Release(gstate);
 }
 
 void DistributedPythonNode::dealException(CORBA::Exception *exc, const char *method, const char *ref)
index 3a49bd999cac13853442fb4a45066a13856edca9..99d5694404599f4a28775d8c2c3eec167b66a241 100644 (file)
@@ -34,6 +34,8 @@
 #include <Python.h>
 #include <omniORB4/CORBA.h>
 #include "YACSRuntimeSALOMEExport.hxx"
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOME_PyNode)
 
 namespace YACS
 {
@@ -66,6 +68,7 @@ namespace YACS
       PyObject* _context;
       PyObject* _pyfuncSer;
       PyObject* _pyfuncUnser;
+      Engines::PyNode_var _pynode;
     };
   }
 }
index bfd3b3a6814aa482658b581a9ea1b68f9c2f6b9d..e8cbc26248a5a640f154355bd4dfc214cc51af0e 100644 (file)
 #include "PythonNode.hxx"
 #include "PythonPorts.hxx"
 #include "TypeCode.hxx"
+#include "AutoGIL.hxx"
 #include "Container.hxx"
 #include "SalomeContainer.hxx"
+#include "SalomeHPContainer.hxx"
+#include "SalomeContainerTmpForHP.hxx"
 #include "ConversionException.hxx"
 
 #include "PyStdout.hxx"
@@ -48,68 +51,287 @@ using namespace std;
 const char PythonNode::IMPL_NAME[]="Python";
 const char PythonNode::KIND[]="Python";
 
-PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father)
+const char PythonNode::SCRIPT_FOR_SERIALIZATION[]="import cPickle\n"
+    "def pickleForDistPyth2009(kws):\n"
+    "  return cPickle.dumps(((),kws),-1)\n"
+    "\n"
+    "def unPickleForDistPyth2009(st):\n"
+    "  args=cPickle.loads(st)\n"
+    "  return args\n";
+
+const char PyFuncNode::SCRIPT_FOR_SERIALIZATION[]="import cPickle\n"
+    "def pickleForDistPyth2009(*args,**kws):\n"
+    "  return cPickle.dumps((args,kws),-1)\n"
+    "\n"
+    "def unPickleForDistPyth2009(st):\n"
+    "  args=cPickle.loads(st)\n"
+    "  return args\n";
+
+PythonEntry::PythonEntry():_context(0),_pyfuncSer(0),_pyfuncUnser(0)
 {
-  _implementation=IMPL_NAME;
-  PyGILState_STATE gstate=PyGILState_Ensure();
-  _context=PyDict_New();
-  if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+}
+
+PythonEntry::~PythonEntry()
+{
+  AutoGIL agil;
+  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
+  // not Py_XDECREF of _pyfuncUnser because it is returned by PyDict_GetItem -> borrowed
+  // not Py_XDECREF of _pyfuncSer because it is returned by PyDict_GetItem -> borrowed
+  Py_XDECREF(_context);
+}
+
+void PythonEntry::commonRemoteLoadPart1(InlineNode *reqNode)
+{
+  DEBTRACE( "---------------PythonEntry::CommonRemoteLoad function---------------" );
+  Container *container(reqNode->getContainer());
+  bool isContAlreadyStarted(false);
+  if(container)
     {
-      stringstream msg;
-      msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
-      PyGILState_Release(gstate);
-      _errorDetails=msg.str();
-      throw Exception(msg.str());
+      isContAlreadyStarted=container->isAlreadyStarted(reqNode);
+      if(!isContAlreadyStarted)
+        {
+          try
+          {
+              container->start(reqNode);
+          }
+          catch(Exception& e)
+          {
+              reqNode->setErrorDetails(e.what());
+              throw e;
+          }
+        }
+    }
+  else
+    {
+      std::string what("PythonEntry::CommonRemoteLoad : a load operation requested on \"");
+      what+=reqNode->getName(); what+="\" with no container specified.";
+      reqNode->setErrorDetails(what);
+      throw Exception(what);
     }
-  PyGILState_Release(gstate);
 }
 
-PythonNode::PythonNode(const std::string& name):InlineNode(name)
+Engines::Container_var PythonEntry::commonRemoteLoadPart2(InlineNode *reqNode, bool& isInitializeRequested)
 {
-  _implementation=IMPL_NAME;
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  _context=PyDict_New();
-  if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+  Container *container(reqNode->getContainer());
+  Engines::Container_var objContainer=Engines::Container::_nil();
+  if(!container)
+    throw Exception("No container specified !");
+  SalomeContainer *containerCast0(dynamic_cast<SalomeContainer *>(container));
+  SalomeHPContainer *containerCast1(dynamic_cast<SalomeHPContainer *>(container));
+  if(containerCast0)
+    objContainer=containerCast0->getContainerPtr(reqNode);
+  else if(containerCast1)
     {
-      stringstream msg;
-      msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
-      PyGILState_Release(gstate);
-      _errorDetails=msg.str();
-      throw Exception(msg.str());
+      YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,reqNode));
+      objContainer=tmpCont->getContainerPtr(reqNode);
     }
-  PyGILState_Release(gstate);
+  else
+    throw Exception("Unrecognized type of container ! Salome one is expected for PythonNode/PyFuncNode !");
+  if(CORBA::is_nil(objContainer))
+    throw Exception("Container corba pointer is NULL for PythonNode !");
+  isInitializeRequested=false;
+  try
+  {
+      if(containerCast0)
+        {
+          createRemoteAdaptedPyInterpretor(objContainer);
+        }
+      else
+        {
+          Engines::PyNodeBase_var dftPyScript(retrieveDftRemotePyInterpretorIfAny(objContainer));
+          if(CORBA::is_nil(dftPyScript))
+            {
+              isInitializeRequested=true;
+              createRemoteAdaptedPyInterpretor(objContainer);
+            }
+          else
+            assignRemotePyInterpretor(dftPyScript);
+        }
+  }
+  catch( const SALOME::SALOME_Exception& ex )
+  {
+      std::string msg="Exception on remote python node creation ";
+      msg += '\n';
+      msg += ex.details.text.in();
+      reqNode->setErrorDetails(msg);
+      throw Exception(msg);
+  }
+  Engines::PyNodeBase_var pynode(getRemoteInterpreterHandle());
+  if(CORBA::is_nil(pynode))
+    throw Exception("In PythonNode the ref in NULL ! ");
+  return objContainer;
+}
+
+void PythonEntry::commonRemoteLoadPart3(InlineNode *reqNode, Engines::Container_ptr objContainer, bool isInitializeRequested)
+{
+  Container *container(reqNode->getContainer());
+  Engines::PyNodeBase_var pynode(getRemoteInterpreterHandle());
+  ///
+  {
+    AutoGIL agil;
+    const char *picklizeScript(getSerializationScript());
+    PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
+    if(res == NULL)
+      {
+        std::string errorDetails;
+        PyObject* new_stderr = newPyStdOut(errorDetails);
+        reqNode->setErrorDetails(errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during load");
+      }
+    Py_DECREF(res);
+    _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
+    _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
+    if(_pyfuncSer == NULL)
+      {
+        std::string errorDetails;
+        PyObject *new_stderr(newPyStdOut(errorDetails));
+        reqNode->setErrorDetails(errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during load");
+      }
+    if(_pyfuncUnser == NULL)
+      {
+        std::string errorDetails;
+        PyObject *new_stderr(newPyStdOut(errorDetails));
+        reqNode->setErrorDetails(errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during load");
+      }
+  }
+  if(isInitializeRequested)
+    {//This one is called only once at initialization in the container if an init-script is specified.
+      try
+      {
+          std::string zeInitScriptKey(container->getProperty(HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY));
+          if(!zeInitScriptKey.empty())
+            pynode->executeAnotherPieceOfCode(zeInitScriptKey.c_str());
+      }
+      catch( const SALOME::SALOME_Exception& ex )
+      {
+          std::string msg="Exception on PythonNode::loadRemote python invocation of initializisation py script !";
+          msg += '\n';
+          msg += ex.details.text.in();
+          reqNode->setErrorDetails(msg);
+          throw Exception(msg);
+      }
+      DEBTRACE( "---------------End PyNode::loadRemote function---------------" );
+    }
+}
+
+std::string PythonEntry::GetContainerLog(const std::string& mode, Container *container, const Task *askingTask)
+{
+  if(mode=="local")
+    return "";
+
+  std::string msg;
+  try
+  {
+      SalomeContainer *containerCast(dynamic_cast<SalomeContainer *>(container));
+      SalomeHPContainer *objContainer2(dynamic_cast<SalomeHPContainer *>(container));
+      if(containerCast)
+        {
+          Engines::Container_var objContainer(containerCast->getContainerPtr(askingTask));
+          CORBA::String_var logname = objContainer->logfilename();
+          DEBTRACE(logname);
+          msg=logname;
+          std::string::size_type pos = msg.find(":");
+          msg=msg.substr(pos+1);
+        }
+      else if(objContainer2)
+        {
+          msg="Remote PythonNode is on HP Container : no log because no info of the location by definition of HP Container !";
+        }
+      else
+        {
+          msg="Not implemented yet for container log for that type of container !";
+        }
+  }
+  catch(...)
+  {
+      msg = "Container no longer reachable";
+  }
+  return msg;
+}
+
+void PythonEntry::commonRemoteLoad(InlineNode *reqNode)
+{
+  commonRemoteLoadPart1(reqNode);
+  bool isInitializeRequested;
+  Engines::Container_var objContainer(commonRemoteLoadPart2(reqNode,isInitializeRequested));
+  commonRemoteLoadPart3(reqNode,objContainer,isInitializeRequested);
+}
+
+PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father)
+{
+  _implementation=IMPL_NAME;
+  {
+    AutoGIL agil;
+    _context=PyDict_New();
+    if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+      {
+        stringstream msg;
+        msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
+        _errorDetails=msg.str();
+        throw Exception(msg.str());
+      }
+  }
+}
+
+PythonNode::PythonNode(const std::string& name):InlineNode(name)
+{
+  _implementation=IMPL_NAME;
+  {
+    AutoGIL agil;
+    _context=PyDict_New();
+    if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+      {
+        stringstream msg;
+        msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
+        _errorDetails=msg.str();
+        throw Exception(msg.str());
+      }
+  }
 }
 
 PythonNode::~PythonNode()
 {
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-  Py_DECREF(_context);
-  PyGILState_Release(gstate);
+  if(!CORBA::is_nil(_pynode))
+    {
+      _pynode->UnRegister();
+    }
 }
 
 void PythonNode::checkBasicConsistency() const throw(YACS::Exception)
 {
   DEBTRACE("checkBasicConsistency");
   InlineNode::checkBasicConsistency();
-
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  PyObject* res;
-  res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
-  if(res == NULL)
-    {
-      std::string error="";
-      PyObject* new_stderr = newPyStdOut(error);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-      PyGILState_Release(gstate);
-      throw Exception(error);
-    }
-  else
-    Py_XDECREF(res);
-  PyGILState_Release(gstate);
+  {
+    AutoGIL agil;
+    PyObject* res;
+    res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
+    if(res == NULL)
+      {
+        std::string error="";
+        PyObject* new_stderr = newPyStdOut(error);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception(error);
+      }
+    else
+      Py_XDECREF(res);
+  }
 }
 
 void PythonNode::load()
@@ -129,97 +351,7 @@ void PythonNode::loadLocal()
 
 void PythonNode::loadRemote()
 {
-  DEBTRACE( "---------------PyNode::loadRemote function---------------" );
-  if(_container)
-    {
-      if(!_container->isAlreadyStarted(0))
-        {
-          try
-            {
-              _container->start(0);
-            }
-          catch(Exception& e)
-            {
-              _errorDetails=e.what();
-              throw e;
-            }
-        }
-    }
-  else
-    {
-      std::string what("PyNode::loadRemote : a load operation requested on \"");
-      what+=_name; what+="\" with no container specified.";
-      _errorDetails=what;
-      throw Exception(what);
-    }
-
-  Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
-
-  try
-    {
-      _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str());
-    }
-  catch( const SALOME::SALOME_Exception& ex )
-    {
-      std::string msg="Exception on remote python node creation ";
-      msg += '\n';
-      msg += ex.details.text.in();
-      _errorDetails=msg;
-      throw Exception(msg);
-    }
-
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  const char picklizeScript[]="import cPickle\n"
-                              "def pickleForDistPyth2009(kws):\n"
-                              "  return cPickle.dumps(((),kws),-1)\n"
-                              "\n"
-                              "def unPickleForDistPyth2009(st):\n"
-                              "  args=cPickle.loads(st)\n"
-                              "  return args\n";
-  PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
-  if(res == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during load");
-    }
-  Py_DECREF(res);
-
-  _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
-  _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
-  if(_pyfuncSer == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during load");
-    }
-  if(_pyfuncUnser == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during load");
-    }
-  DEBTRACE( "---------------End PyNode::loadRemote function---------------" );
-  PyGILState_Release(gstate);
-
+  commonRemoteLoad(this);
 }
 
 void PythonNode::execute()
@@ -235,47 +367,53 @@ void PythonNode::executeRemote()
   DEBTRACE( "++++++++++++++ PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
   if(!_pyfuncSer)
     throw Exception("DistributedPythonNode badly loaded");
-  PyGILState_STATE gstate = PyGILState_Ensure();
-
-  //===========================================================================
-  // Get inputs in input ports, build a Python dict and pickle it
-  //===========================================================================
-  PyObject* ob;
-  PyObject* args = PyDict_New();
-  std::list<InputPort *>::iterator iter2;
-  int pos=0;
-  for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
+  //
+  if(dynamic_cast<HomogeneousPoolContainer *>(getContainer()))
     {
-      InputPyPort *p=(InputPyPort *)*iter2;
-      ob=p->getPyObj();
-      PyDict_SetItemString(args,p->getName().c_str(),ob);
-      pos++;
+      bool dummy;
+      commonRemoteLoadPart2(this,dummy);
+      _pynode->assignNewCompiledCode(getScript().c_str());
     }
+  //
+  Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);
+  {
+      AutoGIL agil;
+      PyObject *args(0),*ob(0);
+      //===========================================================================
+      // Get inputs in input ports, build a Python dict and pickle it
+      //===========================================================================
+      args = PyDict_New();
+      std::list<InputPort *>::iterator iter2;
+      int pos(0);
+      for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
+        {
+          InputPyPort *p=(InputPyPort *)*iter2;
+          ob=p->getPyObj();
+          PyDict_SetItemString(args,p->getName().c_str(),ob);
+          pos++;
+        }
 #ifdef _DEVDEBUG_
-  PyObject_Print(args,stderr,Py_PRINT_RAW);
-  std::cerr << endl;
+      PyObject_Print(args,stderr,Py_PRINT_RAW);
+      std::cerr << endl;
 #endif
-  PyObject *serializationInput=PyObject_CallFunctionObjArgs(_pyfuncSer,args,NULL);
-  //The pickled string may contain NULL characters so use PyString_AsStringAndSize
-  char* serializationInputC;
-  Py_ssize_t len;
-  if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
-    {
-      PyGILState_Release(gstate);
-      throw Exception("DistributedPythonNode problem in python pickle");
-    }
-  PyGILState_Release(gstate);
-
-  Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
-  serializationInputCorba->length(len);
-  for(int i=0; i < len ; i++)
-    serializationInputCorba[i]=serializationInputC[i];
+      PyObject *serializationInput(PyObject_CallFunctionObjArgs(_pyfuncSer,args,NULL));
+      Py_DECREF(args);
+      //The pickled string may contain NULL characters so use PyString_AsStringAndSize
+      char *serializationInputC(0);
+      Py_ssize_t len;
+      if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
+        throw Exception("DistributedPythonNode problem in python pickle");
+      serializationInputCorba->length(len);
+      for(int i=0; i < len ; i++)
+        serializationInputCorba[i]=serializationInputC[i];
+      Py_DECREF(serializationInput);
+  }
 
   //get the list of output argument names
   std::list<OutputPort *>::iterator iter;
   Engines::listofstring myseq;
   myseq.length(getNumberOfOutputPorts());
-  pos=0;
+  int pos=0;
   for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
     {
       OutputPyPort *p=(OutputPyPort *)*iter;
@@ -312,200 +450,177 @@ void PythonNode::executeRemote()
   for(int i=0;i<resultCorba->length();i++)
     resultCorbaC[i]=resultCorba[i];
 
-  gstate = PyGILState_Ensure();
-
-  PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
-  delete [] resultCorbaC;
-  args = PyTuple_New(1);
-  PyTuple_SetItem(args,0,resultPython);
-  PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
-  Py_DECREF(args);
-
-  if (finalResult == NULL)
   {
-    std::stringstream msg;
-    msg << "Conversion with pickle of output ports failed !";
-    msg << " : " << __FILE__ << ":" << __LINE__;
-    PyGILState_Release(gstate);
-    _errorDetails=msg.str();
-    throw YACS::ENGINE::ConversionException(msg.str());
-  }
-
-  DEBTRACE( "-----------------PythonNode::outputs-----------------" );
-  int nres=1;
-  if(finalResult == Py_None)
-    nres=0;
-  else if(PyTuple_Check(finalResult))
-    nres=PyTuple_Size(finalResult);
+      AutoGIL agil;
+      PyObject *args(0),*ob(0);
+      PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
+      delete [] resultCorbaC;
+      args = PyTuple_New(1);
+      PyTuple_SetItem(args,0,resultPython);
+      PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
+      Py_DECREF(args);
+
+      if (finalResult == NULL)
+        {
+          std::stringstream msg;
+          msg << "Conversion with pickle of output ports failed !";
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          _errorDetails=msg.str();
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
 
-  if(getNumberOfOutputPorts() != nres)
-    {
-      std::string msg="Number of output arguments : Mismatch between definition and execution";
-      Py_DECREF(finalResult);
-      PyGILState_Release(gstate);
-      _errorDetails=msg;
-      throw Exception(msg);
-    }
+      DEBTRACE( "-----------------PythonNode::outputs-----------------" );
+      int nres=1;
+      if(finalResult == Py_None)
+        nres=0;
+      else if(PyTuple_Check(finalResult))
+        nres=PyTuple_Size(finalResult);
 
-  pos=0;
-  try
-    {
-      for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
+      if(getNumberOfOutputPorts() != nres)
         {
-          OutputPyPort *p=(OutputPyPort *)*iter;
-          DEBTRACE( "port name: " << p->getName() );
-          DEBTRACE( "port kind: " << p->edGetType()->kind() );
-          DEBTRACE( "port pos : " << pos );
-          if(PyTuple_Check(finalResult))
-            ob=PyTuple_GetItem(finalResult,pos) ;
-          else
-            ob=finalResult;
-          DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
-          p->put(ob);
-          pos++;
+          std::string msg="Number of output arguments : Mismatch between definition and execution";
+          Py_DECREF(finalResult);
+          _errorDetails=msg;
+          throw Exception(msg);
         }
-      Py_DECREF(finalResult);
-    }
-  catch(ConversionException& ex)
-    {
-      Py_DECREF(finalResult);
-      PyGILState_Release(gstate);
-      _errorDetails=ex.what();
-      throw;
-    }
-
-  PyGILState_Release(gstate);
 
+      pos=0;
+      try
+      {
+          for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
+            {
+              OutputPyPort *p=(OutputPyPort *)*iter;
+              DEBTRACE( "port name: " << p->getName() );
+              DEBTRACE( "port kind: " << p->edGetType()->kind() );
+              DEBTRACE( "port pos : " << pos );
+              if(PyTuple_Check(finalResult))
+                ob=PyTuple_GetItem(finalResult,pos) ;
+              else
+                ob=finalResult;
+              DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
+              p->put(ob);
+              pos++;
+            }
+          Py_DECREF(finalResult);
+      }
+      catch(ConversionException& ex)
+      {
+          Py_DECREF(finalResult);
+          _errorDetails=ex.what();
+          throw;
+      }
+  }
   DEBTRACE( "++++++++++++++ ENDOF PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
 }
 
 void PythonNode::executeLocal()
 {
   DEBTRACE( "++++++++++++++ PyNode::executeLocal: " << getName() << " ++++++++++++++++++++" );
-  PyGILState_STATE gstate = PyGILState_Ensure();
-
-  DEBTRACE( "---------------PyNode::inputs---------------" );
-  list<InputPort *>::iterator iter2;
-  for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
-    {
-      InputPyPort *p=(InputPyPort *)*iter2;
-      DEBTRACE( "port name: " << p->getName() );
-      DEBTRACE( "port kind: " << p->edGetType()->kind() );
-      PyObject* ob=p->getPyObj();
-      DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
+  {
+    AutoGIL agil;
+
+    DEBTRACE( "---------------PyNode::inputs---------------" );
+    list<InputPort *>::iterator iter2;
+    for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
+      {
+        InputPyPort *p=(InputPyPort *)*iter2;
+        DEBTRACE( "port name: " << p->getName() );
+        DEBTRACE( "port kind: " << p->edGetType()->kind() );
+        PyObject* ob=p->getPyObj();
+        DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
 #ifdef _DEVDEBUG_
-      PyObject_Print(ob,stderr,Py_PRINT_RAW);
-      cerr << endl;
+        PyObject_Print(ob,stderr,Py_PRINT_RAW);
+        cerr << endl;
 #endif
-      int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob);
-      DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt );
-    }
-  
-  DEBTRACE( "---------------End PyNode::inputs---------------" );
-  
-  //calculation
-  DEBTRACE( "----------------PyNode::calculation---------------" );
-  DEBTRACE(  _script );
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-
-  std::ostringstream stream;
-  stream << "/tmp/PythonNode_";
-  stream << getpid();
-
-  PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
-  if(code == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-    }
-  PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
-
-  Py_DECREF(code);
-  Py_XDECREF(res);
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-  fflush(stdout);
-  fflush(stderr);
-  if(PyErr_Occurred ())
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      ofstream errorfile(stream.str().c_str());
-      if (errorfile.is_open())
-        {
-          errorfile << _script;
-          errorfile.close();
-        }
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-    }
-  
-  DEBTRACE( "-----------------PyNode::outputs-----------------" );
-  list<OutputPort *>::iterator iter;
-  try
-    {
-      for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
-        {
-          OutputPyPort *p=(OutputPyPort *)*iter;
-          DEBTRACE( "port name: " << p->getName() );
-          DEBTRACE( "port kind: " << p->edGetType()->kind() );
-          PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str());
-          if(ob==NULL){
-             PyGILState_Release(gstate);
-             std::string msg="Error during execution: there is no variable ";
-             msg=msg+p->getName()+" in node context";
-             _errorDetails=msg;
-             throw Exception(msg);
+        int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob);
+        DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt );
+      }
+
+    DEBTRACE( "---------------End PyNode::inputs---------------" );
+
+    //calculation
+    DEBTRACE( "----------------PyNode::calculation---------------" );
+    DEBTRACE(  _script );
+    DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
+
+    std::ostringstream stream;
+    stream << "/tmp/PythonNode_";
+    stream << getpid();
+
+    PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
+    if(code == NULL)
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+      }
+    PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
+
+    Py_DECREF(code);
+    Py_XDECREF(res);
+    DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
+    fflush(stdout);
+    fflush(stderr);
+    if(PyErr_Occurred ())
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        ofstream errorfile(stream.str().c_str());
+        if (errorfile.is_open())
+          {
+            errorfile << _script;
+            errorfile.close();
           }
-          DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt );
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+      }
+
+    DEBTRACE( "-----------------PyNode::outputs-----------------" );
+    list<OutputPort *>::iterator iter;
+    try
+    {
+        for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
+          {
+            OutputPyPort *p=(OutputPyPort *)*iter;
+            DEBTRACE( "port name: " << p->getName() );
+            DEBTRACE( "port kind: " << p->edGetType()->kind() );
+            PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str());
+            if(ob==NULL)
+              {
+                std::string msg="Error during execution: there is no variable ";
+                msg=msg+p->getName()+" in node context";
+                _errorDetails=msg;
+                throw Exception(msg);
+              }
+            DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt );
 #ifdef _DEVDEBUG_
-          PyObject_Print(ob,stderr,Py_PRINT_RAW);
-          cerr << endl;
+            PyObject_Print(ob,stderr,Py_PRINT_RAW);
+            cerr << endl;
 #endif
-          p->put(ob);
-        }
+            p->put(ob);
+          }
     }
-  catch(ConversionException& ex)
+    catch(ConversionException& ex)
     {
-      PyGILState_Release(gstate);
-      _errorDetails=ex.what();
-      throw;
+        _errorDetails=ex.what();
+        throw;
     }
 
-  DEBTRACE( "-----------------End PyNode::outputs-----------------" );
-  PyGILState_Release(gstate);
+    DEBTRACE( "-----------------End PyNode::outputs-----------------" );
+  }
   DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" );
 }
 
 std::string PythonNode::getContainerLog()
 {
-  if(_mode=="local")return "";
-
-  std::string msg;
-  try
-    {
-      Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
-      CORBA::String_var logname = objContainer->logfilename();
-      DEBTRACE(logname);
-      msg=logname;
-      std::string::size_type pos = msg.find(":");
-      msg=msg.substr(pos+1);
-    }
-  catch(...)
-    {
-      msg = "Container no longer reachable";
-    }
-  return msg;
+  return PythonEntry::GetContainerLog(_mode,_container,this);
 }
 
 void PythonNode::shutdown(int level)
@@ -525,6 +640,41 @@ Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
   return new PythonNode(*this,father);
 }
 
+void PythonNode::createRemoteAdaptedPyInterpretor(Engines::Container_ptr objContainer)
+{
+  if(!CORBA::is_nil(_pynode))
+    _pynode->UnRegister();
+  _pynode=objContainer->createPyScriptNode(getName().c_str(),getScript().c_str());
+}
+
+Engines::PyNodeBase_var PythonNode::retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const
+{
+  Engines::PyScriptNode_var ret(objContainer->getDefaultPyScriptNode());
+  if(!CORBA::is_nil(ret))
+    {
+      ret->Register();
+    }
+  return Engines::PyNodeBase::_narrow(ret);
+}
+
+void PythonNode::assignRemotePyInterpretor(Engines::PyNodeBase_var remoteInterp)
+{
+  if(!CORBA::is_nil(_pynode))
+    {
+      Engines::PyScriptNode_var tmpp(Engines::PyScriptNode::_narrow(remoteInterp));
+      if(_pynode->_is_equivalent(tmpp))
+        return ;
+    }
+  if(!CORBA::is_nil(_pynode))
+    _pynode->UnRegister();
+  _pynode=Engines::PyScriptNode::_narrow(remoteInterp);
+}
+
+Engines::PyNodeBase_var PythonNode::getRemoteInterpreterHandle()
+{
+  return Engines::PyNodeBase::_narrow(_pynode);
+}
+
 //! Create a new node of same type with a given name
 PythonNode* PythonNode::cloneNode(const std::string& name)
 {
@@ -552,18 +702,18 @@ PythonNode* PythonNode::cloneNode(const std::string& name)
 PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0)
 {
   _implementation = PythonNode::IMPL_NAME;
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  _context=PyDict_New();
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-  if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
-    {
-      stringstream msg;
-      msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
-      _errorDetails=msg.str();
-      PyGILState_Release(gstate);
-      throw Exception(msg.str());
-    }
-  PyGILState_Release(gstate);
+  {
+    AutoGIL agil;
+    _context=PyDict_New();
+    DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
+    if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+      {
+        stringstream msg;
+        msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
+        _errorDetails=msg.str();
+        throw Exception(msg.str());
+      }
+  }
 }
 
 PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0)
@@ -571,28 +721,22 @@ PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0)
 
   _implementation = PythonNode::IMPL_NAME;
   DEBTRACE( "PyFuncNode::PyFuncNode " << name );
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  _context=PyDict_New();
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-  if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
-    {
-      stringstream msg;
-      msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
-      _errorDetails=msg.str();
-      PyGILState_Release(gstate);
-      throw Exception(msg.str());
-    }
-  PyGILState_Release(gstate);
+  {
+    AutoGIL agil;
+    _context=PyDict_New();
+    DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
+    if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
+      {
+        stringstream msg;
+        msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
+        _errorDetails=msg.str();
+        throw Exception(msg.str());
+      }
+  }
 }
 
 PyFuncNode::~PyFuncNode()
 {
-  DEBTRACE( getName() );
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-  if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
-  Py_DECREF(_context);
-  PyGILState_Release(gstate);
   if(!CORBA::is_nil(_pynode))
     {
       _pynode->UnRegister();
@@ -603,24 +747,23 @@ void PyFuncNode::checkBasicConsistency() const throw(YACS::Exception)
 {
   DEBTRACE("checkBasicConsistency");
   InlineFuncNode::checkBasicConsistency();
-
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  PyObject* res;
-  res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
-  if(res == NULL)
-    {
-      std::string error="";
-      PyObject* new_stderr = newPyStdOut(error);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-      PyGILState_Release(gstate);
-      throw Exception(error);
-    }
-  else
-    Py_XDECREF(res);
-  PyGILState_Release(gstate);
+  {
+    AutoGIL agil;
+    PyObject* res;
+    res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
+    if(res == NULL)
+      {
+        std::string error="";
+        PyObject* new_stderr = newPyStdOut(error);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception(error);
+      }
+    else
+      Py_XDECREF(res);
+  }
 }
 
 void PyFuncNode::load()
@@ -634,95 +777,7 @@ void PyFuncNode::load()
 
 void PyFuncNode::loadRemote()
 {
-  DEBTRACE( "---------------PyfuncNode::loadRemote function---------------" );
-  if(_container)
-    {
-      if(!_container->isAlreadyStarted(0))
-        {
-          try
-            {
-              _container->start(0);
-            }
-          catch(Exception& e)
-            {
-              _errorDetails=e.what();
-              throw e;
-            }
-        }
-    }
-  else
-    {
-      std::string what("PyFuncNode::loadRemote : a load operation requested on \"");
-      what+=_name; what+="\" with no container specified.";
-      _errorDetails=what;
-      throw Exception(what);
-    }
-
-  Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
-  try
-    {
-      _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
-    }
-  catch( const SALOME::SALOME_Exception& ex )
-    {
-      std::string msg="Exception on remote python node creation ";
-      msg += '\n';
-      msg += ex.details.text.in();
-      _errorDetails=msg;
-      throw Exception(msg);
-    }
-
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  const char picklizeScript[]="import cPickle\n"
-                              "def pickleForDistPyth2009(*args,**kws):\n"
-                              "  return cPickle.dumps((args,kws),-1)\n"
-                              "\n"
-                              "def unPickleForDistPyth2009(st):\n"
-                              "  args=cPickle.loads(st)\n"
-                              "  return args\n";
-  PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
-  if(res == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during load");
-    }
-  Py_DECREF(res);
-
-  _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
-  _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
-  if(_pyfuncSer == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during load");
-    }
-  if(_pyfuncUnser == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during load");
-    }
-  DEBTRACE( "---------------End PyfuncNode::loadRemote function---------------" );
-  PyGILState_Release(gstate);
+  commonRemoteLoad(this);
 }
 
 void PyFuncNode::loadLocal()
@@ -740,65 +795,61 @@ void PyFuncNode::loadLocal()
     }
 #endif
 
-  PyGILState_STATE gstate = PyGILState_Ensure();
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-
-  std::ostringstream stream;
-  stream << "/tmp/PythonNode_";
-  stream << getpid();
-
-  PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
-  if(code == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-    }
-  PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
-  Py_DECREF(code);
-  Py_XDECREF(res);
-
-  DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
-  if(PyErr_Occurred ())
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      ofstream errorfile(stream.str().c_str());
-      if (errorfile.is_open())
-        {
-          errorfile << _script;
-          errorfile.close();
-        }
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
+  {
+    AutoGIL agil;
+    DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
+
+    std::ostringstream stream;
+    stream << "/tmp/PythonNode_";
+    stream << getpid();
+
+    PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
+    if(code == NULL)
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+      }
+    PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
+    Py_DECREF(code);
+    Py_XDECREF(res);
 
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-      return;
-    }
-  _pyfunc=PyDict_GetItemString(_context,_fname.c_str());
-  DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
-  if(_pyfunc == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-    }
-  DEBTRACE( "---------------End PyFuncNode::load function---------------" );
-  PyGILState_Release(gstate);
+    DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
+    if(PyErr_Occurred ())
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        ofstream errorfile(stream.str().c_str());
+        if (errorfile.is_open())
+          {
+            errorfile << _script;
+            errorfile.close();
+          }
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+        return;
+      }
+    _pyfunc=PyDict_GetItemString(_context,_fname.c_str());
+    DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
+    if(_pyfunc == NULL)
+      {
+        _errorDetails="";
+        PyObject* new_stderr = newPyStdOut(_errorDetails);
+        PySys_SetObject((char*)"stderr", new_stderr);
+        PyErr_Print();
+        PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+        Py_DECREF(new_stderr);
+        throw Exception("Error during execution");
+      }
+    DEBTRACE( "---------------End PyFuncNode::load function---------------" );
+  }
 }
 
 void PyFuncNode::execute()
@@ -814,42 +865,47 @@ void PyFuncNode::executeRemote()
   DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
   if(!_pyfuncSer)
     throw Exception("DistributedPythonNode badly loaded");
-  PyGILState_STATE gstate = PyGILState_Ensure();
-
-  //===========================================================================
-  // Get inputs in input ports, build a Python tuple and pickle it
-  //===========================================================================
-  PyObject* ob;
-  PyObject* args = PyTuple_New(getNumberOfInputPorts());
-  std::list<InputPort *>::iterator iter2;
-  int pos=0;
-  for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
+  //
+  if(dynamic_cast<HomogeneousPoolContainer *>(getContainer()))
     {
-      InputPyPort *p=(InputPyPort *)*iter2;
-      ob=p->getPyObj();
-      Py_INCREF(ob);
-      PyTuple_SetItem(args,pos,ob);
-      pos++;
+      bool dummy;
+      commonRemoteLoadPart2(this,dummy);
+      _pynode->executeAnotherPieceOfCode(getScript().c_str());
     }
+  //
+  Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);;
+  {
+      AutoGIL agil;
+      PyObject *ob(0);
+      //===========================================================================
+      // Get inputs in input ports, build a Python tuple and pickle it
+      //===========================================================================
+      PyObject *args(PyTuple_New(getNumberOfInputPorts()));
+      int pos(0);
+      for(std::list<InputPort *>::iterator iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++,pos++)
+        {
+          InputPyPort *p=(InputPyPort *)*iter2;
+          ob=p->getPyObj();
+          Py_INCREF(ob);
+          PyTuple_SetItem(args,pos,ob);
+        }
 #ifdef _DEVDEBUG_
-  PyObject_Print(args,stderr,Py_PRINT_RAW);
-  std::cerr << endl;
+      PyObject_Print(args,stderr,Py_PRINT_RAW);
+      std::cerr << endl;
 #endif
-  PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
-  //The pickled string may contain NULL characters so use PyString_AsStringAndSize
-  char* serializationInputC;
-  Py_ssize_t len;
-  if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
-    {
-      PyGILState_Release(gstate);
-      throw Exception("DistributedPythonNode problem in python pickle");
-    }
-  PyGILState_Release(gstate);
-
-  Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
-  serializationInputCorba->length(len);
-  for(int i=0; i < len ; i++)
-    serializationInputCorba[i]=serializationInputC[i];
+      PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
+      Py_DECREF(args);
+      //The pickled string may contain NULL characters so use PyString_AsStringAndSize
+      char *serializationInputC(0);
+      Py_ssize_t len;
+      if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
+        throw Exception("DistributedPythonNode problem in python pickle");
+
+      serializationInputCorba->length(len);
+      for(int i=0; i < len ; i++)
+        serializationInputCorba[i]=serializationInputC[i];
+      Py_DECREF(serializationInput);
+  }
 
   //===========================================================================
   // Execute in remote Python node
@@ -877,60 +933,56 @@ void PyFuncNode::executeRemote()
   for(int i=0;i<resultCorba->length();i++)
     resultCorbaC[i]=resultCorba[i];
 
-  gstate = PyGILState_Ensure();
-
-  PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
-  delete [] resultCorbaC;
-  args = PyTuple_New(1);
-  PyTuple_SetItem(args,0,resultPython);
-  PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
-  Py_DECREF(args);
-
-  DEBTRACE( "-----------------PythonNode::outputs-----------------" );
-  int nres=1;
-  if(finalResult == Py_None)
-    nres=0;
-  else if(PyTuple_Check(finalResult))
-    nres=PyTuple_Size(finalResult);
-
-  if(getNumberOfOutputPorts() != nres)
-    {
-      std::string msg="Number of output arguments : Mismatch between definition and execution";
-      Py_DECREF(finalResult);
-      PyGILState_Release(gstate);
-      _errorDetails=msg;
-      throw Exception(msg);
-    }
-
-  pos=0;
-  std::list<OutputPort *>::iterator iter;
-  try
-    {
-      for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
+  {
+      AutoGIL agil;
+
+      PyObject *resultPython(PyString_FromStringAndSize(resultCorbaC,resultCorba->length()));
+      delete [] resultCorbaC;
+      PyObject *args(PyTuple_New(1)),*ob(0);
+      PyTuple_SetItem(args,0,resultPython);
+      PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
+      Py_DECREF(args);
+
+      DEBTRACE( "-----------------PythonNode::outputs-----------------" );
+      int nres=1;
+      if(finalResult == Py_None)
+        nres=0;
+      else if(PyTuple_Check(finalResult))
+        nres=PyTuple_Size(finalResult);
+
+      if(getNumberOfOutputPorts() != nres)
         {
-          OutputPyPort *p=(OutputPyPort *)*iter;
-          DEBTRACE( "port name: " << p->getName() );
-          DEBTRACE( "port kind: " << p->edGetType()->kind() );
-          DEBTRACE( "port pos : " << pos );
-          if(PyTuple_Check(finalResult))
-            ob=PyTuple_GetItem(finalResult,pos) ;
-          else 
-            ob=finalResult;
-          DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
-          p->put(ob);
-          pos++;
+          std::string msg="Number of output arguments : Mismatch between definition and execution";
+          Py_DECREF(finalResult);
+          _errorDetails=msg;
+          throw Exception(msg);
         }
-      Py_DECREF(finalResult);
-    }
-  catch(ConversionException& ex)
-    {
-      Py_DECREF(finalResult);
-      PyGILState_Release(gstate);
-      _errorDetails=ex.what();
-      throw;
-    }
 
-  PyGILState_Release(gstate);
+      try
+      {
+          int pos(0);
+          for(std::list<OutputPort *>::iterator iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++, pos++)
+            {
+              OutputPyPort *p=(OutputPyPort *)*iter;
+              DEBTRACE( "port name: " << p->getName() );
+              DEBTRACE( "port kind: " << p->edGetType()->kind() );
+              DEBTRACE( "port pos : " << pos );
+              if(PyTuple_Check(finalResult))
+                ob=PyTuple_GetItem(finalResult,pos) ;
+              else
+                ob=finalResult;
+              DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
+              p->put(ob);
+            }
+          Py_DECREF(finalResult);
+      }
+      catch(ConversionException& ex)
+      {
+          Py_DECREF(finalResult);
+          _errorDetails=ex.what();
+          throw;
+      }
+  }
 
   DEBTRACE( "++++++++++++++ ENDOF PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
 }
@@ -942,117 +994,112 @@ void PyFuncNode::executeLocal()
   int pos=0;
   PyObject* ob;
   if(!_pyfunc)throw Exception("PyFuncNode badly loaded");
-  PyGILState_STATE gstate = PyGILState_Ensure();
-
-  DEBTRACE( "---------------PyFuncNode::inputs---------------" );
-  PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
-  list<InputPort *>::iterator iter2;
-  for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
-    {
-      InputPyPort *p=(InputPyPort *)*iter2;
-      DEBTRACE( "port name: " << p->getName() );
-      DEBTRACE( "port kind: " << p->edGetType()->kind() );
-      ob=p->getPyObj();
+  {
+      AutoGIL agil;
+      DEBTRACE( "---------------PyFuncNode::inputs---------------" );
+      PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
+      list<InputPort *>::iterator iter2;
+      for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
+        {
+          InputPyPort *p=(InputPyPort *)*iter2;
+          DEBTRACE( "port name: " << p->getName() );
+          DEBTRACE( "port kind: " << p->edGetType()->kind() );
+          ob=p->getPyObj();
 #ifdef _DEVDEBUG_
-      PyObject_Print(ob,stderr,Py_PRINT_RAW);
-      cerr << endl;
+          PyObject_Print(ob,stderr,Py_PRINT_RAW);
+          cerr << endl;
 #endif
-      DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
-      Py_INCREF(ob);
-      PyTuple_SetItem(args,pos,ob);
-      DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
-      pos++;
-    }
-  DEBTRACE( "---------------End PyFuncNode::inputs---------------" );
+          DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
+          Py_INCREF(ob);
+          PyTuple_SetItem(args,pos,ob);
+          DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
+          pos++;
+        }
+      DEBTRACE( "---------------End PyFuncNode::inputs---------------" );
 
-  DEBTRACE( "----------------PyFuncNode::calculation---------------" );
+      DEBTRACE( "----------------PyFuncNode::calculation---------------" );
 #ifdef _DEVDEBUG_
-  PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
-  cerr << endl;
-  PyObject_Print(args,stderr,Py_PRINT_RAW);
-  cerr << endl;
+      PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
+      cerr << endl;
+      PyObject_Print(args,stderr,Py_PRINT_RAW);
+      cerr << endl;
 #endif
-  DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
-  PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
-  DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
-  Py_DECREF(args);
-  fflush(stdout);
-  fflush(stderr);
-  if(result == NULL)
-    {
-      _errorDetails="";
-      PyObject* new_stderr = newPyStdOut(_errorDetails);
-      PySys_SetObject((char*)"stderr", new_stderr);
-      std::ostringstream stream;
-      stream << "/tmp/PythonNode_";
-      stream << getpid();
-      ofstream errorfile(stream.str().c_str());
-      if (errorfile.is_open())
+      DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
+      PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
+      DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
+      Py_DECREF(args);
+      fflush(stdout);
+      fflush(stderr);
+      if(result == NULL)
         {
-          errorfile << _script;
-          errorfile.close();
+          _errorDetails="";
+          PyObject* new_stderr = newPyStdOut(_errorDetails);
+          PySys_SetObject((char*)"stderr", new_stderr);
+          std::ostringstream stream;
+          stream << "/tmp/PythonNode_";
+          stream << getpid();
+          ofstream errorfile(stream.str().c_str());
+          if (errorfile.is_open())
+            {
+              errorfile << _script;
+              errorfile.close();
+            }
+          PyErr_Print();
+          PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
+          Py_DECREF(new_stderr);
+          throw Exception("Error during execution");
         }
-      PyErr_Print();
-      PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
-      Py_DECREF(new_stderr);
-
-      PyGILState_Release(gstate);
-      throw Exception("Error during execution");
-    }
-  DEBTRACE( "----------------End PyFuncNode::calculation---------------" );
+      DEBTRACE( "----------------End PyFuncNode::calculation---------------" );
 
-  DEBTRACE( "-----------------PyFuncNode::outputs-----------------" );
-  int nres=1;
-  if(result == Py_None)
-    nres=0;
-  else if(PyTuple_Check(result))
-    nres=PyTuple_Size(result);
+      DEBTRACE( "-----------------PyFuncNode::outputs-----------------" );
+      int nres=1;
+      if(result == Py_None)
+        nres=0;
+      else if(PyTuple_Check(result))
+        nres=PyTuple_Size(result);
 
-  if(getNumberOfOutputPorts() != nres)
-    {
-      std::string msg="Number of output arguments : Mismatch between definition and execution";
-      Py_DECREF(result);
-      PyGILState_Release(gstate);
-      _errorDetails=msg;
-      throw Exception(msg);
-    }
+      if(getNumberOfOutputPorts() != nres)
+        {
+          std::string msg="Number of output arguments : Mismatch between definition and execution";
+          Py_DECREF(result);
+          _errorDetails=msg;
+          throw Exception(msg);
+        }
 
-  pos=0;
+      pos=0;
 #ifdef _DEVDEBUG_
-  PyObject_Print(result,stderr,Py_PRINT_RAW);
-  cerr << endl;
+      PyObject_Print(result,stderr,Py_PRINT_RAW);
+      cerr << endl;
 #endif
-  list<OutputPort *>::iterator iter;
-  try
-    {
-      for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
-        {
-          OutputPyPort *p=(OutputPyPort *)*iter;
-          DEBTRACE( "port name: " << p->getName() );
-          DEBTRACE( "port kind: " << p->edGetType()->kind() );
-          DEBTRACE( "port pos : " << pos );
-          if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
-          else ob=result;
-          DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
+      list<OutputPort *>::iterator iter;
+      try
+      {
+          for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
+            {
+              OutputPyPort *p=(OutputPyPort *)*iter;
+              DEBTRACE( "port name: " << p->getName() );
+              DEBTRACE( "port kind: " << p->edGetType()->kind() );
+              DEBTRACE( "port pos : " << pos );
+              if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
+              else ob=result;
+              DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
 #ifdef _DEVDEBUG_
-          PyObject_Print(ob,stderr,Py_PRINT_RAW);
-          cerr << endl;
+              PyObject_Print(ob,stderr,Py_PRINT_RAW);
+              cerr << endl;
 #endif
-          p->put(ob);
-          pos++;
-        }
-    }
-  catch(ConversionException& ex)
-    {
+              p->put(ob);
+              pos++;
+            }
+      }
+      catch(ConversionException& ex)
+      {
+          Py_DECREF(result);
+          _errorDetails=ex.what();
+          throw;
+      }
+      DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" );
       Py_DECREF(result);
-      PyGILState_Release(gstate);
-      _errorDetails=ex.what();
-      throw;
-    }
-  DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" );
-
-  Py_DECREF(result);
-  PyGILState_Release(gstate);
+  }
   DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
 }
 
@@ -1061,6 +1108,41 @@ Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const
   return new PyFuncNode(*this,father);
 }
 
+void PyFuncNode::createRemoteAdaptedPyInterpretor(Engines::Container_ptr objContainer)
+{
+  if(!CORBA::is_nil(_pynode))
+    _pynode->UnRegister();
+  _pynode=objContainer->createPyNode(getName().c_str(),getScript().c_str());
+}
+
+Engines::PyNodeBase_var PyFuncNode::retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const
+{
+  Engines::PyNode_var ret(objContainer->getDefaultPyNode());
+  if(!CORBA::is_nil(ret))
+    {
+      ret->Register();
+    }
+  return Engines::PyNodeBase::_narrow(ret);
+}
+
+void PyFuncNode::assignRemotePyInterpretor(Engines::PyNodeBase_var remoteInterp)
+{
+  if(!CORBA::is_nil(_pynode))
+    {
+      Engines::PyNode_var tmpp(Engines::PyNode::_narrow(remoteInterp));
+      if(_pynode->_is_equivalent(tmpp))
+        return ;
+    }
+  if(!CORBA::is_nil(_pynode))
+    _pynode->UnRegister();
+  _pynode=Engines::PyNode::_narrow(remoteInterp);
+}
+
+Engines::PyNodeBase_var PyFuncNode::getRemoteInterpreterHandle()
+{
+  return Engines::PyNodeBase::_narrow(_pynode);
+}
+
 //! Create a new node of same type with a given name
 PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
 {
@@ -1084,23 +1166,7 @@ PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
 
 std::string PyFuncNode::getContainerLog()
 {
-  if(_mode=="local")return "";
-
-  std::string msg;
-  try
-    {
-      Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
-      CORBA::String_var logname = objContainer->logfilename();
-      DEBTRACE(logname);
-      msg=logname;
-      std::string::size_type pos = msg.find(":");
-      msg=msg.substr(pos+1);
-    }
-  catch(...)
-    {
-      msg = "Container no longer reachable";
-    }
-  return msg;
+  return PythonEntry::GetContainerLog(_mode,_container,this);
 }
 
 void PyFuncNode::shutdown(int level)
index 863961579695a05d68af47b97a501e49fd7eb8ce..c54232f2b0008dd278dc41bfcc68080183500752 100644 (file)
@@ -24,6 +24,7 @@
 #include "InlineNode.hxx"
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SALOME_PyNode)
+#include CORBA_CLIENT_HEADER(SALOME_Component)
 
 #include <Python.h>
 
@@ -31,10 +32,40 @@ namespace YACS
 {
   namespace ENGINE
   {
-    class YACSRUNTIMESALOME_EXPORT PythonNode : public InlineNode 
+    class YACSRUNTIMESALOME_EXPORT PythonEntry
+    {
+    protected:
+      PythonEntry();
+      ~PythonEntry();
+      virtual void assignRemotePyInterpretor(Engines::PyNodeBase_var remoteInterp) = 0;
+      //! returns (if any) an object, you have to deal with (UnRegister)
+      virtual Engines::PyNodeBase_var retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const = 0;
+      //! returns an object, you have to deal with (UnRegister)
+      virtual void createRemoteAdaptedPyInterpretor(Engines::Container_ptr objContainer) = 0;
+      virtual Engines::PyNodeBase_var getRemoteInterpreterHandle() = 0;
+      virtual const char *getSerializationScript() const = 0;
+      //
+      void commonRemoteLoad(InlineNode *reqNode);
+      void commonRemoteLoadPart1(InlineNode *reqNode);
+      Engines::Container_var commonRemoteLoadPart2(InlineNode *reqNode, bool& isInitializeRequested);
+      void commonRemoteLoadPart3(InlineNode *reqNode, Engines::Container_ptr objContainer, bool isInitializeRequested);
+      static std::string GetContainerLog(const std::string& mode, Container *container, const Task *askingTask);
+    protected:
+      PyObject *_context;
+      PyObject *_pyfuncSer;
+      PyObject *_pyfuncUnser;
+    };
+
+    class YACSRUNTIMESALOME_EXPORT PythonNode : public InlineNode, public PythonEntry
     {
     protected:
       Node *simpleClone(ComposedNode *father, bool editionOnly) const;
+      // overload part of PythonEntry
+      void createRemoteAdaptedPyInterpretor(Engines::Container_ptr objContainer);
+      Engines::PyNodeBase_var retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const;
+      void assignRemotePyInterpretor(Engines::PyNodeBase_var remoteInterp);
+      Engines::PyNodeBase_var getRemoteInterpreterHandle();
+      const char *getSerializationScript() const  { return SCRIPT_FOR_SERIALIZATION; }
     public:
       PythonNode(const PythonNode& other, ComposedNode *father);
       PythonNode(const std::string& name);
@@ -49,20 +80,25 @@ namespace YACS
       virtual void shutdown(int level);
       std::string getContainerLog();
       PythonNode* cloneNode(const std::string& name);
+      virtual std::string typeName() { return "YACS__ENGINE__PythonNode"; }
+    public:
       static const char KIND[];
       static const char IMPL_NAME[];
-      virtual std::string typeName() {return "YACS__ENGINE__PythonNode";}
+      static const char SCRIPT_FOR_SERIALIZATION[];
     protected:
-      PyObject* _context;
-      PyObject* _pyfuncSer;
-      PyObject* _pyfuncUnser;
       Engines::PyScriptNode_var _pynode;
     };
 
-    class PyFuncNode : public InlineFuncNode 
+    class PyFuncNode : public InlineFuncNode, public PythonEntry
     {
     protected:
       Node *simpleClone(ComposedNode *father, bool editionOnly) const;
+      // overload part of PythonEntry
+      void createRemoteAdaptedPyInterpretor(Engines::Container_ptr objContainer);Engines::
+      PyNodeBase_var retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const;
+      void assignRemotePyInterpretor(Engines::PyNodeBase_var remoteInterp);
+      Engines::PyNodeBase_var getRemoteInterpreterHandle();
+      const char *getSerializationScript() const { return SCRIPT_FOR_SERIALIZATION; }
     public:
       PyFuncNode(const PyFuncNode& other, ComposedNode *father);
       PyFuncNode(const std::string& name);
@@ -77,12 +113,11 @@ namespace YACS
       virtual void shutdown(int level);
       std::string getContainerLog();
       PyFuncNode* cloneNode(const std::string& name);
-      virtual std::string typeName() {return "YACS__ENGINE__PyFuncNode";}
+      virtual std::string typeName() { return "YACS__ENGINE__PyFuncNode"; }
+    public:
+      static const char SCRIPT_FOR_SERIALIZATION[];
     protected:
-      PyObject* _context;
       PyObject* _pyfunc;
-      PyObject* _pyfuncSer;
-      PyObject* _pyfuncUnser;
       Engines::PyNode_var _pynode;
     };
   }
index da74e14ca31396bc5da1f979dabe445071f8007b..58e5e8e504cc69a5066ac71237fdc590d02c295c 100644 (file)
 //Components
 #include "CORBAComponent.hxx"
 #include "SalomeComponent.hxx"
+#include "SalomeHPComponent.hxx"
 #include "SalomePythonComponent.hxx"
 #include "CppComponent.hxx"
 
 #include "SalomeContainer.hxx"
 #include "CppContainer.hxx"
+#include "SalomeHPContainer.hxx"
 
 //Nodes
 #include "PythonNode.hxx"
@@ -587,15 +589,19 @@ ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& nam
     return new SalomePythonComponent(name);
   else if (kind == CppComponent::KIND)
     return new CppComponent(name);
+  else if (kind == SalomeHPComponent::KIND)
+    return new SalomeHPComponent(name);
   std::string msg="Component Instance kind ("+kind+") unknown";
   throw Exception(msg);
 }
 
 Container *RuntimeSALOME::createContainer(const std::string& kind)
 {
-  if(kind == "" || kind == SalomeComponent::KIND)
+  if(kind == "" || kind == SalomeContainer::KIND)
     return new SalomeContainer;
-  else if (kind == CppComponent::KIND)
+  if(kind==SalomeHPContainer::KIND)
+    return new SalomeHPContainer;
+  else if (kind == CppContainer::KIND)
     return new CppContainer;
   std::string msg="Container kind ("+kind+") unknown";
   throw Exception(msg);
index ad344b9f9c27243c9c8f08a26b396c6ef69c53be..9721d87efaa982cf53a5bb511f950027d982769f 100644 (file)
@@ -20,7 +20,9 @@
 #include "RuntimeSALOME.hxx"
 #include "SalomeComponent.hxx"
 #include "SalomeContainer.hxx"
+#include "SalomeHPContainer.hxx"
 #include "CORBANode.hxx"
+#include "AutoLocker.hxx"
 
 #ifdef SALOME_KERNEL
 #include "SALOME_NamingService.hxx"
@@ -60,15 +62,20 @@ std::string SalomeComponent::getKind() const
   return KIND;
 }
 
+std::string SalomeComponent::getKindForNode() const
+{
+  return KIND;
+}
+
 //! Unload the component 
-void SalomeComponent::unload()
+void SalomeComponent::unload(Task *askingNode)
 {
   //Not implemented
   std::cerr << "SalomeComponent::unload : not implemented " << std::endl;
 }
 
 //! Is the component instance already loaded ?
-bool SalomeComponent::isLoaded()
+bool SalomeComponent::isLoaded(Task *askingNode) const
 {
   if(CORBA::is_nil(_objComponent))
     return false;
@@ -76,14 +83,19 @@ bool SalomeComponent::isLoaded()
     return true;
 }
 
-#ifdef SALOME_KERNEL
+//#ifdef SALOME_KERNEL
 //! Load the component 
-void SalomeComponent::load()
+void SalomeComponent::load(Task *askingNode)
 {
   if(_container)
     {
-      _objComponent=((SalomeContainer*)_container)->loadComponent(this);
-      return;
+      SalomeContainer *salomeContainer(dynamic_cast<SalomeContainer *>(_container));
+      if(salomeContainer)
+        {
+          _objComponent=salomeContainer->loadComponent(askingNode);
+          return ;
+        }
+      throw Exception("Unrecognized type of Container ! Only Salome are supported by the Salome components !");
     }
   //throw Exception("SalomeComponent::load : no container specified !!! To be implemented in executor to allocate default a Container in case of presenceOfDefaultContainer.");
   //This component has no specified container : use default container policy
@@ -95,12 +107,12 @@ void SalomeComponent::load()
   params.container_name ="FactoryServer";
   _objComponent=LCC.LoadComponent(params,_compoName.c_str());
 }
-#else
-void SalomeComponent::load()
+/*#else
+void SalomeComponent::load(Task *askingNode)
 {
   throw Exception("YACS has been built without SALOME support");
 }
-#endif
+#endif*/
 
 //! Create a ServiceNode with this component instance and no input or output port
 /*!
@@ -126,6 +138,11 @@ ComponentInstance* SalomeComponent::clone() const
     return new SalomeComponent(*this);
 }
 
+ComponentInstance *SalomeComponent::cloneAlways() const
+{
+  return new SalomeComponent(*this);
+}
+
 std::string SalomeComponent::getFileRepr() const
 {
   ostringstream stream;
@@ -133,21 +150,18 @@ std::string SalomeComponent::getFileRepr() const
   return stream.str();
 }
 
-void SalomeComponent::setContainer(Container *cont)
+bool SalomeComponent::setContainer(Container *cont)
 {
-  if (cont == _container) return;
-
-  if(cont)
-    cont->checkCapabilityToDealWith(this);
-
-  if(_container)
-    _container->decrRef();
-  _container=cont;
-  if(_container)
-  {
-    _container->incrRef();
-    ((SalomeContainer*)_container)->addComponentName(_compoName);
-  }
+  if(!dynamic_cast<SalomeContainer *>(cont))
+    throw Exception("SalomeComponent::setContainer : a Salome component must be attached to a Salome container !");
+  if(ComponentInstance::setContainer(cont))
+    {
+      if(_container)
+        _container->addComponentName(_compoName);
+      return true;
+    }
+  else
+    return false;
 }
 
 void SalomeComponent::shutdown(int level)
index 9b76ea7c164eca98e66b3a8185e2af11fd33ca0a..e812f87627b27ce6d8a0044ab441c66e7d859fbc 100644 (file)
@@ -28,8 +28,6 @@ namespace YACS
 {
   namespace ENGINE
   {
-    class ServiceNode;
-
 /*! \brief Class for Salome component instance
  *
  *
@@ -40,18 +38,20 @@ namespace YACS
       SalomeComponent(const std::string& name);
       SalomeComponent(const SalomeComponent& other);
       virtual ~SalomeComponent();
-      virtual void load();
-      virtual void unload();
-      virtual bool isLoaded();
-      virtual void setContainer(Container *cont);
+      virtual void load(Task *askingNode);
+      virtual void unload(Task *askingNode);
+      virtual bool isLoaded(Task *askingNode) const;
+      virtual bool setContainer(Container *cont);
       virtual ServiceNode* createNode(const std::string& name);
       virtual ComponentInstance* clone() const;
+      virtual ComponentInstance* cloneAlways() const;
       virtual std::string getFileRepr() const;
       virtual CORBA::Object_ptr getCompoPtr(){return CORBA::Object::_duplicate(_objComponent);}
       virtual void shutdown(int level);
     public:
       static const char KIND[];
       virtual std::string getKind() const;
+      virtual std::string getKindForNode() const;
     protected:
       CORBA::Object_var _objComponent;
     };
index dfd755035f80f8afe0d2460623b07f2a2b355e11..38b4d5709c4231ebd88a66140d97409f084e44f8 100644 (file)
@@ -29,6 +29,7 @@
 #include "RuntimeSALOME.hxx"
 #include "SalomeContainer.hxx"
 #include "SalomeComponent.hxx"
+#include "ServiceNode.hxx"
 #include "Proc.hxx"
 
 #include "SALOME_NamingService.hxx"
 using namespace YACS::ENGINE;
 using namespace std;
 
-SalomeContainer::SalomeContainer():_trueCont(Engines::Container::_nil()),_type("mono"),_shutdownLevel(999)
+const char SalomeContainer::KIND[]="Salome";
+
+const char SalomeContainer::TYPE_PROPERTY_STR[]="type";
+
+SalomeContainer::SalomeContainer():_launchModeType(new SalomeContainerMonoHelper),_shutdownLevel(999)
 {
-  /* Init ContainerParameters */
-  SALOME_LifeCycleCORBA::preSet(_params);
-  _params.mode= "start";
 }
 
 SalomeContainer::SalomeContainer(const SalomeContainer& other)
-: Container(other),
-  _trueCont(Engines::Container::_nil()),
-  _type(other._type),
+: Container(other),_componentNames(other._componentNames),
+  _launchModeType(other._launchModeType->deepCpyOnlyStaticInfo()),
   _shutdownLevel(other._shutdownLevel),
-  _params(other._params)
+  _sct(other._sct)
+{
+}
+
+SalomeContainer::SalomeContainer(const Container& other, const SalomeContainerTools& sct, const SalomeContainerHelper *lmt,
+                                 const std::vector<std::string>& componentNames, int shutdownLev):Container(other),_componentNames(componentNames),
+                                     _launchModeType(const_cast<SalomeContainerHelper *>(lmt)),_shutdownLevel(shutdownLev),_sct(sct)
 {
+  if(lmt)
+    lmt->incrRef();
 }
 
 SalomeContainer::~SalomeContainer()
 {
+  _launchModeType->decrRef();
 }
 
 void SalomeContainer::lock()
@@ -78,7 +88,12 @@ void SalomeContainer::lock()
 
 void SalomeContainer::unLock()
 {
-  _mutex.unlock();
+  _mutex.unLock();
+}
+
+std::string SalomeContainer::getKind() const
+{
+  return KIND;
 }
 
 Container *SalomeContainer::clone() const
@@ -92,6 +107,11 @@ Container *SalomeContainer::clone() const
     return new SalomeContainer(*this);
 }
 
+Container *SalomeContainer::cloneAlways() const
+{
+  return new SalomeContainer(*this);
+}
+
 void SalomeContainer::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception)
 {
   if(inst->getKind()!=SalomeComponent::KIND)
@@ -100,228 +120,66 @@ void SalomeContainer::checkCapabilityToDealWith(const ComponentInstance *inst) c
 
 void SalomeContainer::setProperty(const std::string& name, const std::string& value)
 {
-  DEBTRACE("SalomeContainer::setProperty : " << name << " ; " << value);
-   
-  // Container Part
-  if (name == "container_name")
-    _params.container_name = CORBA::string_dup(value.c_str());
-  else if (name == "type")
-  {
-    if (value == "mono")
-      _params.mode = "start";
-    else if (value == "multi")
-      _params.mode = "getorstart";
-    else 
-      throw Exception("SalomeContainer::setProperty : type value is not correct (mono or multi): " + value);
-    _type=value;
-  }
-  else if (name == "workingdir")
-    _params.workingdir = CORBA::string_dup(value.c_str());
-  else if (name == "nb_parallel_procs")
-  {
-    std::istringstream iss(value);
-    if (!(iss >> _params.nb_proc))
-      throw Exception("salomecontainer::setproperty : params.nb_proc value not correct : " + value);
-  }
-  else if (name == "isMPI")
-  {
-    if (value == "true")
-      _params.isMPI = true;
-    else if (value == "false")
-      _params.isMPI = false;
-    else 
-      throw Exception("SalomeContainer::setProperty : params.isMPI value not correct : " + value);
-  }
-  else if (name == "parallelLib")
-    _params.parallelLib = CORBA::string_dup(value.c_str());
-
-  // Resource part
-  else if (name == "name")
-    _params.resource_params.name = CORBA::string_dup(value.c_str());
-  else if (name == "hostname")
-    _params.resource_params.hostname = CORBA::string_dup(value.c_str());
-  else if (name == "OS")
-    _params.resource_params.OS = CORBA::string_dup(value.c_str());
-  else if (name == "nb_resource_procs")
-  {
-    std::istringstream iss(value);
-    if (!(iss >> _params.resource_params.nb_proc))
-      throw Exception("salomecontainer::setproperty : params.resource_params.nb_proc value not correct : " + value);
-  }
-  else if (name == "mem_mb")
-  {
-    std::istringstream iss(value);
-    if (!(iss >> _params.resource_params.mem_mb))
-      throw Exception("salomecontainer::setproperty : params.resource_params.mem_mb value not correct : " + value);
-  }
-  else if (name == "cpu_clock")
-  {
-    std::istringstream iss(value);
-    if (!(iss >> _params.resource_params.cpu_clock))
-      throw Exception("salomecontainer::setproperty : params.resource_params.cpu_clock value not correct : " + value);
-  }
-  else if (name == "nb_node")
-  {
-    std::istringstream iss(value);
-    if (!(iss >> _params.resource_params.nb_node))
-      throw Exception("salomecontainer::setproperty : params.nb_node value not correct : " + value);
-  }
-  else if (name == "nb_proc_per_node")
-  {
-    std::istringstream iss(value);
-    if (!(iss >> _params.resource_params.nb_proc_per_node))
-      throw Exception("salomecontainer::setproperty : params.nb_proc_per_node value not correct : " + value);
-  }
-  else if (name == "policy")
-    _params.resource_params.policy = CORBA::string_dup(value.c_str());
-  else if (name == "component_list")
-  {
-    std::string clean_value(value);
-
-    // Step 1: remove blanks
-    while(clean_value.find(" ") != std::string::npos)
-      clean_value = clean_value.erase(clean_value.find(" "), 1);
-
-    // Step 2: get values
-    while(!clean_value.empty())
+  if (name == AOC_ENTRY)
+    {
+      std::istringstream iss(value);
+      int val;
+      iss >> val;
+      setAttachOnCloningStatus((bool)val);
+    }
+  else if (name == TYPE_PROPERTY_STR)
     {
-      std::string result("");
-      std::string::size_type loc = clean_value.find(",", 0);
-      if (loc != std::string::npos)
-      {
-        result = clean_value.substr(0, loc);
-        clean_value = clean_value.erase(0, loc+1);
-      }
+      if (value == SalomeContainerMonoHelper::TYPE_NAME)
+        {
+          _launchModeType->decrRef();
+          _launchModeType=new SalomeContainerMonoHelper;
+        }
+      else if (value == SalomeContainerMultiHelper::TYPE_NAME)
+        {
+          _launchModeType->decrRef();
+          _launchModeType=new SalomeContainerMultiHelper;
+        }
       else
-      {
-        result = clean_value;
-        clean_value.erase();
-      }
-      if (result != "," && result != "")
-      {
-        addToComponentList(result);
-      }
+        throw Exception("SalomeContainer::setProperty : type value is not correct (mono or multi): " + value);
     }
+  _sct.setProperty(name,value);
+}
 
-  }
-  else if (name == "resource_list")
-  {
-    std::string clean_value(value);
-
-    // Step 1: remove blanks
-    while(clean_value.find(" ") != std::string::npos)
-      clean_value = clean_value.erase(clean_value.find(" "), 1);
-
-    // Step 2: get values
-    while(!clean_value.empty())
+std::string SalomeContainer::getProperty(const std::string& name) const
+{
+  if (name == TYPE_PROPERTY_STR)
+    return _launchModeType->getType();
+  if (name==AOC_ENTRY)
     {
-      std::string result("");
-      std::string::size_type loc = clean_value.find(",", 0);
-      if (loc != std::string::npos)
-      {
-        result = clean_value.substr(0, loc);
-        clean_value = clean_value.erase(0, loc+1);
-      }
-      else
-      {
-        result = clean_value;
-        clean_value.erase();
-      }
-      if (result != "," && result != "")
-      {
-        addToResourceList(result);
-      }
+      int reti(_isAttachedOnCloning);
+      std::ostringstream oss; oss << reti;
+      return oss.str();
     }
+  return _sct.getProperty(name);
+}
 
-  }
-  // End
-  Container::setProperty(name, value);
+void SalomeContainer::clearProperties()
+{
+  _sct.clearProperties();
 }
 
-void SalomeContainer::addComponentName(std::string name)
+void SalomeContainer::addComponentName(const std::string& name)
 {
   _componentNames.push_back(name);
 }
 
+void SalomeContainer::addToResourceList(const std::string& name)
+{
+  _sct.addToResourceList(name);
+}
+
 //! Load a component instance in this container
 /*!
  * \param inst the component instance to load
  */
-CORBA::Object_ptr SalomeContainer::loadComponent(ComponentInstance *inst)
+CORBA::Object_ptr SalomeContainer::loadComponent(Task *askingNode)
 {
-  DEBTRACE("SalomeContainer::loadComponent ");
-  lock();//To be sure
-  if(!isAlreadyStarted(inst))
-    {
-      try
-        {
-          start(inst);
-        }
-      catch(Exception& e)
-        {
-          unLock();
-          throw e;
-        }
-    }
-  unLock();
-  lock();//To be sure
-  CORBA::Object_ptr objComponent=CORBA::Object::_nil();
-  std::string compoName=inst->getCompoName();
-  const char* componentName=compoName.c_str();
-  Engines::Container_var container;
-  if(_type=="multi")
-    container=_trueContainers[inst];
-  else
-    container=_trueCont;
-
-  char* reason;
-
-  bool isLoadable = container->load_component_Library(componentName, reason);
-  if (isLoadable)
-    {
-      CORBA::string_free(reason);
-      int studyid=1;
-      Proc* p=getProc();
-      if(p)
-        {
-          std::string value=p->getProperty("DefaultStudyID");
-          if(!value.empty())
-            studyid= atoi(value.c_str());
-        }
-      // prepare component instance properties
-      Engines::FieldsDict_var env = new Engines::FieldsDict;
-      std::map<std::string, std::string> properties = inst->getProperties();
-      if(p)
-        {
-          std::map<std::string,std::string> procMap=p->getProperties();
-          properties.insert(procMap.begin(),procMap.end());
-        }
-
-      std::map<std::string, std::string>::const_iterator itm;
-      env->length(properties.size());
-      int item=0;
-      for(itm = properties.begin(); itm != properties.end(); ++itm, item++)
-        {
-          DEBTRACE("envname="<<itm->first<<" envvalue="<< itm->second);
-          env[item].key= CORBA::string_dup(itm->first.c_str());
-          env[item].value <<= itm->second.c_str();
-        }
-
-      objComponent=container->create_component_instance_env(componentName, studyid, env, reason);
-    }
-
-  if(CORBA::is_nil(objComponent))
-    {
-      unLock();
-      std::string text="Error while trying to create a new component: component '"+ compoName;
-      text=text+"' is not installed or it's a wrong name";
-      text += '\n';
-      text += reason;
-      CORBA::string_free(reason);
-      throw Exception(text);
-    }
-  unLock();
-  return objComponent;
+  return SalomeContainerTools::LoadComponent(_launchModeType,this,askingNode);
 }
 
 //! Get the container placement id for a component instance
@@ -329,30 +187,9 @@ CORBA::Object_ptr SalomeContainer::loadComponent(ComponentInstance *inst)
  * \param inst the component instance
  * \return the placement id
  */
-std::string SalomeContainer::getPlacementId(const ComponentInstance *inst) const
+std::string SalomeContainer::getPlacementId(const Task *askingNode) const
 {
-
-  if(isAlreadyStarted(inst))
-    {
-      Engines::Container_var container=_trueCont;
-      if(_type=="multi")
-        {
-          std::map<const ComponentInstance *, Engines::Container_var>::const_iterator found = _trueContainers.find(inst);
-          container=found->second;
-        }
-      const char *what="/";
-      CORBA::String_var corbaStr=container->name();
-      string ret(corbaStr);
-
-      //Salome FOREVER ...
-      std::string::size_type i=ret.find_first_of(what,0);
-      i=ret.find_first_of(what, i==std::string::npos ? i:i+1);
-      if(i!=std::string::npos)
-        return ret.substr(i+1);
-      return ret;
-    }
-  else
-    return "Not placed yet !!!";
+  return SalomeContainerTools::GetPlacementId(_launchModeType,this,askingNode);
 }
 
 //! Get the container full path for a component instance
@@ -360,30 +197,9 @@ std::string SalomeContainer::getPlacementId(const ComponentInstance *inst) const
  * \param inst the component instance
  * \return the full placement id
  */
-std::string SalomeContainer::getFullPlacementId(const ComponentInstance *inst) const
+std::string SalomeContainer::getFullPlacementId(const Task *askingNode) const
 {
-
-  if(isAlreadyStarted(inst))
-    {
-      Engines::Container_var container=_trueCont;
-      if(_type=="multi")
-        {
-          std::map<const ComponentInstance *, Engines::Container_var>::const_iterator found = _trueContainers.find(inst);
-          container=found->second;
-        }
-      try
-        {
-          CORBA::String_var corbaStr=container->name();
-          string ret(corbaStr);
-          return ret;
-        }
-      catch(...)
-        {
-          return "Unknown_placement";
-        }
-    }
-  else
-    return "Not_placed_yet";
+  return SalomeContainerTools::GetFullPlacementId(_launchModeType,this,askingNode);
 }
 
 //! Check if the component instance container is already started
@@ -391,174 +207,23 @@ std::string SalomeContainer::getFullPlacementId(const ComponentInstance *inst) c
  * \param inst the component instance
  * \return true, if the container is already started, else false
  */
-bool SalomeContainer::isAlreadyStarted(const ComponentInstance *inst) const
+bool SalomeContainer::isAlreadyStarted(const Task *askingNode) const
 {
-  if(_type=="mono")
-    {
-      if(CORBA::is_nil(_trueCont))
-        return false;
-      else
-        return true;
-    }
-  else
-    {
-      if(_trueContainers.count(inst)==0)
-        return false;
-      else
-        return true;
-    }
+  return _launchModeType->isAlreadyStarted(askingNode);
 }
 
-Engines::Container_ptr SalomeContainer::getContainerPtr(const ComponentInstance *inst) const
+Engines::Container_ptr SalomeContainer::getContainerPtr(const Task *askingNode) const
 {
-  if(_type=="mono")
-    {
-      if(CORBA::is_nil(_trueCont))
-        return Engines::Container::_nil();
-      else
-        return Engines::Container::_duplicate(_trueCont);
-    }
-  else
-    {
-      if(_trueContainers.count(inst)==0)
-        return Engines::Container::_nil();
-      else
-        {
-          std::map<const ComponentInstance *,Engines::Container_var>::const_iterator iter=_trueContainers.find(inst);
-          return Engines::Container::_duplicate(iter->second);
-        }
-    }
+  return Engines::Container::_duplicate(_launchModeType->getContainer(askingNode));
 }
 
 //! Start a salome container (true salome container not yacs one) with given ContainerParameters (_params)
 /*!
  * \param inst the component instance
  */
-void SalomeContainer::start(const ComponentInstance *inst) throw(YACS::Exception)
+void SalomeContainer::start(const Task *askingNode) throw(YACS::Exception)
 {
-  CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
-  SALOME_NamingService ns;
-  try
-    {
-      ns.init_orb(orb);
-    }
-  catch(SALOME_Exception& e)
-    {
-      throw Exception("SalomeContainer::start : Unable to contact the SALOME Naming Service");
-    }
-  CORBA::Object_var obj=ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS);
-  Engines::ContainerManager_var contManager=Engines::ContainerManager::_narrow(obj);
-
-  std::string str(_params.container_name);
-  DEBTRACE("SalomeContainer::start " << str <<";"<<_params.resource_params.hostname <<";"<<_type);
-
-  // Finalize parameters with components found in the container
-  std::vector<std::string>::iterator iter;
-  for(CORBA::ULong i=0; i < _componentNames.size();i++)
-    addToComponentList(_componentNames[i]);
-  Engines::ContainerParameters myparams = _params;
-
-  bool namedContainer=false;
-  if(str != "")
-    namedContainer=true;
-
-  //If a container_name is given try to find an already existing container in naming service
-  //If not found start a new container with the given parameters
-  if (_type=="mono" && str != "")
-    {
-      myparams.mode="getorstart";
-    }
-
-  if (str == "")
-  {
-    //give a almost unique name to the container : Pid_Name_Addr
-    std::ostringstream stream;
-    stream << getpid();
-    stream << "_";
-    stream << _name;
-    stream << "_";
-    stream << (void *)(this);
-    DEBTRACE("container_name="<<stream.str());
-    myparams.container_name=CORBA::string_dup(stream.str().c_str());
-    _shutdownLevel=1;
-  }
-
-  _trueCont=Engines::Container::_nil();
-  if(namedContainer && _shutdownLevel==999)
-    {
-      //Make this only the first time start is called (_shutdownLevel==999)
-      //If the container is named, first try to get an existing container
-      //If there is an existing container use it and set the shutdown level to 3
-      //If there is no existing container, try to launch a new one and set the shutdown level to 2
-      myparams.mode="get";
-      try
-        { 
-          _trueCont=contManager->GiveContainer(myparams);
-        }
-      catch( const SALOME::SALOME_Exception& ex )
-        {
-          std::string msg="SalomeContainer::start : no existing container : ";
-          msg += '\n';
-          msg += ex.details.text.in();
-          DEBTRACE( msg );
-        }
-      catch(...)
-        {
-        }
-
-      if(!CORBA::is_nil(_trueCont))
-        {
-          _shutdownLevel=3;
-          DEBTRACE( "container found: " << str << " " << _shutdownLevel );
-        }
-      else
-        {
-          _shutdownLevel=2;
-          myparams.mode="start";
-          DEBTRACE( "container not found: " << str << " " << _shutdownLevel);
-        }
-    }
-
-  if(CORBA::is_nil(_trueCont))
-    try
-      { 
-        // --- GiveContainer is used in batch mode to retreive launched containers,
-        //     and is equivalent to StartContainer when not in batch.
-        _trueCont=contManager->GiveContainer(myparams);
-      }
-    catch( const SALOME::SALOME_Exception& ex )
-      {
-        std::string msg="SalomeContainer::start : Unable to launch container in Salome : ";
-        msg += '\n';
-        msg += ex.details.text.in();
-        throw Exception(msg);
-      }
-    catch(CORBA::COMM_FAILURE&)
-      {
-        throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected");
-      }
-    catch(CORBA::Exception&)
-      {
-        throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected");
-      }
-
-  if(CORBA::is_nil(_trueCont))
-    throw Exception("SalomeContainer::start : Unable to launch container in Salome. Check your CatalogResources.xml file");
-
-  _trueContainers[inst]=_trueCont;
-
-  CORBA::String_var containerName=_trueCont->name();
-  CORBA::String_var hostName=_trueCont->getHostName();
-  std::cerr << "SalomeContainer launched : " << containerName << " " << hostName << " " << _trueCont->getPID() << std::endl;
-
-#ifdef REFCNT
-    DEBTRACE(_trueCont->_PR_getobj()->pd_refCount );
-    std::map<const ComponentInstance *, Engines::Container_var >::const_iterator it;
-    for(it = _trueContainers.begin(); it != _trueContainers.end(); ++it)
-      {
-        DEBTRACE(it->second->_PR_getobj()->pd_refCount );
-      }
-#endif
+  SalomeContainerTools::Start(_componentNames,_launchModeType,_sct,_shutdownLevel,this,askingNode);
 }
 
 void SalomeContainer::shutdown(int level)
@@ -569,117 +234,15 @@ void SalomeContainer::shutdown(int level)
 
   _shutdownLevel=999;
   //shutdown the SALOME containers
-  if(_type=="multi")
-    {
-      std::map<const ComponentInstance *, Engines::Container_var >::const_iterator it;
-      for(it = _trueContainers.begin(); it != _trueContainers.end(); ++it)
-        {
-          try
-            {
-              DEBTRACE("shutdown SALOME container: " );
-              CORBA::String_var containerName=it->second->name();
-              DEBTRACE(containerName);
-              it->second->Shutdown();
-              std::cerr << "shutdown SALOME container: " << containerName << std::endl;
-            }
-          catch(CORBA::Exception&)
-            {
-              DEBTRACE("Unexpected CORBA failure detected." );
-            }
-          catch(...)
-            {
-              DEBTRACE("Unknown exception ignored." );
-            }
-        }
-      _trueContainers.clear();
-    }
-  else
-    {
-      try
-        {
-          DEBTRACE("shutdown SALOME container: " );
-          CORBA::String_var containerName=_trueCont->name();
-          DEBTRACE(containerName);
-          _trueCont->Shutdown();
-          std::cerr << "shutdown SALOME container: " << containerName << std::endl;
-        }
-      catch(...)
-        {
-          DEBTRACE("Unknown exception ignored." );
-        }
-      _trueCont=Engines::Container::_nil();
-    }
-}
-
-void
-SalomeContainer::addToComponentList(const std::string & name)
-{
-  // Search if name is already in the list
-  for (CORBA::ULong i = 0; i < _params.resource_params.componentList.length(); i++)
-  {
-    std::string component_name = _params.resource_params.componentList[i].in();
-    if (component_name == name)
-      return;
-  }
-
-  // Add name to list
-  CORBA::ULong lgth = _params.resource_params.componentList.length();
-  _params.resource_params.componentList.length(lgth + 1);
-  _params.resource_params.componentList[lgth] = CORBA::string_dup(name.c_str());
+  _launchModeType->shutdown();
 }
 
-void
-SalomeContainer::addToResourceList(const std::string & name)
+std::map<std::string,std::string> SalomeContainer::getResourceProperties(const std::string& name) const
 {
-  // Search if name is already in the list
-  for (CORBA::ULong i = 0; i < _params.resource_params.resList.length(); i++)
-  {
-    std::string component_name = _params.resource_params.resList[i].in();
-    if (component_name == name)
-      return;
-  }
-
-  // Add name to list
-  CORBA::ULong lgth = _params.resource_params.resList.length();
-  _params.resource_params.resList.length(lgth + 1);
-  _params.resource_params.resList[lgth] = CORBA::string_dup(name.c_str());
+  return _sct.getResourceProperties(name);
 }
 
-std::map<std::string,std::string> SalomeContainer::getResourceProperties(const std::string& name)
+std::map<std::string,std::string> SalomeContainer::getProperties() const
 {
-  std::map<std::string,std::string> properties;
-
-  YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
-  CORBA::ORB_ptr orb = runTime->getOrb();
-  if (!orb) return properties;
-  SALOME_NamingService namingService(orb);
-  SALOME_LifeCycleCORBA lcc(&namingService);
-  CORBA::Object_var obj = namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
-  if (CORBA::is_nil(obj)) return properties;
-  Engines::ResourcesManager_var resManager = Engines::ResourcesManager::_narrow(obj);
-  if (CORBA::is_nil(resManager)) return properties;
-
-  std::ostringstream value;
-  Engines::ResourceDefinition_var resource_definition = resManager->GetResourceDefinition(name.c_str());
-  properties["hostname"]=resource_definition->hostname.in();
-  properties["OS"]=resource_definition->OS.in();
-  value.str(""); value << resource_definition->mem_mb;
-  properties["mem_mb"]=value.str();
-  value.str(""); value << resource_definition->cpu_clock;
-  properties["cpu_clock"]=value.str();
-  value.str(""); value << resource_definition->nb_node;
-  properties["nb_node"]=value.str();
-  value.str(""); value << resource_definition->nb_proc_per_node;
-  properties["nb_proc_per_node"]=value.str();
-  /*
-  properties["component_list"]="";
-  for(CORBA::ULong i=0; i < resource_definition->componentList.length(); i++)
-    {
-      if(i > 0)
-        properties["component_list"]=properties["component_list"]+",";
-      properties["component_list"]=properties["component_list"]+resource_definition->componentList[i].in();
-    }
-    */
-
-  return properties;
+  return _sct.getProperties();
 }
index 4ab0cd9b1f5ca35bf72be97c391f4d68a0e23292..275d09843534b6fe24c9f577e70b05e015422bea 100644 (file)
 
 #include "YACSRuntimeSALOMEExport.hxx"
 #include "Container.hxx"
+#include "SalomeContainerTools.hxx"
+#include "SalomeContainerHelper.hxx"
 #include "Mutex.hxx"
 #include <string>
 #include <vector>
-#include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SALOME_Component)
-#include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
 
 namespace YACS
 {
@@ -41,25 +41,34 @@ namespace YACS
     public:
       SalomeContainer();
       SalomeContainer(const SalomeContainer& other);
+#ifndef SWIG
+      SalomeContainer(const Container& other, const SalomeContainerTools& sct, const SalomeContainerHelper *lmt, const std::vector<std::string>& componentNames, int shutdownLev);
+#endif
       //! For thread safety for concurrent load operation on same Container.
       void lock();
       //! For thread safety for concurrent load operation on same Container.
       void unLock();
-      bool isAlreadyStarted(const ComponentInstance *inst) const;
-      Engines::Container_ptr getContainerPtr(const ComponentInstance *inst) const;
-      void start(const ComponentInstance *inst) throw (Exception);
+      std::string getKind() const;
+      bool isAlreadyStarted(const Task *askingNode) const;
+      Engines::Container_ptr getContainerPtr(const Task *askingNode) const;
+      void start(const Task *askingNode) throw (Exception);
       Container *clone() const;
-      std::string getPlacementId(const ComponentInstance *inst) const;
-      std::string getFullPlacementId(const ComponentInstance *inst) const;
+      Container *cloneAlways() const;
+      std::string getPlacementId(const Task *askingNode) const;
+      std::string getFullPlacementId(const Task *askingNode) const;
       void checkCapabilityToDealWith(const ComponentInstance *inst) const throw (Exception);
-      virtual void setProperty(const std::string& name, const std::string& value);
-      virtual void addComponentName(std::string name);
-      virtual CORBA::Object_ptr loadComponent(ComponentInstance *inst);
-      virtual void shutdown(int level);
+      void setProperty(const std::string& name, const std::string& value);
+      std::string getProperty(const std::string& name) const;
+      void clearProperties();
+      void addComponentName(const std::string& name);
+      void addToResourceList(const std::string& name);
+      virtual CORBA::Object_ptr loadComponent(Task *inst);
+      void shutdown(int level);
       // Helper methods
-      void addToComponentList(const std::string & name);
-      void addToResourceList(const std::string & name);
-      virtual std::map<std::string,std::string> getResourceProperties(const std::string& name);
+      std::map<std::string,std::string> getResourceProperties(const std::string& name) const;
+      std::map<std::string,std::string> getProperties() const;
+      static const char KIND[];
+      static const char TYPE_PROPERTY_STR[];
     protected:
 #ifndef SWIG
       virtual ~SalomeContainer();
@@ -67,13 +76,10 @@ namespace YACS
     protected:
       //! thread safety in Salome ???
       YACS::BASES::Mutex _mutex;
-      Engines::Container_var _trueCont;
       std::vector<std::string> _componentNames;
-      std::map<const ComponentInstance *,Engines::Container_var> _trueContainers;
-      std::string _type;
+      SalomeContainerHelper *_launchModeType;
       int _shutdownLevel;
-    public:
-      Engines::ContainerParameters _params;
+      SalomeContainerTools _sct;
     };
   }
 }
diff --git a/src/runtime/SalomeContainerHelper.cxx b/src/runtime/SalomeContainerHelper.cxx
new file mode 100644 (file)
index 0000000..fe84e2d
--- /dev/null
@@ -0,0 +1,178 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SalomeContainerHelper.hxx"
+
+#include "ServiceNode.hxx"
+#include "YacsTrace.hxx"
+
+#include <sstream>
+#include <iostream>
+
+using namespace YACS::ENGINE;
+using namespace std;
+
+const char SalomeContainerMonoHelper::TYPE_NAME[]="mono";
+
+const char SalomeContainerMonoHelper::DFT_LAUNCH_MODE[]="start";
+
+const char SalomeContainerMultiHelper::TYPE_NAME[]="multi";
+
+const char SalomeContainerMultiHelper::DFT_LAUNCH_MODE[]="getorstart";
+
+SalomeContainerHelper::~SalomeContainerHelper()
+{
+}
+
+SalomeContainerMonoHelper::SalomeContainerMonoHelper():_trueCont(Engines::Container::_nil())
+{
+
+}
+
+std::string SalomeContainerMonoHelper::getType() const
+{
+  return TYPE_NAME;
+}
+
+std::string SalomeContainerMonoHelper::getDftLaunchMode() const
+{
+  return std::string(DFT_LAUNCH_MODE);
+}
+
+SalomeContainerMonoHelper *SalomeContainerMonoHelper::deepCpyOnlyStaticInfo() const
+{
+  return new SalomeContainerMonoHelper;
+}
+
+Engines::Container_var SalomeContainerMonoHelper::getContainer(const Task *askingNode) const
+{
+  return _trueCont;
+}
+
+bool SalomeContainerMonoHelper::isAlreadyStarted(const Task *askingNode) const
+{
+  if(CORBA::is_nil(_trueCont))
+    return false;
+  else
+    return true;
+}
+
+void SalomeContainerMonoHelper::setContainer(const Task *askingNode, Engines::Container_var cont)
+{
+  _trueCont=cont;
+#ifdef REFCNT
+    DEBTRACE(_trueCont->_PR_getobj()->pd_refCount );
+#endif
+}
+
+void SalomeContainerMonoHelper::shutdown()
+{
+  try
+  {
+      DEBTRACE("shutdown SALOME container: " );
+      CORBA::String_var containerName=_trueCont->name();
+      DEBTRACE(containerName);
+      _trueCont->Shutdown();
+      std::cerr << "shutdown SALOME container: " << containerName << std::endl;
+  }
+  catch(...)
+  {
+      DEBTRACE("Unknown exception ignored." );
+  }
+  _trueCont=Engines::Container::_nil();
+}
+
+SalomeContainerMonoHelper::~SalomeContainerMonoHelper()
+{
+}
+
+std::string SalomeContainerMultiHelper::getType() const
+{
+  return TYPE_NAME;
+}
+
+std::string SalomeContainerMultiHelper::getDftLaunchMode() const
+{
+  return std::string(DFT_LAUNCH_MODE);
+}
+
+SalomeContainerMultiHelper *SalomeContainerMultiHelper::deepCpyOnlyStaticInfo() const
+{
+  return new SalomeContainerMultiHelper;
+}
+
+Engines::Container_var SalomeContainerMultiHelper::getContainer(const Task *askingNode) const
+{
+  const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
+  std::map<const ComponentInstance *,Engines::Container_var>::const_iterator it(_trueContainers.find(inst));
+  if(it!=_trueContainers.end())
+    return (*it).second;
+  else
+    return Engines::Container::_nil();
+}
+
+bool SalomeContainerMultiHelper::isAlreadyStarted(const Task *askingNode) const
+{
+  const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
+  if(_trueContainers.count(inst)==0)
+    return false;
+  else
+    return true;
+}
+
+void SalomeContainerMultiHelper::setContainer(const Task *askingNode, Engines::Container_var cont)
+{
+  const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
+  _trueContainers[inst]=cont;
+#ifdef REFCNT
+    std::map<const ComponentInstance *, Engines::Container_var >::const_iterator it;
+    for(it = _trueContainers.begin(); it != _trueContainers.end(); ++it)
+      {
+        DEBTRACE(it->second->_PR_getobj()->pd_refCount );
+      }
+#endif
+}
+
+void SalomeContainerMultiHelper::shutdown()
+{
+  for(std::map<const ComponentInstance *, Engines::Container_var >::const_iterator it = _trueContainers.begin(); it != _trueContainers.end(); ++it)
+    {
+      try
+      {
+          DEBTRACE("shutdown SALOME container: " );
+          CORBA::String_var containerName=it->second->name();
+          DEBTRACE(containerName);
+          it->second->Shutdown();
+          std::cerr << "shutdown SALOME container: " << containerName << std::endl;
+      }
+      catch(CORBA::Exception&)
+      {
+          DEBTRACE("Unexpected CORBA failure detected." );
+      }
+      catch(...)
+      {
+          DEBTRACE("Unknown exception ignored." );
+      }
+    }
+  _trueContainers.clear();
+}
+
+SalomeContainerMultiHelper::~SalomeContainerMultiHelper()
+{
+}
diff --git a/src/runtime/SalomeContainerHelper.hxx b/src/runtime/SalomeContainerHelper.hxx
new file mode 100644 (file)
index 0000000..2237bad
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __SALOMECONTAINERHELPER_HXX__
+#define __SALOMECONTAINERHELPER_HXX__
+
+#include "YACSRuntimeSALOMEExport.hxx"
+
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SALOME_Component)
+
+#include "RefCounter.hxx"
+
+#include <map>
+#include <string>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Task;
+    class ComponentInstance;
+
+    class SalomeContainerHelper : public RefCounter
+    {
+    public:
+      virtual std::string getType() const = 0;
+      virtual std::string getDftLaunchMode() const = 0;
+      virtual SalomeContainerHelper *deepCpyOnlyStaticInfo() const = 0;
+      virtual Engines::Container_var getContainer(const Task *askingNode) const = 0;
+      virtual bool isAlreadyStarted(const Task *askingNode) const = 0;
+      virtual void setContainer(const Task *askingNode, Engines::Container_var cont) = 0;
+      virtual void shutdown() = 0;
+    protected:
+      virtual ~SalomeContainerHelper();
+    };
+
+    class SalomeContainerMonoHelper : public SalomeContainerHelper
+    {
+    public:
+      SalomeContainerMonoHelper();
+      std::string getType() const;
+      std::string getDftLaunchMode() const;
+      SalomeContainerMonoHelper *deepCpyOnlyStaticInfo() const;
+      Engines::Container_var getContainer(const Task *askingNode) const;
+      bool isAlreadyStarted(const Task *askingNode) const;
+      void setContainer(const Task *askingNode, Engines::Container_var cont);
+      void shutdown();
+    private:
+      ~SalomeContainerMonoHelper();
+    public:
+      static const char TYPE_NAME[];
+      static const char DFT_LAUNCH_MODE[];
+    private:
+      Engines::Container_var _trueCont;
+    };
+
+    class SalomeContainerMultiHelper : public SalomeContainerHelper
+    {
+    public:
+      std::string getType() const;
+      std::string getDftLaunchMode() const;
+      SalomeContainerMultiHelper *deepCpyOnlyStaticInfo() const;
+      Engines::Container_var getContainer(const Task *askingNode) const;
+      bool isAlreadyStarted(const Task *askingNode) const;
+      void setContainer(const Task *askingNode, Engines::Container_var cont);
+      void shutdown();
+    private:
+      ~SalomeContainerMultiHelper();
+    public:
+      static const char TYPE_NAME[];
+      static const char DFT_LAUNCH_MODE[];
+    private:
+      std::map<const ComponentInstance *,Engines::Container_var> _trueContainers;
+    };
+  }
+}
+
+#endif
diff --git a/src/runtime/SalomeContainerTmpForHP.cxx b/src/runtime/SalomeContainerTmpForHP.cxx
new file mode 100644 (file)
index 0000000..d3a7334
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SalomeContainerTmpForHP.hxx"
+#include "ComponentInstance.hxx"
+#include "SalomeHPContainer.hxx"
+#include "AutoLocker.hxx"
+#include "Task.hxx"
+
+using namespace YACS::ENGINE;
+
+CORBA::Object_ptr SalomeContainerTmpForHP::loadComponent(Task *askingNode)
+{
+  const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
+  if(!inst)
+    throw Exception("SalomeContainerTmpForHP::loadComponent : asking to load a component on the given task whereas this task has no component !");
+  std::string compoName(inst->getCompoName());
+  {
+    YACS::BASES::AutoLocker<Container> alck(this);//To be sure
+    if(!this->isAlreadyStarted(askingNode))
+      this->start(askingNode);
+  }
+  CORBA::Object_ptr objComponent=CORBA::Object::_nil();
+  {
+    YACS::BASES::AutoLocker<Container> alck(this);//To be sure
+    std::string compoName(inst->getCompoName());
+    Engines::Container_var container(_launchModeType->getContainer(askingNode));
+    objComponent=container->find_component_instance(compoName.c_str(),0);
+    if(CORBA::is_nil(objComponent))
+      {
+        char *reason;
+        bool isLoadable(container->load_component_Library(compoName.c_str(), reason));
+        if(isLoadable)
+          objComponent=SalomeContainerTools::CreateComponentInstance(this,container,inst);
+      }
+  }
+  return objComponent;
+}
+
+SalomeContainerTmpForHP *SalomeContainerTmpForHP::BuildFrom(const SalomeHPContainer *cont, const Task *askingNode)
+{
+  const SalomeContainerHelper *lmt(0);
+  std::size_t posIn(0);
+  {
+    YACS::BASES::AutoLocker<Container> altck(const_cast<SalomeHPContainer *>(cont));
+    lmt=cont->getHelperOfTask(askingNode);
+    posIn=cont->locateTask(askingNode);
+  }
+  return new SalomeContainerTmpForHP(*cont,cont->getContainerInfo(),lmt,cont->getComponentNames(),cont->getShutdownLev(),cont,posIn);
+}
diff --git a/src/runtime/SalomeContainerTmpForHP.hxx b/src/runtime/SalomeContainerTmpForHP.hxx
new file mode 100644 (file)
index 0000000..8f92dbe
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __SALOMECONTAINERTMPFORHP_HXX__
+#define __SALOMECONTAINERTMPFORHP_HXX__
+
+#include "YACSRuntimeSALOMEExport.hxx"
+#include "SalomeContainer.hxx"
+
+#include <sstream>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class SalomeHPContainer;
+    class SalomeContainerTmpForHP : public SalomeContainer
+    {
+    public:
+      SalomeContainerTmpForHP(const Container& other, const SalomeContainerTools& sct, const SalomeContainerHelper *lmt,
+                              const std::vector<std::string>& componentNames, int shutdownLev,
+                              const SalomeHPContainer *zeOriginCont, std::size_t pos):SalomeContainer(other,sct,lmt,componentNames,shutdownLev),_zeOriginCont(zeOriginCont),_pos(pos) { }
+      std::string getDiscreminantStrOfThis(const Task *askingNode) const { std::ostringstream oss; oss << _zeOriginCont << "_" << _pos; return oss.str(); }
+      CORBA::Object_ptr loadComponent(Task *inst);
+      static SalomeContainerTmpForHP *BuildFrom(const SalomeHPContainer *cont, const Task *askingNode);
+    private:
+      const SalomeHPContainer *_zeOriginCont;
+      std::size_t _pos;
+    };
+  }
+}
+
+#endif
diff --git a/src/runtime/SalomeContainerTools.cxx b/src/runtime/SalomeContainerTools.cxx
new file mode 100644 (file)
index 0000000..360e67e
--- /dev/null
@@ -0,0 +1,530 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SalomeContainerTools.hxx"
+#include "SALOME_LifeCycleCORBA.hxx"
+#include "SALOME_NamingService.hxx"
+#include "SALOME_ResourcesManager.hxx"
+#include "SALOME_ContainerManager.hxx"
+#include "Container.hxx"
+#include "AutoLocker.hxx"
+
+#include "YacsTrace.hxx"
+#include "Proc.hxx"
+#include "ServiceNode.hxx"
+#include "ComponentInstance.hxx"
+#include "SalomeContainerHelper.hxx"
+#include "RuntimeSALOME.hxx"
+#include "Exception.hxx"
+
+#include <sstream>
+
+using namespace YACS::ENGINE;
+
+SalomeContainerTools::SalomeContainerTools()
+{
+  /* Init ContainerParameters */
+  SALOME_LifeCycleCORBA::preSet(_params);
+}
+
+SalomeContainerTools::SalomeContainerTools(const SalomeContainerTools& other):_params(other._params),_propertyMap(other._propertyMap)
+{
+}
+
+void SalomeContainerTools::clearProperties()
+{
+  _propertyMap.clear();
+  _params=Engines::ContainerParameters();
+}
+
+std::string SalomeContainerTools::getProperty(const std::string& name) const
+{
+  std::map<std::string,std::string>::const_iterator it(_propertyMap.find(name));
+  if(it!=_propertyMap.end())
+    return (*it).second;
+  else
+    return std::string();
+}
+
+void SalomeContainerTools::setProperty(const std::string& name, const std::string& value)
+{
+  //DEBTRACE("SalomeContainer::setProperty : " << name << " ; " << value);
+  // Container Part
+  if (name == "container_name")
+    _params.container_name = CORBA::string_dup(value.c_str());
+  else if (name == "workingdir")
+    _params.workingdir = CORBA::string_dup(value.c_str());
+  else if (name == "nb_parallel_procs")
+  {
+    std::istringstream iss(value);
+    if (!(iss >> _params.nb_proc))
+      throw Exception("salomecontainer::setproperty : params.nb_proc value not correct : " + value);
+  }
+  else if (name == "isMPI")
+  {
+    if (value == "true")
+      _params.isMPI = true;
+    else if (value == "false")
+      _params.isMPI = false;
+    else 
+      throw Exception("SalomeContainer::setProperty : params.isMPI value not correct : " + value);
+  }
+  else if (name == "parallelLib")
+    _params.parallelLib = CORBA::string_dup(value.c_str());
+
+  // Resource part
+  else if (name == "name")
+    _params.resource_params.name = CORBA::string_dup(value.c_str());
+  else if (name == "hostname")
+    _params.resource_params.hostname = CORBA::string_dup(value.c_str());
+  else if (name == "OS")
+    _params.resource_params.OS = CORBA::string_dup(value.c_str());
+  else if (name == "nb_resource_procs")
+  {
+    std::istringstream iss(value);
+    if (!(iss >> _params.resource_params.nb_proc))
+      throw Exception("salomecontainer::setproperty : params.resource_params.nb_proc value not correct : " + value);
+  }
+  else if (name == "mem_mb")
+  {
+    std::istringstream iss(value);
+    if (!(iss >> _params.resource_params.mem_mb))
+      throw Exception("salomecontainer::setproperty : params.resource_params.mem_mb value not correct : " + value);
+  }
+  else if (name == "cpu_clock")
+  {
+    std::istringstream iss(value);
+    if (!(iss >> _params.resource_params.cpu_clock))
+      throw Exception("salomecontainer::setproperty : params.resource_params.cpu_clock value not correct : " + value);
+  }
+  else if (name == "nb_node")
+  {
+    std::istringstream iss(value);
+    if (!(iss >> _params.resource_params.nb_node))
+      throw Exception("salomecontainer::setproperty : params.nb_node value not correct : " + value);
+  }
+  else if (name == "nb_proc_per_node")
+  {
+    std::istringstream iss(value);
+    if (!(iss >> _params.resource_params.nb_proc_per_node))
+      throw Exception("salomecontainer::setproperty : params.nb_proc_per_node value not correct : " + value);
+  }
+  else if (name == "policy")
+    _params.resource_params.policy = CORBA::string_dup(value.c_str());
+  else if (name == "component_list")
+  {
+    std::string clean_value(value);
+
+    // Step 1: remove blanks
+    while(clean_value.find(" ") != std::string::npos)
+      clean_value = clean_value.erase(clean_value.find(" "), 1);
+
+    // Step 2: get values
+    while(!clean_value.empty())
+    {
+      std::string result("");
+      std::string::size_type loc = clean_value.find(",", 0);
+      if (loc != std::string::npos)
+      {
+        result = clean_value.substr(0, loc);
+        clean_value = clean_value.erase(0, loc+1);
+      }
+      else
+      {
+        result = clean_value;
+        clean_value.erase();
+      }
+      if (result != "," && result != "")
+      {
+        addToComponentList(result);
+      }
+    }
+
+  }
+  else if (name == "resource_list")
+  {
+    std::string clean_value(value);
+
+    // Step 1: remove blanks
+    while(clean_value.find(" ") != std::string::npos)
+      clean_value = clean_value.erase(clean_value.find(" "), 1);
+
+    // Step 2: get values
+    while(!clean_value.empty())
+    {
+      std::string result("");
+      std::string::size_type loc = clean_value.find(",", 0);
+      if (loc != std::string::npos)
+      {
+        result = clean_value.substr(0, loc);
+        clean_value = clean_value.erase(0, loc+1);
+      }
+      else
+      {
+        result = clean_value;
+        clean_value.erase();
+      }
+      if (result != "," && result != "")
+      {
+        addToResourceList(result);
+      }
+    }
+
+  }
+  _propertyMap[name]=value;
+}
+
+void SalomeContainerTools::addToComponentList(const std::string& name)
+{
+  // Search if name is already in the list
+  for (CORBA::ULong i = 0; i < _params.resource_params.componentList.length(); i++)
+    {
+      std::string component_name = _params.resource_params.componentList[i].in();
+      if (component_name == name)
+        return;
+    }
+  // Add name to list
+  CORBA::ULong lgth = _params.resource_params.componentList.length();
+  _params.resource_params.componentList.length(lgth + 1);
+  _params.resource_params.componentList[lgth] = CORBA::string_dup(name.c_str());
+}
+
+void SalomeContainerTools::addToResourceList(const std::string& name)
+{
+  // Search if name is already in the list
+  for (CORBA::ULong i = 0; i < _params.resource_params.resList.length(); i++)
+    {
+      std::string component_name = _params.resource_params.resList[i].in();
+      if (component_name == name)
+        return;
+    }
+  // Add name to list
+  CORBA::ULong lgth = _params.resource_params.resList.length();
+  _params.resource_params.resList.length(lgth + 1);
+  _params.resource_params.resList[lgth] = CORBA::string_dup(name.c_str());
+}
+
+std::string SalomeContainerTools::getContainerName() const
+{
+  return std::string(_params.container_name);
+}
+
+void SalomeContainerTools::setContainerName(const std::string& name)
+{
+  SetContainerNameOf(_params,name);
+}
+
+std::string SalomeContainerTools::getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const
+{
+  isEmpty=true;
+  std::string name(_params.container_name);
+  if(!name.empty())
+    {
+      isEmpty=false;
+      return name;
+    }
+  else
+    {
+      //give a almost unique name to the container : Pid_Name_Addr
+      std::ostringstream stream;
+      stream << getpid();
+      stream << "_";
+      stream << contPtr->getName();
+      stream << "_";
+      stream << contPtr->getDiscreminantStrOfThis(askingNode);
+      return stream.str();
+    }
+}
+
+std::string SalomeContainerTools::getHostName() const
+{
+  return std::string(_params.resource_params.hostname);
+}
+
+void SalomeContainerTools::SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name)
+{
+  params.container_name=CORBA::string_dup(name.c_str());
+}
+
+std::map<std::string,std::string> SalomeContainerTools::getResourceProperties(const std::string& name) const
+{
+  std::map<std::string,std::string> properties;
+
+  YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
+  CORBA::ORB_ptr orb = runTime->getOrb();
+  if (!orb) return properties;
+  SALOME_NamingService namingService(orb);
+  SALOME_LifeCycleCORBA lcc(&namingService);
+  CORBA::Object_var obj = namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
+  if (CORBA::is_nil(obj))
+    return properties;
+  Engines::ResourcesManager_var resManager = Engines::ResourcesManager::_narrow(obj);
+  if (CORBA::is_nil(resManager))
+    return properties;
+
+  std::ostringstream value;
+  Engines::ResourceDefinition_var resource_definition = resManager->GetResourceDefinition(name.c_str());
+  properties["hostname"]=resource_definition->hostname.in();
+  properties["OS"]=resource_definition->OS.in();
+  value.str(""); value << resource_definition->mem_mb;
+  properties["mem_mb"]=value.str();
+  value.str(""); value << resource_definition->cpu_clock;
+  properties["cpu_clock"]=value.str();
+  value.str(""); value << resource_definition->nb_node;
+  properties["nb_node"]=value.str();
+  value.str(""); value << resource_definition->nb_proc_per_node;
+  properties["nb_proc_per_node"]=value.str();
+  /*
+  properties["component_list"]="";
+  for(CORBA::ULong i=0; i < resource_definition->componentList.length(); i++)
+    {
+      if(i > 0)
+        properties["component_list"]=properties["component_list"]+",";
+      properties["component_list"]=properties["component_list"]+resource_definition->componentList[i].in();
+    }
+    */
+  return properties;
+}
+
+/*!
+ * \param [in] compoNames
+ * \param [in,out] shutdownLevel
+ */
+void SalomeContainerTools::Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerTools& sct, int& shutdownLevel, const Container *cont, const Task *askingNode)
+{
+  CORBA::ORB_ptr orb(getSALOMERuntime()->getOrb());
+  SALOME_NamingService ns;
+  try
+  {
+      ns.init_orb(orb);
+  }
+  catch(SALOME_Exception& e)
+  {
+      throw Exception("SalomeContainer::start : Unable to contact the SALOME Naming Service");
+  }
+  CORBA::Object_var obj(ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS));
+  Engines::ContainerManager_var contManager(Engines::ContainerManager::_narrow(obj));
+
+  bool isEmptyName;
+  std::string str(sct.getNotNullContainerName(cont,askingNode,isEmptyName));
+  DEBTRACE("SalomeContainer::start " << str <<";"<< _sct.getHostName() <<";"<<_type);
+
+  // Finalize parameters with components found in the container
+
+  for(std::vector<std::string>::const_iterator iter=compoNames.begin();iter!=compoNames.end();iter++)
+    sct.addToComponentList(*iter);
+
+  Engines::ContainerParameters myparams(sct.getParameters());
+  {
+    std::string dftLauchMode(schelp->getDftLaunchMode());
+    myparams.mode=CORBA::string_dup(dftLauchMode.c_str());
+  }
+
+  //If a container_name is given try to find an already existing container in naming service
+  //If not found start a new container with the given parameters
+  if (dynamic_cast<SalomeContainerMonoHelper *>(schelp) && !isEmptyName)
+    {
+      myparams.mode=CORBA::string_dup("getorstart");
+    }
+
+  if (isEmptyName)
+    {
+      shutdownLevel=1;
+    }
+  //sct.setContainerName(str);
+  SetContainerNameOf(myparams,str);
+  Engines::Container_var trueCont(Engines::Container::_nil());
+  if(!isEmptyName && shutdownLevel==999)
+    {
+      //Make this only the first time start is called (_shutdownLevel==999)
+      //If the container is named, first try to get an existing container
+      //If there is an existing container use it and set the shutdown level to 3
+      //If there is no existing container, try to launch a new one and set the shutdown level to 2
+      myparams.mode="get";
+      try
+      {
+          trueCont=contManager->GiveContainer(myparams);
+      }
+      catch( const SALOME::SALOME_Exception& ex )
+      {
+          std::string msg="SalomeContainer::start : no existing container : ";
+          msg += '\n';
+          msg += ex.details.text.in();
+          DEBTRACE( msg );
+      }
+      catch(...)
+      {
+      }
+
+      if(!CORBA::is_nil(trueCont))
+        {
+          shutdownLevel=3;
+          DEBTRACE( "container found: " << str << " " << _shutdownLevel );
+        }
+      else
+        {
+          shutdownLevel=2;
+          myparams.mode="start";
+          DEBTRACE( "container not found: " << str << " " << _shutdownLevel);
+        }
+    }
+
+  if(CORBA::is_nil(trueCont))
+    try
+  {
+        // --- GiveContainer is used in batch mode to retreive launched containers,
+        //     and is equivalent to StartContainer when not in batch.
+        trueCont=contManager->GiveContainer(myparams);
+  }
+  catch( const SALOME::SALOME_Exception& ex )
+  {
+      std::string msg="SalomeContainer::start : Unable to launch container in Salome : ";
+      msg += '\n';
+      msg += ex.details.text.in();
+      throw Exception(msg);
+  }
+  catch(CORBA::COMM_FAILURE&)
+  {
+      throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected");
+  }
+  catch(CORBA::Exception&)
+  {
+      throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected");
+  }
+
+  if(CORBA::is_nil(trueCont))
+    throw Exception("SalomeContainer::start : Unable to launch container in Salome. Check your CatalogResources.xml file");
+
+  schelp->setContainer(askingNode,trueCont);
+
+  CORBA::String_var containerName(trueCont->name()),hostName(trueCont->getHostName());
+  std::cerr << "SalomeContainer launched : " << containerName << " " << hostName << " " << trueCont->getPID() << std::endl;
+}
+
+CORBA::Object_ptr SalomeContainerTools::LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode)
+{
+  DEBTRACE("SalomeContainer::loadComponent ");
+  const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
+  {
+    YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
+    if(!cont->isAlreadyStarted(askingNode))
+      cont->start(askingNode);
+  }
+  if(!inst)
+    throw Exception("SalomeContainerTools::LoadComponent : no instance of component in the task requesting for a load of its component !");
+  CORBA::Object_ptr objComponent=CORBA::Object::_nil();
+  {
+    YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
+    std::string compoName(inst->getCompoName());
+    Engines::Container_var container(launchModeType->getContainer(askingNode));
+
+    char *reason;
+    bool isLoadable(container->load_component_Library(compoName.c_str(), reason));
+    if(isLoadable)
+      objComponent=CreateComponentInstance(cont,container,inst);
+  }
+  return objComponent;
+}
+
+CORBA::Object_ptr SalomeContainerTools::CreateComponentInstance(Container *cont, Engines::Container_ptr contPtr, const ComponentInstance *inst)
+{
+  if(!inst)
+    throw Exception("SalomeContainerTools::CreateComponentInstance : no instance of component in the task requesting for a load of its component !");
+  char *reason(0);
+  std::string compoName(inst->getCompoName());
+  CORBA::Object_ptr objComponent=CORBA::Object::_nil();
+  int studyid(1);
+  Proc* p(cont->getProc());
+  if(p)
+    {
+      std::string value(p->getProperty("DefaultStudyID"));
+      if(!value.empty())
+        studyid= atoi(value.c_str());
+    }
+  // prepare component instance properties
+  Engines::FieldsDict_var env(new Engines::FieldsDict);
+  std::map<std::string, std::string> properties(inst->getProperties());
+  if(p)
+    {
+      std::map<std::string,std::string> procMap=p->getProperties();
+      properties.insert(procMap.begin(),procMap.end());
+    }
+
+  std::map<std::string, std::string>::const_iterator itm;
+  env->length(properties.size());
+  int item=0;
+  for(itm = properties.begin(); itm != properties.end(); ++itm, item++)
+    {
+      DEBTRACE("envname="<<itm->first<<" envvalue="<< itm->second);
+      env[item].key= CORBA::string_dup(itm->first.c_str());
+      env[item].value <<= itm->second.c_str();
+    }
+
+  objComponent=contPtr->create_component_instance_env(compoName.c_str(), studyid, env, reason);
+  if(CORBA::is_nil(objComponent))
+    {
+      std::string text="Error while trying to create a new component: component '"+ compoName;
+      text=text+"' is not installed or it's a wrong name";
+      text += '\n';
+      text += reason;
+      CORBA::string_free(reason);
+      throw Exception(text);
+    }
+  return objComponent;
+}
+
+std::string SalomeContainerTools::GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
+{
+  if(cont->isAlreadyStarted(askingNode))
+    {
+      Engines::Container_var container(launchModeType->getContainer(askingNode));
+      const char *what="/";
+      CORBA::String_var corbaStr(container->name());
+      std::string ret(corbaStr);
+
+      //Salome FOREVER ...
+      std::string::size_type i=ret.find_first_of(what,0);
+      i=ret.find_first_of(what, i==std::string::npos ? i:i+1);
+      if(i!=std::string::npos)
+        return ret.substr(i+1);
+      return ret;
+    }
+  else
+    return "Not placed yet !!!";
+}
+
+std::string SalomeContainerTools::GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
+{
+  if(cont->isAlreadyStarted(askingNode))
+    {
+      Engines::Container_var container(launchModeType->getContainer(askingNode));
+      try
+      {
+          CORBA::String_var corbaStr(container->name());
+          std::string ret(corbaStr);
+          return ret;
+      }
+      catch(...)
+      {
+          return "Unknown_placement";
+      }
+    }
+  else
+    return "Not_placed_yet";
+}
diff --git a/src/runtime/SalomeContainerTools.hxx b/src/runtime/SalomeContainerTools.hxx
new file mode 100644 (file)
index 0000000..1df9044
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __SALOMECONTAINERTOOLS_HXX__
+#define __SALOMECONTAINERTOOLS_HXX__
+
+#include "YACSRuntimeSALOMEExport.hxx"
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
+
+#include <string>
+#include <vector>
+#include <map>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Task;
+    class Container;
+    class ComponentInstance;
+    class SalomeContainerHelper;
+
+    class YACSRUNTIMESALOME_EXPORT SalomeContainerTools
+    {
+    public:
+      SalomeContainerTools();
+      SalomeContainerTools(const SalomeContainerTools& other);
+      std::string getProperty(const std::string& name) const;
+      void setProperty(const std::string& name, const std::string& value);
+      const std::map<std::string,std::string>& getProperties() const { return _propertyMap; }
+      void clearProperties();
+      std::map<std::string,std::string> getResourceProperties(const std::string& name) const;
+      void addToComponentList(const std::string& name);
+      void addToResourceList(const std::string& name);
+    public:
+      std::string getContainerName() const;
+      void setContainerName(const std::string& name);
+      std::string getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const;
+      std::string getHostName() const;
+      Engines::ContainerParameters getParameters() const { return _params; }
+      static void SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name);
+    public:
+      static void Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerTools& sct, int& shutdownLevel, const Container *cont, const Task *askingNode);
+      static CORBA::Object_ptr LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode);
+      static CORBA::Object_ptr CreateComponentInstance(Container *cont, Engines::Container_ptr contPtr, const ComponentInstance *inst);
+      static std::string GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode);
+      static std::string GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode);
+    protected:
+      std::map<std::string,std::string> _propertyMap;
+      Engines::ContainerParameters _params;
+    };
+  }
+}
+
+#endif
diff --git a/src/runtime/SalomeHPComponent.cxx b/src/runtime/SalomeHPComponent.cxx
new file mode 100644 (file)
index 0000000..d84261d
--- /dev/null
@@ -0,0 +1,162 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SalomeHPComponent.hxx"
+#include "RuntimeSALOME.hxx"
+#include "SalomeContainer.hxx"
+#include "SalomeHPContainer.hxx"
+#include "SalomeComponent.hxx" // for KIND
+#include "SalomeContainerTmpForHP.hxx"
+#include "CORBANode.hxx"
+
+#ifdef SALOME_KERNEL
+#include "SALOME_NamingService.hxx"
+#include "SALOME_LifeCycleCORBA.hxx"
+#endif
+
+#include <omniORB4/CORBA.h>
+#include <iostream>
+#include <sstream>
+
+//#define _DEVDEBUG_
+#include "YacsTrace.hxx"
+
+using namespace YACS::ENGINE;
+using namespace std;
+
+const char SalomeHPComponent::KIND[]="HPSalome";
+
+SalomeHPComponent::SalomeHPComponent(const std::string& name): ComponentInstance(name)
+{
+  _objComponent=CORBA::Object::_nil();
+}
+
+SalomeHPComponent::SalomeHPComponent(const SalomeHPComponent& other):ComponentInstance(other)
+{
+  _objComponent=CORBA::Object::_nil();
+}
+
+SalomeHPComponent::~SalomeHPComponent()
+{
+}
+
+std::string SalomeHPComponent::getKind() const
+{
+  return KIND;
+}
+
+std::string SalomeHPComponent::getKindForNode() const
+{
+  return SalomeComponent::KIND;
+}
+
+//! Unload the component 
+void SalomeHPComponent::unload(Task *askingNode)
+{
+  //Not implemented
+  std::cerr << "SalomeHPComponent::unload : not implemented " << std::endl;
+}
+
+//! Is the component instance already loaded ?
+bool SalomeHPComponent::isLoaded(Task *askingNode) const
+{
+  return false;
+}
+
+//#ifdef SALOME_KERNEL
+//! Load the component 
+void SalomeHPComponent::load(Task *askingNode)
+{
+  if(_container)
+    {
+      SalomeHPContainer *salomeContainer(dynamic_cast<SalomeHPContainer *>(_container));
+      if(salomeContainer)
+        {
+          YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(salomeContainer,askingNode));
+          _objComponent=tmpCont->loadComponent(askingNode);
+          return ;
+        }
+      throw Exception("Unrecognized type of Container ! Only Salome and HPSalome container are supported by the Salome components !");
+    }
+  else
+    throw Exception("No container on HP component ! Impossible to load !");
+}
+/*#else
+void SalomeComponent::load(Task *askingNode)
+{
+  throw Exception("YACS has been built without SALOME support");
+}
+#endif*/
+
+//! Create a ServiceNode with this component instance and no input or output port
+/*!
+ *   \param name : node name
+ *   \return       a new SalomeNode node
+ */
+ServiceNode* SalomeHPComponent::createNode(const std::string& name)
+{
+  SalomeNode* node(new SalomeNode(name));
+   node->setComponent(this);
+   return node;
+}
+
+//! Clone the component instance
+ComponentInstance* SalomeHPComponent::clone() const
+{
+  if(_isAttachedOnCloning)
+    {
+      incrRef();
+      return (ComponentInstance*) (this);
+    }
+  else
+    return new SalomeHPComponent(*this);
+}
+
+ComponentInstance *SalomeHPComponent::cloneAlways() const
+{
+  return new SalomeHPComponent(*this);
+}
+
+std::string SalomeHPComponent::getFileRepr() const
+{
+  ostringstream stream;
+  stream << "<component>" << getCompoName() << "</component>";
+  return stream.str();
+}
+
+bool SalomeHPComponent::setContainer(Container *cont)
+{
+  if(!dynamic_cast<SalomeHPContainer *>(cont))
+    throw Exception("SalomeHPComponent::setContainer : a Salome HP component must be attached to a Salome HP container !");
+  if(ComponentInstance::setContainer(cont))
+    {
+      if(_container)
+        _container->addComponentName(_compoName);
+      return true;
+    }
+  else
+    return false;
+}
+
+void SalomeHPComponent::shutdown(int level)
+{
+  DEBTRACE("SalomeHPComponent::shutdown " << level);
+  if(_container)
+    _container->shutdown(level);
+}
diff --git a/src/runtime/SalomeHPComponent.hxx b/src/runtime/SalomeHPComponent.hxx
new file mode 100644 (file)
index 0000000..e5fa9ab
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _SALOMEHPCOMPONENT_HXX_
+#define _SALOMEHPCOMPONENT_HXX_
+
+#include "YACSRuntimeSALOMEExport.hxx"
+#include "ComponentInstance.hxx"
+#include <omniORB4/CORBA.h>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class YACSRUNTIMESALOME_EXPORT SalomeHPComponent : public ComponentInstance
+    {
+    public:
+      SalomeHPComponent(const std::string& name);
+      SalomeHPComponent(const SalomeHPComponent& other);
+      virtual ~SalomeHPComponent();
+      virtual void load(Task *askingNode);
+      virtual void unload(Task *askingNode);
+      virtual bool isLoaded(Task *askingNode) const;
+      virtual bool setContainer(Container *cont);
+      virtual ServiceNode* createNode(const std::string& name);
+      virtual ComponentInstance* clone() const;
+      virtual ComponentInstance* cloneAlways() const;
+      virtual std::string getFileRepr() const;
+      virtual CORBA::Object_ptr getCompoPtr(){return CORBA::Object::_duplicate(_objComponent);}
+      virtual void shutdown(int level);
+    public:
+      static const char KIND[];
+      virtual std::string getKind() const;
+      virtual std::string getKindForNode() const;
+    protected:
+      CORBA::Object_var _objComponent;
+    };
+  }
+}
+
+#endif
diff --git a/src/runtime/SalomeHPContainer.cxx b/src/runtime/SalomeHPContainer.cxx
new file mode 100644 (file)
index 0000000..de5f1a4
--- /dev/null
@@ -0,0 +1,215 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SalomeHPContainer.hxx"
+#include "SalomeHPComponent.hxx"
+#include "SalomeContainerTmpForHP.hxx"
+#include "AutoLocker.hxx"
+
+#include <algorithm>
+
+using namespace YACS::ENGINE;
+
+const char SalomeHPContainer::KIND[]="HPSalome";
+
+SalomeHPContainer::SalomeHPContainer():_shutdownLevel(999)
+{
+}
+
+SalomeHPContainer::SalomeHPContainer(const SalomeHPContainer& other):_componentNames(other._componentNames),_shutdownLevel(999),_sct(other._sct),_initScript(other._initScript)
+{
+}
+
+void SalomeHPContainer::setSizeOfPool(int sz)
+{
+  _launchModeType.resize(sz);
+}
+
+int SalomeHPContainer::getSizeOfPool() const
+{
+  return _launchModeType.size();
+}
+
+std::size_t SalomeHPContainer::getNumberOfFreePlace() const
+{
+  return _launchModeType.getNumberOfFreePlace();
+}
+
+void SalomeHPContainer::allocateFor(const std::vector<const Task *>& nodes)
+{
+  _launchModeType.allocateFor(nodes);
+}
+
+void SalomeHPContainer::release(const Task *node)
+{
+  _launchModeType.release(node);
+}
+
+SalomeHPContainer::~SalomeHPContainer()
+{
+}
+
+void SalomeHPContainer::lock()
+{
+  _mutex.lock();
+}
+
+void SalomeHPContainer::unLock()
+{
+  _mutex.unLock();
+}
+
+std::string SalomeHPContainer::getKind() const
+{
+  return KIND;
+}
+
+std::string SalomeHPContainer::getDiscreminantStrOfThis(const Task *askingNode) const
+{
+  YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(this,askingNode));
+  return tmpCont->getDiscreminantStrOfThis(askingNode);
+}
+
+bool SalomeHPContainer::isAlreadyStarted(const Task *askingNode) const
+{
+  const SalomeContainerMonoHelper *helper(_launchModeType.getHelperOfTaskThreadSafe(this,askingNode));
+  return helper->isAlreadyStarted(askingNode);
+}
+
+void SalomeHPContainer::start(const Task *askingNode) throw(Exception)
+{
+  SalomeContainerMonoHelper *helper(_launchModeType.getHelperOfTaskThreadSafe(this,askingNode));
+  SalomeContainerTools::Start(_componentNames,helper,_sct,_shutdownLevel,this,askingNode);
+}
+
+void SalomeHPContainer::shutdown(int level)
+{
+  if(level < _shutdownLevel)
+      return;
+  _shutdownLevel=999;
+  for(std::size_t i=0;i<_launchModeType.size();i++)
+    {
+      SalomeContainerMonoHelper *helper(_launchModeType.at(i));
+      helper->shutdown();
+    }
+}
+
+std::string SalomeHPContainer::getPlacementId(const Task *askingNode) const
+{
+  const SalomeContainerMonoHelper *helper(0);
+  {
+    YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainer *>(this));
+    helper=_launchModeType.getHelperOfTask(askingNode);
+  }
+  return SalomeContainerTools::GetPlacementId(helper,this,askingNode);
+}
+
+std::string SalomeHPContainer::getFullPlacementId(const Task *askingNode) const
+{
+  const SalomeContainerMonoHelper *helper(0);
+  {
+    YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainer *>(this));
+    helper=_launchModeType.getHelperOfTask(askingNode);
+  }
+  return SalomeContainerTools::GetFullPlacementId(helper,this,askingNode);
+}
+
+/*!
+ * It is not a bug here ! clone for homogeneous container is not supposed to be copied !
+ */
+Container *SalomeHPContainer::clone() const
+{
+  incrRef();
+  return const_cast<SalomeHPContainer*>(this);
+}
+
+Container *SalomeHPContainer::cloneAlways() const
+{
+  return new SalomeHPContainer(*this);
+}
+
+void SalomeHPContainer::setProperty(const std::string& name,const std::string& value)
+{
+  if(name==AOC_ENTRY)//no sense to set it ! It is always true ! ignore it !
+    return ;
+  else if(name==SIZE_OF_POOL_KEY)
+    {
+      std::istringstream iss(value);
+      int val(0);
+      iss >> val;
+      setSizeOfPool(val);
+    }
+  else if(name==INITIALIZE_SCRIPT_KEY)
+    {
+      _initScript=value;
+    }
+  else
+    _sct.setProperty(name,value);
+}
+
+std::string SalomeHPContainer::getProperty(const std::string& name) const
+{
+  if(name==AOC_ENTRY)
+    {
+      return std::string("1");
+    }
+  else if(name==SIZE_OF_POOL_KEY)
+    {
+      std::ostringstream oss; oss << getSizeOfPool();
+      return oss.str();
+    }
+  else if(name==INITIALIZE_SCRIPT_KEY)
+    {
+      return _initScript;
+    }
+  else
+    return _sct.getProperty(name);
+}
+
+void SalomeHPContainer::clearProperties()
+{
+  _initScript.clear();
+  _sct.clearProperties();
+}
+
+void SalomeHPContainer::addComponentName(const std::string& name)
+{
+  _componentNames.push_back(name);
+}
+
+std::map<std::string,std::string> SalomeHPContainer::getProperties() const
+{
+  std::map<std::string,std::string> ret(_sct.getProperties());
+  std::ostringstream oss; oss << getSizeOfPool();
+  ret[SIZE_OF_POOL_KEY]=oss.str();
+  if(!_initScript.empty())
+    ret[INITIALIZE_SCRIPT_KEY]=_initScript;
+  return ret;
+}
+
+std::map<std::string,std::string> SalomeHPContainer::getResourceProperties(const std::string& name) const
+{
+  return _sct.getResourceProperties(name);
+}
+
+void SalomeHPContainer::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception)
+{
+  if(inst->getKind()!=SalomeHPComponent::KIND)
+    throw Exception("SalomeHPContainer::checkCapabilityToDealWith : SalomeContainer is not able to deal with this type of ComponentInstance.");
+}
diff --git a/src/runtime/SalomeHPContainer.hxx b/src/runtime/SalomeHPContainer.hxx
new file mode 100644 (file)
index 0000000..0a0bcca
--- /dev/null
@@ -0,0 +1,104 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __SALOMEHPCONTAINER_HXX__
+#define __SALOMEHPCONTAINER_HXX__
+
+#include "YACSRuntimeSALOMEExport.hxx"
+#include "HomogeneousPoolContainer.hxx"
+#include "SalomeContainerHelper.hxx"
+#include "SalomeContainerTools.hxx"
+#include "SalomeHPContainerTools.hxx"
+#include "Mutex.hxx"
+#include <string>
+#include <vector>
+#include <map>
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOME_Component)
+#include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Task;
+    class SalomeComponent;
+
+    class YACSRUNTIMESALOME_EXPORT SalomeHPContainer : public HomogeneousPoolContainer
+    {
+    public:
+      SalomeHPContainer();
+      SalomeHPContainer(const SalomeHPContainer& other);
+      //HP specific part
+      void setSizeOfPool(int sz);
+      int getSizeOfPool() const;
+      std::size_t getNumberOfFreePlace() const;
+      void allocateFor(const std::vector<const Task *>& nodes);
+      void release(const Task *node);
+      //! For thread safety for concurrent load operation on same Container.
+      void lock();
+      //! For thread safety for concurrent load operation on same Container.
+      void unLock();
+      //
+      std::string getKind() const;
+      std::string getDiscreminantStrOfThis(const Task *askingNode) const;
+      bool isAlreadyStarted(const Task *askingNode) const;
+      void start(const Task *askingNode) throw(Exception);
+      void shutdown(int level);
+      std::string getPlacementId(const Task *askingNode) const;
+      std::string getFullPlacementId(const Task *askingNode) const;
+      Container *clone() const;
+      Container *cloneAlways() const;
+      void setProperty(const std::string& name,const std::string& value);
+      std::string getProperty(const std::string& name) const;
+      void clearProperties();
+      void addComponentName(const std::string& name);
+      std::map<std::string,std::string> getProperties() const;
+      std::map<std::string,std::string> getResourceProperties(const std::string& name) const;
+      void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception);
+      //
+#ifndef SWIG
+      std::size_t locateTask(const Task *askingNode) const { return _launchModeType.locateTask(askingNode); }
+      const SalomeContainerTools &getContainerInfo() const { return _sct; }
+      std::vector<std::string> getComponentNames() const { return _componentNames; }
+      int getShutdownLev() const { return _shutdownLevel; }
+      SalomeContainerMonoHelper *getHelperOfTask(const Task *node) { return _launchModeType.getHelperOfTask(node); }
+      const SalomeContainerMonoHelper *getHelperOfTask(const Task *node) const { return _launchModeType.getHelperOfTask(node); }
+      //
+      YACS::BASES::Mutex& getLocker() { return _mutex; }
+#endif
+    public:
+      static const char KIND[];
+    protected:
+#ifndef SWIG
+      ~SalomeHPContainer();
+#endif
+    protected:
+      int _shutdownLevel;
+      SalomeContainerTools _sct;
+      YACS::BASES::Mutex _mutex;
+      std::vector<std::string> _componentNames;
+      //
+      SalomeHPContainerVectOfHelper _launchModeType;
+      std::string _initScript;
+    };
+  }
+}
+
+#endif
diff --git a/src/runtime/SalomeHPContainerTools.cxx b/src/runtime/SalomeHPContainerTools.cxx
new file mode 100644 (file)
index 0000000..323b200
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "SalomeHPContainerTools.hxx"
+#include "SalomeHPContainer.hxx"
+#include "AutoLocker.hxx"
+#include "Exception.hxx"
+
+#include <algorithm>
+
+using namespace YACS::ENGINE;
+
+void SalomeHPContainerVectOfHelper::resize(std::size_t sz)
+{
+  std::size_t oldSize(_launchModeType.size());
+  if(sz==oldSize)
+    return;
+  checkNoCurrentWork();
+  _whichOccupied.resize(sz); std::fill(_whichOccupied.begin(),_whichOccupied.end(),false);
+  _launchModeType.resize(sz);
+  for(std::size_t i=oldSize;i<sz;i++)
+      _launchModeType[i]=new SalomeContainerMonoHelper;
+  _currentlyWorking.clear();
+}
+
+std::size_t SalomeHPContainerVectOfHelper::getNumberOfFreePlace() const
+{
+  return std::count(_whichOccupied.begin(),_whichOccupied.end(),false);
+}
+
+void SalomeHPContainerVectOfHelper::allocateFor(const std::vector<const Task *>& nodes)
+{
+  for(std::vector<const Task *>::const_iterator it=nodes.begin();it!=nodes.end();it++)
+    {
+      if(!(*it))
+        continue;
+      if(_currentlyWorking.find(*it)!=_currentlyWorking.end())
+        throw Exception("Searching to allocate for a ServiceNode instance already declared as allocated !");
+      std::vector<bool>::iterator it2(std::find(_whichOccupied.begin(),_whichOccupied.end(),false));
+      if(it2==_whichOccupied.end())
+        throw Exception("All ressources are already occupied ! You are expected to wait for released resources !");
+      std::size_t pos(std::distance(_whichOccupied.begin(),it2));
+      _currentlyWorking[*it]=pos; _whichOccupied[pos]=true;
+    }
+}
+
+void SalomeHPContainerVectOfHelper::release(const Task *node)
+{
+  if(!node)
+    return ;
+  std::map< const Task *,std::size_t >::iterator it(_currentlyWorking.find(node));
+  if(it==_currentlyWorking.end())
+    throw Exception("Request to release a resource not declared as working !");
+  _whichOccupied[(*it).second]=false;
+  _currentlyWorking.erase(it);
+}
+
+std::size_t SalomeHPContainerVectOfHelper::locateTask(const Task *node) const
+{
+  std::map< const Task *,std::size_t >::const_iterator it(_currentlyWorking.find(node));
+  if(it==_currentlyWorking.end())
+    throw Exception("current Node to be located is not marked as launched !");
+  std::size_t ret((*it).second);
+  checkPosInVec(ret);
+  return ret;
+}
+
+const SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTaskThreadSafe(const SalomeHPContainer *cont, const Task *node) const
+{
+  YACS::BASES::AutoLocker<Container> alck(const_cast<SalomeHPContainer *>(cont));
+  return _launchModeType[locateTask(node)];
+}
+
+const SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTask(const Task *node) const
+{
+  return _launchModeType[locateTask(node)];
+}
+
+SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTaskThreadSafe(SalomeHPContainer *cont, const Task *node)
+{
+  YACS::BASES::AutoLocker<Container> alck(cont);
+  return _launchModeType[locateTask(node)];
+}
+
+SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTask(const Task *node)
+{
+  return _launchModeType[locateTask(node)];
+}
+
+void SalomeHPContainerVectOfHelper::checkNoCurrentWork() const
+{
+  for(std::map<const Task *,std::size_t >::const_iterator it=_currentlyWorking.begin();it!=_currentlyWorking.end();it++)
+    if((*it).first)
+      throw Exception("Something wrong a node is still declared to be using the ressource !");
+  for(std::vector< YACS::BASES::AutoRefCnt<SalomeContainerMonoHelper> >::const_iterator it=_launchModeType.begin();it!=_launchModeType.end();it++)
+    if((*it)->isAlreadyStarted(0))
+      throw Exception("Some of the containers have be started ! Please shutdown them before !");
+}
+
+void SalomeHPContainerVectOfHelper::checkPosInVec(std::size_t pos) const
+{
+  if(pos<0 || pos>=_launchModeType.size())
+    throw Exception("The task has been found, but its id is not in the correct range ! resize of of container size during run ?");
+}
diff --git a/src/runtime/SalomeHPContainerTools.hxx b/src/runtime/SalomeHPContainerTools.hxx
new file mode 100644 (file)
index 0000000..34a40af
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __SALOMEHPCONTAINERTOOLS_HXX__
+#define __SALOMEHPCONTAINERTOOLS_HXX__
+
+#include "YACSRuntimeSALOMEExport.hxx"
+#include "SalomeContainerHelper.hxx"
+
+#include "AutoRefCnt.hxx"
+
+#include <map>
+#include <vector>
+
+namespace YACS
+{
+  namespace ENGINE
+  {
+    class Task;
+    class SalomeComponent;
+    class SalomeHPContainer;
+    class SalomeContainerMonoHelper;
+    class SalomeHPContainerVectOfHelper
+    {
+    public:
+      std::size_t size() const { return _launchModeType.size(); }
+      void resize(std::size_t sz);
+      std::size_t getNumberOfFreePlace() const;
+      void allocateFor(const std::vector<const Task *>& nodes);
+      void release(const Task *node);
+      std::size_t locateTask(const Task *node) const;
+      const SalomeContainerMonoHelper *at(std::size_t pos) const { checkPosInVec(pos); return _launchModeType[pos]; }
+      SalomeContainerMonoHelper *at(std::size_t pos) { checkPosInVec(pos); return _launchModeType[pos]; }
+      const SalomeContainerMonoHelper *getHelperOfTaskThreadSafe(const SalomeHPContainer *cont, const Task *node) const;
+      const SalomeContainerMonoHelper *getHelperOfTask(const Task *node) const;
+      SalomeContainerMonoHelper *getHelperOfTaskThreadSafe(SalomeHPContainer *cont, const Task *node);
+      SalomeContainerMonoHelper *getHelperOfTask(const Task *node);
+    private:
+      void checkNoCurrentWork() const;
+      void checkPosInVec(std::size_t pos) const;
+    private:
+      std::vector<bool> _whichOccupied;
+      std::vector< BASES::AutoRefCnt<YACS::ENGINE::SalomeContainerMonoHelper> > _launchModeType;
+      std::map<const Task *,std::size_t > _currentlyWorking;
+    };
+  }
+}
+
+#endif
index 7e79c081ea02f68b8bec697b5952af3116ef99d8..01a90b187496f226f5744911e650f1ce344dc9f6 100644 (file)
@@ -44,11 +44,11 @@ SalomePythonComponent::~SalomePythonComponent()
 {
 }
 
-void SalomePythonComponent::load()
+void SalomePythonComponent::load(Task *askingNode)
 {
   if(_container)
     {
-      _container->start(this);
+      _container->start(askingNode);
       return;
     }
   //This component has no specified container : use default container policy
@@ -56,16 +56,16 @@ void SalomePythonComponent::load()
   //throw Exception("SalomePythonComponent::load : no container specified !!! To be implemented in executor to allocate default a Container in case of presenceOfDefaultContainer.");
 }
 
-void SalomePythonComponent::unload()
+void SalomePythonComponent::unload(Task *askingNode)
 {
 }
 
-bool SalomePythonComponent::isLoaded()
+bool SalomePythonComponent::isLoaded(Task *askingNode) const
 {
   if(!_container)
     return false;
   else
-    return _container->isAlreadyStarted(this);
+    return _container->isAlreadyStarted(askingNode);
 }
 
 std::string SalomePythonComponent::getKind() const
@@ -85,6 +85,11 @@ ComponentInstance* SalomePythonComponent::clone() const
     return new SalomePythonComponent(*this);
 }
 
+ComponentInstance *SalomePythonComponent::cloneAlways() const
+{
+  return new SalomePythonComponent(*this);
+}
+
 ServiceNode *SalomePythonComponent::createNode(const std::string &name)
 {
   ServiceNode* node=new SalomePythonNode(name);
@@ -99,10 +104,10 @@ std::string SalomePythonComponent::getFileRepr() const
   return stream.str();
 }
 
-std::string SalomePythonComponent::getStringValueToExportInInterp() const
+std::string SalomePythonComponent::getStringValueToExportInInterp(const Task *askingNode) const
 {
   if(!_container)
     return "localhost/FactoryServer";
   else
-    return _container->getPlacementId(this);
+    return _container->getPlacementId(askingNode);
 }
index ec1246a24e95122dc86952cf362e6af04a7a9439..445aff7ae496faf8f598c1460f585f6c1594bc3e 100644 (file)
@@ -33,15 +33,16 @@ namespace YACS
       SalomePythonComponent(const SalomePythonComponent& other);
       std::string getPlacementId() const;
       virtual ~SalomePythonComponent();
-      virtual void load();
-      virtual void unload();
-      virtual bool isLoaded();
+      virtual void load(Task *askingNode);
+      virtual void unload(Task *askingNode);
+      virtual bool isLoaded(Task *askingNode) const;
       virtual std::string getKind() const;
       virtual ComponentInstance* clone() const;
+      virtual ComponentInstance* cloneAlways() const;
       virtual std::string getFileRepr() const;
       virtual ServiceNode *createNode(const std::string &name);
       //! The specific method that justified SalomePythonComponent class.
-      std::string getStringValueToExportInInterp() const;
+      std::string getStringValueToExportInInterp(const Task *askingNode) const;
     public:
       unsigned _cntForRepr;
       static unsigned _cntForReprS;
index 4f3b55d102a0d918a6b309743dba8e8c369a21fa..773efe7addb08c23108def53bab38683661224e6 100644 (file)
@@ -71,7 +71,7 @@ void SalomePythonNode::load()
   ServiceInlineNode::load();
   cerr << "---------------SalomePythonNode::load function---------------" << endl;
   list<OutputPort *>::iterator iter;
-  string value2Export=((SalomePythonComponent*)_component)->getStringValueToExportInInterp();
+  string value2Export=((SalomePythonComponent*)_component)->getStringValueToExportInInterp(this);
   PyObject* ob=PyString_FromString(value2Export.c_str());
   PyDict_SetItemString(_context,PLACEMENT_VAR_NAME_IN_INTERP,ob);
   for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
index e2563387569b712c79b3b7289b52674c9d65bc48..e44a60a32ce3009b89de56e33bf95f1d2f2a0c33 100644 (file)
@@ -21,6 +21,7 @@
 #include "XMLPorts.hxx"
 #include "Mutex.hxx"
 #include "TypeCode.hxx"
+#include "AutoLocker.hxx"
 
 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -91,21 +92,22 @@ void XmlNode::execute()
   DEBTRACE("execute");
   char dir[]="yacsXXXXXX";
   // add a lock around mkdtemp (seems not thread safe)
-  MUTEX.lock();
+  {
+    YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&MUTEX);
 #ifdef WIN32
-  char mdir [512+1];
-  GetTempPath(MAX_PATH+1, mdir);
-  CreateDirectory(mdir, NULL);
+    char mdir [512+1];
+    GetTempPath(MAX_PATH+1, mdir);
+    CreateDirectory(mdir, NULL);
 #else
-  char* mdir=mkdtemp(dir);
+    char* mdir=mkdtemp(dir);
 #endif
-  MUTEX.unlock();
-  if(mdir==NULL)
-    {
-      perror("mkdtemp failed");
-      std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl;
-      throw Exception("Execution problem in mkdtemp");
-    }
+    if(mdir==NULL)
+      {
+        perror("mkdtemp failed");
+        std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl;
+        throw Exception("Execution problem in mkdtemp");
+      }
+  }
   std::string sdir(dir);
   std::string input=sdir+"/input";
   std::ofstream f(input.c_str());
index b7eb87f44a8f501a92d276db985e90fce43d09d8..b06663b1946abd5a86623b275d166d938ec73106 100644 (file)
@@ -44,6 +44,7 @@
 
 %{
 #include "SalomeContainer.hxx"
+#include "SalomeHPContainer.hxx"
 #include "RuntimeSALOME.hxx"
 #include "SALOMEDispatcher.hxx"
 #include "SalomeProc.hxx"
 
 %include <YACSRuntimeSALOMEExport.hxx>
 %include "SalomeContainer.hxx"
+%include "SalomeHPContainer.hxx"
 %include "RuntimeSALOME.hxx"
 %include "SALOMEDispatcher.hxx"
 %include "SalomeProc.hxx"
index b5a0879bf729a41814b23c79e04c68421f40f008..fab182bac7cf74ed73782a683b6e71f2ab7f6d2c 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "containerParsers.hxx"
 #include "propertyParsers.hxx"
+#include "HomogeneousPoolContainer.hxx"
 
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
@@ -58,6 +59,7 @@ namespace YACS
       parser* pp=&parser::main_parser;
       if(element == "machine")pp=&machinetypeParser::machineParser;
       if(element == "property")pp=&propertytypeParser::propertyParser;
+      if(element == "initializescriptkey")pp=&codetypeParser::codeParser;
       SetUserDataAndPush(pp);
       pp->init();
       pp->pre();
@@ -68,6 +70,7 @@ namespace YACS
       std::string element(el);
       if(element == "machine")machine_(((machinetypeParser*)child)->post());
       if(element == "property")property(((propertytypeParser*)child)->post());
+      if(element == "initializescriptkey")initializescriptkey(((codetypeParser*)child)->post());
     }
   void containertypeParser::pre ()
     {
@@ -85,6 +88,11 @@ namespace YACS
       DEBTRACE( "property_set: " << prop._name << " " << prop._value );
       _container._props[prop._name]=prop._value;
     }
+  void containertypeParser::initializescriptkey(const myfunc& f)
+  {
+    _container._props[YACS::ENGINE::HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY]=f._code;
+  }
+
   mycontainer containertypeParser::post()
     {
       //mincount("machine",1);
index be9b83436a9fba9c544861854f45aa3ace6d185b..d8e2ee1a58acd88d7c57a542fca6f9fc87cbaa22 100644 (file)
@@ -21,6 +21,7 @@
 #define _CONTAINERPARSER_HXX_
 
 #include "parserBase.hxx"
+#include "codeParsers.hxx"
 #include "factory.hxx"
 
 namespace YACS
@@ -72,6 +73,7 @@ struct containertypeParser: parser
   virtual void name(const std::string& name);
   virtual void machine_(const machine& m);
   virtual void property (const myprop& prop);
+  virtual void initializescriptkey(const myfunc& f);
   mycontainer post();
   mycontainer _container;
 };
index 8384fbb4c1dab80e4a7ccadb5ada83cf462a069b..cc02ff46aa7150364b906a82276ceab511d755bd 100644 (file)
@@ -53,11 +53,13 @@ struct proctypeParser: bloctypeParser<T>
     {
       for (int i = 0; attr[i]; i += 2) 
         {
-          if(std::string(attr[i]) == "state")this->state(attr[i+1]);
-          if(std::string(attr[i]) == "name")name(attr[i+1]);
+          if(std::string(attr[i]) == "state")
+            this->state(attr[i+1]);
+          if(std::string(attr[i]) == "name")
+            name(attr[i+1]);
         }
     }
-  virtual void pre ()
+  virtual void pre()
     {
         std::string name("proc");
         currentProc=theRuntime->createProc(name);
@@ -65,34 +67,34 @@ struct proctypeParser: bloctypeParser<T>
         currentProc->names.push_back("");
     }
 
-  virtual void name (const std::string& name)
+  virtual void name(const std::string& name)
     {
       currentProc->setName(name);
     }
 
-  virtual void type (const mytype& t)
+  virtual void type(const mytype& t)
     {
         DEBTRACE( "type_set" );
         YACS::ENGINE::TypeCode* tt=currentProc->createType(t._name,t._kind);
         tt->decrRef();
     }
-  virtual void sequence (ENGINE::TypeCode* const& t)
+  virtual void sequence(ENGINE::TypeCode* const& t)
     {
         DEBTRACE( "sequence_set" );
         t->decrRef();
     }
-  virtual void objref (ENGINE::TypeCode* const& t)
+  virtual void objref(ENGINE::TypeCode* const& t)
     {
         DEBTRACE( "objref_set" );
         t->decrRef();
     }
-  virtual void struct_ (ENGINE::TypeCode* const& t)
+  virtual void struct_(ENGINE::TypeCode* const& t)
     {
         DEBTRACE( "struct_set" );
         t->decrRef();
     }
 
-  virtual void componentinstance (const mycomponentinstance& t)
+  virtual void componentinstance(const mycomponentinstance& t)
     {
       DEBTRACE( "componentinstance: " << t._name );
       YACS::ENGINE::ComponentInstance* inst=currentProc->createComponentInstance(t._component,t._name,t._kind);
@@ -128,7 +130,7 @@ struct proctypeParser: bloctypeParser<T>
       inst->decrRef();
     }
 
-  virtual void container (const mycontainer& t)
+  virtual void container(const mycontainer& t)
     {
       DEBTRACE( "container_set: " << t._name )             
       std::vector<machine>::const_iterator iter;
@@ -143,16 +145,20 @@ struct proctypeParser: bloctypeParser<T>
         }
       else
         {
-          YACS::ENGINE::Container* cont=currentProc->createContainer(t._name);
           // Set all properties for this container
-          std::map<std::string, std::string>::const_iterator pt;
+          std::string kindOfContainer;
+          std::map<std::string, std::string>::const_iterator pt(t._props.find(std::string(ENGINE::Container::KIND_ENTRY)));
+          if(pt!=t._props.end())
+            kindOfContainer=pt->second;
+          YACS::ENGINE::Container *cont(currentProc->createContainer(t._name,kindOfContainer));
           for(pt=t._props.begin();pt!=t._props.end();pt++)
-            cont->setProperty((*pt).first,(*pt).second);
+            if((*pt).second!=ENGINE::Container::KIND_ENTRY)
+              cont->setProperty((*pt).first,(*pt).second);
           cont->decrRef();
         }
     }
 
-  T post(){return this->_bloc;}
+  T post() { return this->_bloc; }
 };
 
 template <class T> proctypeParser<T> proctypeParser<T>::procParser;
index 3a3cdd0014d49cf4539af27f963b7ee5b1316fc4..11b65a1abedf278350f8ee17b1afce11407e5300 100644 (file)
@@ -68,10 +68,18 @@ struct servertypeParser:public inlinetypeParser<T>
     {
       DEBTRACE( "server_loadcontainer: " << name )             
       this->_node=(YACS::ENGINE::ServerNode*)theRuntime->createFuncNode("DistPython",this->_name);
-      YACS::ENGINE::Container *cont=currentProc->createContainer(this->_node->getEffectiveKindOfServer());
-      cont->setName(name);
-      this->_node->setContainer(cont);
-      cont->decrRef();
+      std::map<std::string,YACS::ENGINE::Container *>::const_iterator it(currentProc->containerMap.find(name));
+      if(it!=currentProc->containerMap.end())
+        {
+          this->_node->setContainer((*it).second);
+        }
+      else
+        {
+          YACS::ENGINE::Container *cont=currentProc->createContainer(this->_node->getEffectiveKindOfServer());
+          cont->setName(name);
+          this->_node->setContainer(cont);
+          cont->decrRef();
+        }
     }
   virtual void script (const myfunc& f)
   {
old mode 100755 (executable)
new mode 100644 (file)
index 1059186..a4d1e3b
@@ -31,7 +31,7 @@ class StdAloneYacsLoaderTest1(unittest.TestCase):
     pass
 
   def test1(self):
-    """tests imbrication od"""
+    """tests imbrication of foreach loop."""
     SALOMERuntime.RuntimeSALOME_setRuntime()
     l=loader.YACSLoader()
     ex=pilot.ExecutorSwig()
index 9e6718e2df4f8760442f5eea9619cb5cb1bf6128..83db9dcf2b99793eb5442330644f756544e2f7b4 100644 (file)
@@ -87,7 +87,15 @@ if [ $ret5 -gt 0 ]; then
   exit $ret5
 fi
 
-let ret=$ret0+$ret1+$ret2+$ret3+$ret4+$ret5
+chmod +x @CMAKE_CURRENT_SOURCE_DIR@/testSaveLoadRun.py
+python  @CMAKE_CURRENT_SOURCE_DIR@/testSaveLoadRun.py
+ret6=$?
+if [ $ret6 -gt 0 ]; then
+  echo "exec status testSaveLoadRun : " $ret6
+  exit $ret6
+fi
+
+let ret=$ret0+$ret1+$ret2+$ret3+$ret4+$ret5+$ret6
 
 # --- return unit tests status
 
diff --git a/src/yacsloader_swig/Test/testSaveLoadRun.py b/src/yacsloader_swig/Test/testSaveLoadRun.py
new file mode 100644 (file)
index 0000000..4899838
--- /dev/null
@@ -0,0 +1,590 @@
+# Copyright (C) 2006-2014  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import unittest
+import pilot
+import SALOMERuntime
+import loader
+
+import datetime
+
+class TestSaveLoadRun(unittest.TestCase):
+  def setUp(self):
+    SALOMERuntime.RuntimeSALOME.setRuntime()
+    self.r=SALOMERuntime.getSALOMERuntime()
+    pass
+
+  def test0(self):
+    """First test of HP Container no loop here only the 3 sorts of python nodes (the Distributed is it still used and useful ?) """
+    fname="TestSaveLoadRun0.xml"
+    nbOfNodes=8
+    sqrtOfNumberOfTurn=1000 # 3000 -> 3.2s/Node, 1000 -> 0.1s/Node
+    l=loader.YACSLoader()
+    p=self.r.createProc("prTest0")
+    td=p.createType("double","double")
+    ti=p.createType("int","int")
+    cont=p.createContainer("gg","HPSalome")
+    cont.setSizeOfPool(4)
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    script0="""
+def ff(nb,dbg):
+    from math import cos
+    import datetime
+    
+    ref=datetime.datetime.now()
+    t=0. ; pas=1./float(nb)
+    for i in xrange(nb):
+        for j in xrange(nb):
+            x=j*pas
+            t+=1.+cos(1.*(x*3.14159))
+            pass
+        pass
+    print "coucou from script0-%i  -> %s"%(dbg,str(datetime.datetime.now()-ref))
+    return t
+"""
+    script1="""
+from math import cos
+import datetime
+ref=datetime.datetime.now()
+o2=0. ; pas=1./float(i1)
+for i in xrange(i1):
+  for j in xrange(i1):
+    x=j*pas
+    o2+=1.+cos(1.*(x*3.14159))
+    pass
+print "coucou from script1-%i  -> %s"%(dbg,str(datetime.datetime.now()-ref))
+"""
+    for i in xrange(nbOfNodes):
+      node0=self.r.createFuncNode("DistPython","node%i"%(i))
+      p.edAddChild(node0)
+      node0.setFname("ff")
+      node0.setContainer(cont)
+      node0.setScript(script0)
+      nb=node0.edAddInputPort("nb",ti) ; nb.edInitInt(sqrtOfNumberOfTurn)
+      dbg=node0.edAddInputPort("dbg",ti) ; dbg.edInitInt(i+1)
+      out0=node0.edAddOutputPort("s",td)
+      #
+      nodeMiddle=self.r.createFuncNode("Salome","node%i_1"%(i))
+      p.edAddChild(nodeMiddle)
+      p.edAddCFLink(node0,nodeMiddle)
+      nodeMiddle.setFname("ff")
+      nodeMiddle.setContainer(cont)
+      nodeMiddle.setScript(script0)
+      nb=nodeMiddle.edAddInputPort("nb",ti) ; nb.edInitInt(sqrtOfNumberOfTurn)
+      dbg=nodeMiddle.edAddInputPort("dbg",ti) ; dbg.edInitInt(i+1)
+      out0=nodeMiddle.edAddOutputPort("s",td)
+      nodeMiddle.setExecutionMode("remote")
+      #
+      nodeEnd=self.r.createScriptNode("Salome","node%i_2"%(i+1))
+      p.edAddChild(nodeEnd)
+      p.edAddCFLink(nodeMiddle,nodeEnd)
+      nodeEnd.setContainer(cont)
+      nodeEnd.setScript(script1)
+      i1=nodeEnd.edAddInputPort("i1",ti) ; i1.edInitInt(sqrtOfNumberOfTurn)
+      dbg=nodeEnd.edAddInputPort("dbg",ti) ; dbg.edInitInt(i)
+      o2=nodeEnd.edAddOutputPort("o2",td)
+      nodeEnd.setExecutionMode("remote")
+      pass
+    p.saveSchema(fname)
+    p=l.load(fname)
+    ex=pilot.ExecutorSwig()
+    self.assertEqual(p.getState(),pilot.READY)
+    st=datetime.datetime.now()
+    # 1st exec
+    ex.RunW(p,0)
+    print "Time spend of test0 to run 1st %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    # 2nd exec using the same already launched remote python interpreters
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test0 to run 2nd %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    # 3rd exec using the same already launched remote python interpreters
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test0 to run 3rd %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    pass
+
+  def test1(self):
+    """ HP Container again like test0 but the initialization key of HPContainer is used here."""
+    fname="TestSaveLoadRun1.xml"
+    nbOfNodes=8
+    sqrtOfNumberOfTurn=1000 # 3000 -> 3.2s/Node, 1000 -> 0.1s/Node
+    l=loader.YACSLoader()
+    p=self.r.createProc("prTest1")
+    td=p.createType("double","double")
+    ti=p.createType("int","int")
+    cont=p.createContainer("gg","HPSalome")
+    cont.setSizeOfPool(4)
+    cont.setProperty("InitializeScriptKey","aa=123.456")
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    script0="""
+def ff(nb,dbg):
+    from math import cos
+    import datetime
+    
+    ref=datetime.datetime.now()
+    t=0. ; pas=1./float(nb)
+    for i in xrange(nb):
+        for j in xrange(nb):
+            x=j*pas
+            t+=1.+cos(1.*(x*3.14159))
+            pass
+        pass
+    print "coucou from script0-%i  -> %s"%(dbg,str(datetime.datetime.now()-ref))
+    return t
+"""
+    # here in script1 aa is refered ! aa will exist thanks to HPCont Init Script
+    script1="""
+from math import cos
+import datetime
+ref=datetime.datetime.now()
+o2=0. ; pas=1./float(i1)
+for i in xrange(i1):
+  for j in xrange(i1):
+    x=j*pas
+    o2+=1.+cos(1.*(x*3.14159))
+    pass
+print "coucou %lf from script1-%i  -> %s"%(aa,dbg,str(datetime.datetime.now()-ref))
+aa+=1.
+"""
+    #
+    for i in xrange(nbOfNodes):
+      nodeMiddle=self.r.createFuncNode("Salome","node%i_1"%(i)) # PyFuncNode remote
+      p.edAddChild(nodeMiddle)
+      nodeMiddle.setFname("ff")
+      nodeMiddle.setContainer(cont)
+      nodeMiddle.setScript(script0)
+      nb=nodeMiddle.edAddInputPort("nb",ti) ; nb.edInitInt(sqrtOfNumberOfTurn)
+      dbg=nodeMiddle.edAddInputPort("dbg",ti) ; dbg.edInitInt(i+1)
+      out0=nodeMiddle.edAddOutputPort("s",td)
+      nodeMiddle.setExecutionMode("remote")
+      #
+      nodeEnd=self.r.createScriptNode("Salome","node%i_2"%(i+1)) # PythonNode remote
+      p.edAddChild(nodeEnd)
+      p.edAddCFLink(nodeMiddle,nodeEnd)
+      nodeEnd.setContainer(cont)
+      nodeEnd.setScript(script1)
+      i1=nodeEnd.edAddInputPort("i1",ti) ; i1.edInitInt(sqrtOfNumberOfTurn)
+      dbg=nodeEnd.edAddInputPort("dbg",ti) ; dbg.edInitInt(i)
+      o2=nodeEnd.edAddOutputPort("o2",td)
+      nodeEnd.setExecutionMode("remote")
+      pass
+    #
+    p.saveSchema(fname)
+    p=l.load(fname)
+    self.assertEqual(p.edGetDirectDescendants()[0].getContainer().getProperty("InitializeScriptKey"),"aa=123.456")
+    # 1st exec
+    ex=pilot.ExecutorSwig()
+    self.assertEqual(p.getState(),pilot.READY)
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test1 to 1st run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    # 2nd exec
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test1 to 2nd run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    # 3rd exec
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test1 to 3rd run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    pass
+
+  def test2(self):
+    """ Test on HP Containers in foreach context."""
+    script0="""def ff():
+    global aa
+    print "%%lf - %%s"%%(aa,str(my_container))
+    return 16*[%i],0
+"""
+    script1="""from math import cos
+import datetime
+ref=datetime.datetime.now()
+o2=0. ; pas=1./float(i1)
+for i in xrange(i1):
+  for j in xrange(i1):
+    x=j*pas
+    o2+=1.+cos(1.*(x*3.14159))
+    pass
+print "coucou %lf from script  -> %s"%(aa,str(datetime.datetime.now()-ref))
+aa+=1.
+o3=0
+"""
+    script2="""o9=sum(i8)
+"""
+    fname="TestSaveLoadRun2.xml"
+    nbOfNodes=8
+    sqrtOfNumberOfTurn=1000 # 3000 -> 3.2s/Node, 1000 -> 0.1s/Node
+    l=loader.YACSLoader()
+    p=self.r.createProc("prTest1")
+    td=p.createType("double","double")
+    ti=p.createType("int","int")
+    tdi=p.createSequenceTc("seqint","seqint",ti)
+    tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+    cont=p.createContainer("gg","HPSalome")
+    cont.setSizeOfPool(4)
+    cont.setProperty("InitializeScriptKey","aa=123.456")
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    #
+    node0=self.r.createFuncNode("Salome","PyFunction0") # PyFuncNode remote
+    p.edAddChild(node0)
+    node0.setFname("ff")
+    node0.setContainer(cont)
+    node0.setScript(script0%(sqrtOfNumberOfTurn))
+    out0_0=node0.edAddOutputPort("o1",tdi)
+    out1_0=node0.edAddOutputPort("o2",ti)
+    node0.setExecutionMode("remote")
+    #
+    node1=self.r.createForEachLoop("node1",ti)
+    p.edAddChild(node1)
+    p.edAddCFLink(node0,node1)
+    p.edAddLink(out0_0,node1.edGetSeqOfSamplesPort())
+    node1.edGetNbOfBranchesPort().edInitInt(8)
+    #
+    node2=self.r.createScriptNode("Salome","PyScript3")
+    node1.edAddChild(node2)
+    node2.setContainer(cont)
+    node2.setScript(script1)
+    i1=node2.edAddInputPort("i1",ti)
+    p.edAddLink(node1.edGetSamplePort(),i1)
+    out0_2=node2.edAddOutputPort("o2",td)
+    out1_2=node2.edAddOutputPort("o3",ti)
+    node2.setExecutionMode("remote")
+    #
+    node3=self.r.createScriptNode("Salome","PyScript7")
+    p.edAddChild(node3)
+    node3.setScript(script2)
+    p.edAddCFLink(node1,node3)
+    i8=node3.edAddInputPort("i8",tdd)
+    o9=node3.edAddOutputPort("o9",td)
+    p.edAddLink(out0_2,i8)
+    #
+    p.saveSchema(fname)
+    p=l.load(fname)
+    o9=p.getChildByName("PyScript7").getOutputPort("o9")
+    self.assertTrue(len(p.edGetDirectDescendants()[1].getChildByName("PyScript3").getContainer().getProperty("InitializeScriptKey"))!=0)
+    # 1st exec
+    refExpected=16016013.514623128
+    ex=pilot.ExecutorSwig()
+    self.assertEqual(p.getState(),pilot.READY)
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test2 to 1st run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    self.assertAlmostEqual(refExpected,o9.getPyObj(),5)
+    # 2nd exec
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test2 to 2nd run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    self.assertAlmostEqual(refExpected,o9.getPyObj(),5)
+    # 3rd exec
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test2 to 3rd run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    self.assertAlmostEqual(refExpected,o9.getPyObj(),5)
+    pass
+
+  def test3(self):
+    """ Test that focuses on parallel load of containers."""
+    script0="""def ff():
+    global aa
+    print "%%lf - %%s"%%(aa,str(my_container))
+    return 100*[%i],0
+"""
+    script1="""from math import cos
+import datetime
+ref=datetime.datetime.now()
+o2=0. ; pas=1./float(i1)
+for i in xrange(i1):
+  for j in xrange(i1):
+    x=j*pas
+    o2+=1.+cos(1.*(x*3.14159))
+    pass
+print "coucou %lf from script  -> %s"%(aa,str(datetime.datetime.now()-ref))
+aa+=1.
+o3=0
+"""
+    script2="""o9=sum(i8)
+"""
+    fname="TestSaveLoadRun3.xml"
+    nbOfNodes=8
+    sqrtOfNumberOfTurn=10
+    l=loader.YACSLoader()
+    p=self.r.createProc("prTest1")
+    td=p.createType("double","double")
+    ti=p.createType("int","int")
+    tdi=p.createSequenceTc("seqint","seqint",ti)
+    tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+    cont=p.createContainer("gg","HPSalome")
+    cont.setSizeOfPool(8)
+    cont.setProperty("InitializeScriptKey","aa=123.456")
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    #
+    node0=self.r.createFuncNode("Salome","PyFunction0") # PyFuncNode remote
+    p.edAddChild(node0)
+    node0.setFname("ff")
+    node0.setContainer(cont)
+    node0.setScript(script0%(sqrtOfNumberOfTurn))
+    out0_0=node0.edAddOutputPort("o1",tdi)
+    out1_0=node0.edAddOutputPort("o2",ti)
+    node0.setExecutionMode("remote")
+    #
+    node1=self.r.createForEachLoop("node1",ti)
+    p.edAddChild(node1)
+    p.edAddCFLink(node0,node1)
+    p.edAddLink(out0_0,node1.edGetSeqOfSamplesPort())
+    node1.edGetNbOfBranchesPort().edInitInt(16)
+    #
+    node2=self.r.createScriptNode("Salome","PyScript3")
+    node1.edAddChild(node2)
+    node2.setContainer(cont)
+    node2.setScript(script1)
+    i1=node2.edAddInputPort("i1",ti)
+    p.edAddLink(node1.edGetSamplePort(),i1)
+    out0_2=node2.edAddOutputPort("o2",td)
+    out1_2=node2.edAddOutputPort("o3",ti)
+    node2.setExecutionMode("remote")
+    #
+    node3=self.r.createScriptNode("Salome","PyScript7")
+    p.edAddChild(node3)
+    node3.setScript(script2)
+    p.edAddCFLink(node1,node3)
+    i8=node3.edAddInputPort("i8",tdd)
+    o9=node3.edAddOutputPort("o9",td)
+    p.edAddLink(out0_2,i8)
+    #
+    p.saveSchema(fname)
+    p=l.load(fname)
+    o9=p.getChildByName("PyScript7").getOutputPort("o9")
+    self.assertTrue(len(p.edGetDirectDescendants()[1].getChildByName("PyScript3").getContainer().getProperty("InitializeScriptKey"))!=0)
+    # 1st exec
+    refExpected=11000.008377058712
+    ex=pilot.ExecutorSwig()
+    self.assertEqual(p.getState(),pilot.READY)
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test3 to 1st run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    self.assertAlmostEqual(refExpected,o9.getPyObj(),5)
+    # 2nd exec
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test3 to 2nd run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    self.assertAlmostEqual(refExpected,o9.getPyObj(),5)
+    # 3rd exec
+    st=datetime.datetime.now()
+    ex.RunW(p,0)
+    print "Time spend of test3 to 3rd run %s"%(str(datetime.datetime.now()-st))
+    self.assertEqual(p.getState(),pilot.DONE)
+    self.assertAlmostEqual(refExpected,o9.getPyObj(),5)
+    pass
+  
+  def test4(self):
+    """Non regression test of multi pyScriptNode, pyFuncNode sharing the same HPContainer instance."""
+    fname="TestSaveLoadRun4.xml"
+    script1="""nb=7
+ii=0
+o1=nb*[None]
+for i in xrange(nb):
+    tmp=(i+10)*[None]
+    for j in xrange(i+10):
+        tmp[j]=ii
+        ii+=1
+        pass
+    o1[i]=tmp
+    pass
+"""
+    l=loader.YACSLoader()
+    ex=pilot.ExecutorSwig()
+    p=self.r.createProc("pr")
+    cont=p.createContainer("gg","HPSalome")
+    cont.setSizeOfPool(10)
+    td=p.createType("int","int")
+    td2=p.createSequenceTc("seqint","seqint",td)
+    td3=p.createSequenceTc("seqintvec","seqintvec",td2)
+    node1=self.r.createScriptNode("","node1")
+    node1.setScript(script1)
+    o1=node1.edAddOutputPort("o1",td3)
+    p.edAddChild(node1)
+    #
+    node2=self.r.createForEachLoop("node2",td2)
+    p.edAddChild(node2)
+    p.edAddCFLink(node1,node2)
+    p.edAddLink(o1,node2.edGetSeqOfSamplesPort())
+    node2.edGetNbOfBranchesPort().edInitInt(2)
+    node20=self.r.createBloc("node20")
+    node2.edAddChild(node20)
+    node200=self.r.createForEachLoop("node200",td)
+    node20.edAddChild(node200)
+    node200.edGetNbOfBranchesPort().edInitInt(10)
+    p.edAddLink(node2.edGetSamplePort(),node200.edGetSeqOfSamplesPort())
+    node2000=self.r.createScriptNode("","node2000")
+    node2000.setContainer(cont)
+    node2000.setExecutionMode("remote")
+    node200.edAddChild(node2000)
+    i5=node2000.edAddInputPort("i5",td)
+    o6=node2000.edAddOutputPort("o6",td)
+    node2000.setScript("o6=2+i5")
+    p.edAddLink(node200.edGetSamplePort(),i5)
+    #
+    node3=self.r.createForEachLoop("node3",td)
+    p.edAddChild(node3)
+    p.edAddCFLink(node2,node3)
+    p.edAddLink(o6,node3.edGetSeqOfSamplesPort())
+    node3.edGetNbOfBranchesPort().edInitInt(2)
+    node30=self.r.createBloc("node30")
+    node3.edAddChild(node30)
+    node300=self.r.createForEachLoop("node300",td)
+    node30.edAddChild(node300)
+    node300.edGetNbOfBranchesPort().edInitInt(10)
+    p.edAddLink(node3.edGetSamplePort(),node300.edGetSeqOfSamplesPort())
+    node3000=self.r.createScriptNode("","node3000")
+    node3000.setContainer(cont)
+    node3000.setExecutionMode("remote")
+    node300.edAddChild(node3000)
+    i14=node3000.edAddInputPort("i14",td)
+    o15=node3000.edAddOutputPort("o15",td)
+    node3000.setScript("o15=3+i14")
+    p.edAddLink(node300.edGetSamplePort(),i14)
+    #
+    node4=self.r.createScriptNode("","node4")
+    node4.setScript("o9=i8")
+    p.edAddChild(node4)
+    i8=node4.edAddInputPort("i8",td3)
+    o9=node4.edAddOutputPort("o9",td3)
+    p.edAddCFLink(node3,node4)
+    p.edAddLink(o15,i8)
+    p.saveSchema(fname)
+    p=l.load(fname)
+    ex = pilot.ExecutorSwig()
+    self.assertEqual(p.getState(),pilot.READY)
+    ex.RunW(p,0)
+    self.assertEqual(p.getState(),pilot.DONE)
+    zeResu=p.getChildByName("node4").getOutputPort("o9").get()
+    self.assertEqual(zeResu,[[5,6,7,8,9,10,11,12,13,14],[15,16,17,18,19,20,21,22,23,24,25],[26,27,28,29,30,31,32,33,34,35,36,37],[38,39,40,41,42,43,44,45,46,47,48,49,50],[51,52,53,54,55,56,57,58,59,60,61,62,63,64],[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79], [80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95]])
+    pass
+
+  def test5(self):
+    """Non regression test 2 of multi pyNode, pyFuncNode sharing the same HPContainer instance."""
+    fname="TestSaveLoadRun5.xml"
+    script1="""nb=7
+ii=0
+o1=nb*[None]
+for i in xrange(nb):
+    tmp=(i+10)*[None]
+    for j in xrange(i+10):
+        tmp[j]=ii
+        ii+=1
+        pass
+    o1[i]=tmp
+    pass
+"""
+    l=loader.YACSLoader()
+    ex=pilot.ExecutorSwig()
+    p=self.r.createProc("pr")
+    cont=p.createContainer("gg","HPSalome")
+    cont.setSizeOfPool(10)
+    td=p.createType("int","int")
+    td2=p.createSequenceTc("seqint","seqint",td)
+    td3=p.createSequenceTc("seqintvec","seqintvec",td2)
+    node1=self.r.createScriptNode("","node1")
+    node1.setScript(script1)
+    o1=node1.edAddOutputPort("o1",td3)
+    p.edAddChild(node1)
+    #
+    node2=self.r.createForEachLoop("node2",td2)
+    p.edAddChild(node2)
+    p.edAddCFLink(node1,node2)
+    p.edAddLink(o1,node2.edGetSeqOfSamplesPort())
+    node2.edGetNbOfBranchesPort().edInitInt(2)
+    node20=self.r.createBloc("node20")
+    node2.edAddChild(node20)
+    node200=self.r.createForEachLoop("node200",td)
+    node20.edAddChild(node200)
+    node200.edGetNbOfBranchesPort().edInitInt(10)
+    p.edAddLink(node2.edGetSamplePort(),node200.edGetSeqOfSamplesPort())
+    node2000=self.r.createFuncNode("Salome","node2000")
+    node2000.setFname("ff")
+    node2000.setContainer(cont)
+    node2000.setExecutionMode("remote")
+    node200.edAddChild(node2000)
+    i5=node2000.edAddInputPort("i5",td)
+    o6=node2000.edAddOutputPort("o6",td)
+    node2000.setScript("def ff(x):\n  return 2+x")
+    p.edAddLink(node200.edGetSamplePort(),i5)
+    #
+    node3=self.r.createForEachLoop("node3",td)
+    p.edAddChild(node3)
+    p.edAddCFLink(node2,node3)
+    p.edAddLink(o6,node3.edGetSeqOfSamplesPort())
+    node3.edGetNbOfBranchesPort().edInitInt(2)
+    node30=self.r.createBloc("node30")
+    node3.edAddChild(node30)
+    node300=self.r.createForEachLoop("node300",td)
+    node30.edAddChild(node300)
+    node300.edGetNbOfBranchesPort().edInitInt(10)
+    p.edAddLink(node3.edGetSamplePort(),node300.edGetSeqOfSamplesPort())
+    node3000=self.r.createFuncNode("Salome","node3000")
+    node3000.setFname("ff")
+    node3000.setContainer(cont)
+    node3000.setExecutionMode("remote")
+    node300.edAddChild(node3000)
+    i14=node3000.edAddInputPort("i14",td)
+    o15=node3000.edAddOutputPort("o15",td)
+    node3000.setScript("def ff(x):\n  return 3+x")
+    p.edAddLink(node300.edGetSamplePort(),i14)
+    #
+    node4=self.r.createScriptNode("","node4")
+    node4.setScript("o9=i8")
+    p.edAddChild(node4)
+    i8=node4.edAddInputPort("i8",td3)
+    o9=node4.edAddOutputPort("o9",td3)
+    p.edAddCFLink(node3,node4)
+    p.edAddLink(o15,i8)
+    p.saveSchema(fname)
+    p=l.load(fname)
+    ex = pilot.ExecutorSwig()
+    self.assertEqual(p.getState(),pilot.READY)
+    ex.RunW(p,0)
+    self.assertEqual(p.getState(),pilot.DONE)
+    zeResu=p.getChildByName("node4").getOutputPort("o9").get()
+    self.assertEqual(zeResu,[[5,6,7,8,9,10,11,12,13,14],[15,16,17,18,19,20,21,22,23,24,25],[26,27,28,29,30,31,32,33,34,35,36,37],[38,39,40,41,42,43,44,45,46,47,48,49,50],[51,52,53,54,55,56,57,58,59,60,61,62,63,64],[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79], [80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95]])
+    pass
+
+  pass
+
+import os
+U = os.getenv('USER')
+f=open("/tmp/" + U + "/UnitTestsResult", 'a')
+f.write("  --- TEST src/yacsloader: testSaveLoadRun.py\n")
+suite = unittest.makeSuite(TestSaveLoadRun)
+result=unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite)
+f.close()
+sys.exit(not result.wasSuccessful())
index d591c3eb59fa07a41f288100143a29b8b7afe541..ff844ef44e5e71e290ce5f96c31849a400479f57 100644 (file)
@@ -51,6 +51,7 @@
 %types(YACS::ENGINE::Node *);
 %types(YACS::ENGINE::InputPort *,YACS::ENGINE::OutputPort *,YACS::ENGINE::InputDataStreamPort *,YACS::ENGINE::OutputDataStreamPort *);
 %types(YACS::ENGINE::InGate *,YACS::ENGINE::OutGate *,YACS::ENGINE::InPort *,YACS::ENGINE::OutPort *,YACS::ENGINE::Port *);
+%types(YACS::ENGINE::Container *, YACS::ENGINE::HomogeneousPoolContainer *);
 
 %import "pilot.i"