Commit | Line | Data |
20038dd8 |
1 | package App::Clifton::Component; |
2 | |
3 | # define this up here to avoid uninitialised warnings |
4 | sub _debug_self { |
5 | my ($self, $args) = @_; |
6 | "${self}: ".join ', ', map "$_ => ".$args->{$_}, keys %$args; |
7 | } |
8 | |
327a4b1a |
9 | use Try::Tiny; |
20038dd8 |
10 | use Log::Contextual qw(:log); |
11 | use Moo; |
12 | |
d3a0b2ab |
13 | extends 'Moo::Object', 'IO::Async::Notifier'; |
14 | |
15 | # we're replacing Notifier's constructor so need to set up its default |
16 | has children => (is => 'bare', default => sub { [] }); |
20038dd8 |
17 | |
18 | sub 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 |
28 | sub _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 |
39 | around _replace_weakself => sub { |
40 | my ($orig, $self) = (shift, shift); |
41 | $self->_eval_cb($self->$orig(@_)); |
42 | }; |
43 | |
44 | around _capture_weakself => sub { |
45 | my ($orig, $self) = (shift, shift); |
46 | $self->_eval_cb($self->$orig(@_)); |
47 | }; |
48 | |
20038dd8 |
49 | sub _schedule { |
50 | my ($self, $code) = @_; |
21a18863 |
51 | $self->get_loop->later($self->_eval_cb($code)); |
52 | } |
53 | |
54 | sub _eval_cb { |
55 | my ($self, $code) = @_; |
56 | my $str = "$self"; |
57 | sub { |
38180dc8 |
58 | my @args = @_; |
59 | try { $code->(@args) } catch { log_error { "Exception from ${self}: $_" } } |
21a18863 |
60 | }; |
20038dd8 |
61 | } |
62 | |
63 | sub DESTROY { |
64 | my ($self) = @_; |
65 | log_debug { "Destroying "._debug_self($self, $self) }; |
66 | } |
67 | |
68 | 1; |