Changeset 65

Show
Ignore:
Timestamp:
05/04/08 02:10:55 (8 months ago)
Author:
scott
Message:

Finally, after hours and hours of futzing with it, I think I got
Curses::UI::POE reasonably refactored.

There is a bunch of commented out code that looks like it can be jettisoned,
and I can't seem to find out the purpose of this "callbackmodalfocus" override,
it seems nothing of this nature exists in Curses::UI.

Fixed the tests, whoot.

Location:
trunk/Curses-UI-POE
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/Curses-UI-POE/POE.pm

    r64 r65  
    2828 
    2929use constant TOP => -1; 
    30 use constant PARENT => -2; 
    31 use constant ROOT => 0; 
    3230 
    3331sub import { 
     
    4745sub new { 
    4846    my ($type, %options) = @_; 
    49     my $self = bless &Curses::UI::new(@_), $type; 
    50  
    51     $self->{modal_objects}      = \@modal_objects; 
    52     $self->{modal_callbacks}    = \@modal_callbacks; 
     47    my $self = &Curses::UI::new(@_); 
     48#   my $self = bless Curses::UI->new, $type; 
     49#   my $self = bless &Curses::UI::new(@_), $type; 
     50 
     51    # I have to do this here, because if our first order of business is a 
     52    # dialog then the _start event will be too late.  This self reference is 
     53    # just so we can stack and peel onto the list of modal objects, and get to 
     54    # ourselves when we reach the top. 
     55    push @modal_objects, $self; 
     56 
    5357    $self->{options}            = \%options; 
     58    $self->{__start_callback}   = delete $options{inline_states}{_start}; 
     59 
     60    delete $options{package_states}{_start}; 
    5461 
    5562    # Default so we don't get a warning about using undef as an array. 
    5663    $options{object_states}   ||= []; 
    57     $options{package_states}  ||= []; 
     64    $options{inline_states}   ||= {}; 
    5865    $options{options}         ||= {}; 
    5966 
     
    6269          args           => $options{args}, 
    6370          inline_states  => $options{inline_states}, 
    64           package_states => $options{package_states}, 
    6571 
    6672          object_states  => [ 
     
    7379 
    7480    # Copy the no-output option 
    75     $self->{-no_output} = $options{no_output} || 0; 
    76  
     81    $self->{-no_output} = $options{-no_output} || 0; 
     82 
     83    return $self; 
     84} 
     85 
     86sub _start { 
     87    my ($self, $kernel) = @_[ OBJECT, KERNEL ]; 
     88 
     89    $kernel->select(\*STDIN, "keyin"); 
     90 
     91    # Turn blocking back on for STDIN.  Some Curses 
     92    # implementations don't deal well with non-blocking STDIN. 
     93    my $flags = fcntl STDIN, F_GETFL, 0 or die $!; 
     94    fcntl STDIN, F_SETFL, $flags & ~O_NONBLOCK or die $!; 
     95 
     96    # If we're in a dialog, then the TOP modal object is more appropriate than 
     97    # $self, although if we're not in a dialog $self is what this actually is. 
     98    set_read_timeout($modal_objects[TOP]); 
     99 
     100    # Unmask... 
     101    $self->{__start_callback}(@_) 
     102        if defined $self->{__start_callback}; 
     103} 
     104 
     105sub _clear_modal_callback { 
     106    my ($self) = @_; 
     107 
     108    my $top     = pop @modal_objects; 
     109 
     110    # Reset focus 
     111    $top->{-focus} = 0; 
     112 
     113    # Dispatch callback. 
     114    my $args    = pop @modal_callbacks; 
     115    my $sub     = shift @$args; 
     116    &{$sub}(@$args); 
     117} 
     118 
     119sub keyin { 
     120    my ($self, $kernel) = @_[ OBJECT, KERNEL ]; 
     121 
     122    unless ($#modal_objects) { 
     123        $self->do_one_event; 
     124    } 
     125    else { 
     126        # dispatch the event to the top-most modal object, or the root. 
     127        $self->do_one_event($modal_objects[TOP]); 
     128 
     129# I didn't originally do this here, I'm not quite sure what I'm up to... 
     130# 
     131#   # If this is a callback modal focus widget, and we lost modal focus, 
     132#   # execute the callback an clear the level in the stack. 
     133#       $self->_clear_modal_callback  
     134#           unless $modal_objects[TOP]->{-has_modal_focus}; 
     135 
     136# This other wierdness seems unnecessary. 
     137#       $top_object->root->do_one_event($top_object); 
     138    } 
     139 
     140# This was a hack to make sure to pick up the extra events when things got out 
     141# of sync.  I'm not sure if I need it.  But let's try getting C::U::P working 
     142# first. 
     143#   if (my $key = $self->get_key(0)) { 
     144#       $self->feedkey($key) unless $key eq "-1"; 
     145#       $self->do_one_event; 
     146#   } 
     147 
     148    # Set the root cursor mode 
     149    unless ($self->{-no_output}) { 
     150        Curses::curs_set($self->{-cursor_mode}); 
     151    } 
     152} 
     153 
     154sub timer { 
     155    my ($self) = @_; 
     156 
     157    # dispatch the event to the top-most modal object, or the root. 
     158    my $top_object = $modal_objects[TOP]; 
     159 
     160    $top_object->do_timer; 
     161 
     162    # Set the root cursor mode. 
     163    unless ($self->{-no_output}) { 
     164        Curses::curs_set($self->{-cursor_mode}); 
     165    } 
     166 
     167    set_read_timeout($top_object); 
     168 
     169# Looks like older versions didn't support callbackmodalfocus, whatever that 
     170# is. 
     171# I'm not sure what the deal is with the callbackmodalfocus shit... 
     172#   $self->_clear_modal_callback unless $top_object->{-has_modal_focus}; 
     173} 
     174 
     175sub shutdown { 
     176    my ($kernel) = $_[ KERNEL ]; 
     177 
     178    # Unselect stdin 
     179    $kernel->select(\*STDIN); 
     180} 
     181 
     182sub mainloop { 
     183    my ($this) = @_; 
     184 
     185    unless ($this->{-no_output}) { 
     186        $this->focus(undef, 1); 
     187        $this->draw; 
     188 
     189        Curses::doupdate; 
     190    } 
     191 
     192    POE::Kernel->run; 
     193} 
     194 
     195sub set_read_timeout { 
     196    my $this = shift;  
     197 
     198    my $new_timeout = -1; 
     199 
     200    while (my ($id, $config) = each %{$this->{-timers}}) { 
     201        next unless $config->{-enabled}; 
     202 
     203        $new_timeout = $config->{-time} 
     204        unless $new_timeout != -1 and 
     205            $new_timeout < $config->{-time}; 
     206    } 
     207 
     208    $poe_kernel->delay(timer => $new_timeout) if $new_timeout >= 0; 
     209 
     210    # Force the read timeout to be 0, so Curses::UI polls. 
     211    $this->{-read_timeout} = 0; 
     212 
     213    return $this; 
     214} 
     215 
     216{ 
    77217    no warnings "redefine"; 
     218    # None of this work's if POE isn't running... 
    78219    # Redefine the callbackmodalfocus to ensure that callbacks and objects make 
    79220    # it on to our own private stack. 
     
    128269        return $this; 
    129270    } 
    130  
    131     return $self; 
    132 } 
    133  
    134 sub _start { 
    135     my ($self, $kernel) = @_[ OBJECT, KERNEL ]; 
    136  
    137     $kernel->select(\*STDIN, "-keyin"); 
    138  
    139     # Turn blocking back on for STDIN.  Some Curses 
    140     # implementations don't deal well with non-blocking STDIN. 
    141     my $flags = fcntl STDIN, F_GETFL, 0 or die $!; 
    142     fcntl STDIN, F_SETFL, $flags & ~O_NONBLOCK or die $!; 
    143  
    144     # This self reference is just so we can stack and peel onto the list of 
    145     # modal objects, and get to ourselves when we reach the top. 
    146     $self->{modal_objects} = [ $self ]; 
    147  
    148     set_read_timeout($self); 
    149  
    150     # Unmask... 
    151     $self->{options}{inline_states}{_start}(@_) 
    152         if (defined $self->{options}->{inline_states} && 
    153             defined $self->{options}{inline_states}{_start}); 
    154 } 
    155  
    156 sub _clear_modal_callback { 
    157     my ($self) = @_; 
    158  
    159     my $top_object = pop @{ $self->{_modal_objects} }; 
    160  
    161     # Reset focus 
    162     $top_object->{-focus} = 0; 
    163  
    164     # Dispatch callback. 
    165     my @args = @{ pop @{ $self->{_modal_callbacks} } }; 
    166     my ($sub) = shift @args; 
    167     &{$sub}(@args); 
    168 } 
    169  
    170 sub keyin { 
    171     my ($self, $kernel) = @_[ OBJECT, KERNEL ]; 
    172  
    173     my $top_object = $self->{modal_objects}->[TOP]; 
    174     # dispatch the event to the top-most modal object, or the root. 
    175     $top_object->root->do_one_event($top_object); 
    176  
    177     # Set the root cursor mode 
    178     Curses::curs_set($self->{-cursor_mode}); 
    179  
    180     _clear_modal_callback($self) unless $top_object->{-has_modal_focus}; 
    181 } 
    182  
    183 sub timer { 
    184     my ($self) = @_; 
    185  
    186     my $top_object = $self->{modal_objects}->[TOP]; 
    187     # dispatch the event to the top-most modal object, or the root. 
    188     $top_object->do_timer; 
    189  
    190     # Set the root cursor mode. 
    191     Curses::curs_set($self->{-cursor_mode}); 
    192  
    193     set_read_timeout($top_object); 
    194  
    195     _clear_modal_callback($self) unless $top_object->{-has_modal_focus}; 
    196 } 
    197  
    198 sub shutdown { 
    199     my ($kernel) = $_[ KERNEL ]; 
    200  
    201     # Unselect stdin 
    202     $kernel->select(\*STDIN); 
    203 } 
    204  
    205 sub MainLoop {  
    206     # When does this even happen!? 
    207     # I need more comments! 
    208     my $root = $Curses::UI::rootobject; 
    209     die "MainLoop: Must create a curses UI object first." unless defined $root; 
    210  
    211     # If some how we didn't get our object into the rootobject...redefine that 
    212     # bad boy. 
    213     if (ref $root ne __PACKAGE__) { 
    214         $root = bless $root, __PACKAGE__; 
    215         $Curses::UI::rootobject = $root; 
    216     } 
    217  
    218     $root->mainloop; 
    219 } 
    220  
    221 sub mainloop { 
    222     my ($this) = @_; 
    223  
    224     $this->focus(undef, 1); 
    225     $this->draw; 
    226  
    227     Curses::doupdate; 
    228  
    229     run POE::Kernel; 
    230 } 
    231  
    232 sub set_read_timeout { 
    233     my $this = shift;  
    234  
    235     my $new_timeout = -1; 
    236  
    237     while (my ($id, $config) = each %{$this->{-timers}}) { 
    238         next unless $config->{-enabled}; 
    239  
    240         $new_timeout = $config->{-time} 
    241         unless $new_timeout != -1 and 
    242             $new_timeout < $config->{-time}; 
    243     } 
    244  
    245     $poe_kernel->delay(-timer => $new_timeout) if $new_timeout >= 0; 
    246  
    247     # Force the read timeout to be 0, so Curses::UI polls. 
    248     $this->{-read_timeout} = 0; 
    249  
    250     return $this; 
    251271} 
    252272 
  • trunk/Curses-UI-POE/examples/irc_client

    r13 r65  
    1313$Curses = new Curses::UI::POE inline_states => { 
    1414    _start => sub { 
    15         POE::Component::IRC->new("IRC"); 
     15        $_[HEAP]->{irc} = 
     16            POE::Component::IRC->spawn(); 
    1617 
    1718        # Even if we dont use all events, it shouldn't create an error since 
     
    2122        # efficiency *really* isn't a big issue here. 
    2223 
    23         $_[KERNEL]->post(IRC => register => "all"); 
     24        $_[KERNEL]->yield(register => "all"); 
    2425 
    2526    }, 
    2627 
    2728    irc_connected => sub { 
    28         printf "Connected to %s", $_[ARG0]; 
     29        printf "Connected to %s", $_[SENDER]->get_heap->server_name(); 
    2930    }, 
    3031 
     
    4041        my ($nick) = ($_[ARG1] =~ m/^(\S+)/); 
    4142 
    42         $_[KERNEL]->post( IRC => nick => sprintf "%s_", $nick ); 
     43        $_[KERNEL]->yield( nick => sprintf "%s_", $nick ); 
    4344 
    4445        printf "--- %s in use, trying %s_", $nick, $nick; 
     
    112113use warnings FATAL => "all"; 
    113114 
     115use POE; 
    114116use POSIX qw( strftime cuserid ); 
    115117use Curses; 
     
    270272            printf "Sending Connect EVENT for %s:%s", $server, $port; 
    271273 
    272             POE::Kernel->post 
    273                 ( IRC => connect => { 
     274            $_[KERNEL]->yield 
     275                ( connect => { 
    274276                    Nick        => cuserid, 
    275277                    Server      => $server, 
     
    289291            else { 
    290292                $Channel{$Join} = 1; 
    291                 POE::Kernel->post( IRC => join => $Join ); 
     293                $_[KERNEL]->yield( join => $Join ); 
    292294                $CurrentChannel = $Join; 
    293295            } 
    294296        }, 
    295297 
    296         nick => sub { POE::Kernel->post( IRC => nick => $_[1] ) }, 
    297         kick => sub { POE::Kernel->post( IRC => kick => $_[1..$#_] ) }, 
    298         msg  => sub { POE::Kernel->post( IRC => privmsg => $_[1..$#_] ) }, 
     298        nick => sub { $_[KERNEL]->yield( nick => $_[1] ) }, 
     299        kick => sub { $_[KERNEL]->yield( kick => $_[1..$#_] ) }, 
     300        msg  => sub { $_[KERNEL]->yield( privmsg => $_[1..$#_] ) }, 
    299301         
    300302        quote => sub { 
    301             POE::Kernel->post( IRC => sl => join " ", @_[1..$#_] ); 
     303            $_[KERNEL]->yield( sl => join " ", @_[1..$#_] ); 
    302304        }, 
    303305 
    304306        quit => sub { 
    305             POE::Kernel->post( IRC => quit => join " ", @_[1..$#_] ); 
     307            $_[KERNEL]->yield( quit => join " ", @_[1..$#_] ); 
    306308 
    307309            print "Have a nice day"; 
     
    330332        else { 
    331333            if ($CurrentChannel) { 
    332                 POE::Kernel->post( IRC => privmsg => $CurrentChannel, $line ); 
     334                $_[KERNEL]->yield( privmsg => $CurrentChannel, $line ); 
    333335                print "> $line"; 
    334336            } 
  • trunk/Curses-UI-POE/t/session.t

    r64 r65  
    88use Test::Simple tests => 4; 
    99 
    10 # Trick Curses... 
    1110BEGIN { 
    1211    open OLDERR, ">&", \*STDERR; 
    1312    open OLDOUT, ">&", \*STDOUT; 
     13 
    1414    open STDOUT, ">>", "/dev/null"; 
    1515    open STDERR, ">>", "/dev/null"; 
    1616} 
    1717 
    18 #sub POE::Kernel::ASSERT_DEFAULT () { 1 } 
    1918use Curses::UI::POE; 
    2019 
     
    3938        open STDERR, ">>", "/dev/null"; 
    4039    }, 
    41 }; 
     40}, -no_output => 1; # Lotta good -no_output does.. 
    4241 
    4342$cui->mainloop;