basically operating chain code
[scpubgit/Clifton.git] / lib / App / Clifton / Component.pm
CommitLineData
20038dd8 1package App::Clifton::Component;
2
3# define this up here to avoid uninitialised warnings
4sub _debug_self {
5 my ($self, $args) = @_;
6 "${self}: ".join ', ', map "$_ => ".$args->{$_}, keys %$args;
7}
8
327a4b1a 9use Try::Tiny;
20038dd8 10use Log::Contextual qw(:log);
11use Moo;
12
d3a0b2ab 13extends 'Moo::Object', 'IO::Async::Notifier';
14
15# we're replacing Notifier's constructor so need to set up its default
16has children => (is => 'bare', default => sub { [] });
20038dd8 17
18sub BUILD {
19 my ($self, $args) = @_;
20 log_debug {
21 "Constructing "._debug_self($self, $args);
22 };
23 if (my $parent = $args->{parent_component}) {
24 $parent->add_child($self);
25 }
26}
27
20038dd8 28sub _new_child {
29 my ($self, $class, $args) = @_;
8b2081ac 30 if ($class->isa('App::Clifton::Component')) {
31 $class->new(%{$args||{}}, parent_component => $self);
32 } else {
33 my $new = $class->new(%{$args||{}});
34 $self->add_child($new);
35 $new;
36 }
20038dd8 37}
38
21a18863 39around _replace_weakself => sub {
40 my ($orig, $self) = (shift, shift);
41 $self->_eval_cb($self->$orig(@_));
42};
43
44around _capture_weakself => sub {
45 my ($orig, $self) = (shift, shift);
46 $self->_eval_cb($self->$orig(@_));
47};
48
20038dd8 49sub _schedule {
50 my ($self, $code) = @_;
21a18863 51 $self->get_loop->later($self->_eval_cb($code));
52}
53
54sub _eval_cb {
55 my ($self, $code) = @_;
56 my $str = "$self";
57 sub {
327a4b1a 58 try { $code->(@_) } catch { log_error { "Exception from ${self}: $_" } }
21a18863 59 };
20038dd8 60}
61
62sub DESTROY {
63 my ($self) = @_;
64 log_debug { "Destroying "._debug_self($self, $self) };
65}
66
671;