2021-06-19 06:23:34 +02:00
|
|
|
# File: EventDispatcher.pm
|
|
|
|
#
|
|
|
|
# Purpose: Registers event handlers and dispatches events to them.
|
2021-06-22 02:26:24 +02:00
|
|
|
#
|
|
|
|
# Note: PBot::EventDispatcher has no relation to PBot::EventQueue.
|
2021-06-19 06:23:34 +02:00
|
|
|
|
2017-03-05 22:33:31 +01:00
|
|
|
# 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/.
|
|
|
|
|
2014-11-01 01:15:21 +01:00
|
|
|
package PBot::EventDispatcher;
|
2020-02-08 20:04:13 +01:00
|
|
|
use parent 'PBot::Class';
|
2014-11-01 01:15:21 +01:00
|
|
|
|
2021-06-19 06:23:34 +02:00
|
|
|
use PBot::Imports;
|
2014-11-01 01:15:21 +01:00
|
|
|
|
|
|
|
sub initialize {
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($self, %conf) = @_;
|
2021-07-05 07:25:41 +02:00
|
|
|
|
|
|
|
# hash table of event handlers
|
|
|
|
$self->{handlers} = {};
|
2014-11-01 01:15:21 +01:00
|
|
|
}
|
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# add an event handler
|
2014-11-01 01:15:21 +01:00
|
|
|
sub register_handler {
|
2021-07-05 07:25:41 +02:00
|
|
|
my ($self, $event_name, $subref) = @_;
|
|
|
|
|
|
|
|
# get the package of the calling subroutine
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($package) = caller(0);
|
2021-07-05 07:25:41 +02:00
|
|
|
|
|
|
|
# internal identifier to find calling package's event handler
|
|
|
|
my $event_id = "$package-$event_name";
|
|
|
|
|
|
|
|
# add the event handler
|
|
|
|
$self->{handlers}->{$event_name}->{$event_id} = $subref;
|
|
|
|
|
|
|
|
# debugging
|
|
|
|
if ($self->{pbot}->{registry}->get_value('eventdispatcher', 'debug')) {
|
|
|
|
$self->{pbot}->{logger}->log("EventDispatcher: Add handler: $event_id\n");
|
|
|
|
}
|
2014-11-01 01:15:21 +01:00
|
|
|
}
|
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# remove an event handler
|
2020-02-07 21:12:55 +01:00
|
|
|
sub remove_handler {
|
2021-07-05 07:25:41 +02:00
|
|
|
my ($self, $event_name) = @_;
|
|
|
|
|
|
|
|
# get the package of the calling subroutine
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($package) = caller(0);
|
2021-07-05 07:25:41 +02:00
|
|
|
|
|
|
|
# internal identifier to find calling package's event handler
|
|
|
|
my $event_id = "$package-$event_name";
|
|
|
|
|
|
|
|
# remove the event handler
|
|
|
|
if (exists $self->{handlers}->{$event_name}) {
|
|
|
|
delete $self->{handlers}->{$event_name}->{$event_id};
|
|
|
|
|
|
|
|
# remove root event-name key if it has are no more handlers
|
|
|
|
if (not keys %{$self->{handlers}->{$event_name}}) {
|
|
|
|
delete $self->{handlers}->{$event_name};
|
2020-02-15 23:38:32 +01:00
|
|
|
}
|
2020-02-07 21:12:55 +01:00
|
|
|
}
|
2021-07-05 07:25:41 +02:00
|
|
|
|
|
|
|
# debugging
|
|
|
|
if ($self->{pbot}->{registry}->get_value('eventdispatcher', 'debug')) {
|
|
|
|
$self->{pbot}->{logger}->log("EventDispatcher: Remove handler: $event_id\n");
|
|
|
|
}
|
2020-02-07 21:12:55 +01:00
|
|
|
}
|
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# send an event to its handlers
|
2014-11-01 01:15:21 +01:00
|
|
|
sub dispatch_event {
|
2021-07-05 07:25:41 +02:00
|
|
|
my ($self, $event_name, $event_data) = @_;
|
2020-02-15 23:38:32 +01:00
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# debugging flag
|
|
|
|
my $debug = $self->{pbot}->{registry}->get_value('eventdispatcher', 'debug') // 0;
|
2020-02-15 23:38:32 +01:00
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# event handler return value
|
|
|
|
my $ret = undef;
|
2020-02-15 23:38:32 +01:00
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# if the event-name has handlers
|
|
|
|
if (exists $self->{handlers}->{$event_name}) {
|
|
|
|
# then dispatch the event to each one
|
|
|
|
foreach my $event_id (keys %{$self->{handlers}->{$event_name}}) {
|
|
|
|
# event handler subref
|
|
|
|
my $subref = $self->{handlers}->{$event_name}->{$event_id};
|
2020-02-15 23:38:32 +01:00
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# debugging
|
|
|
|
if ($debug) {
|
|
|
|
$self->{pbot}->{logger}->log("Dispatching $event_name to handler $event_id\n");
|
2020-02-15 23:38:32 +01:00
|
|
|
}
|
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# invoke event handler
|
|
|
|
eval { $ret = $subref->($event_name, $event_data) };
|
2020-02-15 23:38:32 +01:00
|
|
|
|
2021-07-05 07:25:41 +02:00
|
|
|
# check for error
|
|
|
|
if (my $error = $@) {
|
|
|
|
chomp $error;
|
|
|
|
$self->{pbot}->{logger}->log("Error in event handler: $error\n");
|
|
|
|
}
|
2020-02-15 23:38:32 +01:00
|
|
|
}
|
2015-09-07 07:17:07 +02:00
|
|
|
}
|
2021-07-05 07:25:41 +02:00
|
|
|
|
|
|
|
# return event handler result
|
2020-02-15 23:38:32 +01:00
|
|
|
return $ret;
|
2014-11-01 01:15:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
1;
|