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