#!/usr/bin/perl
package Widget;
use Coro::State;
use Moose;
has 'results' => (is => 'rw');
has 'parent_state' => (is => 'rw');
has 'params' => (is => 'rw');
has 'state' => (is => 'rw', default => sub {
my $self = shift;
new Coro::State sub {
$self->main(@{$self->params})
}
});
sub yield {
my ($self, @results) = @_;
$self->results( [@results] );
print STDERR "About to transfer...\n";
$self->state->transfer($self->parent_state);
print STDERR "back from transfer.\n";
return @{$self->params};
}
sub exec {
my ($self, @params) = @_;
$self->params( \@params );
my $parent = new Coro::State;
$self->parent_state($parent);
print STDERR "Transferring to child.\n";
$parent->transfer($self->{state});
print STDERR "Back from child.\n";
#$self->parent_state(undef); # Kill circular reference!
return wantarray ? @{$self->results} : $self->results->[0];
}
sub main { die "You should have overriden this!\n" }
package CounterWidget;
use Moose;
extends 'Widget';
use Data::UUID;
has 'uuid' => (
is => 'ro',
isa => 'Str',
default => sub {
my $d = Data::UUID->new;
$d->to_string($d->create);
}
);
has 'request' => (is => 'rw');
has 'output' => (is => 'rw');
# Ask a question and keep asking until they answer. General purpose prompt.
sub prompt {
my ($self, $msg, @ops) = @_;
my $id = $self->uuid;
$self->request->print("$msg
");
for(my $i = 0; $i < scalar @ops; $i++) {
$self->request->print(qq{$ops[$i] });
}
# Subtle! Halt, wait for next request, and grab the 'option' param
$self->yield;
my $option = $self->request->param("$id-option");
return $option || $self->prompt($msg, @ops);
}
# Main is invoked when we get a new session
sub main {
my ($self) = @_;
# This keeps track of the number we're currently on
my $counter = 0;
# After we're done with that we enter a loop. Forever.
while(1) {
print STDERR "Displaying current count and waiting for instructions.\n";
my $action = $self->prompt("Count: $counter", "++", "--");
print STDERR "Got '$action' back from the user.\n";
if($action eq '--' && $counter == 0) {
my $choice = $self->prompt("Do you really want to GO NEGATIVE?", "Yes", "No");
$action = '' if $choice eq 'No';
}
$counter++ if $action eq '++';
$counter-- if $action eq '--';
if($counter == 42) {
$self->request->print(q{