File Coverage

blib/lib/WWW/Slides/Controller.pm
Criterion Covered Total %
statement 69 72 95.8
branch 13 18 72.2
condition n/a
subroutine 18 18 100.0
pod 9 10 90.0
total 109 118 92.3


line stmt bran cond sub pod time code
1             package WWW::Slides::Controller;
2             {
3              
4 28     28   164617 use version; our $VERSION = qv('0.0.9');
  28         11064  
  28         194  
5              
6 28     28   2654 use warnings;
  28         59  
  28         777  
7 28     28   144 use strict;
  28         61  
  28         942  
8 28     28   153 use Carp;
  28         48  
  28         2009  
9 28     28   8765 use English qw( -no_match_vars );
  28         31404  
  28         185  
10              
11 28     28   23214 use Object::InsideOut;
  28         243838  
  28         383  
12              
13             # Module implementation here
14             my @selector : Field # For selector handling...
15             : Set(Name => 'set_selector') : Get(Name => 'selector');
16             my @buffer : Field : Std(Name => 'buffer', Private => 1);
17              
18             sub balk_for_not_overriding : Private {
19 4         160 my $self = shift;
20 4         5 my ($name) = @_;
21 4 100       12 $name = '' unless defined $name;
22 4         46 croak "$name: this method must be overridden";
23 28     28   5997 } ## end sub balk_for_not_overriding :
  28         57  
  28         191  
24              
25             my %init_args : InitArgs = ( selector => '' );
26             sub _init : Init {
27 28         181555 my ($self, $args) = @_;
28 28         907 $self->set_buffer('');
29 28 100       2244 $self->set_selector($args->{selector}) if $args->{selector};
30 27         141 return;
31 28     28   9817 }
  28         91  
  28         158  
32 1     1 1 603 sub is_alive { shift->balk_for_not_overriding('is_alive'); }
33 2     2 1 293 sub shut_down { return }
34              
35             # set_selector() auto-implemented
36             # selector() auto-implemented
37 6     6 1 1170 sub release_selector { return; }
38              
39 1     1 1 1128 sub owns { balk_for_not_overriding('owns'); }
40 1     1 0 1091 sub get_input_chunk { balk_for_not_overriding('get_input_chunk'); }
41 1     1 1 1044 sub output { balk_for_not_overriding('output'); }
42              
43             #-------------- COMMAND EXECUTION FRAMEWORK -------------------------
44             my %commands = (
45             'nothing' => sub {
46             print "nothing\n";
47             },
48              
49             # Slide transition management
50             'first' => sub {
51             my $self = shift;
52             my ($command, $talk) = @_;
53             $talk->show_first(@{$command->{target}});
54             $self->output("200 OK\n");
55             },
56             'last' => sub {
57             my $self = shift;
58             my ($command, $talk) = @_;
59             $talk->show_last(@{$command->{target}});
60             $self->output("200 OK\n");
61             },
62             'next' => sub {
63             my $self = shift;
64             my ($command, $talk) = @_;
65             $talk->show_next(@{$command->{target}});
66             $self->output("200 OK\n");
67             },
68             'previous' => sub {
69             my $self = shift;
70             my ($command, $talk) = @_;
71             $talk->show_previous(@{$command->{target}});
72             $self->output("200 OK\n");
73             },
74             'show' => sub {
75             my ($self, $command, $talk) = @_;
76             $talk->show($command->{slide}, @{$command->{target}});
77             $self->output("200 OK\n");
78             },
79              
80             # Attendee management
81             'book' => sub {
82             my $self = shift;
83             my ($command, $talk) = @_;
84             $talk->book($command->{code});
85             $self->output("200 OK\n");
86             },
87             'attach' => sub {
88             my ($self, $command, $talk) = @_;
89             $talk->attach(@{$command->{target}});
90             $self->output("200 OK\n");
91             },
92             'detach' => sub {
93             my ($self, $command, $talk) = @_;
94             $talk->detach(@{$command->{target}});
95             $self->output("200 OK\n");
96             },
97             'clamp' => sub {
98             my ($self, $command, $talk) = @_;
99             $talk->clamp();
100             $self->output("200 OK\n");
101             },
102             'loose' => sub {
103             my ($self, $command, $talk) = @_;
104             $talk->loose();
105             $self->output("200 OK\n");
106             },
107              
108             # Requests from far
109             'get_current' => sub {
110             my ($self, $command, $talk) = @_;
111             my $current = $talk->get_current();
112             my $total = $talk->get_total();
113             $self->output("200 OK current=$current;total=$total\n");
114             },
115              
116             'get_attendees' => sub {
117             my ($self, $command, $talk) = @_;
118             my $output = join "\n", map {
119             my @elements;
120             while (my ($k, $v) = each %$_) {
121             $v = '' unless defined $v;
122             push @elements, "$k=$v";
123             }
124             join ';', @elements;
125             } $talk->get_attendees_details();
126             $self->output("200 OK\n$output\n");
127             },
128              
129             # Ehr... quit
130             'quit' => sub {
131             my $self = shift;
132             my ($command, $talk) = @_;
133             $talk->quit();
134             $self->output("200 OK\n");
135             },
136             );
137              
138             sub execute_commands {
139 42     42 1 87915 my $self = shift;
140 42         61 my ($fh, $talk) = @_;
141              
142             # Execute each command
143 42         171 $self->execute_command($_, $talk) for $self->get_commands();
144              
145 42         216 return;
146             } ## end sub execute_commands
147              
148             sub get_commands {
149 42     42 1 53 my $self = shift;
150              
151             # Get new stuff from filehandle, extract full commands
152 42 50       113 if (defined(my $newstuff = $self->get_input_chunk())) {
153              
154             # Get new stuff and append to current buffer
155 42         1796 my $buffer = $self->get_buffer() . $newstuff;
156              
157 42         2716 my @full_lines = split /\n/, $buffer;
158              
159             # Set buffer with the incomplete last line, if any
160 42         52 my $remaining = '';
161 42 50       124 $remaining = pop @full_lines unless substr($buffer, -1) eq "\n";
162 42         1036 $self->set_buffer($remaining);
163              
164             # Return parsed commands
165 42         2427 return map { $self->parse_command($_) } @full_lines;
  42         154  
166             } ## end if (defined(my $newstuff...
167              
168             # Otherwise, there's no more input for us, we shut_down and leave
169 0         0 $self->shut_down();
170 0         0 return;
171             } ## end sub get_commands
172              
173             sub execute_command {
174 42     42 1 52 my $self = shift;
175 42         57 my ($command, $talk) = @_;
176              
177 42         65 my $cmd = $command->{command};
178 42 50       102 $cmd = '' unless defined $cmd;
179 42 100       96 if (exists $commands{$cmd}) {
180 40         50 eval { $commands{$cmd}->($self, $command, $talk); };
  40         112  
181 40 50       775 if ($EVAL_ERROR) {
182 0         0 $self->output("500 error executing '$cmd': $EVAL_ERROR\n");
183             }
184             } ## end if (exists $commands{$cmd...
185             else {
186 2         11 $self->output("500 command '$cmd' not supported\n");
187             }
188              
189 42         135 return;
190             } ## end sub execute_command
191              
192             sub parse_command {
193 42     42 1 54 my $self = shift;
194 42         49 my ($command_string) = @_;
195 76         162 my $command = {
196             map {
197 42         167 my ($k, $v) = split /=/;
198 76 50       145 $v = '' unless defined $v;
199 76         227 $k => $v;
200             } split /[\s;]+/,
201             $command_string
202             };
203 42 100       192 $command->{target} =
204             defined($command->{target})
205             ? [split /,/, $command->{target}]
206             : [];
207 42         295 return $command;
208             } ## end sub parse_command
209             }
210              
211             1; # Magic true value required at end of module
212             __END__