2024-08-17 12:35:36 +03:00
# include "../graph.h"
# include "../module_registry.h"
typedef struct {
GraphNode as_GraphNode ;
size_t length ;
EventPredicateHandle * predicates ;
} RouterGraphNode ;
static bool
handle_event ( EventPositionBase * self , EventNode * event )
{
RouterGraphNode * node = DOWNCAST ( RouterGraphNode , GraphNode , DOWNCAST ( GraphNode , EventPositionBase , self ) ) ;
2024-08-18 19:03:46 +03:00
for ( ssize_t i = node - > length - 1 ; i > = 0 ; - - i ) {
if ( ( size_t ) i > = node - > as_GraphNode . outputs . length ) {
continue ;
2024-08-17 12:35:36 +03:00
}
if ( event_predicate_apply ( node - > predicates [ i ] , event ) = = EVPREDRES_ACCEPTED ) {
if ( event_replicate ( event , 1 ) ) {
event - > next - > position = & node - > as_GraphNode . outputs . elements [ i ] - > as_EventPositionBase ;
}
}
}
event_destroy ( event ) ;
return true ;
}
static GraphNode *
create ( GraphNodeSpecification * spec , GraphNodeConfig * config , InitializationEnvironment * env )
{
2024-08-19 12:21:51 +03:00
if ( ! config - > options ) {
return NULL ;
}
2024-08-17 12:35:36 +03:00
RouterGraphNode * node = T_ALLOC ( 1 , RouterGraphNode ) ;
if ( ! node ) {
return NULL ;
}
config_setting_t * predicates_setting = config_setting_get_member ( config - > options , " predicates " ) ;
if ( ! predicates_setting ) {
free ( node ) ;
return NULL ;
}
EventPredicateHandle * predicates = NULL ;
size_t length = config_setting_length ( predicates_setting ) ;
if ( length > 0 ) {
predicates = T_ALLOC ( length , EventPredicateHandle ) ;
if ( ! predicates ) {
free ( node ) ;
return NULL ;
}
for ( size_t i = 0 ; i < length ; + + i ) {
predicates [ i ] = env_resolve_event_predicate ( env , config_setting_get_elem ( predicates_setting , i ) ) ;
}
}
* node = ( RouterGraphNode ) {
. as_GraphNode = {
. as_EventPositionBase = {
. handle_event = & handle_event ,
. waiting_new_event = false ,
} ,
. specification = spec ,
. inputs = EMPTY_GRAPH_CHANNEL_LIST ,
. outputs = EMPTY_GRAPH_CHANNEL_LIST ,
} ,
. length = length ,
. predicates = predicates ,
} ;
return & node - > as_GraphNode ;
}
static void destroy
( GraphNodeSpecification * self , GraphNode * target )
{
( void ) self ;
RouterGraphNode * node = DOWNCAST ( RouterGraphNode , GraphNode , target ) ;
if ( node - > predicates ) {
free ( node - > predicates ) ;
node - > predicates = NULL ;
node - > length = 0 ;
}
free ( target ) ;
}
GraphNodeSpecification nodespec_router = ( GraphNodeSpecification ) {
. create = & create ,
. destroy = & destroy ,
. register_io = NULL ,
. name = " router " ,
2024-08-18 16:26:54 +03:00
. documentation = " Conditionally copies the received events \n Accepts events on any connector \n Sends events on all connectors with configured predicates "
" \n Option 'predicates' (required): collection of predicates in the order of output connectors from zero, a received event is copied to the given connector iff it satisfies the predicate "
,
2024-08-17 12:35:36 +03:00
} ;
MODULE_CONSTRUCTOR ( init )
{
register_graph_node_specification ( & nodespec_router ) ;
}