Added etl::type_list to etl::observer

This commit is contained in:
John Wellbelove 2026-01-21 09:26:48 +01:00
parent fcd50486ce
commit 2cae496620
2 changed files with 119 additions and 2 deletions

View File

@ -57,6 +57,7 @@ SOFTWARE.
#include "exception.h"
#include "error_handler.h"
#include "utility.h"
#include "type_list.h"
namespace etl
{
@ -338,6 +339,19 @@ namespace etl
virtual void notification() = 0;
};
//*****************************************************************
/// The observer class for N types.
/// Configured from a type list.
///\ingroup observer
//*****************************************************************
template <typename... TTypes>
class observer<etl::type_list<TTypes...>> : public observer<TTypes...>
{
public:
using observer<TTypes...>::notification;
};
#else
//*********************************************************************

View File

@ -68,12 +68,24 @@ namespace
// The Notification2 is passed by reference.
// The Notification3 is passed by const reference.
//*****************************************************************************
typedef etl::observer<Notification1, Notification2&, const Notification3&> ObserverType;
using ObserverType = etl::observer<Notification1, Notification2&, const Notification3&>;
#if !defined(ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION)
//*****************************************************************************
// The observer base type.
// Declare what notifications you want to observe and how they are passed to 'notification'.
// The Notification1 is passed by value.
// The Notification2 is passed by reference.
// The Notification3 is passed by const reference.
//*****************************************************************************
using NotificationList = etl::type_list<Notification1, Notification2&, const Notification3&>;
using ObserverTypeFromTypeList = etl::observer<NotificationList>;
#endif
//*****************************************************************************
// The observer base type that does not take a notification type.
//*****************************************************************************
typedef etl::observer<void, int> ObserverVoidIntType;
using ObserverVoidIntType = etl::observer<void, int>;
}
//*****************************************************************************
@ -115,6 +127,29 @@ public:
}
};
#if !defined(ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION)
//*****************************************************************************
// The concrete observable 3 class.
//*****************************************************************************
class Observable3 : public etl::observable<ObserverTypeFromTypeList, 2>
{
public:
Notification1 data1;
Notification2 data2;
Notification1& data3 = data1;
//*********************************
// Notify all of the observers.
//*********************************
void send_notifications()
{
notify_observers(data3);
notify_observers(data2);
}
};
#endif
//*****************************************************************************
// The concrete observable 3 class.
//*****************************************************************************
@ -229,6 +264,53 @@ public:
int data3_count;
};
#if !defined(ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION)
//*****************************************************************************
// The third observer type.
// If any one of the overloads is missing or a parameter declaration is incorrect
// then the class will be 'abstract' and will not compile.
//*****************************************************************************
class Observer3 : public ObserverTypeFromTypeList
{
public:
Observer3()
: data1_count(0)
, data2_count(0)
, data3_count(0)
{
}
//*******************************************
// Notification1 is passed by value.
//*******************************************
void notification(Notification1 /*data1*/)
{
++data1_count;
}
//*******************************************
// Notification2 is passed by reference.
//*******************************************
void notification(Notification2& /*data2*/)
{
++data2_count;
}
//*******************************************
// Notification3 is passed by const reference.
//*******************************************
void notification(const Notification3& /*data3*/)
{
++data3_count;
}
int data1_count;
int data2_count;
int data3_count;
};
#endif
//*****************************************************************************
// The third observer type.
// If any one of the overloads is missing or a parameter declaration is incorrect
@ -399,6 +481,27 @@ namespace
CHECK_EQUAL(3, observer2.data1_count);
}
#if !defined(ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION)
//*************************************************************************
TEST(test_observer_created_from_a_type_list)
{
// The observable objects.
Observable3 observable3;
// The observer objects.
Observer3 observer3;
observable3.add_observer(observer3);
// Send the notifications.
observable3.send_notifications(); // Updates data1 & data2.
CHECK_EQUAL(1, observer3.data1_count);
CHECK_EQUAL(1, observer3.data2_count);
CHECK_EQUAL(0, observer3.data3_count);
}
#endif
//*************************************************************************
TEST(test_8_notifications)
{