}
void CalciumCouplingPolicy::disconnect(bool provideLastGivenValue) {
- // TODO Réveiller les ports en attente ! OU timeout ?
+
if (provideLastGivenValue) {
std::cout << "-------- CalciumCouplingPolicy::disconnect CP_CONT ------------------" << std::endl;
_disconnectDirective = CalciumTypes::CONTINUE;
std::cout << "-------- CalciumCouplingPolicy::disconnect CP_ARRET ------------------" << std::endl;
_disconnectDirective = CalciumTypes::STOP;
}
- //Wakeup get data if any
- //wakeupWaiting();
-// if (waitingForAnyDataId || waitingForConvenientDataId);
-// cond_instance.signal();
-
+ //Wakeup get data if any
+ wakeupWaiting();
}
typedef CalciumTypes::DisconnectDirective DisconnectDirective;
private:
+
DependencyType _dependencyType;
size_t _storageLevel;
DateCalSchem _dateCalSchem;
// Classe DataId rassemblant les paramètres de la méthode PORT::put
// qui identifient l'instance d'une donnée pour Calcium
// Rem : Le DataId doit pouvoir être une key dans une map stl
- // typedef CORBA::Double TimeType;
- // typedef CORBA::Long TagType;
typedef double TimeType;
typedef long TagType;
typedef std::pair< TimeType , TagType > DataId;
TimeType getEffectiveTime(TimeType ti, TimeType tf);
void disconnect(bool provideLastGivenValue);
- virtual void wakeupWaiting(){};
}; //Fin de CalciumCouplingPolicy
template <typename DataManipulator>
struct CalciumCouplingPolicy::BoundedDataIdProcessor{
- CalciumCouplingPolicy _couplingPolicy;
+ const CalciumCouplingPolicy & _couplingPolicy;
- BoundedDataIdProcessor(CalciumCouplingPolicy couplingPolicy):
+ BoundedDataIdProcessor(const CalciumCouplingPolicy &couplingPolicy):
_couplingPolicy(couplingPolicy) {};
// Méthode implémentant l'interpolation temporelle
template < typename MapIterator >
void inline apply (typename iterator_t<MapIterator>::value_type & data,
- const DataId & dataId, const MapIterator & it1) {
+ const DataId & dataId, const MapIterator & it1) const {
typedef typename iterator_t<MapIterator>::value_type value_type;
typedef typename DataManipulator::InnerType InnerType;
// REM : Pour des buffers de type int
// le compilo indiquera warning: converting to `long int' from `Double'
std::transform(InIt1,InIt1+dataSize,InIt2,OutIt,
- ( _1 - _2 ) * coeff + _2 );
+ ( _1 - _2 ) * coeff + _2 );
+// for(size_t i =0; i < dataSize3; ++i) {
+// OutIt[i]=(InIt1[i] - InIt2[i]) * coeff + InIt2[i];
+// }
+
}
std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données calculées à t : " << std::endl;
std::copy(OutIt,OutIt+dataSize,std::ostream_iterator<InnerType>(std::cout," "));
template < typename DataManipulator >
struct CalciumCouplingPolicy::EraseDataIdProcessor {
- CalciumCouplingPolicy _couplingPolicy;
+ CalciumCouplingPolicy &_couplingPolicy;
- EraseDataIdProcessor(CalciumCouplingPolicy couplingPolicy):
+ EraseDataIdProcessor(CalciumCouplingPolicy &couplingPolicy):
_couplingPolicy(couplingPolicy) {};
template < typename Container >
template < typename DataManipulator >
struct CalciumCouplingPolicy::DisconnectProcessor {
- CalciumCouplingPolicy _couplingPolicy;
+ const CalciumCouplingPolicy & _couplingPolicy;
- DisconnectProcessor(CalciumCouplingPolicy couplingPolicy):
+ DisconnectProcessor(const CalciumCouplingPolicy & couplingPolicy):
_couplingPolicy(couplingPolicy) {};
template < typename Container, typename DataId >
typedef typename Container::iterator iterator;
// Pas de traitement particulier a effectuer
- std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK1 --------" << std::endl;
- if ( _couplingPolicy._disconnectDirective == CalciumTypes::UNDEFINED_DIRECTIVE ) return false;
- std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor, CP_CONT : " << (*wDataIt1).first << std::endl;
+ std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK1 ("<< _couplingPolicy._disconnectDirective<<") --------" << std::endl;
+ if ( (_couplingPolicy._disconnectDirective) == (CalciumTypes::UNDEFINED_DIRECTIVE) ) return false;
+
std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK2 --------" << std::endl;
+
+ if ( _couplingPolicy._disconnectDirective == CalciumTypes::CP_ARRET )
throw(DATASTREAM_EXCEPTION(LOC(OSS()<< "La directive CP_ARRET"
<< " provoque l'interruption de toute lecture de données")));
std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK3 --------" << std::endl;
+
// S'il n'y a plus de données indique que l'on a pas pu effectuer de traitement
if ( storedDatas.empty() )
throw(DATASTREAM_EXCEPTION(LOC(OSS()<< "La directive CP_CONT"
// qu'en mode itératif il ne soit pas plus grand que le plus grand DataId stocké auquel
// cas on doit renvoyer une expection car on n'est plus connecté et on ne pourra jamais
// fournir de données pour ce dataId.
- std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK4 --------" << std::endl;
+ std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK4 " << expectedDataId <<" --------" << std::endl;
+ // >= expectedDataId
iterator it1 = storedDatas.lower_bound(expectedDataId);
- if (it1 != storedDatas.end())
+ std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK5 " << std::endl;
+ for (iterator it=storedDatas.begin();it!=storedDatas.end();++it)
+ std::cout <<" "<<(*it).first ;
+ std::cout <<std::endl;
+
+ if (it1 == storedDatas.end())
throw(DATASTREAM_EXCEPTION(LOC(OSS()<< "La directive CP_CONT"
<< " est active mais le dataId demandé est inférieur ou égal au dernier reçu.")));
+ std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK6 " << std::endl;
wDataIt1 = storedDatas.end();
--wDataIt1;
port->disconnect(provideLastGivenValue);
} catch(const CORBA::SystemException& ex){
throw DSC_Exception(LOC(OSS() << "Impossible d'invoquer la méthode disconnect sur le port provide n°"
- << i << "( i>= 0)"));
+ << i << " ( i>= 0)"));
}
}
std::vector<std::string>::const_iterator it;
component.get_uses_port_names(usesPortNames);
- //récupérer le type de réel su port est un peu difficile
+ //récupérer le type de réel du port est un peu difficile
//car l'interface nous donne aucune indication
uses_port *myUsesPort;
myCalciumUsesPort->disconnect(provideLastGivenValue);
} catch ( const Superv_Component_i::PortNotDefined & ex) {
std::cerr << ex.what() << std::endl;
- throw (DatastreamException(CalciumTypes::CPNMVR,ex));
+ //throw (DatastreamException(CalciumTypes::CPNMVR,ex));
+ // On continue à traiter la deconnexion des autres ports uses
} catch ( const Superv_Component_i::PortNotConnected & ex) {
- std::cerr << ex.what() << std::endl;;
- throw (DatastreamException(CalciumTypes::CPLIEN,ex));
- } catch ( const Superv_Component_i::BadCast & ex) {
+ std::cerr << ex.what() << std::endl;
+ // throw (DatastreamException(CalciumTypes::CPLIEN,ex));
+ // On continue à traiter la deconnexion des autres ports uses
+ } catch ( const Superv_Component_i::BadCast & ex) {
std::cerr << ex.what() << std::endl;
throw (DatastreamException(CalciumTypes::CPTPVR,ex));
- } // Laisse passer les autres exceptions.
+ } catch ( const DSC_Exception & ex) {
+ // exception venant du port uses
+ std::cerr << ex.what() << std::endl;
+ // On continue à traiter la deconnexion des autres ports uses
+ } catch (...) {// On laisse passer les autres exceptions
+ std::cout << "ecp_fin : Exception innatendue " <<std::endl;
+ throw;
+ }
}
}
typedef enum {TI_SCHEM=TI,TF_SCHEM=TF,ALPHA_SCHEM} DateCalSchem;
typedef enum {L0_SCHEM=CP_ESCALIER,L1_SCHEM=CP_LINEAIRE} InterpolationSchem;
typedef enum {UNDEFINED_EXTRA_SCHEM,E0_SCHEM,E1_SCHEM} ExtrapolationSchem;
- typedef enum {UNDEFINED_DIRECTIVE,CONTINUE=CP_CONT,STOP=CP_ARRET} DisconnectDirective;
+ typedef enum {UNDEFINED_DIRECTIVE=0,CONTINUE=CP_CONT,STOP=CP_ARRET} DisconnectDirective;
/* Codes d'erreur */
libSalomeCalcium_la_LDFLAGS = -no-undefined -version-info=0:0:0
+AM_CFLAGS = -fexceptions
lib_LTLIBRARIES = libCalciumC.la
-
libCalciumC_la_SOURCES = Calcium.c
#
# ===============================================================
#
noinst_PROGRAMS = test_DataIdContainer
+## testInterpolation
+
+testInterpolation_SOURCES = testInterpolation.cxx
+testInterpolation_CXXFLAGS = -I/usr/include
test_DataIdContainer_SOURCES = test_DataIdContainer.cxx
// Date : $LastChangedDate: 2007-01-08 19:01:14 +0100 (lun, 08 jan 2007) $
// Id : $Id$
-#include "lambda.hpp"
+#include <boost/lambda/lambda.hpp>
+
#include <vector>
#include <algorithm>
#include <iostream>
+#include <iterator>
+#include <functional>
+#include <ext/functional>
struct MyRand {
static const double MAXVALUE = 150.0;
int main() {
- typedef double Type;
+ typedef long Type;
typedef double TimeType;
const int dataSize1=20;
const int dataSize2=30;
const int dataSize3=std::min< size_t >(dataSize1,dataSize2);
- std::vector<Type> vect1(dataSize1),vect2(dataSize2),vect3(dataSize3);
+ std::vector<Type> vect1(dataSize1),vect2(dataSize2),vect3(dataSize3),vect4(dataSize3);
MyRand myRand;
//TEST1
std::generate(vect1.begin(),vect1.end(),myRand);
std::cout << "Vecteur1 généré aléatoirement :" << std::endl;
- copy(vect1.begin(),vect1.end(),std::ostream_iterator<Type>(std::cout," "));
+ std::copy(vect1.begin(),vect1.end(),std::ostream_iterator<Type>(std::cout," "));
std::cout<< std::endl;
std::generate(vect2.begin(),vect2.end(),myRand);
std::cout << "Vecteur2 généré aléatoirement :" << std::endl;
- copy(vect2.begin(),vect2.end(),std::ostream_iterator<Type>(std::cout," "));
+ std::copy(vect2.begin(),vect2.end(),std::ostream_iterator<Type>(std::cout," "));
std::cout<< std::endl;
- std::vector<Type>::iterator InIt1=vect1.begin(),InIt2=vect2.begin(),OutIt=vect3.begin();
+
+ std::vector<Type>::iterator
+ InIt1=vect1.begin(),
+ InIt2=vect2.begin(),
+ OutIt1=vect3.begin(),
+ OutIt2=vect4.begin();
TimeType t = 2.4;
TimeType t2 = 3.4;
TimeType deltaT = t2-t1;
TimeType coeff = (t2-t)/deltaT;
+ // Calcul avec Lambda
boost::lambda::placeholder1_type _1;
boost::lambda::placeholder2_type _2;
- std::transform(InIt1,InIt1+dataSize3,InIt2,OutIt, ( _1 - _2 ) * coeff + _2 );
+ std::transform(InIt1,InIt1+dataSize3,InIt2,OutIt1, ( _1 - _2 ) * coeff + _2 );
std::cout << "Vecteur3 calculé :" << std::endl;
- copy(vect3.begin(),vect3.end(),std::ostream_iterator<Type>(std::cout," "));
+ std::copy(vect3.begin(),vect3.end(),std::ostream_iterator<Type>(std::cout," "));
std::cout<< std::endl;
-
+
+ //Calcul sans Lambda
+ // ERREUR : il faut produire une binary pas avec compose2
+ // std::transform(InIt1,InIt1+dataSize3,InIt2,OutIt2,
+ // //std::minus<Type>(),
+ // __gnu_cxx::compose2(std::minus<Type>(),
+ // // __gnu_cxx::identity<Type>(),
+ // std::bind2nd( std::multiplies<Type>(), 1. ),
+ // std::bind2nd( std::multiplies<Type>(), 1.1 ) )
+ // );
+ // InIt2 =vect2.begin();
+ // OutIt2=vect4.begin();
+
+ // std::transform(InIt2,InIt2+dataSize3,OutIt2,OutIt2,
+ // std::plus<Type>() );
+
+ // Calcul direct
+ InIt1=vect1.begin(); InIt2=vect2.begin();OutIt2=vect4.begin();
+ for(int i =0; i < dataSize3; ++i) {
+// *OutIt2=(*InIt1 - *InIt2) * coeff + *InIt2;
+// ++InIt1;++InIt2;++OutIt2;
+ OutIt2[i]=(InIt1[i] - InIt2[i]) * coeff + InIt2[i];
+ }
+
+ std::cout << "Vecteur4 calculé :" << std::endl;
+ std::copy(vect4.begin(),vect4.end(),std::ostream_iterator<Type>(std::cout," "));
+ std::cout<< std::endl;
};
// le cas d'une demande de dataId inexistant mais encadré par deux autres
template <typename DataManipulator>
struct BoundedDataIdProcessor{
- BoundedDataIdProcessor(CouplingPolicy couplingPolicy) {};
+ BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
template < typename Iterator, typename DataId >
void inline apply(typename iterator_t<Iterator>::value_type & data,
- const DataId & dataId,
- const Iterator & it1) {
+ const DataId & dataId,
+ const Iterator & it1) const {
typedef typename iterator_t<Iterator>::value_type value_type;
std::cout << "-------- Generic BoundedDataIdProcessor.apply() called " << std::endl;
template < typename DataManipulator >
struct DisconnectProcessor {
- DisconnectProcessor(CouplingPolicy couplingPolicy) {};
+ DisconnectProcessor(const CouplingPolicy & couplingPolicy) {};
template < typename Container, typename DataId >
bool apply(Container & storedDatas,
}
};
+ // Permet de réveiller les méthodes d'un GenericPort en attente
+ // depuis une CouplingPolicy
+ virtual void wakeupWaiting(){};
+
virtual ~CouplingPolicy() {}
};
GenericPort<DataManipulator, COUPLING_POLICY>::wakeupWaiting()
{
std::cout << "-------- wakeupWaiting ------------------" << std::endl;
- if (waitingForAnyDataId || waitingForConvenientDataId)
- {
+ storedDatas_mutex.lock();
+ if (waitingForAnyDataId || waitingForConvenientDataId) {
std::cout << "-------- wakeupWaiting:signal --------" << std::endl;
std::cout << std::flush;
cond_instance.signal();
- }
+ }
+ storedDatas_mutex.unlock();
+
}
/* Methode put_generique
// Par construction, les valeurs de waitingForAnyDataId, waitingForConvenientDataId et de
// expectedDataId ne peuvent pas être modifiées pendant le traitement de la boucle
// sur les dataIds (à cause du lock utilisé dans la méthode put et les méthodes get )
- // rem : Utilisation de l'évaluation gauche droite su logical C or
+ // rem : Utilisation de l'évaluation gauche droite du logical C or
if ( waitingForAnyDataId ||
( waitingForConvenientDataId &&
isDataIdConveniant(storedDatas, expectedDataId, dummy1, dummy2, dummy3) )
wDataIt1 = storedDatas.end();
//Recherche le prochain dataId à renvoyer
+ // - lastDataIdset == true indique que lastDataId
+ // contient le dernier DataId renvoyé
+ // - lastDataIdset == false indique que l'on renverra
+ // le premier dataId trouvé
+ // - upper_bound(lastDataId) situe le prochain DataId
+ // à renvoyer
+ // Rem : les données renvoyées ne sont effacées par eraseDataIds
+ // si necessaire
if (lastDataIdSet)
wDataIt1 = storedDatas.upper_bound(lastDataId);
else if ( !storedDatas.empty() ) {
wDataIt1 = storedDatas.begin();
}
+ typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);
+
while ( storedDatas.empty() || wDataIt1 == storedDatas.end() ) {
// Délègue au mode de couplage la gestion d'une demande de donnée non disponible
// si le port est deconnecté
- typename COUPLING_POLICY::template DisconnectProcessor<DataManipulator> processDisconnect(*this);
- if ( processDisconnect.apply(storedDatas, lastDataId, wDataIt1) ) break;
-
+ if ( processDisconnect.apply(storedDatas, lastDataId, wDataIt1) ) {
+ waitingForAnyDataId = false; break;
+ }
+
std::cout << "-------- Next : MARK 2 ------------------" << std::endl;
//Positionné à faux dans la méthode put
waitingForAnyDataId = true;
std::cout << "-------- Next : waiting datas ------------------" << std::endl;
fflush(stdout);fflush(stderr);
cond_instance.wait();
-
+
if (lastDataIdSet) {
std::cout << "-------- Next : MARK 4 ------------------" << std::endl;
wDataIt1 = storedDatas.upper_bound(lastDataId);
- } else {
+ } else {
std::cout << "-------- Next : MARK 5 ------------------" << std::endl;
lastDataIdSet = true;
wDataIt1 = storedDatas.begin();
std::cout << "-------- Next : MARK 8 ------------------" << std::endl;
} catch (...) {
+ std::cout << "-------- Next : MARK 8bis ------------------" << std::endl;
+ waitingForAnyDataId = false;
storedDatas_mutex.unlock();
throw;
}