towers are constructable
[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
9use Log::Contextual qw(:log);
10use Moo;
11
d3a0b2ab 12extends 'Moo::Object', 'IO::Async::Notifier';
13
14# we're replacing Notifier's constructor so need to set up its default
15has children => (is => 'bare', default => sub { [] });
20038dd8 16
17sub BUILD {
18 my ($self, $args) = @_;
19 log_debug {
20 "Constructing "._debug_self($self, $args);
21 };
22 if (my $parent = $args->{parent_component}) {
23 $parent->add_child($self);
24 }
25}
26
20038dd8 27sub _new_child {
28 my ($self, $class, $args) = @_;
8b2081ac 29 if ($class->isa('App::Clifton::Component')) {
30 $class->new(%{$args||{}}, parent_component => $self);
31 } else {
32 my $new = $class->new(%{$args||{}});
33 $self->add_child($new);
34 $new;
35 }
20038dd8 36}
37
21a18863 38around _replace_weakself => sub {
39 my ($orig, $self) = (shift, shift);
40 $self->_eval_cb($self->$orig(@_));
41};
42
43around _capture_weakself => sub {
44 my ($orig, $self) = (shift, shift);
45 $self->_eval_cb($self->$orig(@_));
46};
47
20038dd8 48sub _schedule {
49 my ($self, $code) = @_;
21a18863 50 $self->get_loop->later($self->_eval_cb($code));
51}
52
53sub _eval_cb {
54 my ($self, $code) = @_;
55 my $str = "$self";
56 sub {
57 local $@;
58 eval { $code->(@_); 1 }
59 or log_error { "Exception from ${self}: $@" };
60 };
20038dd8 61}
62
63sub DESTROY {
64 my ($self) = @_;
65 log_debug { "Destroying "._debug_self($self, $self) };
66}
67
681;