# ParadisEO-PEOMovingObjects: peoSynchronousMultiStart.h Source File

# peoSynchronousMultiStart.h

    00001 /*
    00002 * <peoSynchronousMultiStart.h>
    00003 * Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2007
    00004 * (C) OPAC Team, LIFL, 2002-2007
    00005 *
    00006 * Sebastien Cahon, Alexandru-Adrian Tantar
    00007 *
    00008 * This software is governed by the CeCILL license under French law and
    00009 * abiding by the rules of distribution of free software.  You can  use,
    00010 * modify and/ or redistribute the software under the terms of the CeCILL
    00011 * license as circulated by CEA, CNRS and INRIA at the following URL
    00012 * "http://www.cecill.info".
    00013 *
    00014 * As a counterpart to the access to the source code and  rights to copy,
    00015 * modify and redistribute granted by the license, users are provided only
    00016 * with a limited warranty  and the software's author,  the holder of the
    00017 * economic rights,  and the successive licensors  have only  limited liability.
    00018 *
    00019 * In this respect, the user's attention is drawn to the risks associated
    00020 * with loading,  using,  modifying and/or developing or reproducing the
    00021 * software by the user in light of its specific status of free software,
    00022 * that may mean  that it is complicated to manipulate,  and  that  also
    00023 * therefore means  that it is reserved for developers  and  experienced
    00024 * professionals having in-depth computer knowledge. Users are therefore
    00025 * encouraged to load and test the software's suitability as regards their
    00026 * requirements in conditions enabling the security of their systems and/or
    00027 * data to be ensured and,  more generally, to use and operate it in the
    00028 * same conditions as regards security.
    00029 * The fact that you are presently reading this means that you have had
    00030 * knowledge of the CeCILL license and that you accept its terms.
    00031 *
    00032 * ParadisEO WebSite : http://paradiseo.gforge.inria.fr
    00033 * Contact: paradiseo-help@lists.gforge.inria.fr
    00034 *
    00035 */
    00036 #ifndef __peoSynchronousMultiStart_h
    00037 #define __peoSynchronousMultiStart_h
    00038
    00039 #include <vector>
    00040
    00041 #include "core/service.h"
    00042 #include "core/messaging.h"
    00043
    00044
    00045 template < typename EntityType > class peoSynchronousMultiStart : public Service {
    00046
    00047 public:
    00048
    00049         template < typename AlgorithmType > peoSynchronousMultiStart( AlgorithmType& externalAlgorithm ) {
    00050
    00051                 singularAlgorithm = new Algorithm< AlgorithmType >( externalAlgorithm );
    00052                 algorithms.push_back( singularAlgorithm );
    00053
    00054                 aggregationFunction = new NoAggregationFunction();
    00055         }
    00056
    00057         template < typename AlgorithmType, typename AggregationFunctionType > peoSynchronousMultiStart( std::vector< AlgorithmType* >& externalAlgorithms, AggregationFunctionType& externalAggregationFunction ) {
    00058
    00059                 for ( unsigned int index = 0; index < externalAlgorithms; index++ ) {
    00060
    00061                         algorithms.push_back( new Algorithm< AlgorithmType >( *externalAlgorithms[ index ] ) );
    00062                 }
    00063
    00064                 aggregationFunction = new Algorithm< AggregationFunctionType >( externalAggregationFunction );
    00065         }
    00066
    00067
    00068         ~peoSynchronousMultiStart() {
    00069
    00070                 for ( unsigned int index = 0; index < data.size(); index++ ) delete data[ index ];
    00071                 for ( unsigned int index = 0; index < algorithms.size(); index++ ) delete algorithms[ index ];
    00072
    00073                 delete aggregationFunction;
    00074         }
    00075
    00076
    00077         template < typename Type > void operator()( Type& externalData ) {
    00078
    00079                 for ( typename Type::iterator externalDataIterator = externalData.begin(); externalDataIterator != externalData.end(); externalDataIterator++ ) {
    00080
    00081                         data.push_back( new DataType< EntityType >( *externalDataIterator ) );
    00082                 }
    00083
    00084                 functionIndex = dataIndex = idx = num_term = 0;
    00085                 requestResourceRequest( data.size() * algorithms.size() );
    00086                 stop();
    00087         }
    00088
    00089
    00090         template < typename Type > void operator()( const Type& externalDataBegin, const Type& externalDataEnd ) {
    00091
    00092                 for ( Type externalDataIterator = externalDataBegin; externalDataIterator != externalDataEnd; externalDataIterator++ ) {
    00093
    00094                         data.push_back( new DataType< EntityType >( *externalDataIterator ) );
    00095                 }
    00096
    00097                 functionIndex = dataIndex = idx = num_term = 0;
    00098                 requestResourceRequest( data.size() * algorithms.size() );
    00099                 stop();
    00100         }
    00101
    00102
    00103         void packData();
    00104
    00105         void unpackData();
    00106
    00107         void execute();
    00108
    00109         void packResult();
    00110
    00111         void unpackResult();
    00112
    00113         void notifySendingData();
    00114
    00115         void notifySendingAllResourceRequests();
    00116
    00117
    00118 private:
    00119
    00120         template < typename Type > struct DataType;
    00121
    00122         struct AbstractDataType {
    00123
    00124                 virtual ~AbstractDataType() { }
    00125
    00126                 template < typename Type > operator Type& () {
    00127
    00128                         return ( dynamic_cast< DataType< Type >& >( *this ) ).data;
    00129                 }
    00130         };
    00131
    00132         template < typename Type > struct DataType : public AbstractDataType {
    00133
    00134                 DataType( Type& externalData ) : data( externalData ) { }
    00135
    00136                 Type& data;
    00137         };
    00138
    00139         struct AbstractAlgorithm {
    00140
    00141                 virtual ~AbstractAlgorithm() { }
    00142
    00143                 virtual void operator()( AbstractDataType& dataTypeInstance ) {}
    00144         };
    00145
    00146         template < typename AlgorithmType > struct Algorithm : public AbstractAlgorithm {
    00147
    00148                 Algorithm( AlgorithmType& externalAlgorithm ) : algorithm( externalAlgorithm ) { }
    00149
    00150                 void operator()( AbstractDataType& dataTypeInstance ) { algorithm( dataTypeInstance ); }
    00151
    00152                 AlgorithmType& algorithm;
    00153         };
    00154
    00155
    00156
    00157         struct AbstractAggregationAlgorithm {
    00158
    00159                 virtual ~AbstractAggregationAlgorithm() { }
    00160
    00161                 virtual void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) {};
    00162         };
    00163
    00164         template < typename AggregationAlgorithmType > struct AggregationAlgorithm : public AbstractAggregationAlgorithm {
    00165
    00166                 AggregationAlgorithm( AggregationAlgorithmType& externalAggregationAlgorithm ) : aggregationAlgorithm( externalAggregationAlgorithm ) { }
    00167
    00168                 void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) {
    00169
    00170                         aggregationAlgorithm( dataTypeInstanceA, dataTypeInstanceB );
    00171                 }
    00172
    00173                 AggregationAlgorithmType& aggregationAlgorithm;
    00174         };
    00175
    00176         struct NoAggregationFunction : public AbstractAggregationAlgorithm {
    00177
    00178                 void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) {
    00179
    00180                         static_cast< EntityType& >( dataTypeInstanceA ) = static_cast< EntityType& >( dataTypeInstanceB );
    00181                 }
    00182         };
    00183
    00184
    00185
    00186         AbstractAlgorithm* singularAlgorithm;
    00187
    00188         std::vector< AbstractAlgorithm* > algorithms;
    00189         AbstractAggregationAlgorithm* aggregationFunction;
    00190
    00191
    00192         EntityType entityTypeInstance;
    00193         std::vector< AbstractDataType* > data;
    00194
    00195         unsigned idx;
    00196         unsigned num_term;
    00197         unsigned dataIndex;
    00198         unsigned functionIndex;
    00199 };
    00200
    00201
    00202 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::packData() {
    00203
    00204         ::pack( functionIndex );
    00205         ::pack( idx );
    00206         ::pack( ( EntityType& ) *data[ idx++ ]  );
    00207
    00208         // done with functionIndex for the entire data set - moving to another
    00209         //  function/algorithm starting all over with the entire data set ( idx is set to 0 )
    00210         if ( idx == data.size() ) {
    00211
    00212                 ++functionIndex; idx = 0;
    00213         }
    00214 }
    00215
    00216 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::unpackData() {
    00217
    00218         ::unpack( functionIndex );
    00219         ::unpack( dataIndex );
    00220         ::unpack( entityTypeInstance );
    00221 }
    00222
    00223 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::execute() {
    00224
    00225         // wrapping the unpacked data - the definition of an abstract algorithm imposes
    00226         // that its internal function operator acts only on abstract data types
    00227         AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance );
    00228         algorithms[ functionIndex ]->operator()( *entityWrapper );
    00229
    00230         delete entityWrapper;
    00231 }
    00232
    00233 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::packResult() {
    00234
    00235         ::pack( dataIndex );
    00236         ::pack( entityTypeInstance );
    00237 }
    00238
    00239 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::unpackResult() {
    00240
    00241         ::unpack( dataIndex );
    00242         ::unpack( entityTypeInstance );
    00243
    00244         // wrapping the unpacked data - the definition of an abstract algorithm imposes
    00245         // that its internal function operator acts only on abstract data types
    00246         AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance );
    00247         aggregationFunction->operator()( *data[ dataIndex ], *entityWrapper );
    00248         delete entityWrapper;
    00249
    00250         num_term++;
    00251
    00252         if ( num_term == data.size() * algorithms.size() ) {
    00253
    00254                 getOwner()->setActive();
    00255                 resume();
    00256         }
    00257 }
    00258
    00259 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::notifySendingData() {
    00260
    00261 }
    00262
    00263 template < typename EntityType > void peoSynchronousMultiStart< EntityType >::notifySendingAllResourceRequests() {
    00264
    00265         getOwner()->setPassive();
    00266 }
    00267
    00268
    00269 #endif