@ -8,47 +8,82 @@ Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com>
# pragma once
# pragma once
# include "espurna.h"
# include <functional>
# include <functional>
# include <vector>
# include <utility>
# include <utility>
# include <vector>
# include <tuple>
enum class TBrokerType {
System ,
Status ,
SensorRead ,
SensorReport ,
Datetime ,
Config
} ;
/ / Example usage :
/ /
/ / module . h
/ / BrokerDeclare ( CustomBroker , void ( int ) ) ;
/ /
/ / module . cpp
/ / BrokerBind ( CustomBroker ) ;
/ /
/ / other . cpp
/ / # include " module.h "
/ / void func ( ) {
/ / CustomBroker : : Register ( [ ] ( int arg ) { Serial . println ( arg ) ; }
/ / CustomBroker : : Publish ( 12345 ) ;
/ / }
template < typename Func >
struct TBroker { } ;
template < typename R , typename . . . Args >
struct TBroker < R ( Args . . . ) > {
template < typename . . . TArgs >
using TBrokerCallback = std : : function < void ( TArgs . . . ) > ;
using TArgs = typename std : : tuple < Args . . . > ;
using TCallback = std : : function < R ( Args . . . ) > ;
using TCallbacks = std : : vector < TCallback > ;
template < typename . . . TArgs >
using TBrokerCallbacks = std : : vector < TBrokerCallback < TArgs . . . > > ;
TBroker ( const TBroker & ) = delete ;
TBroker & operator = ( const TBroker & ) = delete ;
template < TBrokerType type , typename . . . TArgs >
struct TBroker {
static TBrokerCallbacks < TArgs . . . > callbacks ;
TBroker ( ) = default ;
static void Register ( TBrokerCallback < TArgs . . . > callback ) {
/ / TODO : https : / / source . chromium . org / chromium / chromium / src / + / master : base / callback_list . h
/ / Consider giving out ' subscription ' / ' token ' , so that the caller can remove callback later
void Register ( TCallback callback ) {
callbacks . push_back ( callback ) ;
callbacks . push_back ( callback ) ;
}
}
static void Publish ( TArgs . . . args ) {
void Publish ( Args . . . args ) {
for ( auto & callback : callbacks ) {
for ( auto & callback : callbacks ) {
callback ( args . . . ) ;
callback ( args . . . ) ;
}
}
}
}
protected :
TCallbacks callbacks ;
} ;
} ;
template < TBrokerType type , typename . . . TArgs >
TBrokerCallbacks < TArgs . . . > TBroker < type , TArgs . . . > : : callbacks ;
/ / TODO : since 1.14 .0 we intoduced static syntax for Brokers , : : Register & : : Publish .
/ / Preserve it ( up to a point ) when creating module - level objects .
/ / Provide a helper namespace with Register & Publish , instance and
/ / To help out VS Code with argument discovery , put TArgs as the first template parameter .
using StatusBroker = TBroker < TBrokerType : : Status , const String & , unsigned char , unsigned int > ;
# define BrokerDeclare(Name, Signature) \
namespace Name { \
using type = TBroker < Signature > ; \
extern type Instance ; \
template < typename S = type : : TArgs , typename . . . Args > \
inline void Register ( Args & & . . . args ) { \
Instance . Register ( std : : forward < Args > ( args ) . . . ) ; \
} \
\
template < typename S = type : : TArgs , typename . . . Args > \
inline void Publish ( Args & & . . . args ) { \
Instance . Publish ( std : : forward < Args > ( args ) . . . ) ; \
} \
}
using SensorReadBroker = TBroker < TBrokerType : : SensorRead , const String & , unsigned char , double , const char * > ;
using SensorReportBroker = TBroker < TBrokerType : : SensorReport , const String & , unsigned char , double , const char * > ;
# define BrokerBind(Name) \
namespace Name { \
Name : : type Instance ; \
}
using ConfigBroker = TBroker < TBrokerType : : Config , const String & , const String & > ;