Re: Announce: Net:GPSD3::POE

2011-04-05 Thread Rocco Caputo
On Apr 5, 2011, at 12:45, Michael R. Davis wrote:

> POE Folks,
> I've not used POE before but have plans to use a POE capability shortly.  
> Last night I added a POE::Session wrapper in my Net::GPSD3 (v0.15) package 
> but I'm not entirely sure it's using best practices.
> 
> http://search.cpan.org/dist/Net-GPSD3/lib/Net/GPSD3/POE.pm
> 
> Specifically, should I use a more specific HEAP key than "wheel".
> 
> $heap->{"wheel"}=...

You may call it whatever you like.  More specific names are good because they 
help make the code more readable.

> I've also not seen any best practices about passing the parent object around 
> in HEAP.
> 
> $heap->{"gpsd"}=$self;

Using object_states instead of inline_states makes sense in your case.  All 
your callbacks are essentially object methods.  Here's an untested rewrite of 
the guts of Net::GPSD3::POE.  I'm sure it's not quite functional, but I hope 
it's a good example.

### Called as a plain method, not a POE callback.
# @_ is $self and whatever the caller provides.

# In this case, object_states are being used because the callbacks are
# object methods.  The $_[OBJECT] parameter will be populated with the
# $self for the callback.  This eliminates the need to store $self
# explicitly.

sub start_session {
  my $self = shift;#ISA Net::GPSD::POE

  # Don't start another one.
  return if $self->{sid};

  $self->{sid} = POE::Session->create(
object_states => [
  $self => {
_start  => '_handle_poe_start',
input_event => '_handle_input_event',
shutdown=> '_handle_poe_shutdown',
  },
]
  )->ID();
}

# POE callback.  Start the session's resources.  We're skipping
# $_[HEAP] altogether because the original code only shows need for
# one I/O watcher per object.  We can use a single name for the
# ReadWrite resource ("io").  If we were managing multiple wheels,
# then we might create a hash of them keyed on wheel ID.

sub _handle_poe_start {
  my $self = $_[OBJECT];

  $self->{io} = POE::Wheel::ReadWrite->new(
InputEvent => "input_event",
Handle => $self->socket(),
Filter => POE::Filter::Line->new(
  InputLiteral  => "\r\n",
  OutputLiteral => "\n",
),
  );

  $self->{io}->put(qq(?WATCH={"enable":true,"json":true};));
},

### Called as a plain method, not a POE callback.
# @_ is $self and whatever the caller provides.
#
# This method asks the session to clean up and stop.  POE's session
# encapsulation makes it difficult (but not impossible---this is Perl)
# to release another session's resources.

sub stop_session {
  my $self = shift;

  # Don't re-stop a dead one.
  return unless $self->{sid};

  $poe_kernel->call($self->{sid}, "shutdown");
  $self->{sid} = undef;
}

# POE callback.  Deletes the wheel from within the context of the
# session that owns it.

sub _handle_poe_shutdown {
  my $self = $_[OBJECT];
  delete $self->{io};
}

# POE callback.  Handle input.

sub _handle_input_event {
  my ($self, $line) = @_[OBJECT, ARG0];

  my @handler = $self->handlers();
  push @handler, \&Net::GPSD3::default_handler unless @handler;

  my $object = $self->constructor($self->decode($line), string => $line);
  foreach my $handler (@handler) {
$handler->($object);
  }

  $self->cache($object);
}

-- 
Rocco Caputo 



Announce: Net:GPSD3::POE

2011-04-05 Thread Michael R. Davis
POE Folks,
I've not used POE before but have plans to use a POE capability shortly.  Last 
night I added a POE::Session wrapper in my Net::GPSD3 (v0.15) package but I'm 
not entirely sure it's using best practices.

http://search.cpan.org/dist/Net-GPSD3/lib/Net/GPSD3/POE.pm

Specifically, should I use a more specific HEAP key than "wheel".

$heap->{"wheel"}=...

I've also not seen any best practices about passing the parent object around in 
HEAP.

$heap->{"gpsd"}=$self;

Here's a one liner if any one cares to test it out.  Any feedback on style or 
best practices would be welcome.

perl -MPOE -MNet::GPSD3::POE -e 
'Net::GPSD3::POE->new(host=>shift)->session;POE::Kernel->run;' gpsd.mainframe.cx

Thanks,
Mike

mrdvt92