Commit 61bc6f23 authored by Pascal Palenda's avatar Pascal Palenda
Browse files

Refine audibility filter interface and add condition filter - WIP

parent c2dbc366
......@@ -5,6 +5,7 @@ set( SubDirs
set( DirFiles
audibility_filter_interface.h
condition_filter_interface.h
rate_filter.h
#_SourceFiles.cmake
)
......
......@@ -4,9 +4,13 @@
// API includes
#include <ITA/simulation_scheduler/definitions.h>
// simulation scheduler includes
#include <ITA/simulation_scheduler/audibility_filter/condition_filter_interface.h>
// std includes
#include <memory>
#include <functional>
#include <vector>
// Vista includes
#include <VistaAspects/VistaPropertyList.h>
......@@ -22,14 +26,13 @@ namespace ITA
///
/// \brief The interface for an audibility filter.
///
/// A audibility filter is used to determine the audibility of the change between two CUpdateScenes.
/// These filters can deploy other filters to increase their possibilities.
/// An audibility filter is used to determine the audibility of the change between two CUpdateScenes.
///
/// A filter is created by CFilterFactory.
/// An audibility filter is created by CAudibilityFilterFactory.
/// For this, a function like this is necessary:
/// \code{.cpp}
/// ///
/// /// \brief Factory function for a filter.
/// /// \brief Factory function for an audibility filter.
/// /// \remark This function should to be static.
/// ///
/// static std::unique_ptr<IAudibilityFilter> createFilter ( const IAudibilityFilter::AudibilityFilterConfig& );
......@@ -39,40 +42,82 @@ namespace ITA
{
public:
///
/// \brief Configuration class for filter.
/// \todo This class might be only used to hold other filter configs. See if we should keep this.
///
class ITA_SIMULATION_SCHEDULER_API AudibilityFilterConfig : public VistaPropertyList
/// \brief Configuration class for an audibility filter.
///
struct ITA_SIMULATION_SCHEDULER_API AudibilityFilterConfig : public VistaPropertyList
{
int i = 6;
};
///
/// \brief Available properties of the IAudibilityFilter.
///
/// This struct primarily maps a variable to the string that is the key to the property.
/// \remark The format of the properties is the following: {property function}_{type of property}
///
struct ITA_SIMULATION_SCHEDULER_API Properties
{
static const std::string getConditionFilterKey_Section ( ); ///< Section containing all condition filter configs.
static const std::string getConditionFilterOrderKey_Section ( ); ///< Section containing the order of the condition filters.
};
virtual ~IAudibilityFilter ( ) = 0;
///
/// \brief Set the condition filter config of the AudibilityFilterConfig.
///
/// The order of the condition filters is also saved in the config.
/// \param vFilterConfig all filter to add to the config.
/// \todo Do we set or add filter configs? If we set, do we overwrite?
///
void setConditionFilterConfig ( const std::vector<IConditionFilter::ConditionFilterConfig>& vFilterConfig );
///
/// \brief Get all condition filter configs from the AudibilityFilterConfig.
///
/// The order in which the condition filters were set in the config is also represented in the vector.
/// \return a vector with all condition filter configs.
///
std::vector<IConditionFilter::ConditionFilterConfig> getConditionFilterConfig ( ) const;
};
///
/// \brief Check if the condition is met.
/// \brief Constructor for IAudibilityFilter.
///
/// A filter might have a condition that has to be fulfilled to be actually useful.
/// Another filter might just be a conditional filter.
/// This function should handle both of these cases.
/// \note Default behaviour it to return true if \p previousState was created before \p newUpdate.
/// \param previousState the previous state of the scene to check against.
/// \param newUpdate the CUpdateScene to check.
/// \return true if the condition is fulfilled, else false.
/// This constructor configures the condition filters of the IAudibilityFilter.
/// \param oConfig the AudibilityFilterConfig used to configure the IAudibilityFilter.
///
virtual bool conditionFulfilled(const CUpdateScene& previousState, const CUpdateScene& newUpdate);
explicit IAudibilityFilter ( const AudibilityFilterConfig& oConfig );
///
/// \brief Pure virtual destructor.
///
virtual ~IAudibilityFilter ( ) = 0;
IAudibilityFilter ( const IAudibilityFilter& other ) = delete;
IAudibilityFilter& operator=( const IAudibilityFilter& other ) = delete;
//
///
/// \brief Check if the change between \p previousState and \p newUpdate is audible.
///
/// This function might call ::conditionFulfilled to check if the condition for its test is fulfilled.
/// \note Default behaviour it to return the result of conditionFulfilled.
/// \note Default behaviour it to return the default result of IConditionFilter::conditionFulfilled.
/// \param previousState the previous state of the scene to check against.
/// \param newUpdate the CUpdateScene to check for audibility.
/// \return true if the change between \p previousState and \p newUpdate is audible, else false.
///
virtual bool changeIsAudible ( const CUpdateScene& previousState, const CUpdateScene& newUpdate );
protected:
///
/// \brief Check if all conditions are met.
///
/// This functions calls IConditionFilter::conditionFulfilled of all IConditionFilter%s in ::m_lpConditionFilters.
/// \param previousState the previous state of the scene to check against.
/// \param newUpdate the CUpdateScene to check for audibility.
/// \return true, if all conditions are fulfilled.
///
bool checkAllConditions ( const CUpdateScene& previousState, const CUpdateScene& newUpdate );
///
/// \brief Vector of the condition filters belonging to IAudibilityFilter.
///
virtual bool changeIsAudible(const CUpdateScene& previousState, const CUpdateScene& newUpdate);
std::vector<std::unique_ptr<IConditionFilter>> m_lpConditionFilters;
};
///
......
#ifndef INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_AUDIBILITY_FILTER_CONDITION_FILTER_INTERFACE
#define INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_AUDIBILITY_FILTER_CONDITION_FILTER_INTERFACE
// API includes
#include <ITA/simulation_scheduler/definitions.h>
// std includes
#include <memory>
#include <functional>
// Vista includes
#include <VistaAspects/VistaPropertyList.h>
namespace ITA
{
namespace simulation_scheduler
{
class CUpdateScene;
namespace audibility_filter
{
///
/// \brief The interface for an condition filter.
///
/// A condition filter is used to determine if a condition is met for the two CUpdateScenes.
/// These filters can deploy other filters to increase their possibilities.
///
/// A filter is created by CConditionFilterFactory.
/// For this, a function like this is necessary:
/// \code{.cpp}
/// ///
/// /// \brief Factory function for a filter.
/// /// \remark This function should to be static.
/// ///
/// static std::unique_ptr<IConditionFilter> createFilter ( const IConditionFilter::ConditionFilterConfig& );
/// \endcode
///
struct ITA_SIMULATION_SCHEDULER_API IConditionFilter
{
///
/// \brief Configuration class for condition filter.
/// \todo This class might be only used to hold other filter configs. See if we should keep this.
///
class ITA_SIMULATION_SCHEDULER_API ConditionFilterConfig : public VistaPropertyList
{
};
virtual ~IConditionFilter ( ) = 0;
///
/// \brief Check if the condition is met.
///
/// \note Default behaviour it to return true if \p previousState was created before \p newUpdate.
/// \param previousState the previous state of the scene to check against.
/// \param newUpdate the CUpdateScene to check.
/// \return true if the condition is fulfilled, else false.
///
virtual bool conditionFulfilled(const CUpdateScene& previousState, const CUpdateScene& newUpdate);
};
///
/// \brief Factory class for condition filter.
///
/// This class implements an extensible factory for condition filter.
/// After a type of condition filter is registered with its IConditionFilter::createFilter, it can be created using this factory.
///
class ITA_SIMULATION_SCHEDULER_API CConditionFilterFactory
{
public:
///
/// \brief The function signature for a create function.
///
typedef std::function<std::unique_ptr<IConditionFilter> ( const IConditionFilter::ConditionFilterConfig& )> CreateCallback;
///
/// \brief Register a type of condition filter to the factory.
/// \param type name of the condition filter type to be registered.
/// \param createFunction the corresponding create function.
///
static void registerFilter ( const std::string& type, CreateCallback createFunction );
///
/// \brief Unregister a type of condition filter from the factory.
/// \param type name of the condition filter type to be removed.
///
static void unregisterFilter ( const std::string& type );
///
/// \brief Factory method.
/// \param pConfig the configuration for the condition filter.
/// \return a pointer to the created condition filter.
///
static std::unique_ptr<IConditionFilter> createFilter ( const IConditionFilter::ConditionFilterConfig& pConfig );
private:
///
/// \brief Map containing all creation functions.
///
static std::map<std::string, CreateCallback> m_mFilters;
};
} // namespace audibility_filter
} // namespace simulation_scheduler
} // namespace ITA
#endif // INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_AUDIBILITY_FILTER_CONDITION_FILTER_INTERFACE
\ No newline at end of file
......@@ -5,6 +5,7 @@ set( SubDirs
set( DirFiles
audibility_filter_interface.cpp
condition_filter_interface.cpp
rate_filter.cpp
#_SourceFiles.cmake
)
......
......@@ -3,6 +3,8 @@
// simulation scheduler includes
#include <ITA/simulation_scheduler/update_scene.h>
#include "ITAException.h"
namespace ITA
{
namespace simulation_scheduler
......@@ -11,18 +13,131 @@ namespace ITA
{
std::map<std::string, CAudibilityFilterFactory::CreateCallback> CAudibilityFilterFactory::m_mFilters;
class CDefaultConditionFilter : public IConditionFilter
{
};
const std::string IAudibilityFilter::AudibilityFilterConfig::Properties::getConditionFilterKey_Section ( )
{
return "ConditionFilter";
}
const std::string IAudibilityFilter::AudibilityFilterConfig::Properties::
getConditionFilterOrderKey_Section ( )
{
return "ConditionFilterOrder";
}
void IAudibilityFilter::AudibilityFilterConfig::setConditionFilterConfig (
const std::vector<IConditionFilter::ConditionFilterConfig>& vFilterConfig )
{
// We expect only one item in the given config -> One sublist with the config.
// Thus begin points to the expected config.
if ( size ( ) == 1 )
{
auto&& audibilityFilterConfig = GetSubListRef ( begin ( )->first );
auto config = VistaPropertyList ( );
int counter = 0;
for ( auto filterConfig : vFilterConfig )
{
// Check whether there is only one item in filterConfig.
// If so, begin() points to this item.
// So we check if it is a property list so we can use it as the config.
if ( filterConfig.size ( ) == 1 &&
filterConfig.begin ( )->second.GetPropertyType ( ) == VistaProperty::ePropType::PROPT_PROPERTYLIST )
{
audibilityFilterConfig.SetValueInSubList ( std::to_string ( counter ), Properties::getConditionFilterOrderKey_Section ( ), filterConfig.begin ( )->first );
config.MergeWith ( filterConfig );
}
else
ITA_EXCEPT_INVALID_PARAMETER ( "The given config should only have one sub list entry." );
counter++;
}
audibilityFilterConfig.SetPropertyListValue ( Properties::getConditionFilterKey_Section ( ), config );
}
else
ITA_EXCEPT_INVALID_PARAMETER ( "Config is not a compatible audibility filter config." );
}
std::vector<IConditionFilter::ConditionFilterConfig> IAudibilityFilter::AudibilityFilterConfig::
getConditionFilterConfig ( ) const
{
if ( size ( ) == 1 )
{
const auto audibilityFilterConfig = GetSubListConstRef ( begin ( )->first );
if ( audibilityFilterConfig.HasSubList ( Properties::getConditionFilterKey_Section ( ) ) && audibilityFilterConfig.HasSubList ( Properties::getConditionFilterOrderKey_Section ( ) ) )
{
const auto filterConfigs = audibilityFilterConfig.GetSubListConstRef ( Properties::getConditionFilterKey_Section ( ) );
const auto filterOrder = audibilityFilterConfig.GetSubListConstRef ( Properties::getConditionFilterOrderKey_Section ( ) );
std::vector<IConditionFilter::ConditionFilterConfig> configs;
for ( int i = 0; i < filterOrder.size ( ); ++i )
{
auto filterName = filterOrder.GetValue<std::string> ( std::to_string ( i ) );
IConditionFilter::ConditionFilterConfig filterConfig;
filterConfig.SetPropertyListValue ( filterName, filterConfigs.GetSubListCopy ( filterName ) );
configs.push_back ( filterConfig );
}
return configs;
}
else
return std::vector<IConditionFilter::ConditionFilterConfig> ( );
}
else
ITA_EXCEPT_INVALID_PARAMETER ( "Config is not a compatible audibility filter config." );
}
IAudibilityFilter::IAudibilityFilter ( const AudibilityFilterConfig& oConfig )
{
auto lConditionFilterConfigs = oConfig.getConditionFilterConfig ( );
if ( lConditionFilterConfigs.empty ( ) )
{
m_lpConditionFilters.push_back ( std::make_unique<CDefaultConditionFilter> ( ) );
}
else
{
for ( const auto conditionConfig : lConditionFilterConfigs )
{
m_lpConditionFilters.push_back ( CConditionFilterFactory::createFilter ( conditionConfig ) );
}
}
}
// Definition of the pure virtual destructor.
IAudibilityFilter::~IAudibilityFilter ( )
{ }
bool IAudibilityFilter::conditionFulfilled ( const CUpdateScene& previousState, const CUpdateScene& newUpdate )
bool IAudibilityFilter::changeIsAudible ( const CUpdateScene& previousState, const CUpdateScene& newUpdate )
{
return previousState.getTimeStamp ( ) < newUpdate.getTimeStamp ( );
return checkAllConditions ( previousState, newUpdate );
}
bool IAudibilityFilter::changeIsAudible ( const CUpdateScene& previousState, const CUpdateScene& newUpdate )
bool IAudibilityFilter::checkAllConditions ( const CUpdateScene& previousState, const CUpdateScene& newUpdate )
{
return conditionFulfilled ( previousState, newUpdate );
auto bConditionFulfilled = true;
// Test if the conditions are fulfilled.
// Note the extra condition in the for loop, this gains performance if a previous condition was false.
for ( auto filterIter = m_lpConditionFilters.begin ( );
bConditionFulfilled && filterIter != m_lpConditionFilters.end ( );
++filterIter )
{
bConditionFulfilled &= ( *filterIter )->conditionFulfilled ( previousState, newUpdate );
}
return bConditionFulfilled;
}
void CAudibilityFilterFactory::registerFilter ( const std::string& type, CreateCallback createFunction )
......
#include <ITA/simulation_scheduler/audibility_filter/condition_filter_interface.h>
// simulation scheduler includes
#include <ITA/simulation_scheduler/update_scene.h>
namespace ITA
{
namespace simulation_scheduler
{
namespace audibility_filter
{
std::map<std::string, CConditionFilterFactory::CreateCallback> CConditionFilterFactory::m_mFilters;
// Definition of the pure virtual destructor.
IConditionFilter::~IConditionFilter ( )
{ }
bool IConditionFilter::conditionFulfilled ( const CUpdateScene& previousState, const CUpdateScene& newUpdate )
{
return previousState.getTimeStamp ( ) < newUpdate.getTimeStamp ( );
}
void CConditionFilterFactory::registerFilter ( const std::string& type, CreateCallback createFunction )
{
m_mFilters [type] = createFunction;
}
void CConditionFilterFactory::unregisterFilter ( const std::string& type )
{
m_mFilters.erase ( type );
}
std::unique_ptr<IConditionFilter> CConditionFilterFactory::createFilter ( const IConditionFilter::ConditionFilterConfig& pConfig )
{
auto it = m_mFilters.find ( pConfig.begin ( )->first );
if ( it != m_mFilters.end ( ) )
{
// call the creation callback to construct this derived type
return it->second ( pConfig );
}
return nullptr;
}
} // namespace audibility_filter
} // namespace simulation_scheduler
} // namespace ITA
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment