#!/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{

The Answer to Life, The Universe, and Everything

}); } } } # sub main { # my ($self, $request) = @_; # my $counter = 0; # print "In 'a' ($p - $thing)\n"; # ($p) = $self->yield(42); # print "... more in a ...\n"; # $self->yield(7); # print "... last of a.\n"; # $self->yield; # } package main; use Continuity; Continuity->new( port => 8080 )->loop; sub main { my ($request) = @_; my $child = CounterWidget->new(request => $request); $child->exec; $request->next; $child->exec; $request->next; $child->exec; }