32 #include <boost/regex.hpp>
33 #include <boost/lexical_cast.hpp>
35 #include "../WKernel.h"
36 #include "../WModuleCombiner.h"
37 #include "../WModuleFactory.h"
38 #include "../WModuleConnector.h"
39 #include "../WModule.h"
40 #include "../WDataModule.h"
41 #include "../WModuleInputConnector.h"
42 #include "../WModuleOutputConnector.h"
43 #include "../exceptions/WModuleConnectorNotFound.h"
45 #include "../../common/exceptions/WFileNotFound.h"
46 #include "../../common/WProperties.h"
47 #include "../../common/WPropertyBase.h"
48 #include "../../common/WPropertyVariable.h"
49 #include "../../common/WPropertyTypes.h"
50 #include "../../common/WLogger.h"
51 #include "../../common/math/linearAlgebra/WLinearAlgebra.h"
53 #include "WModuleProjectFileCombiner.h"
75 static const boost::regex modRe(
"^ *MODULE:([0-9]*):(.*)$" );
76 static const boost::regex dataRe(
"^ *DATA:([0-9]*):(.*)$" );
77 static const boost::regex conRe(
"^ *CONNECTION:\\(([0-9]*),(.*)\\)->\\(([0-9]*),(.*)\\)$" );
78 static const boost::regex propRe(
"^ *PROPERTY:\\(([0-9]*),(.*)\\)=(.*)$" );
80 boost::smatch matches;
81 if( boost::regex_match( line, matches, modRe ) )
87 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Module \"" << matches[2] <<
"\" with ID " << matches[1];
95 wlog::error(
"Project Loader" ) <<
"There is no prototype available for module \"" << matches[2] <<
"\". Skipping.";
97 else if( proto->getType() == MODULE_DATA )
99 wlog::error(
"Project Loader" ) <<
"Data modules are not allowed to be specified in a \"MODULE\" Statement." <<
100 " Use the \"DATA\" statement instead. Skipping.";
105 m_modules.insert(
ModuleID( boost::lexical_cast< unsigned int >( matches[1] ), module ) );
108 else if( boost::regex_match( line, matches, dataRe ) )
113 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Data \"" << matches[2] <<
"\" with ID " << matches[1];
119 wlog::error(
"Project Loader" ) <<
"There is no prototype available for module \"" <<
"Data Module" <<
"\"."
120 <<
" This should not happen!. Skipping.";
124 std::string parameter = std::string( matches[2] );
126 if( parameter.empty() )
128 wlog::error(
"Project Loader" ) <<
"Data modules need an additional filename parameter. Skipping.";
132 boost::shared_static_cast<
WDataModule >( module )->setFilename( parameter );
133 m_modules.insert(
ModuleID( boost::lexical_cast< unsigned int >( matches[1] ), module ) );
137 else if( boost::regex_match( line, matches, conRe ) )
143 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Connection between \"" << matches[2] <<
"\" of module "
144 << matches[1] <<
" and \"" << matches[4] <<
"\" of module " << matches[3] <<
".";
148 Connector( boost::lexical_cast< unsigned int >( matches[3] ), matches[4] ) ) );
150 else if( boost::regex_match( line, matches, propRe ) )
157 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Property \"" << matches[2] <<
"\" of module " << matches[1]
158 <<
" set to " << matches[3];
173 for( std::map<
unsigned int, boost::shared_ptr< WModule > >::const_iterator iter =
m_modules.begin(); iter !=
m_modules.end(); ++iter )
180 for( std::map<
unsigned int, boost::shared_ptr< WModule > >::iterator iter =
m_modules.begin(); iter !=
m_modules.end(); ++iter )
182 ( *iter ).second->isReadyOrCrashed().wait();
185 if( ( *iter ).second->isCrashed()() )
187 wlog::warn(
"Project Loader" ) <<
"In the module with ID "
189 <<
" a problem occurred. Connections and properties relating to this"
190 <<
" module will fail.";
199 if( !
m_modules.count( ( *iter ).first.first ) )
201 wlog::error(
"Project Loader" ) <<
"There is no module with ID \"" << ( *iter ).first.first <<
"\" to set the property \"" <<
202 ( *iter ).first.second <<
"\" for. Skipping.";
205 boost::shared_ptr< WModule > m =
m_modules[ ( *iter ).first.first ];
208 boost::shared_ptr< WPropertyBase > prop = m->getProperties()->findProperty( ( *iter ).first.second );
211 wlog::error(
"Project Loader" ) <<
"The module \"" << m->getName() <<
"\" has no property named \"" <<
212 ( *iter ).first.second <<
"\". Skipping.";
217 if( prop->getPurpose() != PV_PURPOSE_INFORMATION )
220 bool result = prop->setAsString( ( *iter ).second );
223 wlog::error(
"Project Loader" ) <<
"Failed to set property " << ( *iter ).first.second <<
" in module \"" <<
224 m->getName() <<
"\".";
229 wlog::error(
"Project Loader" ) <<
"The module \"" << m->getName() <<
"\" has a property named \"" <<
230 ( *iter ).first.second <<
"\" which is an INFORMATION property. Skipping.";
244 boost::shared_ptr< WModule > m1;
247 wlog::error(
"Project Loader" ) <<
"There is no module with ID \"" << c1.first <<
"\" for the connection "
248 <<
"(" << c1.first <<
"," << c1.second <<
")->(" << c2.first <<
"," << c2.second <<
"). Skipping.";
254 boost::shared_ptr< WModule > m2;
257 wlog::error(
"Project Loader" ) <<
"There is no module with ID \"" << c2.first <<
"\" for the connection "
258 <<
"(" << c1.first <<
"," << c1.second <<
")->(" << c2.first <<
"," << c2.second <<
"). Skipping.";
267 boost::shared_ptr< WModuleOutputConnector > con1;
270 con1 = m1->getOutputConnector( c1.second );
274 wlog::error(
"Project Loader" ) <<
"There is no output connector \"" << c1.second <<
"\" in module \"" << m1->getName() <<
"\"";
277 boost::shared_ptr< WModuleInputConnector > con2;
280 con2 = m2->getInputConnector( c2.second );
284 wlog::error(
"Project Loader" ) <<
"There is no input connector \"" << c2.second <<
"\" in module \"" << m2->getName() <<
"\"";
291 con1->connect( con2 );
295 wlog::error(
"Project Loader" ) <<
"Connection " <<
"(" << c1.first <<
"," << c1.second <<
")->(" << c2.first <<
"," << c2.second <<
296 ") could not be created. Incompatible connectors?. Skipping.";
313 std::string prefix,
unsigned int module )
318 output << indent <<
"// Property Group: " << props->getName() << std::endl;
324 if( ( *iter )->getPurpose () == PV_PURPOSE_INFORMATION )
328 if( ( *iter )->getType() != PV_GROUP )
330 output << indent +
" " <<
"PROPERTY:(" << module <<
"," << prefix + ( *iter )->getName() <<
")="
331 << ( *iter )->getAsString() << std::endl;
338 printProperties( output, ( *iter )->toPropGroup(), indent +
" ", ( *iter )->getName() +
"/", module );
342 printProperties( output, ( *iter )->toPropGroup(), indent +
" ", prefix + ( *iter )->getName() +
"/", module );
347 output << indent <<
"// Property Group END: " << props->getName() << std::endl;
355 std::map< boost::shared_ptr< WModule >,
unsigned int > moduleToIDMap;
357 output <<
"//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
358 "// Modules and Properties" << std::endl <<
359 "//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
367 moduleToIDMap[ ( *iter ) ] = i;
370 if( ( *iter )->getType() == MODULE_DATA )
372 output <<
"DATA:" << i <<
":" << boost::shared_static_cast<
WDataModule >( ( *iter ) )->getFilename() << std::endl;
376 output <<
"MODULE:" << i <<
":" << ( *iter )->
getName() << std::endl;
388 output <<
"//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
389 "// Connections" << std::endl <<
390 "//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
399 for( WModule::OutputConnectorList::const_iterator citer = outs.begin(); citer != outs.end(); ++citer )
403 boost::unique_lock<boost::shared_mutex> lock( ( *citer )->m_connectionListLock );
404 for( std::set<boost::shared_ptr<WModuleConnector> >::const_iterator iciter = ( *citer )->m_connected.begin();
405 iciter != ( *citer )->m_connected.end(); ++iciter )
408 boost::shared_ptr< WModule > theOtherModule = ( *iciter )->m_module.lock();
409 output <<
"CONNECTION:(" << moduleToIDMap[ ( *iter ) ] <<
"," << ( *citer )->getName() <<
")->(" <<
410 moduleToIDMap[ theOtherModule ] <<
"," << ( *iciter )->getName() <<
")" << std::endl;