Network.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2007 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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                 //std::cerr <<" *\t\t\t~NETWORK"<<std::endl;
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                         // if exists canvas geometries, store them
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                 // second iteration to store ports. 
00098                 // XR: maybe it should be all in one iteration but this way
00099                 // the xml file is clearer.
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                         // if exists canvas geometries, restore them
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 //              OrderSinksAndSources(_processingsGeometries);
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                 //TODO: use the map find!!!!
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 /*      // TODO: use individual geometries loadings/storings??:
00439         const Network::Geometry Network::GetAndEraseGeometry(std::string name)
00440         {
00441                 const ProcessingsGeometriesMap::iterator itGeometry =_processingsGeometries.find(name);
00442                 Geometry geometry=itGeometry->second;
00443                 if (itGeometry == _processingsGeometries.end())
00444                 {
00445                         geometry.width=0;
00446                         geometry.height=0;
00447                         return geometry;
00448                 }
00449                 _processingsGeometries.erase(name); // if exists, erase geometry from map
00450                 return geometry;
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         // flow and player related methods
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         // returns the name that was used so the same one can be used when calling CreateProcessingController (hack)
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) ) //they have different type
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) ) //they have different type
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                         //std::cerr << "REMOVING <"<<_processings.begin()->first<<">"<<std::endl;
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         // accessors to text boxes
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; // To avoid warning message
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() ) // newName is being used
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         // TODO: Test GetConfigurationErrors
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 
Generated by  doxygen 1.6.3