00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Network.hxx"
00024 #include "NaiveFlowControl.hxx"
00025 #include "NetworkPlayer.hxx"
00026 #include <algorithm>
00027 #include "ProcessingDefinitionAdapter.hxx"
00028 #include "ConnectionDefinitionAdapter.hxx"
00029 #include "InformationTextAdapter.hxx"
00030 #include "ProcessingFactory.hxx"
00031 #include "XmlStorageErr.hxx"
00032 #ifdef USE_LADSPA //TODO alway include it. move conditional code in LFactory.hxx
00033 #include "ProcessingFactory.hxx"
00034 #endif
00035 #include "ControlSink.hxx"
00036 #include "ControlSource.hxx"
00037 #include "CLAMVersion.hxx"
00038
00039 #include <sstream>
00040 #include <algorithm>
00041 #include <iterator>
00042
00043
00044 namespace CLAM
00045 {
00046 Network::Network() :
00047 _name("Unnamed Network"),
00048 _flowControl(new NaiveFlowControl),
00049 _player(0),
00050 _setPasteMode(false)
00051 {}
00052
00053 Network::~Network()
00054 {
00055
00056 Clear();
00057 if (_flowControl) delete _flowControl;
00058 if (_player) delete _player;
00059 }
00060
00061 void Network::StoreOn( Storage & storage) const
00062 {
00063 XMLAdapter<std::string> strAdapter( _name, "id");
00064 storage.Store(strAdapter);
00065
00066 std::string version = CLAM::GetVersion();
00067 XMLAdapter<std::string> versionAdapter( version, "clamVersion");
00068 storage.Store(versionAdapter);
00069
00070 if (not _description.empty())
00071 {
00072 XMLAdapter<Text> descriptionAdapter(_description, "description", true);
00073 storage.Store(descriptionAdapter);
00074 }
00075
00076 ProcessingsMap::const_iterator it;
00077 for(it=BeginProcessings();it!=EndProcessings();it++)
00078 {
00079 Processing * proc = it->second;
00080 const std::string & name = it->first;
00081 if (!HasSelectionAndContains(name))
00082 continue;
00083 std::string processingPosition;
00084 std::string processingSize;
00085
00086 if (!_processingsGeometries.empty())
00087 {
00088 Geometry & geometry=_processingsGeometries.find(name)->second;
00089 processingPosition=IntsToString (geometry.x, geometry.y);
00090 processingSize=IntsToString (geometry.width, geometry.height);
00091 }
00092 ProcessingDefinitionAdapter procDefinition(proc, name, processingPosition, processingSize);
00093 XMLComponentAdapter xmlAdapter(procDefinition, "processing", true);
00094 storage.Store(xmlAdapter);
00095 }
00096
00097
00098
00099
00100
00101 for(it=BeginProcessings();it!=EndProcessings();it++)
00102 {
00103 const std::string & name = it->first;
00104 Processing * proc = it->second;
00105
00106 if (!HasSelectionAndContains(name))
00107 continue;
00108
00109 unsigned nOutPorts = proc->GetNOutPorts();
00110 for (unsigned i = 0; i<nOutPorts; i++)
00111 {
00112 OutPortBase & outport = proc->GetOutPort(i);
00113 if (!outport.HasConnections())
00114 continue;
00115
00116 std::string outPortName = name + "." + outport.GetName();
00117 NamesList namesInPorts = GetInPortsConnectedTo(outPortName);
00118 NamesList::iterator namesIterator;
00119 for(namesIterator=namesInPorts.begin();
00120 namesIterator!=namesInPorts.end();
00121 namesIterator++)
00122 {
00123 if (!HasSelectionAndContains(GetProcessingIdentifier(*namesIterator)))
00124 continue;
00125 ConnectionDefinitionAdapter connectionDefinition( outPortName, *namesIterator );
00126 XMLComponentAdapter xmlAdapter(connectionDefinition, "port_connection", true);
00127 storage.Store(xmlAdapter);
00128 }
00129 }
00130 }
00131
00132 for(it=BeginProcessings();it!=EndProcessings();it++)
00133 {
00134 const std::string & name = it->first;
00135 Processing * proc = it->second;
00136
00137 if (!HasSelectionAndContains(name))
00138 continue;
00139
00140 unsigned nOutControls = proc->GetNOutControls();
00141 for (unsigned i = 0; i<nOutControls; i++)
00142 {
00143 OutControlBase & outControl = proc->GetOutControl(i);
00144 std::string outControlName = name+ "." + outControl.GetName();
00145 NamesList namesInControls = GetInControlsConnectedTo(outControlName);
00146 NamesList::iterator namesIterator;
00147 for(namesIterator=namesInControls.begin();
00148 namesIterator!=namesInControls.end();
00149 namesIterator++)
00150 {
00151 if (!HasSelectionAndContains(GetProcessingIdentifier(*namesIterator)))
00152 continue;
00153 ConnectionDefinitionAdapter connectionDefinition( outControlName, *namesIterator );
00154 XMLComponentAdapter xmlAdapter(connectionDefinition, "control_connection", true);
00155 storage.Store(xmlAdapter);
00156 }
00157 }
00158 }
00159
00160 InformationTexts::const_iterator ibIt;
00161 for(ibIt=BeginInformationTexts();ibIt!=EndInformationTexts();ibIt++)
00162 {
00163 InformationTextAdapter infoTextDefinition((*ibIt)->x, (*ibIt)->y, (*ibIt)->text);
00164 XMLComponentAdapter xmlAdapter(infoTextDefinition, "information", true);
00165 storage.Store(xmlAdapter);
00166 }
00167
00168 _selectedProcessings.clear();
00169 _processingsGeometries.clear();
00170 }
00171
00172 void Network::LoadFrom( Storage & storage)
00173 {
00174 typedef std::map <std::string, std::string> NamesMap;
00175 NamesMap namesMap;
00176 if (!_setPasteMode) Clear();
00177 XMLAdapter<std::string> strAdapter( _name, "id");
00178 storage.Load(strAdapter);
00179 _processingsGeometries.clear();
00180
00181 XMLAdapter<Text> descriptionAdapter(_description, "description", true);
00182 if(not storage.Load(descriptionAdapter)) _description="";
00183
00184 while(1)
00185 {
00186 ProcessingDefinitionAdapter procDefinition;
00187 XMLComponentAdapter xmlAdapter(procDefinition, "processing", true);
00188 if (not storage.Load(xmlAdapter)) break;
00189
00190 const std::string & definitionName = procDefinition.GetName();
00191 CLAM::Processing * processing = procDefinition.GetProcessing();
00192 std::string finalName = definitionName;
00193 if (_setPasteMode)
00194 {
00195 finalName = GetUnusedName(definitionName, true);
00196 namesMap.insert(std::make_pair(definitionName,finalName));
00197 }
00198 AddProcessing(finalName, processing, procDefinition.GetConfiguration());
00199
00200 if (procDefinition.GetPosition()!="" && procDefinition.GetSize()!="")
00201 {
00202 Geometry geometry;
00203 StringPairToInts(procDefinition.GetPosition(),geometry.x,geometry.y);
00204 StringPairToInts(procDefinition.GetSize(),geometry.width,geometry.height);
00205 _processingsGeometries.insert(ProcessingsGeometriesMap::value_type(finalName,geometry));
00206 }
00207 }
00208
00209 while(1)
00210 {
00211 ConnectionDefinitionAdapter connectionDefinition;
00212 XMLComponentAdapter xmlAdapter(connectionDefinition, "port_connection", true);
00213 if (not storage.Load(xmlAdapter)) break;
00214 std::string fullOut = connectionDefinition.GetOutName();
00215 std::string fullIn = connectionDefinition.GetInName();
00216
00217 if (_setPasteMode)
00218 {
00219 fullOut = namesMap.find(GetProcessingIdentifier(fullOut))->second
00220 +"."+GetConnectorIdentifier(fullOut);
00221 fullIn = namesMap.find(GetProcessingIdentifier(fullIn))->second
00222 +"."+GetConnectorIdentifier(fullIn);
00223 }
00224
00225 if (BrokenConnection(fullOut, fullIn))
00226 continue;
00227
00228 if (not ConnectPorts( fullOut, fullIn ))
00229 {
00230 throw XmlStorageErr(std::string("Unable to connect ports '")+fullOut+"->"+fullIn+".");
00231 }
00232 }
00233
00234 while(1)
00235 {
00236 ConnectionDefinitionAdapter connectionDefinition;
00237 XMLComponentAdapter xmlAdapter(connectionDefinition, "control_connection", true);
00238 if (!storage.Load(xmlAdapter)) break;
00239 std::string fullOut = connectionDefinition.GetOutName();
00240 std::string fullIn = connectionDefinition.GetInName();
00241 if (_setPasteMode)
00242 {
00243 fullOut = namesMap.find(GetProcessingIdentifier(fullOut))->second
00244 +"."+GetConnectorIdentifier(fullOut);
00245 fullIn = namesMap.find(GetProcessingIdentifier(fullIn))->second
00246 +"."+GetConnectorIdentifier(fullIn);
00247 }
00248 if (not ConnectControls( fullOut, fullIn ))
00249 throw XmlStorageErr(std::string("Unable to connect controls '")+fullOut+"->"+fullIn+".");
00250 }
00251
00252 while(1)
00253 {
00254 InformationTextAdapter infoTextDefinition;
00255 XMLComponentAdapter xmlAdapter(infoTextDefinition, "information", true);
00256 if (not storage.Load(xmlAdapter)) break;
00257
00258 InformationText *myInformationText=new InformationText();
00259 myInformationText->x=infoTextDefinition.GetCoordX();
00260 myInformationText->y=infoTextDefinition.GetCoordY();
00261 myInformationText->text=infoTextDefinition.GetText();
00262
00263 _informationTexts.push_back(myInformationText);
00264 }
00265
00266 _setPasteMode=false;
00267
00268 }
00269
00270 bool Network::UpdateSelections (const NamesList & processingsNamesList)
00271 {
00272 if (!_selectedProcessings.empty() || processingsNamesList.empty())
00273 {
00274 _selectedProcessings.clear();
00275 return true;
00276 }
00277 NamesList::const_iterator namesIterator;
00278 for (namesIterator=processingsNamesList.begin();namesIterator!=processingsNamesList.end();namesIterator++)
00279 _selectedProcessings.insert(*namesIterator);
00280 return false;
00281 }
00282
00283 bool Network::HasSelectionAndContains(const std::string & name) const
00284 {
00285 NamesSet::const_iterator itFindSelected = _selectedProcessings.find(name);
00286 if (!_selectedProcessings.empty() && itFindSelected==_selectedProcessings.end())
00287 return false;
00288 return true;
00289 }
00290
00291
00292 const Network::Geometry Network::findProcessingGeometry(Processing* processing) const
00293 {
00294
00295 for (ProcessingsGeometriesMap::const_iterator it=_processingsGeometries.begin();it!=_processingsGeometries.end();it++)
00296 {
00297 if ( &GetProcessing(it->first) == processing )
00298 return it->second;
00299 }
00300 Geometry nullGeometry={0,10000,0,0};
00301 return nullGeometry;
00302 }
00303
00304 const Network::Processings Network::getOrderedProcessings(const std::string & type, bool horizontalOrder) const
00305 {
00306 std::list <ProcessingAndGeometry> processingsAndGeometries;
00307 Processings orderedProcessings;
00308 for (ProcessingsMap::const_iterator it=_processings.begin(); it!=_processings.end(); it++)
00309 {
00310 Processing * proc = it->second;
00311 const std::string className = proc->GetClassName();
00312 if (className!=type)
00313 continue;
00314 ProcessingAndGeometry item;
00315 item.processing = proc;
00316 item.geometry = findProcessingGeometry(proc);
00317 processingsAndGeometries.push_back(item);
00318 processingsAndGeometries.sort(horizontalOrder?compareGeometriesUpperXThan:compareGeometriesUpperYThan);
00319 }
00320
00321 for (std::list<ProcessingAndGeometry>::const_iterator it=processingsAndGeometries.begin();
00322 it!=processingsAndGeometries.end();it++)
00323 {
00324 orderedProcessings.push_back( it->processing );
00325 }
00326
00327 return orderedProcessings;
00328 }
00329
00330 const Network::Processings Network::getOrderedProcessingsByAttribute(const std::string & attribute, bool horizontalOrder) const
00331 {
00332 std::list <ProcessingAndGeometry> processingsAndGeometries;
00333 Processings orderedProcessings;
00334 for (ProcessingsMap::const_iterator it=_processings.begin(); it!=_processings.end(); it++)
00335 {
00336 Processing * proc = it->second;
00337 const std::string className = proc->GetClassName();
00338 if (!ProcessingFactory::GetInstance().AttributeExists(className,attribute))
00339 continue;
00340 ProcessingAndGeometry item;
00341 item.processing = proc;
00342 item.geometry = findProcessingGeometry(proc);
00343 processingsAndGeometries.push_back(item);
00344 processingsAndGeometries.sort(horizontalOrder?compareGeometriesUpperXThan:compareGeometriesUpperYThan);
00345 }
00346
00347 for (std::list<ProcessingAndGeometry>::const_iterator it=processingsAndGeometries.begin();
00348 it!=processingsAndGeometries.end();it++)
00349 {
00350 orderedProcessings.push_back( it->processing );
00351 }
00352
00353 return orderedProcessings;
00354 }
00355
00356 const Network::ControlSinks Network::getOrderedControlSinks() const
00357 {
00358 std::list <ProcessingAndGeometry> controlSinksAndGeometries;
00359 ControlSinks orderedControlSinks;
00360 for (ProcessingsMap::const_iterator it=_processings.begin(); it!=_processings.end(); it++)
00361 {
00362 Processing * proc = it->second;
00363 const std::string className = proc->GetClassName();
00364 if (className!="ControlSink")
00365 continue;
00366 ProcessingAndGeometry item;
00367 item.processing = proc;
00368 item.geometry = findProcessingGeometry(proc);
00369 controlSinksAndGeometries.push_back(item);
00370 controlSinksAndGeometries.sort(compareGeometriesUpperXThan);
00371 }
00372
00373 for (std::list<ProcessingAndGeometry>::const_iterator it=controlSinksAndGeometries.begin();
00374 it!=controlSinksAndGeometries.end();it++)
00375 {
00376 ControlSink* controlSink = dynamic_cast<ControlSink*>(it->processing);
00377 CLAM_ASSERT(controlSink, "Expected an AudioSink");
00378 orderedControlSinks.push_back( controlSink );
00379 }
00380
00381 return orderedControlSinks;
00382 }
00383
00384 const Network::ControlSources Network::getOrderedControlSources() const
00385 {
00386 std::list <ProcessingAndGeometry> controlSourcesAndGeometries;
00387 ControlSources orderedControlSources;
00388 for (ProcessingsMap::const_iterator it=_processings.begin(); it!=_processings.end(); it++)
00389 {
00390 Processing * proc = it->second;
00391 const std::string className = proc->GetClassName();
00392 if (className!="ControlSource")
00393 continue;
00394 ProcessingAndGeometry item;
00395 item.processing = proc;
00396 item.geometry = findProcessingGeometry(proc);
00397 controlSourcesAndGeometries.push_back(item);
00398 controlSourcesAndGeometries.sort(compareGeometriesUpperXThan);
00399 }
00400
00401 for (std::list<ProcessingAndGeometry>::const_iterator it=controlSourcesAndGeometries.begin();
00402 it!=controlSourcesAndGeometries.end();it++)
00403 {
00404 ControlSource* controlSource = dynamic_cast<ControlSource*>(it->processing);
00405 CLAM_ASSERT(controlSource, "Expected an AudioSink");
00406 orderedControlSources.push_back( controlSource );
00407 }
00408
00409 return orderedControlSources;
00410 }
00411
00412 bool Network::SetProcessingsGeometries (const ProcessingsGeometriesMap & processingsGeometries)
00413 {
00414 _processingsGeometries.clear();
00415 if (processingsGeometries.empty())
00416 return true;
00417 _processingsGeometries=processingsGeometries;
00418 return false;
00419 }
00420
00421 const Network::ProcessingsGeometriesMap Network::GetAndClearGeometries()
00422 {
00423 const ProcessingsGeometriesMap copyProcessingsGeometry(_processingsGeometries);
00424 _processingsGeometries.clear();
00425 return copyProcessingsGeometry;
00426 }
00427
00428 const bool Network::compareGeometriesUpperYThan (ProcessingAndGeometry & arg1, ProcessingAndGeometry & arg2)
00429 {
00430 return arg1.geometry.y < arg2.geometry.y ;
00431 }
00432
00433 const bool Network::compareGeometriesUpperXThan (ProcessingAndGeometry & arg1, ProcessingAndGeometry & arg2)
00434 {
00435 return arg1.geometry.x < arg2.geometry.x ;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 void Network::StringPairToInts(const std::string & geometryInString, int & a, int & b)
00454 {
00455 a=atoi(geometryInString.substr(0,geometryInString.find(",")).c_str());
00456 b=atoi(geometryInString.substr(geometryInString.find(",")+1,geometryInString.length()).c_str());
00457 }
00458
00459 const std::string Network::IntsToString (const int & a, const int & b) const
00460 {
00461 std::ostringstream stream;
00462 stream<<a<<","<<b;
00463 return stream.str();
00464 }
00465
00466
00467 void Network::AddFlowControl(FlowControl* flowControl)
00468 {
00469 if (_flowControl) delete _flowControl;
00470 _flowControl = flowControl;
00471 _flowControl->AttachToNetwork((CLAM::Network*)this);
00472 }
00473 void Network::SetPlayer(NetworkPlayer* player)
00474 {
00475 if (_player) delete _player;
00476 _player = player;
00477 _player->SetNetworkBackLink(*(CLAM::Network*)this);
00478 _player->Init();
00479 }
00480 unsigned Network::BackendBufferSize()
00481 {
00482 if (!_player) return 512;
00483 return _player->BackendBufferSize();
00484 }
00485 unsigned Network::BackendSampleRate()
00486 {
00487 if (!_player) return 44100;
00488 return _player->BackendSampleRate();
00489 }
00490
00491
00492 Processing& Network::GetProcessing( const std::string & name ) const
00493 {
00494 CLAM_ASSERT( HasProcessing(name),
00495 ("No processing in the network has the name '"+name+"'.").c_str());
00496
00497 ProcessingsMap::const_iterator it = _processings.find( name );
00498 return *it->second;
00499 }
00500
00501 void Network::AddProcessing( const std::string & name, Processing* proc, const ProcessingConfig * config)
00502 {
00503 if (!IsStopped()) Stop();
00504
00505 if (!_processings.insert( ProcessingsMap::value_type( name, proc ) ).second )
00506 CLAM_ASSERT(false, "Network::AddProcessing() Trying to add a processing with a repeated name (key)" );
00507 proc->SetNetworkBackLink((CLAM::Network*)this);
00508 proc->Configure(config ? *config : proc->GetConfig());
00509 _flowControl->ProcessingAddedToNetwork(*proc);
00510 }
00511
00512 Processing & Network::AddProcessing( const std::string & name, const std::string & factoryKey )
00513 {
00514 Processing * proc = ProcessingFactory::GetInstance().CreateSafe( factoryKey );
00515 AddProcessing(name, proc);
00516 return *proc;
00517 }
00518
00519
00520 std::string Network::AddProcessing( const std::string & factoryKey )
00521 {
00522 std::string name = GetUnusedName( factoryKey );
00523 AddProcessing(name, factoryKey );
00524 return name;
00525 }
00526
00527 std::string Network::GetUnusedName( const std::string& prefix, const bool cutOnLastSeparator, const std::string separator ) const
00528 {
00529 std::string name;
00530 std::string newPrefix=prefix;
00531 if (cutOnLastSeparator==true)
00532 {
00533 int lastSeparatorPos=prefix.rfind(separator);
00534 if (lastSeparatorPos!=-1)
00535 newPrefix=prefix.substr(0,lastSeparatorPos);
00536 }
00537
00538 for ( int i = 0; i<9999999; i++ )
00539 {
00540 std::stringstream tmp;
00541 tmp << i;
00542 name = i? newPrefix + separator + tmp.str() : newPrefix;
00543 if (!this->HasProcessing( name ) ) return name;
00544 }
00545 CLAM_ASSERT(false, "All valid id's for given prefix are exhausted");
00546 return "";
00547 }
00548
00549 void Network::RemoveProcessing ( const std::string & name)
00550 {
00551 CLAM_ASSERT( _flowControl,
00552 "Network::RemoveProcessing() - Network should have an attached flow control at this state.");
00553
00554 ProcessingsMap::const_iterator i = _processings.find( name );
00555 if(i==_processings.end())
00556 {
00557 std::string msg("Network::RemoveProcessing() Trying to remove a processing that is not included in the network:");
00558 msg += name;
00559 CLAM_ASSERT(false, msg.c_str() );
00560 }
00561 if ( !IsStopped() ) Stop();
00562 Processing * proc = i->second;
00563 _processings.erase( name );
00564
00565 _flowControl->ProcessingRemovedFromNetwork(*proc);
00566 delete proc;
00567 }
00568
00569 bool Network::HasProcessing( const std::string& name ) const
00570 {
00571 ProcessingsMap::const_iterator i = _processings.find( name );
00572 return i!=_processings.end();
00573 }
00574
00575 bool Network::ConfigureProcessing( const std::string & name, const ProcessingConfig & newConfig )
00576 {
00577 ProcessingsMap::iterator it = _processings.find( name );
00578 CLAM_ASSERT(it!=_processings.end(),"Wrong processing name to configure in a network");
00579 Processing * proc = it->second;
00580 if ( !IsStopped() ) Stop();
00581 bool ok = proc->Configure( newConfig );
00582 _flowControl->ProcessingConfigured(*proc);
00583 return ok;
00584 }
00585
00586 void Network::ReconfigureAllProcessings()
00587 {
00588 ProcessingsMap::iterator it;
00589 for( it=_processings.begin(); it!=_processings.end(); it++)
00590 {
00591 Processing* proc = it->second;
00592 proc->Configure( proc->GetConfig() );
00593 }
00594 }
00595
00596 bool Network::ConnectPorts( const std::string & producer, const std::string & consumer )
00597 {
00598 _flowControl->NetworkTopologyChanged();
00599
00600 OutPortBase & outport = GetOutPortByCompleteName(producer);
00601 InPortBase & inport = GetInPortByCompleteName(consumer);
00602
00603 if ( outport.IsVisuallyConnectedTo(inport) )
00604 return false;
00605
00606 if ( !outport.IsConnectableTo(inport) )
00607 return false;
00608
00609 if( inport.GetVisuallyConnectedOutPort())
00610 return false;
00611
00612 if (!IsStopped()) Stop();
00613
00614 outport.ConnectToIn( inport );
00615 return true;
00616 }
00617
00618 bool Network::ConnectControls( const std::string & producer, const std::string & consumer )
00619 {
00620 OutControlBase & outcontrol = GetOutControlByCompleteName(producer);
00621 InControlBase & incontrol = GetInControlByCompleteName(consumer);
00622
00623 if ( outcontrol.IsConnectedTo(incontrol) )
00624 return false;
00625
00626 if ( !outcontrol.IsLinkable(incontrol) )
00627 return false;
00628
00629 if (!IsStopped()) Stop();
00630
00631 outcontrol.AddLink( incontrol );
00632 return true;
00633 }
00634
00635
00636 bool Network::DisconnectPorts( const std::string & producer, const std::string & consumer)
00637 {
00638 _flowControl->NetworkTopologyChanged();
00639
00640 OutPortBase & outport = GetOutPortByCompleteName(producer);
00641 InPortBase & inport = GetInPortByCompleteName(consumer);
00642
00643 if ( !outport.IsVisuallyConnectedTo(inport))
00644 return false;
00645
00646 if (!IsStopped()) Stop();
00647
00648 outport.DisconnectFromIn( inport );
00649 return true;
00650 }
00651
00652 bool Network::DisconnectControls( const std::string & producer, const std::string & consumer)
00653 {
00654 OutControlBase & outcontrol = GetOutControlByCompleteName(producer);
00655 InControlBase & incontrol = GetInControlByCompleteName(consumer);
00656
00657 if ( !outcontrol.IsConnectedTo( incontrol ))
00658 return false;
00659
00660 if (!IsStopped()) Stop();
00661
00662 outcontrol.RemoveLink( incontrol );
00663 return true;
00664 }
00665
00666 std::string Network::GetConnectorIdentifier( const std::string& str ) const
00667 {
00668 return str.substr( PositionOfLastIdentifier(str)+1 );
00669 }
00670
00671 std::string Network::GetProcessingIdentifier( const std::string& str ) const
00672 {
00673 std::size_t length = PositionOfLastIdentifier(str) - PositionOfProcessingIdentifier(str);
00674 return str.substr( PositionOfProcessingIdentifier(str), length);
00675 }
00676
00677 InPortBase & Network::GetInPortByCompleteName( const std::string & name ) const
00678 {
00679 Processing& proc = GetProcessing( GetProcessingIdentifier(name) );
00680 return proc.GetInPort( GetConnectorIdentifier(name) );
00681 }
00682
00683 OutPortBase & Network::GetOutPortByCompleteName( const std::string & name ) const
00684 {
00685 Processing& proc = GetProcessing( GetProcessingIdentifier(name) );
00686 return proc.GetOutPort( GetConnectorIdentifier(name) );
00687 }
00688
00689 InControlBase & Network::GetInControlByCompleteName( const std::string & name ) const
00690 {
00691 Processing& proc = GetProcessing( GetProcessingIdentifier(name) );
00692 return proc.GetInControl( GetConnectorIdentifier(name) );
00693 }
00694
00695 OutControlBase & Network::GetOutControlByCompleteName( const std::string & name ) const
00696 {
00697 Processing& proc = GetProcessing( GetProcessingIdentifier(name) );
00698 return proc.GetOutControl( GetConnectorIdentifier(name) );
00699 }
00700
00701 bool Network::IsStopped() const
00702 {
00703 if (! _player)
00704 return true;
00705 return _player->IsStopped();
00706 }
00707
00708 bool Network::IsPlaying() const
00709 {
00710 if (! _player)
00711 return false;
00712 return _player->IsPlaying();
00713 }
00714
00715 bool Network::IsPaused() const
00716 {
00717 if (! _player)
00718 return false;
00719 return _player->IsPaused();
00720 }
00721
00722 bool Network::IsRealTime() const
00723 {
00724 if (! _player)
00725 return false;
00726 return _player->IsRealTime();
00727 }
00728
00729 void Network::Start()
00730 {
00731 ProcessingsMap::iterator it;
00732 for (it=BeginProcessings(); it!=EndProcessings(); it++)
00733 {
00734 if (it->second->IsRunning())
00735 {
00736 continue;
00737 }
00738 if (it->second->IsConfigured())
00739 {
00740 it->second->Start();
00741 }
00742 else
00743 {
00744 std::cerr << "Warning: could not start processing for not being Configured: '"
00745 << it->first<< "' of class " << it->second->GetClassName() << std::endl;
00746 }
00747 }
00748 if (_player)
00749 _player->Start();
00750 }
00751
00752 void Network::Stop()
00753 {
00754 if (_player) _player->Stop();
00755 ProcessingsMap::iterator it;
00756 for (it=BeginProcessings(); it!=EndProcessings(); it++)
00757 if (it->second->IsRunning())
00758 it->second->Stop();
00759 }
00760 void Network::Pause()
00761 {
00762 if (_player) _player->Pause();
00763 }
00764
00765 void Network::Do()
00766 {
00767 _flowControl->Do();
00768 }
00769
00770 void Network::Clear()
00771 {
00772 if ( !IsStopped() ) Stop();
00773
00774 while( !_processings.empty() )
00775 {
00776
00777 RemoveProcessing( _processings.begin()->first );
00778 }
00779 for(unsigned i=0;i<_informationTexts.size();i++)
00780 {
00781 removeInformationText(_informationTexts[i]);
00782 }
00783 _informationTexts.clear();
00784 }
00785
00786 Network::ProcessingsMap::iterator Network::BeginProcessings()
00787 {
00788 return _processings.begin();
00789 }
00790
00791 Network::ProcessingsMap::iterator Network::EndProcessings()
00792 {
00793 return _processings.end();
00794 }
00795 Network::ProcessingsMap::const_iterator Network::BeginProcessings() const
00796 {
00797 return _processings.begin();
00798 }
00799
00800 Network::ProcessingsMap::const_iterator Network::EndProcessings() const
00801 {
00802 return _processings.end();
00803 }
00804
00805
00806
00807 void Network::addInformationText(InformationText * informationText)
00808 {
00809 _informationTexts.push_back(informationText);
00810 }
00811
00812 void Network::removeInformationText(InformationText * informationText)
00813 {
00814 InformationTexts::iterator it = find(BeginInformationTexts(), EndInformationTexts(), informationText);
00815
00816 if(it!=EndInformationTexts())
00817 _informationTexts.erase(it);
00818 else
00819 std::cerr << "Warning: Information Text Box does not exist.";
00820 }
00821
00822 Network::InformationTexts::iterator Network::BeginInformationTexts()
00823 {
00824 return _informationTexts.begin();
00825 }
00826
00827 Network::InformationTexts::iterator Network::EndInformationTexts()
00828 {
00829 return _informationTexts.end();
00830 }
00831
00832 Network::InformationTexts::const_iterator Network::BeginInformationTexts() const
00833 {
00834 return _informationTexts.begin();
00835 }
00836
00837 Network::InformationTexts::const_iterator Network::EndInformationTexts() const
00838 {
00839 return _informationTexts.end();
00840 }
00841
00842
00843 Network::NamesList Network::GetInPortsConnectedTo( const std::string & producer ) const
00844 {
00845 OutPortBase & out = GetOutPortByCompleteName( producer );
00846 NamesList consumers;
00847
00848 if(!out.HasConnections())
00849 return consumers;
00850
00851 OutPortBase::InPortsList::iterator it;
00852 for(it=out.BeginVisuallyConnectedInPorts(); it!=out.EndVisuallyConnectedInPorts(); it++)
00853 {
00854 std::string completeName(GetNetworkId((*it)->GetProcessing()));
00855 completeName += ".";
00856 completeName += (*it)->GetName();
00857 consumers.push_back(completeName);
00858 }
00859 return consumers;
00860 }
00861
00862 Network::NamesList Network::GetInControlsConnectedTo( const std::string & producer ) const
00863 {
00864 OutControlBase & out = GetOutControlByCompleteName( producer );
00865 NamesList consumers;
00866
00867 std::list<InControlBase*>::iterator it;
00868 for(it=out.BeginInControlsConnected();
00869 it!=out.EndInControlsConnected();
00870 it++)
00871 {
00872 std::string completeName(GetNetworkId((*it)->GetProcessing()));
00873 completeName += ".";
00874 completeName += (*it)->GetName();
00875 consumers.push_back(completeName);
00876 }
00877 return consumers;
00878 }
00879
00880 Network::InPortsList Network::GetInPortsConnectedTo( OutPortBase & producer ) const
00881 {
00882 InPortsList consumers;
00883 OutPortBase::InPortsList::iterator it;
00884 for(it=producer.BeginVisuallyConnectedInPorts(); it!=producer.EndVisuallyConnectedInPorts(); it++)
00885 consumers.push_back(*it);
00886 return consumers;
00887 }
00888
00889 const std::string & Network::GetNetworkId(const Processing * proc) const
00890 {
00891 ProcessingsMap::const_iterator it;
00892 for(it=BeginProcessings(); it!=EndProcessings(); it++)
00893 if(it->second == proc )
00894 return it->first;
00895
00896 CLAM_ASSERT(false, "Trying to get a network id from a processing not present in it");
00897 throw 0;
00898 }
00899
00900 bool Network::RenameProcessing( const std::string & oldName, const std::string & newName )
00901 {
00902 if (oldName==newName) return true;
00903 if( _processings.find( newName ) != _processings.end() )
00904 return false;
00905 ProcessingsMap::iterator it = _processings.find( oldName );
00906 Processing * proc = it->second;
00907 _processings.erase( it );
00908 _processings.insert( ProcessingsMap::value_type( newName, proc ) );
00909 return true;
00910 }
00911
00912 bool Network::IsReady() const
00913 {
00914 if (IsEmpty()) return false;
00915 if (HasMisconfiguredProcessings()) return false;
00916 if (HasUnconnectedInPorts()) return false;
00917 return true;
00918 }
00919
00920 bool Network::IsEmpty() const
00921 {
00922 return _processings.empty();
00923 }
00924
00925 bool Network::HasMisconfiguredProcessings() const
00926 {
00927 ProcessingsMap::const_iterator it;
00928 for(it=BeginProcessings(); it!=EndProcessings(); it++)
00929 if(!it->second->IsConfigured())
00930 return true;
00931 return false;
00932 }
00933
00934 bool Network::HasUnconnectedInPorts() const
00935 {
00936 for (ProcessingsMap::const_iterator it=BeginProcessings(); it!=EndProcessings(); it++)
00937 {
00938 Processing * proc = it->second;
00939 unsigned nInPorts = proc->GetNInPorts();
00940 for (unsigned i = 0; i<nInPorts; i++)
00941 {
00942 InPortBase & inPort = proc->GetInPort(i);
00943 if (not inPort.GetVisuallyConnectedOutPort())
00944 return true;
00945 }
00946 }
00947 return false;
00948 }
00949 std::string Network::GetUnconnectedInPorts() const
00950 {
00951 std::string result;
00952 for (ProcessingsMap::const_iterator it=BeginProcessings(); it!=EndProcessings(); it++)
00953 {
00954 Processing * proc = it->second;
00955 unsigned nInPorts = proc->GetNInPorts();
00956 for (unsigned i = 0; i<nInPorts; i++)
00957 {
00958 InPortBase & inPort = proc->GetInPort(i);
00959 if (not inPort.GetVisuallyConnectedOutPort())
00960 result+= it->first + "." + inPort.GetName() + "\n";
00961 }
00962 }
00963 return result;
00964 }
00965
00966 bool Network::HasSyncSource() const
00967 {
00968 ProcessingsMap::const_iterator it;
00969 for(it=BeginProcessings(); it!=EndProcessings(); it++)
00970 if(it->second->IsSyncSource())
00971 return true;
00972 return false;
00973 }
00974
00975 bool Network::SupportsVariableAudioSize() const
00976 {
00977 ProcessingsMap::const_iterator it;
00978 for(it=BeginProcessings(); it!=EndProcessings(); it++)
00979 if(!it->second->SupportsVariableAudioSize())
00980 return false;
00981 return true;
00982 }
00983
00984
00985 std::string Network::GetConfigurationErrors() const
00986 {
00987 std::ostringstream errorMessage;
00988 ProcessingsMap::const_iterator it;
00989 for(it=BeginProcessings(); it!=EndProcessings(); it++)
00990 {
00991 if(it->second->IsConfigured()) continue;
00992 errorMessage << "* Processing '" << it->first << "' is misconfigured:\n";
00993 errorMessage << it->second->GetConfigErrorMessage() << std::endl;
00994 }
00995
00996 return errorMessage.str();
00997 }
00998
00999 bool Network::BrokenConnection( const std::string & producer, const std::string & consumer )
01000 {
01001 bool brokenConnection = false;
01002
01003 Processing& prod = GetProcessing( GetProcessingIdentifier(producer) );
01004 Processing& cons = GetProcessing( GetProcessingIdentifier(consumer) );
01005
01006 if (!prod.HasOutPort(GetConnectorIdentifier(producer)))
01007 brokenConnection = true;
01008
01009 if (!cons.HasInPort(GetConnectorIdentifier(consumer)))
01010 brokenConnection = true;
01011
01012 if (brokenConnection)
01013 _brokenConnections.push_back(producer + " -> " + consumer);
01014
01015 return brokenConnection;
01016 }
01017
01018 Network::ConnectionState Network::GetConnectionReport() const
01019 {
01020 std::ostringstream os;
01021 std::copy(_brokenConnections.begin(), _brokenConnections.end(),
01022 std::ostream_iterator<std::string> (os, "<br/> "));
01023
01024 return std::make_pair(_brokenConnections.size() != 0, os.str());
01025 }
01026
01027 void Network::ResetConnectionReport()
01028 {
01029 _brokenConnections.clear();
01030 }
01031 }
01032