]> SALOME platform Git repositories - modules/kernel.git/blob - src/Notebook/SALOME_Notebook.cxx
Salome HOME
Base implementation of Notebook
[modules/kernel.git] / src / Notebook / SALOME_Notebook.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : SALOME_Notebook.cxx
23 //  Author : Alexandre SOLOVYOV
24 //  Module : SALOME
25 //
26
27 #include <SALOME_Notebook.hxx>
28 #include <SALOME_Parameter.hxx>
29
30 SALOME_Notebook::SALOME_Notebook( SALOMEDS::Study_ptr theStudy )
31 {
32   myStudy = SALOMEDS::Study::_duplicate( theStudy );
33 }
34
35 CORBA::Boolean SALOME_Notebook::AddDependency( SALOME::ParameterizedObject_ptr theObj, SALOME::ParameterizedObject_ptr theRef )
36 {
37   return AddDependency( GetKey( theObj ), GetKey( theRef ) );
38 }
39
40 void SALOME_Notebook::RemoveDependency( SALOME::ParameterizedObject_ptr theObj, SALOME::ParameterizedObject_ptr theRef )
41 {
42   std::string anObjKey = GetKey( theObj ), aRefKey = GetKey( theRef );
43   myDeps[anObjKey].remove( aRefKey );
44 }
45
46 void SALOME_Notebook::ClearDependencies( SALOME::ParameterizedObject_ptr theObj )
47 {
48   ClearDependencies( GetKey( theObj ) );
49 }
50
51 void SALOME_Notebook::SetToUpdate( SALOME::ParameterizedObject_ptr theObj )
52 {
53   printf( "SetToUpdate: %s\n", GetKey( theObj ).c_str() );
54
55   SALOME::Parameter_ptr aParam = SALOME::Parameter::_narrow( theObj );
56   if( !CORBA::is_nil( aParam ) )
57   {
58     std::string anEntry = aParam->GetEntry();
59     SALOME_Parameter* aParamPtr = myParams[anEntry];
60     std::string aKey = GetKey( anEntry );
61     ClearDependencies( aKey );
62     AddDependencies( aParamPtr );
63   }
64
65   /*
66   printf( "Dependencies:\n" );
67   std::map< std::string, std::list<std::string> >::const_iterator mit = myDeps.begin(), mlast = myDeps.end();
68   for( ; mit!=mlast; mit++ )
69   {
70     printf( "%s -> [ ", mit->first.c_str() );
71     std::list<std::string>::const_iterator lit = mit->second.begin(), llast = mit->second.end();
72     for( ; lit!=llast; lit++ )
73       printf( "%s ", (*lit).c_str() );
74     printf( "]\n" );
75   }
76   */
77
78   std::string anObjKey = GetKey( theObj );
79   std::list<std::string> aDeps = GetAllDependingOn( anObjKey );
80   std::list<std::string>::const_iterator it = aDeps.begin(), last = aDeps.end();
81   for( ; it!=last; it++ )
82     if( find( myToUpdate.begin(), myToUpdate.end(), *it ) == myToUpdate.end() )
83       myToUpdate.push_back( KeyHelper( *it, this ) );
84
85   //myToUpdate.sort();
86   std::list<KeyHelper>::iterator uit = myToUpdate.begin(), uit1, ulast = myToUpdate.end();
87   for( ; uit!=ulast; uit++ )
88     for( uit1=uit, uit1++; uit1!=ulast; uit1++ )
89       if( *uit1 < *uit )
90       {
91         KeyHelper tmp = *uit1;
92         *uit1 = *uit;
93         *uit = tmp;
94       }
95
96   uit = myToUpdate.begin(); ulast = myToUpdate.end();
97   for( ; uit!=ulast; uit++ )
98     printf( "To update: %s\n", (*uit).key().c_str() );
99 }
100
101 void SALOME_Notebook::Update()
102 {
103   //printf( "Update\n" );
104   std::list< KeyHelper > aPostponedUpdate;
105   std::list<KeyHelper>::const_iterator it = myToUpdate.begin(), last = myToUpdate.end();
106   for( ; it!=last; it++ )
107   {
108     std::string aKey = (*it).key();
109     SALOME::ParameterizedObject_ptr anObj = FindObject( aKey );
110     if( CORBA::is_nil( anObj ) )
111       aPostponedUpdate.push_back( *it );
112     else
113       anObj->Update();
114   }
115   myToUpdate = aPostponedUpdate;
116 }
117
118 CORBA::Boolean SALOME_Notebook::AddExpr( const char* theExpr )
119 {
120   return AddParam( new SALOME_Parameter( this, theExpr ) );
121 }
122
123 CORBA::Boolean SALOME_Notebook::AddNameExpr( const char* theName, const char* theExpr )
124 {
125   return AddParam( new SALOME_Parameter( this, theName, theExpr ) );
126 }
127
128 CORBA::Boolean SALOME_Notebook::AddValue( const char* theName, CORBA::Double theValue )
129 {
130   return AddParam( new SALOME_Parameter( this, theName, theValue ) );
131 }
132
133 void SALOME_Notebook::Remove( const char* theParamName )
134 {
135   std::string aKey = GetKey( theParamName );
136   ClearDependencies( aKey );
137   myDeps.erase( aKey );
138   myParams.erase( theParamName );
139 }
140
141 SALOME::Parameter_ptr SALOME_Notebook::Param( const char* theParamName )
142 {
143   //printf( "Param, name = %s\n", theParamName );
144   return ParamPtr( theParamName )->_this();
145 }
146
147 SALOME_Parameter* SALOME_Notebook::ParamPtr( const char* theParamName ) const
148 {
149   std::map< std::string, SALOME_Parameter* >::const_iterator it = myParams.find( theParamName );
150   return it==myParams.end() ? 0 : it->second;
151 }
152
153 bool SALOME_Notebook::AddParam( SALOME_Parameter* theParam )
154 {
155   std::string anEntry = theParam->GetEntry();
156   //printf( "Add param: %s\n", anEntry.c_str() );
157
158   std::map< std::string, SALOME_Parameter* >::const_iterator it = myParams.find( anEntry );
159   if( it!=myParams.end() )
160   {
161     delete it->second;
162     ClearDependencies( GetKey( anEntry ) );
163   }
164
165   bool ok = AddDependencies( theParam );
166   //printf( "Add param: %s, Result = %i\n\n", anEntry.c_str(), ok );
167
168   if( !ok )
169   {
170     //printf( "Removed\n" );
171     Remove( anEntry.c_str() );
172   }
173
174   return ok;
175 }
176
177 bool SALOME_Notebook::AddDependencies( SALOME_Parameter* theParam )
178 {
179   //printf( "Dependencies search\n" );
180   std::string anEntry = theParam->GetEntry();
181   std::string aParamKey = GetKey( anEntry );
182   myParams[anEntry] = theParam;
183   SALOME_StringList aDeps = theParam->Dependencies();
184   SALOME_StringList::const_iterator dit = aDeps.begin(), dlast = aDeps.end();
185   bool ok = true;
186   for( ; dit!=dlast && ok; dit++ )
187   {
188     std::string aKey = GetKey( *dit );
189     ok = AddDependency( aParamKey, aKey );
190     //printf( "add dep to %s, res = %i\n", aKey.c_str(), ok );
191   }
192   return ok;
193 }
194
195 bool SALOME_Notebook::AddDependency( const std::string& theObjKey, const std::string& theRefKey )
196 {
197   std::list<std::string> aDeps = GetAllDependingOn( theObjKey );
198   if( find( aDeps.begin(), aDeps.end(), theRefKey ) != aDeps.end () )
199     return false; //after creation a cyclic dependency could appear
200
201   std::list<std::string>& aList = myDeps[theObjKey];
202   bool ok = find( aList.begin(), aList.end(), theRefKey ) == aList.end();
203   if( ok )
204     aList.push_back( theRefKey );
205
206   return ok;
207 }
208
209 void SALOME_Notebook::ClearDependencies( const std::string& theObjKey )
210 {
211   //printf( "Clear dependencies: %s\n", theObjKey.c_str() );
212   myDeps.erase( theObjKey );
213 }
214
215 std::string SALOME_Notebook::GetKey( SALOME::ParameterizedObject_ptr theObj )
216 {
217   return std::string( theObj->GetComponent() ) + "#" + theObj->GetEntry();
218 }
219
220 std::string SALOME_Notebook::GetKey( const std::string& theParamName )
221 {
222   return PARAM_COMPONENT + "#" + theParamName;
223 }
224
225 std::list<std::string> SALOME_Notebook::GetAllDependingOn( const std::string& theKey )
226 {
227   std::list<std::string> aDeps, aCurrents, aNewCurrents;
228   aCurrents.push_back( theKey );
229   aDeps.push_back( theKey );
230   while( aCurrents.size() > 0 )
231   {
232     aNewCurrents.clear();
233     std::list<std::string>::const_iterator cit = aCurrents.begin(), clast = aCurrents.end();
234     for( ; cit!=clast; cit++ )
235     {
236       //printf( "Check of %s:\n", (*cit).c_str() );
237       std::map< std::string, std::list<std::string> >::const_iterator dit = myDeps.begin(), dlast = myDeps.end();
238       for( ; dit!=dlast; dit++ )
239       {
240         std::string k = dit->first;
241         //printf( "\t%s\n", k.c_str() );
242         if( find( dit->second.begin(), dit->second.end(), *cit ) != dit->second.end() &&
243             find( aDeps.begin(), aDeps.end(), k ) == aDeps.end() )
244         {
245           //printf( "\t\tadd\n" );
246           aNewCurrents.push_back( k );
247           aDeps.push_back( k );
248         }
249       }
250     }
251
252     aCurrents = aNewCurrents;
253   }
254   return aDeps;
255 }
256
257 SALOME::ParameterizedObject_ptr SALOME_Notebook::FindObject( const std::string& theKey )
258 {
259   int aPos = theKey.find( "#" );
260   std::string aComponent = theKey.substr( 0, aPos ), anEntry = theKey.substr( aPos+1, theKey.length()-aPos-1 );
261   if( aComponent == PARAM_COMPONENT )
262     return Param( anEntry.c_str() );
263   else
264     return SALOME::ParameterizedObject::_narrow( myStudy->FindObjectByInternalEntry( aComponent.c_str(), anEntry.c_str() ) );
265 }
266
267 SALOME_Notebook::KeyHelper::KeyHelper( const std::string& theKey, SALOME_Notebook* theNotebook )
268 : myKey( theKey ), myNotebook( theNotebook )
269 {
270 }
271
272 std::string SALOME_Notebook::KeyHelper::key() const
273 {
274   return myKey;
275 }
276
277 bool SALOME_Notebook::KeyHelper::operator < ( const KeyHelper& theKH ) const
278 {
279   bool ok;
280   const std::list<std::string> &aList1 = myNotebook->myDeps[myKey], &aList2 = myNotebook->myDeps[theKH.myKey];
281   if( find( aList1.begin(), aList1.end(), theKH.myKey ) != aList1.end() )
282     ok = false;
283   else if( find( aList2.begin(), aList2.end(), myKey ) != aList2.end() )
284     ok = true;
285   else
286     ok = myKey < theKH.myKey;
287
288   //printf( "%s < %s ? %i\n", myKey.c_str(), theKH.myKey.c_str(), ok );
289   return ok;
290 }
291
292 bool SALOME_Notebook::KeyHelper::operator == ( const std::string& theKey ) const
293 {
294   return myKey == theKey;
295 }