summaryrefslogtreecommitdiff
path: root/AudioManagerCore/include
diff options
context:
space:
mode:
Diffstat (limited to 'AudioManagerCore/include')
-rw-r--r--AudioManagerCore/include/CAmCommandSender.h13
-rw-r--r--AudioManagerCore/include/CAmDatabaseHandlerMap.h168
-rw-r--r--AudioManagerCore/include/CAmDatabaseObserver.h87
-rw-r--r--AudioManagerCore/include/CAmGraph.h161
-rw-r--r--AudioManagerCore/include/CAmRouter.h606
-rw-r--r--AudioManagerCore/include/CAmRoutingSender.h5
-rw-r--r--AudioManagerCore/include/IAmDatabaseHandler.h34
7 files changed, 582 insertions, 492 deletions
diff --git a/AudioManagerCore/include/CAmCommandSender.h b/AudioManagerCore/include/CAmCommandSender.h
index 82363de..caa72ad 100644
--- a/AudioManagerCore/include/CAmCommandSender.h
+++ b/AudioManagerCore/include/CAmCommandSender.h
@@ -29,21 +29,24 @@
#endif
#include "IAmCommand.h"
+#include "CAmDatabaseHandlerMap.h"
+#include "CAmSerializer.h"
namespace am
{
class CAmCommandReceiver;
+class CAmCommandSender;
/**
* This class is used to send data to the CommandInterface.
* All loaded plugins will be called when a callback is invoked.
*/
-class CAmCommandSender
+class CAmCommandSender: public CAmDatabaseHandlerMap::AmDatabaseObserverCallbacks
{
public:
- CAmCommandSender(const std::vector<std::string>& listOfPluginDirectories);
+ CAmCommandSender(const std::vector<std::string>& listOfPluginDirectories, CAmSocketHandler *iSocketHandler);
~CAmCommandSender();
am_Error_e startupInterfaces(CAmCommandReceiver* iCommandReceiver);
void setCommandReady();
@@ -78,14 +81,18 @@ public:
friend class IAmCommandBackdoor; //this is to get access to the loaded plugins and be able to exchange the interfaces
#endif
private:
+
void unloadLibraries(void); //!< unload the shared libraries
std::vector<IAmCommandSend*> mListInterfaces; //!< list of all interfaces
std::vector<void*> mListLibraryHandles; //!< list of all library handles. This information is used to unload the plugins correctly.
std::vector<std::string> mListLibraryNames; //!< list of all library names. This information is used for getListPlugins.
-
+
CAmCommandReceiver *mCommandReceiver;
+ CAmSerializer mSerializer;
};
+
+
}
#endif /* COMMANDSENDER_H_ */
diff --git a/AudioManagerCore/include/CAmDatabaseHandlerMap.h b/AudioManagerCore/include/CAmDatabaseHandlerMap.h
index 05443b1..3909b05 100644
--- a/AudioManagerCore/include/CAmDatabaseHandlerMap.h
+++ b/AudioManagerCore/include/CAmDatabaseHandlerMap.h
@@ -74,6 +74,51 @@ class CAmDatabaseHandlerMap : public IAmDatabaseHandler
public:
CAmDatabaseHandlerMap();
virtual ~CAmDatabaseHandlerMap();
+
+ /**
+ * Database observer.
+ */
+ struct AmDatabaseObserverCallbacks: public IAmDatabaseObserver
+ {
+ protected:
+ std::function<void()> dboNumberOfSinkClassesChanged;
+ std::function<void()> dboNumberOfSourceClassesChanged;
+ std::function<void(const am_Sink_s&)> dboNewSink;
+ std::function<void(const am_Source_s&)> dboNewSource;
+ std::function<void(const am_Domain_s& )> dboNewDomain;
+ std::function<void (const am_Gateway_s& )> dboNewGateway;
+ std::function<void (const am_Converter_s& )> dboNewConverter;
+ std::function<void (const am_Crossfader_s& )> dboNewCrossfader;
+ std::function<void (const am_MainConnectionType_s& )> dboNewMainConnection;
+ std::function<void (const am_mainConnectionID_t )> dboRemovedMainConnection;
+ std::function<void (const am_sinkID_t , const bool )> dboRemovedSink;
+ std::function<void (const am_sourceID_t , const bool )> dboRemovedSource;
+ std::function<void (const am_domainID_t )> dboRemoveDomain;
+ std::function<void (const am_gatewayID_t )> dboRemoveGateway;
+ std::function<void (const am_converterID_t )> dboRemoveConverter;
+ std::function<void (const am_crossfaderID_t )> dboRemoveCrossfader;
+ std::function<void (const am_mainConnectionID_t , const am_ConnectionState_e )> dboMainConnectionStateChanged;
+ std::function<void (const am_sinkID_t , const am_MainSoundProperty_s& )> dboMainSinkSoundPropertyChanged;
+ std::function<void (const am_sourceID_t , const am_MainSoundProperty_s& )> dboMainSourceSoundPropertyChanged;
+ std::function<void (const am_sinkID_t , const am_Availability_s& )> dboSinkAvailabilityChanged;
+ std::function<void (const am_sourceID_t , const am_Availability_s& )> dboSourceAvailabilityChanged;
+ std::function<void (const am_sinkID_t , const am_mainVolume_t )> dboVolumeChanged;
+ std::function<void (const am_sinkID_t , const am_MuteState_e )> dboSinkMuteStateChanged;
+ std::function<void (const am_SystemProperty_s& )>dboSystemPropertyChanged;
+ std::function<void (const am_mainConnectionID_t , const am_timeSync_t )>dboTimingInformationChanged;
+ std::function<void (const am_sinkID_t , const am_sinkClass_t , const std::vector<am_MainSoundProperty_s>& , const bool )>dboSinkUpdated;
+ std::function<void (const am_sourceID_t , const am_sourceClass_t , const std::vector<am_MainSoundProperty_s>& , const bool )>dboSourceUpdated;
+ std::function<void (const am_sinkID_t , const am_NotificationConfiguration_s )> dboSinkMainNotificationConfigurationChanged;
+ std::function<void (const am_sourceID_t , const am_NotificationConfiguration_s )> dboSourceMainNotificationConfigurationChanged;
+ public:
+ friend class CAmDatabaseHandlerMap;
+ AmDatabaseObserverCallbacks():IAmDatabaseObserver(), mpDatabaseHandler(nullptr) {}
+ virtual ~AmDatabaseObserverCallbacks(){ if(mpDatabaseHandler) mpDatabaseHandler->unregisterObserver(this);}
+ protected:
+ CAmDatabaseHandlerMap *mpDatabaseHandler;
+
+ };
+
am_Error_e enterDomainDB(const am_Domain_s& domainData, am_domainID_t& domainID);
am_Error_e enterMainConnectionDB(const am_MainConnection_s& mainConnectionData, am_mainConnectionID_t& connectionID);
am_Error_e enterSinkDB(const am_Sink_s& sinkData, am_sinkID_t& sinkID);
@@ -196,7 +241,6 @@ public:
bool existConverter(const am_converterID_t converterID) const;
bool existSinkClass(const am_sinkClass_t sinkClassID) const;
bool existSourceClass(const am_sourceClass_t sourceClassID) const;
- void registerObserver(CAmDatabaseObserver *iObserver);
bool sourceVisible(const am_sourceID_t sourceID) const;
bool sinkVisible(const am_sinkID_t sinkID) const;
bool isComponentConnected(const am_Gateway_s & gateway) const;
@@ -206,6 +250,11 @@ public:
am_Error_e enumerateSinks(std::function<void(const am_Sink_s & element)> cb) const;
am_Error_e enumerateGateways(std::function<void(const am_Gateway_s & element)> cb) const;
am_Error_e enumerateConverters(std::function<void(const am_Converter_s & element)> cb) const;
+
+ bool registerObserver(IAmDatabaseObserver * iObserver);
+ bool unregisterObserver(IAmDatabaseObserver * iObserver);
+ unsigned countObservers();
+
/**
* The following structures extend the base structures with the field 'reserved'.
*/
@@ -276,55 +325,55 @@ public:
AM_SUBCLASS_COPY_OP_END()\
AM_SUBCLASS_OP(Subclass, Class)\
-
+private:
AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Domain_Database_s,am_Domain_s)
- AM_SUBCLASS_END(CAmDomain)
+ AM_SUBCLASS_END(AmDomain)
AM_TYPEDEF_SUBCLASS_SOUND_PROPERTIES_BEGIN(am_Sink_Database_s,am_Sink_s)
void getSinkType(am_SinkType_s & sinkType) const;\
- AM_SUBCLASS_END(CAmSink)
+ AM_SUBCLASS_END(AmSink)
AM_TYPEDEF_SUBCLASS_SOUND_PROPERTIES_BEGIN(am_Source_Database_s,am_Source_s)
void getSourceType(am_SourceType_s & sourceType) const;\
- AM_SUBCLASS_END(CAmSource)
+ AM_SUBCLASS_END(AmSource)
AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Connection_Database_s,am_Connection_s)
- AM_SUBCLASS_END(CAmConnection)
+ AM_SUBCLASS_END(AmConnection)
/**
* The following structures extend the base structures with print capabilities.
*/
AM_TYPEDEF_SUBCLASS_BEGIN(am_MainConnection_Database_s, am_MainConnection_s)
void getMainConnectionType(am_MainConnectionType_s & connectionType) const;\
- AM_SUBCLASS_END(CAmMainConnection)
+ AM_SUBCLASS_END(AmMainConnection)
AM_TYPEDEF_SUBCLASS_BEGIN(am_SourceClass_Database_s, am_SourceClass_s)
- AM_SUBCLASS_END(CAmSourceClass)
+ AM_SUBCLASS_END(AmSourceClass)
AM_TYPEDEF_SUBCLASS_BEGIN(am_SinkClass_Database_s, am_SinkClass_s)
- AM_SUBCLASS_END(CAmSinkClass)
+ AM_SUBCLASS_END(AmSinkClass)
AM_TYPEDEF_SUBCLASS_BEGIN(am_Gateway_Database_s, am_Gateway_s)
- AM_SUBCLASS_END(CAmGateway)
+ AM_SUBCLASS_END(AmGateway)
AM_TYPEDEF_SUBCLASS_BEGIN(am_Converter_Database_s, am_Converter_s)
- AM_SUBCLASS_END(CAmConverter)
+ AM_SUBCLASS_END(AmConverter)
AM_TYPEDEF_SUBCLASS_BEGIN(am_Crossfader_Database_s, am_Crossfader_s)
- AM_SUBCLASS_END(CAmCrossfader)
-
- private:
- typedef std::unordered_map<am_domainID_t, CAmDomain> CAmMapDomain;
- typedef std::unordered_map<am_sourceClass_t, CAmSourceClass> CAmMapSourceClass;
- typedef std::unordered_map<am_sinkClass_t, CAmSinkClass> CAmMapSinkClass;
- typedef std::unordered_map<am_sinkID_t, CAmSink> CAmMapSink;
- typedef std::unordered_map<am_sourceID_t, CAmSource> CAmMapSource;
- typedef std::unordered_map<am_gatewayID_t, CAmGateway> CAmMapGateway;
- typedef std::unordered_map<am_converterID_t, CAmConverter> CAmMapConverter;
- typedef std::unordered_map<am_crossfaderID_t, CAmCrossfader> CAmMapCrossfader;
- typedef std::unordered_map<am_connectionID_t, CAmConnection> CAmMapConnection;
- typedef std::unordered_map<am_mainConnectionID_t, CAmMainConnection> CAmMapMainConnection;
- typedef std::vector<am_SystemProperty_s> CAmVectorSystemProperties;
+ AM_SUBCLASS_END(AmCrossfader)
+
+
+ typedef std::unordered_map<am_domainID_t, AmDomain> AmMapDomain;
+ typedef std::unordered_map<am_sourceClass_t, AmSourceClass> AmMapSourceClass;
+ typedef std::unordered_map<am_sinkClass_t, AmSinkClass> AmMapSinkClass;
+ typedef std::unordered_map<am_sinkID_t, AmSink> AmMapSink;
+ typedef std::unordered_map<am_sourceID_t, AmSource> AmMapSource;
+ typedef std::unordered_map<am_gatewayID_t, AmGateway> AmMapGateway;
+ typedef std::unordered_map<am_converterID_t, AmConverter> AmMapConverter;
+ typedef std::unordered_map<am_crossfaderID_t, AmCrossfader> AmMapCrossfader;
+ typedef std::unordered_map<am_connectionID_t, AmConnection> AmMapConnection;
+ typedef std::unordered_map<am_mainConnectionID_t, AmMainConnection> AmMapMainConnection;
+ typedef std::vector<am_SystemProperty_s> AmVectorSystemProperties;
/**
* The following structure groups the map objects needed for the implementation.
* Every map object is coupled with an identifier, which hold the current value.
@@ -332,46 +381,46 @@ public:
* The IDs can be increased through the method increaseID(...), which follows the AudioManager logic.
* For more information about the static and dynamic IDs, please see the documentation.
*/
- typedef struct CAmMappedData
+ struct AmMappedData
{
/**
* The structure encapsulates the id boundary and the current id value.
* It defines a range within the id can vary.
*/
- struct am_Identifier_s
+ struct AmIdentifier
{
int16_t mMin; //!< min possible value
int16_t mMax; //!< max possible value
int16_t mCurrentValue; //!< current value
- am_Identifier_s():mMin(DYNAMIC_ID_BOUNDARY), mMax(SHRT_MAX), mCurrentValue(mMin){};
- am_Identifier_s(const int16_t & min, const int16_t & max):mMin(min), mMax(max), mCurrentValue(mMin){assert(min<max);};
+ AmIdentifier():mMin(DYNAMIC_ID_BOUNDARY), mMax(SHRT_MAX), mCurrentValue(mMin){};
+ AmIdentifier(const int16_t & min, const int16_t & max):mMin(min), mMax(max), mCurrentValue(mMin){assert(min<max);};
};
- am_Identifier_s mCurrentDomainID; //!< domain ID
- am_Identifier_s mCurrentSourceClassesID; //!< source classes ID
- am_Identifier_s mCurrentSinkClassesID; //!< sink classes ID
- am_Identifier_s mCurrentSinkID; //!< sink ID
- am_Identifier_s mCurrentSourceID; //!< source ID
- am_Identifier_s mCurrentGatewayID; //!< gateway ID
- am_Identifier_s mCurrentConverterID; //!< converter ID
- am_Identifier_s mCurrentCrossfaderID; //!< crossfader ID
- am_Identifier_s mCurrentConnectionID; //!< connection ID
- am_Identifier_s mCurrentMainConnectionID; //!< mainconnection ID
-
- CAmVectorSystemProperties mSystemProperties; //!< vector with system properties
- CAmMapDomain mDomainMap; //!< map for domain structures
- CAmMapSourceClass mSourceClassesMap; //!< map for source classes structures
- CAmMapSinkClass mSinkClassesMap; //!< map for sink classes structures
- CAmMapSink mSinkMap; //!< map for sink structures
- CAmMapSource mSourceMap; //!< map for source structures
- CAmMapGateway mGatewayMap; //!< map for gateway structures
- CAmMapConverter mConverterMap; //!< map for converter structures
- CAmMapCrossfader mCrossfaderMap; //!< map for crossfader structures
- CAmMapConnection mConnectionMap; //!< map for connection structures
- CAmMapMainConnection mMainConnectionMap; //!< map for main connection structures
-
- CAmMappedData(): //For Domain, MainConnections, Connections we don't have static IDs.
+ AmIdentifier mCurrentDomainID; //!< domain ID
+ AmIdentifier mCurrentSourceClassesID; //!< source classes ID
+ AmIdentifier mCurrentSinkClassesID; //!< sink classes ID
+ AmIdentifier mCurrentSinkID; //!< sink ID
+ AmIdentifier mCurrentSourceID; //!< source ID
+ AmIdentifier mCurrentGatewayID; //!< gateway ID
+ AmIdentifier mCurrentConverterID; //!< converter ID
+ AmIdentifier mCurrentCrossfaderID; //!< crossfader ID
+ AmIdentifier mCurrentConnectionID; //!< connection ID
+ AmIdentifier mCurrentMainConnectionID; //!< mainconnection ID
+
+ AmVectorSystemProperties mSystemProperties; //!< vector with system properties
+ AmMapDomain mDomainMap; //!< map for domain structures
+ AmMapSourceClass mSourceClassesMap; //!< map for source classes structures
+ AmMapSinkClass mSinkClassesMap; //!< map for sink classes structures
+ AmMapSink mSinkMap; //!< map for sink structures
+ AmMapSource mSourceMap; //!< map for source structures
+ AmMapGateway mGatewayMap; //!< map for gateway structures
+ AmMapConverter mConverterMap; //!< map for converter structures
+ AmMapCrossfader mCrossfaderMap; //!< map for crossfader structures
+ AmMapConnection mConnectionMap; //!< map for connection structures
+ AmMapMainConnection mMainConnectionMap; //!< map for main connection structures
+
+ AmMappedData(): //For Domain, MainConnections, Connections we don't have static IDs.
mCurrentDomainID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
mCurrentSourceClassesID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
mCurrentSinkClassesID(DYNAMIC_ID_BOUNDARY, SHRT_MAX),
@@ -399,7 +448,7 @@ public:
* @param preferedStaticIDBoundary A limit for a given dynamic ID. Default is DYNAMIC_ID_BOUNDARY.
* @return TRUE on successfully changed ID.
*/
- bool increaseID(int16_t & resultID, am_Identifier_s & sourceID, int16_t const desiredStaticID);
+ bool increaseID(int16_t & resultID, AmIdentifier & sourceID, int16_t const desiredStaticID);
/**
* \brief Increases the main connection ID.
*
@@ -426,12 +475,13 @@ public:
{
typename std::unordered_map<TPrintMapKey, TPrintMapObject>::const_iterator iter = t.begin();
for(; iter!=t.end(); iter++)
- CAmMappedData::print(iter->second, output);
+ AmMappedData::print(iter->second, output);
}
private:
- template <typename TMapKey,class TMapObject> bool getNextConnectionID(int16_t & resultID, am_Identifier_s & sourceID,
+ template <typename TMapKey,class TMapObject> bool getNextConnectionID(int16_t & resultID, AmIdentifier & sourceID,
const std::unordered_map<TMapKey, TMapObject> & map);
- } CAmMappedData;
+ };
+
/*
* Helper methods.
*/
@@ -469,9 +519,9 @@ public:
} );
}
- CAmDatabaseObserver *mpDatabaseObserver; //!< pointer to the Observer
ListConnectionFormat mListConnectionFormat; //!< list of connection formats
- CAmMappedData mMappedData; //!< Internal structure encapsulating all the maps used in this class
+ AmMappedData mMappedData; //!< Internal structure encapsulating all the maps used in this class
+ std::vector<AmDatabaseObserverCallbacks*> mDatabaseObservers;
#ifdef UNIT_TEST
public:
diff --git a/AudioManagerCore/include/CAmDatabaseObserver.h b/AudioManagerCore/include/CAmDatabaseObserver.h
deleted file mode 100644
index 7d18be4..0000000
--- a/AudioManagerCore/include/CAmDatabaseObserver.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * SPDX license identifier: MPL-2.0
- *
- * Copyright (C) 2012, BMW AG
- *
- * This file is part of GENIVI Project AudioManager.
- *
- * Contributions are licensed to the GENIVI Alliance under one or more
- * Contribution License Agreements.
- *
- * \copyright
- * This Source Code Form is subject to the terms of the
- * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
- * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- *
- * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
- *
- * \file CAmDatabaseObserver.h
- * For further information see http://www.genivi.org/.
- *
- */
-
-#ifndef DATABASEOBSERVER_H_
-#define DATABASEOBSERVER_H_
-
-#include "audiomanagertypes.h"
-#include <queue>
-#include "CAmSerializer.h"
-
-namespace am
-{
-
-class CAmTelnetServer;
-class CAmCommandSender;
-class CAmRoutingSender;
-class CAmSocketHandler;
-
-/**
- * This class observes the Database and notifies other classes about important events, mainly the CommandSender.
- */
-class CAmDatabaseObserver
-{
-public:
- CAmDatabaseObserver(CAmCommandSender *iCommandSender, CAmRoutingSender *iRoutingSender, CAmSocketHandler *iSocketHandler);
- CAmDatabaseObserver(CAmCommandSender *iCommandSender, CAmRoutingSender *iRoutingSender, CAmSocketHandler *iSocketHandler, CAmTelnetServer *iTelnetServer);
- ~CAmDatabaseObserver();
- void numberOfSinkClassesChanged();
- void numberOfSourceClassesChanged();
- void newSink(const am_Sink_s& sink);
- void newSource(const am_Source_s& source);
- void newDomain(const am_Domain_s& domain);
- void newGateway(const am_Gateway_s& gateway);
- void newConverter(const am_Converter_s& coverter);
- void newCrossfader(const am_Crossfader_s& crossfader);
- void newMainConnection(const am_MainConnectionType_s& mainConnection);
- void removedMainConnection(const am_mainConnectionID_t mainConnection);
- void removedSink(const am_sinkID_t sinkID, const bool visible);
- void removedSource(const am_sourceID_t sourceID, const bool visible);
- void removeDomain(const am_domainID_t domainID);
- void removeGateway(const am_gatewayID_t gatewayID);
- void removeConverter(const am_converterID_t converterID);
- void removeCrossfader(const am_crossfaderID_t crossfaderID);
- void mainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState);
- void mainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty);
- void mainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty);
- void sinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s& availability);
- void sourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s& availability);
- void volumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume);
- void sinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState);
- void systemPropertyChanged(const am_SystemProperty_s& SystemProperty);
- void timingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time);
- void sinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible);
- void sourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties, const bool visible);
- void sinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s mainNotificationConfiguration);
- void sourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s mainNotificationConfiguration);
-
-private:
- CAmCommandSender *mCommandSender; //!< pointer to the comandSender
- CAmRoutingSender* mRoutingSender; //!< pointer to the routingSender
- CAmTelnetServer* mTelnetServer; //!< pointer to the telnetserver
- CAmSerializer mSerializer; //!< serializer to handle the CommandInterface via the mainloop
-};
-
-}
-
-#endif /* DATABASEOBSERVER_H_ */
diff --git a/AudioManagerCore/include/CAmGraph.h b/AudioManagerCore/include/CAmGraph.h
index ff4a09c..45043f7 100644
--- a/AudioManagerCore/include/CAmGraph.h
+++ b/AudioManagerCore/include/CAmGraph.h
@@ -89,6 +89,7 @@ namespace am
* Setters and getters.
*/
NodeData & getData() { return mData; }
+ const NodeData & getData() const { return mData; }
uint16_t getIndex() const { return mIndex; }
void setIndex(uint16_t index) { mIndex = index; }
};
@@ -120,13 +121,13 @@ namespace am
typedef typename std::vector<CAmNode<T>*> CAmListNodePtrs;
typedef typename std::list<CAmVertex<T,V>> CAmListVertices;
typedef typename std::list<CAmVertex<T,V>>::iterator CAmListVerticesItr;
- typedef typename std::list<CAmVertex<T,V>>::const_iterator CAmListVerticesItrConst;
- typedef typename std::list<CAmListVertices> CAmNodesAdjList;
- typedef typename std::list<CAmListVertices>::iterator CAmNodesAdjListItr;
- typedef typename std::list<CAmListVertices>::const_iterator CAmNodesAdjListItrConst;
- typedef typename std::list<CAmNode<T>> CAmListNodes;
- typedef typename std::list<CAmNode<T>>::iterator CAmListNodesItr;
- typedef typename std::list<CAmNode<T>>::const_iterator CAmListNodesItrConst;
+ typedef typename std::list<CAmVertex<T,V>>::const_iterator CAmListVerticesItrConst;
+ typedef typename std::list<CAmListVertices> CAmNodesAdjList;
+ typedef typename std::list<CAmListVertices>::iterator CAmNodesAdjListItr;
+ typedef typename std::list<CAmListVertices>::const_iterator CAmNodesAdjListItrConst;
+ typedef typename std::list<CAmNode<T>> CAmListNodes;
+ typedef typename std::list<CAmNode<T>>::iterator CAmListNodesItr;
+ typedef typename std::list<CAmNode<T>>::const_iterator CAmListNodesItrConst;
typedef typename std::vector<CAmNode<T>*> CAmNodeReferenceList;
typedef typename std::vector<CAmListVertices*> CAmVertexReferenceList;
@@ -136,6 +137,24 @@ namespace am
CAmVertexReferenceList mPointersAdjList; //!< CAmVertexReferenceList vector with pointers to vertices for direct access
bool mIsCyclic; //!< bool the graph has cycles or not
+ struct IterateThroughAllNodesDelegate
+ {
+ CAmNode<T> * source;
+ CAmNode<T> * destination;
+ CAmNodeReferenceList visited;
+ std::function<bool(const CAmNode<T> * )> shouldVisitNode;
+ std::function<void(const CAmNode<T> *)> willVisitNode;
+ std::function<void(const CAmNode<T> *)> didVisitNode;
+ std::function<void(const CAmNodeReferenceList & path)> didFindPath;
+ };
+
+ struct VisitNodeDelegate
+ {
+ CAmNode<T> * source;
+ CAmNode<T> * destination;
+ std::function<void(const am_GraphPathPosition_e, CAmNode<T> &)> visitedNode;
+ };
+
/**
* Updates the node indexes after adding or removing nodes.
*
@@ -162,7 +181,7 @@ namespace am
typedef uint16_t vertex_t;
typedef uint16_t weight_t;
- void findShortestsPathsFromNode(const CAmNode<T> & node, std::vector<weight_t> &minDistance, std::vector<CAmNode<T> *> &previous)
+ void findShortestPathsFromNode(const CAmNode<T> & node, std::vector<weight_t> &minDistance, std::vector<CAmNode<T> *> &previous)
{
typename CAmListVertices::const_iterator nIter;
CAmListVertices * neighbors;
@@ -256,32 +275,40 @@ namespace am
}
/**
- * Generates list with all possible paths to given destination node after findShortestsPathsFromNode has been called.
- * Finding paths is observed through the callback. The caller is informed after a new path has been found.
+ * Iterate through the nodes and generate all paths to given node.
*
* @param dst end node.
* @param visited vector with current path.
- * @param cb callback which is mostly used for constructing.
+ * @param delegate enumeration delegate.
*/
- void goThroughAllPaths(const CAmNode<T> & dst, std::vector<CAmNode<T>*> & visited, std::function<void(const CAmNodeReferenceList & path)> cb)
+ void findAllPaths(IterateThroughAllNodesDelegate & delegate)
{
- CAmListVertices * nodes = mPointersAdjList[visited.back()->getIndex()];
+ CAmListVertices * nodes = mPointersAdjList[delegate.visited.back()->getIndex()];
CAmListVerticesItrConst vItr(nodes->begin());
+
+ CAmVertex<T,V> * pNextVertex;
+ CAmNode<T> * pNextNode;
for (; vItr != nodes->end(); ++vItr)
{
- const CAmVertex<T,V> & vertex = (*vItr);
- if(vertex.getNode()->getStatus()!=GES_NOT_VISITED)
+ pNextVertex = (CAmVertex<T,V> *)&(*vItr);
+ pNextNode = pNextVertex->getNode();
+ if(
+ pNextNode->getStatus()!=GES_NOT_VISITED ||
+ !delegate.shouldVisitNode(pNextNode)
+ )
continue;
- if (vertex.getNode()==&dst)
+ if (pNextNode==delegate.destination)
{
- vertex.getNode()->setStatus(GES_IN_PROGRESS);
- visited.push_back(vertex.getNode());
+ delegate.willVisitNode(pNextNode);
+ pNextNode->setStatus(GES_IN_PROGRESS);
+ delegate.visited.push_back(pNextNode);
//notify observer
- cb(visited);
+ delegate.didFindPath(delegate.visited);
//remove last node from the list
- auto last = visited.end()-1;
- visited.erase(last);
- vertex.getNode()->setStatus(GES_NOT_VISITED);
+ auto last = delegate.visited.end()-1;
+ delegate.visited.erase(last);
+ pNextNode->setStatus(GES_NOT_VISITED);
+ delegate.didVisitNode(pNextNode);
break;
}
}
@@ -289,20 +316,28 @@ namespace am
//bfs like loop
for (; vItr != nodes->end(); ++vItr)
{
- const CAmVertex<T,V> & vertex = (*vItr);
- if(vertex.getNode()->getStatus()!=GES_NOT_VISITED||vertex.getNode()==&dst)
+ pNextVertex = (CAmVertex<T,V> *)&(*vItr);
+ pNextNode = pNextVertex->getNode();
+
+ if(pNextNode->getStatus()!=GES_NOT_VISITED ||
+ pNextNode==delegate.destination ||
+ !delegate.shouldVisitNode(pNextNode)
+ )
continue;
- vertex.getNode()->setStatus(GES_IN_PROGRESS);
- visited.push_back(vertex.getNode());
- goThroughAllPaths(dst, visited, cb);
+ delegate.willVisitNode(pNextNode);
+ pNextNode->setStatus(GES_IN_PROGRESS);
+ delegate.visited.push_back(pNextNode);
+ findAllPaths(delegate);
//remove last node from the list
- auto last = visited.end()-1;
- visited.erase(last);
- vertex.getNode()->setStatus(GES_NOT_VISITED);
+ auto last = delegate.visited.end()-1;
+ delegate.visited.erase(last);
+ pNextNode->setStatus(GES_NOT_VISITED);
+ delegate.didVisitNode(pNextNode);
}
}
public:
+
explicit CAmGraph(const std::vector<T> &v):mStoreNodes(), mStoreAdjList(), mPointersNodes(), mPointersAdjList()
{
typedef typename std::vector<T>::const_iterator inItr;
@@ -374,12 +409,12 @@ namespace am
*/
CAmNode<T> & addNode(const T & in)
{
- size_t index = mStoreNodes.size();
- mStoreNodes.emplace_back(in, index);
- mStoreAdjList.emplace_back();
- mPointersNodes.push_back(&mStoreNodes.back());
- mPointersAdjList.push_back(&mStoreAdjList.back());
- return mStoreNodes.back();
+ size_t index = mStoreNodes.size();
+ mStoreNodes.emplace_back(in, index);
+ mStoreAdjList.emplace_back();
+ mPointersNodes.push_back(&mStoreNodes.back());
+ mPointersAdjList.push_back(&mStoreAdjList.back());
+ return mStoreNodes.back();
}
/**
@@ -428,16 +463,16 @@ namespace am
*/
void removeNode(const CAmNode<T> & node)
{
- uint16_t index = node.getIndex();
- removeAllVerticesToNode(node);
- mPointersAdjList.erase(mPointersAdjList.begin()+index);
- mPointersNodes.erase(mPointersNodes.begin()+index);
- auto iter = std::find_if(mStoreNodes.begin(), mStoreNodes.end(), [&node](const CAmNode<T> & otherNode){
- return &otherNode==&node;
- });
- if(iter!=mStoreNodes.end())
- mStoreNodes.erase(iter);
- updateIndexes(index);
+ uint16_t index = node.getIndex();
+ removeAllVerticesToNode(node);
+ mPointersAdjList.erase(mPointersAdjList.begin()+index);
+ mPointersNodes.erase(mPointersNodes.begin()+index);
+ auto iter = std::find_if(mStoreNodes.begin(), mStoreNodes.end(), [&node](const CAmNode<T> & otherNode){
+ return &otherNode==&node;
+ });
+ if(iter!=mStoreNodes.end())
+ mStoreNodes.erase(iter);
+ updateIndexes(index);
}
/**
@@ -524,7 +559,7 @@ namespace am
std::vector<weight_t> min_distance;
std::vector<CAmNode<T>*> previous;
- findShortestsPathsFromNode(source, min_distance, previous);
+ findShortestPathsFromNode(source, min_distance, previous);
for(auto it=listTargets.begin(); it!=listTargets.end(); it++)
{
@@ -554,7 +589,7 @@ namespace am
return;
std::vector<weight_t> min_distance;
std::vector<CAmNode<T>*> previous;
- findShortestsPathsFromNode(source, min_distance, previous);
+ findShortestPathsFromNode(source, min_distance, previous);
constructShortestPathTo(destination, previous, resultPath);
}
@@ -576,7 +611,7 @@ namespace am
std::vector<weight_t> min_distance;
std::vector<CAmNode<T>*> previous;
- findShortestsPathsFromNode(source, min_distance, previous);
+ findShortestPathsFromNode(source, min_distance, previous);
for(auto it=listTargets.begin(); it!=listTargets.end(); it++)
{
@@ -603,7 +638,7 @@ namespace am
std::vector<weight_t> min_distance;
std::vector<CAmNode<T>*> previous;
- findShortestsPathsFromNode(source, min_distance, previous);
+ findShortestPathsFromNode(source, min_distance, previous);
constructShortestPathTo(destination, previous, cb);
}
@@ -613,15 +648,29 @@ namespace am
*
* @param src start node.
* @param dst destination node.
- * @param cb callabck.
+ * @param cbShouldVisitNode ask the delegate if we should proceed with the current node.
+ * @param cbWillVisitNode tell the delegate the current node will be visited.
+ * @param cbDidVisitNode tell the delegate the current node was visited.
+ * @param cbDidFindPath return the path to the delegate.
*/
- void getAllPaths(const CAmNode<T> & src, const CAmNode<T> & dst, std::function<void(const CAmNodeReferenceList & path)> cb)
+ void getAllPaths(CAmNode<T> & src,
+ CAmNode<T> & dst,
+ std::function<bool(const CAmNode<T> * )> cbShouldVisitNode,
+ std::function<void(const CAmNode<T> *)> cbWillVisitNode,
+ std::function<void(const CAmNode<T> *)> cbDidVisitNode,
+ std::function<void(const CAmNodeReferenceList & path)> cbDidFindPath)
{
- CAmNodeReferenceList visited;
- visited.push_back((CAmNode<T>*)&src);
+ IterateThroughAllNodesDelegate delegate;
+ delegate.source = &src;
+ delegate.destination = &dst;
+ delegate.shouldVisitNode = cbShouldVisitNode;
+ delegate.willVisitNode = cbWillVisitNode;
+ delegate.didVisitNode = cbDidVisitNode;
+ delegate.didFindPath = cbDidFindPath;
+ delegate.visited.push_back((CAmNode<T>*)&src);
((CAmNode<T>*)&src)->setStatus(GES_VISITED);
- goThroughAllPaths(dst, visited, cb);
- reset();
+ findAllPaths(delegate);
+ ((CAmNode<T>*)&src)->setStatus(GES_NOT_VISITED);
}
};
diff --git a/AudioManagerCore/include/CAmRouter.h b/AudioManagerCore/include/CAmRouter.h
index 7e52b7c..88f73ea 100644
--- a/AudioManagerCore/include/CAmRouter.h
+++ b/AudioManagerCore/include/CAmRouter.h
@@ -27,293 +27,353 @@
#include <assert.h>
#include <vector>
+#include <iomanip>
#include <functional>
#include "audiomanagertypes.h"
#include "CAmGraph.h"
-#include "IAmDatabaseHandler.h"
-
+#include "CAmDatabaseHandlerMap.h"
namespace am
{
-#define ROUTING_BUILD_CONNECTIONS 1
-
-/**
- * Optimal path search between a source and a sink is implemented with a graph which contains nodes - sinks, sources, gateways, converters.
- * The nodes are identified by sinkID, sourceID, gatewayID, converterID.
- * A possible connection between two nodes represents the facts that the nodes can be connected with one or more connectionFormats (Node[id=1] ---> Node[id=2]).
- * It is assumption that the two nodes can be connected. The controller itself decides later whether the connection is possible or not.
- *
- */
-
-/**
- * Trace on/off.
- */
-#if !defined(ROUTING_BUILD_CONNECTIONS)
- #undef TRACE_GRAPH
-#endif
-/**
- * Default behavior is to do the search in one step without connections, which are identified during the search.
- * Alternatively the search can be done in two steps.
- */
-#if !defined(ROUTING_BUILD_CONNECTIONS)
- #undef ROUTING_BUILD_CONNECTIONS
-#endif
-
-#if defined(TRACE_GRAPH)
-#if !defined(ROUTING_BUILD_CONNECTIONS)
-#warning "You should define ROUTING_BUILD_CONNECTIONS in order to be able to see the connections in the trace."
+ /**
+ * Optimal path search is implemented with graph which contains nodes - sinks, sources, gateways, converters.
+ * The nodes are identified by sinkID, sourceID, gatewayID, converterID.
+ * A possible connection between two nodes represents the facts that the nodes can be connected with one or more connectionFormats (Node[id=1] ---> Node[id=2]).
+ * It is assumption that the two nodes can be connected. The controller itself decides later whether the connection is possible or not.
+ *
+ */
+
+ /**
+ * Trace on/off.
+ */
+#undef TRACE_GRAPH
+
+ /**
+ * Max paths count returned to the controller
+ */
+#ifndef MAX_ROUTING_PATHS
+#define MAX_ROUTING_PATHS 5
#endif
+ /**
+ * How many times the routing algorithm should look back into domains.
+ *
+ * 0 - no cycles are allowed
+ * 1 - default is one cycle
+ * ...
+ * UINT_MAX - set this define to UINT_MAX in order to allow cycles.
+ *
+ */
+#ifndef MAX_ALLOWED_DOMAIN_CYCLES
+#define MAX_ALLOWED_DOMAIN_CYCLES 1
#endif
-class CAmRouter;
-
-/**
- * A structure used as user data in the graph nodes.
- */
-struct am_RoutingNodeData_s
-{
- typedef enum:uint8_t {SINK, SOURCE, GATEWAY, CONVERTER} am_NodeDataType_e;
- am_NodeDataType_e type; //!< data type:sink, source, gateway or converter
- union
- {
- am_Source_s *source;
- am_Sink_s *sink;
- am_Gateway_s *gateway;
- am_Converter_s *converter;
- } data; //!< union pointer to sink, source, gateway or converter
-
- am_RoutingNodeData_s():type(SINK)
- {}
-
- bool operator==(const am_RoutingNodeData_s & anotherObject) const
- {
- bool result = false;
- if(type==anotherObject.type)
- {
- result = true;
- if(type==SINK)
- result &= (data.sink->sinkID==anotherObject.data.sink->sinkID);
- else if(type==SOURCE)
- result &= (data.source->sourceID==anotherObject.data.source->sourceID);
- else if(type==GATEWAY)
- result &= (data.gateway->gatewayID==anotherObject.data.gateway->gatewayID);
- else if(type==CONVERTER)
- result &= (data.converter->converterID==anotherObject.data.converter->converterID);
- }
- return result;
- };
+ class CAmRouter;
+
+ /**
+ * A structure used as user data in the graph nodes.
+ */
+ struct am_RoutingNodeData_s
+ {
+ typedef enum
+ :int
+ { SINK, SOURCE, GATEWAY, CONVERTER
+ } am_NodeDataType_e;
+ am_NodeDataType_e type; //!< data type:sink, source, gateway or converter
+ union
+ {
+ am_Source_s *source;
+ am_Sink_s *sink;
+ am_Gateway_s *gateway;
+ am_Converter_s *converter;
+ } data; //!< union pointer to sink, source, gateway or converter
+
+ am_RoutingNodeData_s() :
+ type(SINK)
+ {
+ }
+
+ bool operator==(const am_RoutingNodeData_s & anotherObject) const
+ {
+ bool result = false;
+ if (type == anotherObject.type)
+ {
+ result = true;
+ if (type == SINK)
+ result &= (data.sink->sinkID == anotherObject.data.sink->sinkID);
+ else if (type == SOURCE)
+ result &= (data.source->sourceID == anotherObject.data.source->sourceID);
+ else if (type == GATEWAY)
+ result &= (data.gateway->gatewayID == anotherObject.data.gateway->gatewayID);
+ else if (type == CONVERTER)
+ result &= (data.converter->converterID == anotherObject.data.converter->converterID);
+ }
+ return result;
+ }
+ ;
#ifdef TRACE_GRAPH
- void trace() const
- {
- if(type==SINK)
- std::cout << "[SINK:" << data.sink->sinkID << ":" << data.sink->name << "(" << data.sink->domainID << ")"
- << "]";
- else if(type==SOURCE)
- std::cout << "[SOUR:" << data.source->sourceID << ":" << data.source->name << "(" << data.source->domainID << ")"
- << "]";
- else if(type==GATEWAY)
- std::cout << "[GATE:" << data.gateway->gatewayID << ":" << data.gateway->name << "(" << data.gateway->controlDomainID << ")"
- << "]";
- else if(type==CONVERTER)
- std::cout << "[CONV:" << data.converter->converterID << ":" << data.converter->name << "(" << data.converter->domainID << ")"
- << "]";
- };
-#endif
-
- am_domainID_t domainID() const
- {
- if(type==SINK)
- return data.sink->domainID;
- else if(type==SOURCE)
- return data.source->domainID;
- else if(type==GATEWAY)
- return data.gateway->controlDomainID;
- else if(type==CONVERTER)
- return data.converter->domainID;
- return 0;
- };
-};
-
-typedef am_RoutingNodeData_s::am_NodeDataType_e CAmNodeDataType;
-typedef CAmNode<am_RoutingNodeData_s> CAmRoutingNode;
-typedef CAmGraph<am_RoutingNodeData_s, uint16_t> CAmRoutingGraph;
-typedef CAmVertex<am_RoutingNodeData_s, uint16_t> CAmRoutingVertex;
-typedef std::list<CAmRoutingVertex> CAmRoutingListVertices;
-typedef std::vector<CAmRoutingListVertices*> CAmRoutingVertexReferenceList;
-
-class CAmControlSender;
-
-
-/**
- * Implements an autorouting algorithm for connecting sinks and sources via different audio domains.
- */
-class CAmRouter
-{
- IAmDatabaseHandler* mpDatabaseHandler; //!< pointer to database handler
- CAmControlSender* mpControlSender; //!< pointer the controlsender - is used to retrieve information for the optimal route
- bool mOnlyFreeConversionNodes; //!< bool flag whether only disconnected elements should be considered or not
- CAmRoutingGraph mRoutingGraph; //!< graph object
- std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListSources; //!< map with pointers to nodes with sources, used for quick access
- std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListSinks; //!< map with pointers to nodes with sinks, used for quick access
- std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListGateways; //!< map with pointers to nodes with gateways, used for quick access
- std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListConverters;//!< map with pointers to nodes with converters, used for quick access
-
- am_Error_e determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & nodes);
- am_Error_e doConnectionFormatsForPath(am_Route_s & routeObjects,
- std::vector<CAmRoutingNode*> & route,
- std::vector<am_RoutingElement_s>::iterator routingElementIterator,
- std::vector<CAmRoutingNode*>::iterator routeIterator);
-
-
- /**
- * Check whether given converter or gateway has been connected.
- *
- * @param comp converter or gateway .
- */
- template <class Component> bool isComponentConnected(const Component & comp)
- {
- return mpDatabaseHandler->isComponentConnected(comp);
- }
- void generateAllPaths(const CAmRoutingNode & src,
- const CAmRoutingNode & dst,
- const bool includeCycles,
- std::function<void(const std::vector<CAmRoutingNode*> & path)> cb);
- void goThroughAllPaths(const CAmRoutingNode & dst,
- std::vector<CAmRoutingNode*> & visited,
- std::vector<am_domainID_t> & visitedDomains,
- std::function<void(const std::vector<CAmRoutingNode*> & path)> cb);
-
-#ifdef ROUTING_BUILD_CONNECTIONS
- /**
- * Connects all converters to its sink and sources if possible.
- *
- */
- void constructConverterConnections();
-
- /**
- * Connects all gateways to its sink and sources if possible.
- *
- */
- void constructGatewayConnections();
-
- /**
- * Connects all sources to the sinks if possible.
- *
- */
- void constructSourceSinkConnections();
-#else
- /**
- * Construct a list with all vertices
- */
- void getVerticesForNode(const CAmRoutingNode & node, CAmRoutingListVertices & list);
-
- /**
- * Construct a list with all vertices from given source.
- */
- void getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list);
-
- /**
- * Construct a list with all vertices from given sink.
- */
- void getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list);
-
- /**
- * Construct a list with all vertices from given converter.
- */
- void getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list);
-
- /**
- * Construct a list with all vertices from given gateway.
- */
- void getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list);
-#endif
-
-public:
- CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender);
- ~CAmRouter();
-
- /**
- * Finds all possible paths between given source and sink.
- *
- * @param onlyfree only disconnected elements should be included or not.
- * @param sourceID starting point.
- * @param sinkID ending point.
- * @param returnList list with all possible paths
- * @return E_OK on success(0 or more paths) or E_NOT_POSSIBLE on failure.
- */
- am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList);
- am_Error_e getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes);
-
- am_Error_e getAllPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink,
- std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath,
-#if !defined(ROUTING_BUILD_CONNECTIONS)
- __attribute__((unused))
-#endif
- const bool includeCycles = false);
-#ifdef ROUTING_BUILD_CONNECTIONS
- void getShortestPath(const CAmRoutingNode & source, const CAmRoutingNode & destination, std::vector<CAmRoutingNode*> & resultPath);
- void getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, am_Route_s & resultPath, std::vector<CAmRoutingNode*> & resultNodesPath);
+#define COUT_NODE(HEAD, NAME, ID) \
+ std::cout << HEAD << "(" << std::setfill('0') << std::setw(4) << ID << " " << NAME << ")";
+
+ void trace() const
+ {
+ if(type==SINK)
+ COUT_NODE("SI", data.sink->name, data.sink->sinkID )
+ else if(type==SOURCE)
+ COUT_NODE("SO", data.source->name, data.source->sourceID )
+ else if(type==GATEWAY)
+ COUT_NODE("GA", data.gateway->name, data.gateway->gatewayID )
+ else if(type==CONVERTER)
+ COUT_NODE("CO", data.converter->name, data.converter->converterID )
+ };
#endif
- static bool getAllowedFormatsFromConvMatrix( const std::vector<bool> & convertionMatrix,
- const std::vector<am_CustomConnectionFormat_t> & listSourceFormats,
- const std::vector<am_CustomConnectionFormat_t> & listSinkFormats,
- std::vector<am_CustomConnectionFormat_t> & sourceFormats,
- std::vector<am_CustomConnectionFormat_t> & sinkFormats);
- static void listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats,
- std::vector<am_CustomConnectionFormat_t> & inListSinkFormats,
- std::vector<am_CustomConnectionFormat_t> & outListFormats);
- static bool getRestrictedOutputFormats(const std::vector<bool> & convertionMatrix,
- const std::vector<am_CustomConnectionFormat_t> & listSourceFormats,
- const std::vector<am_CustomConnectionFormat_t> & listSinkFormats,
- const am_CustomConnectionFormat_t connectionFormat,
- std::vector<am_CustomConnectionFormat_t> & listFormats);
- static void getSourceSinkPossibleConnectionFormats(std::vector<CAmRoutingNode*>::iterator iteratorSource,
- std::vector<CAmRoutingNode*>::iterator iteratorSink,
- std::vector<am_CustomConnectionFormat_t> & outConnectionFormats);
-
- static bool shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID);
-
- /**
- * Returns a sink node with given sinkID.
- *
- * @param sinkID sink id.
- * @return pointer to node or NULL.
- */
- CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID);
- CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID, const am_domainID_t domainID);
-
- /**
- * Returns a source node with given sourceID.
- *
- * @param sourceID source id.
- * @return pointer to node or NULL.
- */
- CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID);
- CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID, const am_domainID_t domainID);
-
- /**
- * Returns a converter node for given sinkID.
- *
- * @param sinkID sink id.
- * @param domainID domain id.
- * @return pointer to node or NULL.
- */
- CAmRoutingNode* converterNodeWithSinkID(const am_sinkID_t sinkID, const am_domainID_t domainID);
-
- /**
- * Returns a gateway node for given sinkID.
- *
- * @param sinkID sink id.
- * @return pointer to node or NULL.
- */
- CAmRoutingNode* gatewayNodeWithSinkID(const am_sinkID_t sinkID);
-
- void load(const bool onlyFree);
- void clear();
-};
+ am_domainID_t domainID() const
+ {
+ if (type == SINK)
+ return data.sink->domainID;
+ else if (type == SOURCE)
+ return data.source->domainID;
+ else if (type == GATEWAY)
+ return data.gateway->controlDomainID;
+ else if (type == CONVERTER)
+ return data.converter->domainID;
+ return 0;
+ }
+ ;
+ };
+
+ typedef am_RoutingNodeData_s::am_NodeDataType_e CAmNodeDataType;
+ typedef CAmNode<am_RoutingNodeData_s> CAmRoutingNode;
+ typedef CAmGraph<am_RoutingNodeData_s, uint16_t> CAmRoutingGraph;
+ typedef CAmVertex<am_RoutingNodeData_s, uint16_t> CAmRoutingVertex;
+ typedef std::list<CAmRoutingVertex> CAmRoutingListVertices;
+ typedef std::vector<CAmRoutingListVertices*> CAmRoutingVertexReferenceList;
+
+ class CAmControlSender;
+
+ /**
+ * Implements autorouting algorithm for connecting sinks and sources via different audio domains.
+ */
+ class CAmRouter: public CAmDatabaseHandlerMap::AmDatabaseObserverCallbacks
+ {
+ IAmDatabaseHandler* mpDatabaseHandler; //!< pointer to database handler
+ CAmControlSender* mpControlSender; //!< pointer the controlsender - is used to retrieve information for the optimal route
+ bool mUpdateGraphNodesAction; //!< Flag which marks whether the graph should be rebuild
+ unsigned mMaxAllowedCycles; //!< max allowed cycles, default is 1
+ unsigned mMaxPathCount; //!< max paths count returned to the controller, default is 5
+ CAmRoutingGraph mRoutingGraph; //!< graph object
+ std::map<am_domainID_t, std::vector<CAmRoutingNode*>> mNodeListSources; //!< map with pointers to nodes with sources, used for quick access
+ std::map<am_domainID_t, std::vector<CAmRoutingNode*>> mNodeListSinks; //!< map with pointers to nodes with sinks, used for quick access
+ std::map<am_domainID_t, std::vector<CAmRoutingNode*>> mNodeListGateways; //!< map with pointers to nodes with gateways, used for quick access
+ std::map<am_domainID_t, std::vector<CAmRoutingNode*>> mNodeListConverters; //!< map with pointers to nodes with converters, used for quick access
+
+ /**
+ * Check whether given converter or gateway has been connected.
+ *
+ * @param comp converter or gateway .
+ */
+ template<class Component> bool isComponentConnected(const Component & comp)
+ {
+ return mpDatabaseHandler->isComponentConnected(comp);
+ }
+
+ /**
+ * Connect all converters to its sink and sources if possible.
+ *
+ */
+ void constructConverterConnections();
+
+ /**
+ * Connect all gateways to its sink and sources if possible.
+ *
+ */
+ void constructGatewayConnections();
+
+ /**
+ * Connect all sources to the sinks if possible.
+ *
+ */
+ void constructSourceSinkConnections();
+
+ /**
+ * Construct list with all vertices
+ */
+ void getVerticesForNode(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct list with all vertices from given source.
+ */
+ void getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct list with all vertices from given sink.
+ */
+ void getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct list with all vertices from given converter.
+ */
+ void getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Construct list with all vertices from given gateway.
+ */
+ void getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list);
+
+ /**
+ * Connection format permutations.
+ *
+ * @return E_OK on success(1 or more paths), E_NOT_POSSIBLE if the CF couldn't be matached or E_UNKNOWN in any other error case.
+ */
+ am_Error_e determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & nodes, std::vector<am_Route_s> & result);
+ am_Error_e doConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & route,
+ std::vector<am_RoutingElement_s>::iterator routingElementIterator, std::vector<CAmRoutingNode*>::iterator routeIterator,
+ std::vector<am_Route_s> & result);
+ am_Error_e cfPermutationsForPath(am_Route_s shortestRoute, std::vector<CAmRoutingNode*> resultNodesPath, std::vector<am_Route_s>& resultPath);
+
+ /**
+ * Helper method.
+ */
+ static int insertPostion(const std::vector<CAmRoutingNode*>& path, const std::vector<std::vector<CAmRoutingNode*> >& nodes);
+
+ public:
+ CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender);
+ ~CAmRouter();
+
+ unsigned getMaxAllowedCycles()
+ {
+ return mMaxAllowedCycles;
+ }
+ void setMaxAllowedCycles(unsigned count)
+ {
+ mMaxAllowedCycles = count;
+ }
+
+ unsigned getMaxPathCount()
+ {
+ return mMaxPathCount;
+ }
+ void setMaxPathCount(unsigned count)
+ {
+ mMaxPathCount = count;
+ }
+
+ bool getUpdateGraphNodesAction()
+ {
+ return mUpdateGraphNodesAction;
+ }
+
+ /**
+ * Find first mMaxPathCount paths between given source and sink. This method will call the method load() if the parameter mUpdateGraphNodesAction is set which will rebuild the graph.
+ *
+ * @param onlyfree only disconnected elements should be included or not.
+ * @param sourceID start point.
+ * @param sinkID end point.
+ * @param returnList list with all possible paths
+ * @return E_OK on success(1 or more paths), E_NOT_POSSIBLE if the CF couldn't be matached or E_UNKNOWN in any other error case.
+ */
+ am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList);
+ am_Error_e getRoute(const bool onlyfree, const am_Source_s & source, const am_Sink_s & sink, std::vector<am_Route_s> & listRoutes);
+
+ /**
+ * Find first mMaxPathCount paths between given source and sink after the nodes have been loaded. This method doesn't call load().
+ *
+ * @param onlyfree only disconnected elements should be included or not.
+ * @param sourceID start point.
+ * @param sinkID end point.
+ * @param returnList list with all possible paths
+ * @return E_OK on success(1 or more paths), E_NOT_POSSIBLE if the CF couldn't be matached or E_UNKNOWN in any other error case.
+ */
+ am_Error_e getRouteFromLoadedNodes(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s> & returnList);
+ am_Error_e getRouteFromLoadedNodes(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes);
+
+ /**
+ * Find first mMaxPathCount paths between given source and sink. This method doesn't call load().
+ *
+ * @param onlyfree only disconnected elements should be included or not.
+ * @param cycles allowed domain cycles.
+ * @param maxPathCount max count of returned paths.
+ * @param source start point.
+ * @param sink end point.
+ * @param returnList list with all possible paths.
+ * @return E_OK on success(1 or more paths), E_NOT_POSSIBLE if the CF couldn't be matached or E_UNKNOWN in any other error case.
+ */
+ am_Error_e getFirstNShortestPaths(const bool onlyfree, const unsigned cycles, const unsigned maxPathCount, CAmRoutingNode & source,
+ CAmRoutingNode & sink, std::vector<am_Route_s> & resultPath);
+
+ /**
+ * Find the shortest path between given source and sink. This method doesn't call load().
+ * It goes through all possible paths and returns the shortest of them.
+ *
+ * @param source start point.
+ * @param sink end point.
+ * @param returnList list with the connection format permutations of the shortest path.
+ * @return E_OK on success(1 or more paths), E_NOT_POSSIBLE if the CF couldn't be matached or E_UNKNOWN in any other error case.
+ */
+ am_Error_e getShortestPath(CAmRoutingNode & source, CAmRoutingNode & sink, std::vector<am_Route_s> & resultPath);
+
+ static bool getAllowedFormatsFromConvMatrix(const std::vector<bool> & convertionMatrix,
+ const std::vector<am_CustomConnectionFormat_t> & listSourceFormats, const std::vector<am_CustomConnectionFormat_t> & listSinkFormats,
+ std::vector<am_CustomConnectionFormat_t> & sourceFormats, std::vector<am_CustomConnectionFormat_t> & sinkFormats);
+ static void listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats,
+ std::vector<am_CustomConnectionFormat_t> & inListSinkFormats, std::vector<am_CustomConnectionFormat_t> & outListFormats);
+ static bool getRestrictedOutputFormats(const std::vector<bool> & convertionMatrix, const std::vector<am_CustomConnectionFormat_t> & listSourceFormats,
+ const std::vector<am_CustomConnectionFormat_t> & listSinkFormats, const am_CustomConnectionFormat_t connectionFormat,
+ std::vector<am_CustomConnectionFormat_t> & listFormats);
+ static am_Error_e getSourceSinkPossibleConnectionFormats(std::vector<CAmRoutingNode*>::iterator iteratorSource,
+ std::vector<CAmRoutingNode*>::iterator iteratorSink, std::vector<am_CustomConnectionFormat_t> & outConnectionFormats);
+
+ static bool shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID, const unsigned maxCyclesNumber);
+ bool shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID);
+ /**
+ * Returns a sink node with given sinkID.
+ *
+ * @param sinkID sink id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID);
+ CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID, const am_domainID_t domainID);
+
+ /**
+ * Returns a source node with given sourceID.
+ *
+ * @param sourceID source id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID);
+ CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID, const am_domainID_t domainID);
+
+ /**
+ * Returns a converter node for given sinkID.
+ *
+ * @param sinkID sink id.
+ * @param domainID domain id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* converterNodeWithSinkID(const am_sinkID_t sinkID, const am_domainID_t domainID);
+
+ /**
+ * Returns a gateway node for given sinkID.
+ *
+ * @param sinkID sink id.
+ * @return pointer to node or NULL.
+ */
+ CAmRoutingNode* gatewayNodeWithSinkID(const am_sinkID_t sinkID);
+
+ void load();
+ void clear();
+
+ /**
+ * DEPRECATED!
+ */
+ public:
+ am_Error_e getAllPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink, std::vector<am_Route_s> & resultPath,
+ std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath, const bool includeCycles = false,
+ const bool onlyFree = false)
+ __attribute__((deprecated("You should use am_Error_e getFirstNShortestPaths(const bool onlyFree, CAmRoutingNode &, CAmRoutingNode &, std::vector<am_Route_s> &) instead!")));
+ };
} /* namespace am */
#endif /* ROUTER_H_ */
diff --git a/AudioManagerCore/include/CAmRoutingSender.h b/AudioManagerCore/include/CAmRoutingSender.h
index 8804d90..8d8a063 100644
--- a/AudioManagerCore/include/CAmRoutingSender.h
+++ b/AudioManagerCore/include/CAmRoutingSender.h
@@ -32,16 +32,17 @@
#include "../test/IAmRoutingBackdoor.h"
#endif
+#include "CAmDatabaseHandlerMap.h"
+
namespace am
{
class CAmRoutingReceiver;
-class IAmDatabaseHandler;
/**
* Implements the RoutingSendInterface. Loads all plugins and dispatches calls to the plugins
*/
-class CAmRoutingSender
+class CAmRoutingSender: public CAmDatabaseHandlerMap::AmDatabaseObserverCallbacks
{
public:
CAmRoutingSender(const std::vector<std::string>& listOfPluginDirectories, IAmDatabaseHandler* databaseHandler);
diff --git a/AudioManagerCore/include/IAmDatabaseHandler.h b/AudioManagerCore/include/IAmDatabaseHandler.h
index aa275db..f4fe8a1 100644
--- a/AudioManagerCore/include/IAmDatabaseHandler.h
+++ b/AudioManagerCore/include/IAmDatabaseHandler.h
@@ -30,18 +30,14 @@
#include <string>
#include <iostream>
#include <functional>
+#include <memory>
+#include <assert.h>
+#include <algorithm>
#include "audiomanagerconfig.h"
namespace am
{
-class CAmDatabaseObserver;
-class CAmRoutingTree;
-class CAmRoutingTreeItem;
-
-
-//enum { DYNAMIC_ID_BOUNDARY = 100 }; //!< the value below is reserved for staticIDs, the value above will be assigned to dynamically registered items
-
//todo: check the enum values before entering & changing in the database.
//todo: change asserts for dynamic boundary checks into failure answers.#
//todo: check autoincrement boundary and set to 16bit limits
@@ -59,8 +55,12 @@ typedef std::map<am_gatewayID_t, std::vector<bool> > ListConnectionFormat; //!<
class IAmDatabaseHandler
{
public:
- IAmDatabaseHandler () {};
- virtual ~IAmDatabaseHandler () {};
+ IAmDatabaseHandler (){}
+ virtual ~IAmDatabaseHandler (){}
+
+ /**
+ * The following interface methods must be implemented by the subclass.
+ */
virtual am_Error_e enterDomainDB(const am_Domain_s& domainData, am_domainID_t& domainID) = 0;
virtual am_Error_e enterMainConnectionDB(const am_MainConnection_s& mainConnectionData, am_mainConnectionID_t& connectionID) = 0;
virtual am_Error_e enterSinkDB(const am_Sink_s& sinkData, am_sinkID_t& sinkID) = 0;
@@ -117,7 +117,7 @@ public:
virtual am_Error_e getSourceVolume(const am_sourceID_t sourceID, am_volume_t& volume) const = 0;
virtual am_Error_e getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const = 0;
virtual am_Error_e getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomSoundPropertyType_t propertyType, int16_t& value) const = 0;
- virtual am_Error_e getListSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_SoundProperty_s>& listSoundproperties) const =0;
+ virtual am_Error_e getListSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_SoundProperty_s>& listSoundproperties) const =0;
virtual am_Error_e getListSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_SoundProperty_s>& listSoundproperties) const =0;
virtual am_Error_e getMainSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const = 0;
virtual am_Error_e getMainSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_CustomMainSoundPropertyType_t propertyType, int16_t& value) const = 0;
@@ -166,7 +166,6 @@ public:
virtual am_Error_e changeConverterDB(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix) = 0;
virtual am_Error_e changeSinkNotificationConfigurationDB(const am_sinkID_t sinkID,const am_NotificationConfiguration_s notificationConfiguration) = 0;
virtual am_Error_e changeSourceNotificationConfigurationDB(const am_sourceID_t sourceID,const am_NotificationConfiguration_s notificationConfiguration) = 0;
-
virtual bool existMainConnection(const am_mainConnectionID_t mainConnectionID) const = 0;
virtual bool existCrossFader(const am_crossfaderID_t crossfaderID) const = 0;
virtual bool existConnection(const am_Connection_s & connection) const = 0;
@@ -181,7 +180,6 @@ public:
virtual bool existGateway(const am_gatewayID_t gatewayID) const = 0;
virtual bool existSinkClass(const am_sinkClass_t sinkClassID) const = 0;
virtual bool existSourceClass(const am_sourceClass_t sourceClassID) const = 0;
- virtual void registerObserver(CAmDatabaseObserver *iObserver) = 0;
virtual bool sourceVisible(const am_sourceID_t sourceID) const = 0;
virtual bool sinkVisible(const am_sinkID_t sinkID) const = 0;
virtual bool isComponentConnected(const am_Gateway_s & gateway) const = 0;
@@ -192,7 +190,19 @@ public:
virtual am_Error_e enumerateSinks(std::function<void(const am_Sink_s & element)> cb) const = 0 ;
virtual am_Error_e enumerateGateways(std::function<void(const am_Gateway_s & element)> cb) const = 0 ;
virtual am_Error_e enumerateConverters(std::function<void(const am_Converter_s & element)> cb) const = 0 ;
+ /**
+ * Database observer protocol
+ */
+ class IAmDatabaseObserver
+ {
+ public:
+ IAmDatabaseObserver() {}
+ virtual ~IAmDatabaseObserver(){}
+ };
+ virtual bool registerObserver(IAmDatabaseObserver * iObserver) = 0;
+ virtual bool unregisterObserver(IAmDatabaseObserver * iObserver) = 0;
+ virtual unsigned countObservers() = 0;
};