31 #include <shared_mutex>
35 #include <boost/regex.hpp>
37 #include "../../common/WLogger.h"
38 #include "../../common/WProperties.h"
39 #include "../../common/WPropertyBase.h"
40 #include "../../common/WPropertyTypes.h"
41 #include "../../common/WPropertyVariable.h"
42 #include "../../common/WStringUtils.h"
43 #include "../../common/exceptions/WFileNotFound.h"
44 #include "../../graphicsEngine/WGEColormapping.h"
45 #include "../WDataModule.h"
46 #include "../WDataModuleInputFile.h"
47 #include "../WKernel.h"
48 #include "../WModule.h"
49 #include "../WModuleCombiner.h"
50 #include "../WModuleConnector.h"
51 #include "../WModuleFactory.h"
52 #include "../WModuleInputConnector.h"
53 #include "../WModuleOutputConnector.h"
54 #include "../WProjectFile.h"
55 #include "../exceptions/WModuleConnectorNotFound.h"
56 #include "WModuleProjectFileCombiner.h"
80 p->setProject( project );
87 static const boost::regex modRe(
"^ *MODULE:([0-9]*):(.*)$" );
88 static const boost::regex dataReComp(
"^ *DATA:([0-9]*):\"?([^\"]*)\"?$" );
89 static const boost::regex dataRe(
"^ *DATA:([0-9]*):([^:]*):([^:]*):\"?([^\"]*)\"?$" );
90 static const boost::regex conRe(
"^ *CONNECTION:\\(([0-9]*),(.*)\\)->\\(([0-9]*),(.*)\\)$" );
91 static const boost::regex propRe(
"^ *PROPERTY:\\(([0-9]*),(.*)\\)=(.*)$" );
93 boost::smatch matches;
94 if( boost::regex_match( line, matches, modRe ) )
100 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Module \"" << matches[2] <<
"\" with ID " << matches[1];
108 addError(
"There is no prototype available for module \"" + matches[2] +
"\". Skipping." );
110 else if( proto->getType() == MODULE_DATA )
112 addError(
"Data modules are not allowed to be specified in a \"MODULE\" Statement. Use the \"DATA\" statement instead. Skipping." );
118 module->setRestoreNeeded();
120 m_modules.insert(
ModuleID( string_utils::fromString< unsigned int >( matches[1] ), module ) );
123 else if( boost::regex_match( line, matches, dataRe ) )
130 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Data \"" << matches[2] <<
"\" with ID " << matches[1] <<
131 " and input \"" << matches[3] <<
" \" with parameters \"" << matches[4] <<
"\"";
137 addError(
"There is no prototype available for module \"" + matches[2] +
"\". This should not happen!. Skipping." );
141 std::string parameter = std::string( matches[4] );
145 module->setRestoreNeeded();
146 if( parameter.empty() )
148 addError(
"Data modules need an additional parameter. Skipping." );
152 if( !parameter.empty() )
156 m_modules.insert(
ModuleID( string_utils::fromString< unsigned int >( matches[1] ), module ) );
160 else if( boost::regex_match( line, matches, dataReComp ) )
165 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Data \"" << matches[2] <<
"\" with ID " << matches[1];
171 addError(
"There is no prototype available for module \"Data Module\". This should not happen!. Skipping." );
175 std::string parameter = std::string( matches[2] );
179 module->setRestoreNeeded();
180 if( parameter.empty() )
182 addError(
"Data modules need an additional filename parameter. Skipping." );
187 m_modules.insert(
ModuleID( string_utils::fromString< unsigned int >( matches[1] ), module ) );
191 else if( boost::regex_match( line, matches, conRe ) )
197 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Connection between \"" << matches[2] <<
"\" of module "
198 << matches[1] <<
" and \"" << matches[4] <<
"\" of module " << matches[3] <<
".";
202 Connector( string_utils::fromString< unsigned int >( matches[3] ), matches[4] ) ) );
204 else if( boost::regex_match( line, matches, propRe ) )
211 wlog::debug(
"Project Loader [Parser]" ) <<
"Line " << lineNumber <<
": Property \"" << matches[2] <<
"\" of module " << matches[1]
212 <<
" set to " << matches[3];
230 for( std::map<
unsigned int, std::shared_ptr< WModule > >::const_iterator iter =
m_modules.begin(); iter !=
m_modules.end(); ++iter )
237 for( std::map<
unsigned int, std::shared_ptr< WModule > >::iterator iter =
m_modules.begin(); iter !=
m_modules.end(); ++iter )
239 ( *iter ).second->isReadyOrCrashed().wait();
242 if( ( *iter ).second->isCrashed()() )
245 std::string(
" a problem occurred. Connections and properties relating to this module will fail." ) );
254 if( !
m_modules.count( ( *iter ).first.first ) )
257 ( *iter ).first.second + std::string(
"\" for. Skipping." ) );
260 std::shared_ptr< WModule > m =
m_modules[ ( *iter ).first.first ];
263 std::shared_ptr< WPropertyBase > prop = m->getProperties()->findProperty( ( *iter ).first.second );
266 addWarning(
"The module \"" + m->getName() + std::string(
"\" has no property named \"" ) + ( *iter ).first.second +
267 std::string(
"\". Skipping." ) );
272 if( prop->getPurpose() != PV_PURPOSE_INFORMATION )
275 bool result = prop->setAsString( ( *iter ).second );
278 addWarning(
"Failed to set property " + ( *iter ).first.second +
" in module \"" + m->getName() +
"\"." );
283 addWarning(
"The module \"" + m->getName() +
"\" has a property named \"" +
284 ( *iter ).first.second +
"\" which is an INFORMATION property. Skipping." );
298 std::shared_ptr< WModule > m1;
303 c2.second +
"). Skipping." );
308 std::shared_ptr< WModule > m2;
313 "," + c2.second +
"). Skipping." );
322 std::shared_ptr< WModuleOutputConnector > con1;
325 con1 = m1->getOutputConnector( c1.second );
329 addError(
"There is no output connector \"" + c1.second +
"\" in module \"" + m1->getName() +
"\"" );
332 std::shared_ptr< WModuleInputConnector > con2;
335 con2 = m2->getInputConnector( c2.second );
339 addError(
"There is no input connector \"" + c2.second +
"\" in module \"" + m2->getName() +
"\"" );
347 con1->connect( con2,
true );
353 ") could not be created. Incompatible connectors?. Skipping." );
362 for( std::map<
unsigned int, std::shared_ptr< WModule > >::iterator iter =
m_modules.begin(); iter !=
m_modules.end(); ++iter )
364 ( *iter ).second->reportRestoreComplete();
385 std::map< std::shared_ptr< WModule >,
unsigned int > moduleToIDMap;
387 output <<
"//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
388 "// Modules and Properties" << std::endl <<
389 "//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
397 moduleToIDMap[ ( *iter ) ] = i;
400 if( ( *iter )->getType() == MODULE_DATA )
402 output <<
"DATA:" << i <<
":" << std::static_pointer_cast< WDataModule >( ( *iter ) )->getName()
403 <<
":" << std::static_pointer_cast< WDataModule >( ( *iter ) )->getInput()->getName()
408 input->serialize( output );
415 output <<
"MODULE:" << i <<
":" << ( *iter )->getName() << std::endl;
429 output <<
"//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
430 "// Connections" << std::endl <<
431 "//////////////////////////////////////////////////////////////////////////////////////////////////////////////////" << std::endl <<
440 for( WModule::OutputConnectorList::const_iterator citer = outs.begin(); citer != outs.end(); ++citer )
443 std::unique_lock<std::shared_mutex> lock( ( *citer )->m_connectionListLock );
444 for( std::set<std::shared_ptr<WModuleConnector> >::const_iterator iciter = ( *citer )->m_connected.begin();
445 iciter != ( *citer )->m_connected.end(); ++iciter )
448 std::shared_ptr< WModule > theOtherModule = ( *iciter )->m_module.lock();
451 if( moduleToIDMap.find( theOtherModule ) != moduleToIDMap.end() )
453 output <<
"CONNECTION:(" << moduleToIDMap[ ( *iter ) ] <<
"," << ( *citer )->getName() <<
")->(" <<
454 moduleToIDMap[ theOtherModule ] <<
"," << ( *iciter )->getName() <<
")" << std::endl;
465 ModuleIDMap::const_iterator it =
m_modules.find(
id );
471 return ( *it ).second;
477 boost::bind( &ModuleIDMap::value_type::second, boost::placeholders::_1 ) == module
481 return std::numeric_limits< unsigned int >::max();
484 return ( *it ).first;
static std::shared_ptr< WGEColormapping > instance()
Returns instance of the module factory to use to create modules.
OpenWalnut kernel, managing modules and interaction between UI, GE and DataHandler.
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
std::shared_ptr< WModuleContainer > getRootContainer() const
Returns the root module container.
This is a base class for all module combination classes.
std::shared_ptr< WModuleContainer > m_container
The module container to use for the modules.
General purpose exception and therefore base class for all kernel related exceptions.
ModuleContainerType::const_iterator ModuleConstIterator
The const iterator type of the container.
static SPtr getModuleFactory()
Returns instance of the module factory to use to create modules.
std::pair< unsigned int, std::shared_ptr< WModule > > ModuleID
The module ID type.
std::pair< Property, std::string > PropertyValue
A property value is a property and the new value as string.
std::list< PropertyValue > m_properties
All properties.
virtual bool parse(std::string line, unsigned int lineNumber)
This method parses the specified line and interprets it to fill the internal module graph structure.
virtual ~WModuleProjectFileCombiner()
Destructor.
std::map< unsigned int, std::shared_ptr< WModule > > m_modules
All Modules.
std::pair< unsigned int, std::string > Property
A property is a pair of ID and name.
std::pair< unsigned int, std::string > Connector
A connector is described by ID and name.
virtual WProjectFileIO::SPtr clone(WProjectFile *project) const
Create a clone of the IO.
virtual void save(std::ostream &output)
Saves the state to the specified stream.
virtual std::shared_ptr< WModule > mapToModule(unsigned int id) const
Map a given project file ID to a module.
WModuleProjectFileCombiner()
Creates an empty combiner.
virtual unsigned int mapFromModule(std::shared_ptr< WModule > module) const
Map a given module to project file ID.
std::list< Connection > m_connections
All connections.
virtual void apply()
Apply the internal module structure to the target container.
virtual void done()
Called whenever the end of the project file has been reached.
std::pair< Connector, Connector > Connection
A connection is a pair of connectors.
std::shared_ptr< WModule > SPtr
Shared pointer to a WModule.
std::vector< std::shared_ptr< WModuleOutputConnector > > OutputConnectorList
The type for the list of output connectors.
A base class for all parts of OpenWalnut which can be serialized to a project file.
std::shared_ptr< WProjectFileIO > SPtr
Abbreviation for a shared pointer.
void addError(std::string description)
Add an error.
void addWarning(std::string description)
Add an warning.
void printProperties(std::ostream &output, std::shared_ptr< WProperties > props, std::string indent, std::string prefix, unsigned int index, std::string indexPrefix="")
Recursively prints the properties and nested properties.
Class loading project files.
std::shared_ptr< WSharedObjectTicketRead< ModuleContainerType > > ReadTicket
Type for read tickets.
std::string toString(const T &value)
Convert a given value to a string.
WStreamedLogger debug(const std::string &source)
Logging a debug message.