Permalink
Browse files

Initial implementation of promises, completing the callback types.

  • Loading branch information...
rcaputo committed Feb 13, 2010
1 parent bc6cecf commit 701249a5d5afa35ad9bcf0fe998dcdaf8aba4177
View
@@ -0,0 +1,57 @@
+#!/usr/bin/env perl
+
+# This example illustrates explicit a promise-like form of callback.
+# The promise acts as an event pipeline. Events emitted from the
+# object are available one at a time from a promise method.
+#
+# Promises require some form of asynchrony. This example is larger
+# than the others because it includes some custom mock-up code to
+# stand in for the rest of Reflex.
+
+# Reflex::Callbacks and the Reflex::Callback helper classes will
+# abstract callbacks to fulfill a number of goals. The goals are
+# detailed in docs/requirements.otl and summarized in
+# eg/eg-20-rcb-callback.pl
+
+use warnings;
+use strict;
+use lib qw(../lib);
+
+# Create a thing that will invoke callbacks.
+
+{
+ package PromiseThing;
+ use Moose;
+ extends 'Reflex::Object';
+ use Reflex::Timer;
+ use Reflex::Callbacks qw(gather_cb);
+
+ has ticker => (
+ isa => 'Reflex::Timer',
+ is => 'rw',
+ setup => { interval => 1, auto_repeat => 1 },
+ traits => [ 'Reflex::Trait::Observer' ],
+ );
+
+ has cb => ( is => 'rw', isa => 'Reflex::Callbacks' );
+
+ sub BUILD {
+ my ($self, $arg) = @_;
+ $self->cb(gather_cb($arg));
+ }
+
+ sub on_ticker_tick {
+ my $self = shift;
+ $self->cb()->send( event => {} );
+ }
+}
+
+use Reflex::Callbacks qw(cb_promise);
+use ExampleHelpers qw(eg_say);
+
+my $promise;
+my $pt = PromiseThing->new( cb_promise(\$promise) );
+
+while (my $event = $promise->wait()) {
+ eg_say("wait() returned an event (@$event)");
+}
@@ -10,8 +10,8 @@ has code_ref => (
);
sub deliver {
- my $self = shift;
- $self->code_ref()->(@_);
+ my ($self, $event, $arg) = @_;
+ $self->code_ref()->($arg);
}
@@ -17,9 +17,9 @@ has method_name => (
);
sub deliver {
- my $self = shift;
+ my ($self, $event, $arg) = @_;
my $method_name = $self->method_name();
- $self->object()->$method_name(@_);
+ $self->object()->$method_name($arg);
}
1;
@@ -0,0 +1,30 @@
+package Reflex::Callback::Promise;
+
+use Moose;
+extends 'Reflex::Callback';
+extends 'Reflex::Callbacks';
+
+has queue => (
+ is => 'rw',
+ isa => 'ArrayRef[ArrayRef]',
+ default => sub { [] },
+);
+
+# Delivering to a promise enqueues the message.
+sub send {
+ my ($self, $event, $arg) = @_;
+ push @{$self->queue()}, [ $event, $arg ];
+}
+
+sub wait {
+ my $self = shift;
+
+ my $queue = $self->queue();
+
+ # TODO - Probably should bail out if the event loop ends.
+ $POE::Kernel::poe_kernel->run_one_timeslice() while @$queue < 1;
+
+ return shift @$queue;
+}
+
+1;
View
@@ -18,8 +18,7 @@ use Reflex::Callback;
use Reflex::Callback::CodeRef;
#use Reflex::Callback::Emit; # For current Reflex compatibility
use Reflex::Callback::Method;
-#use Reflex::Callback::Promise;
-#use Reflex::Callback::Role;
+use Reflex::Callback::Promise;
use Exporter;
use base qw(Exporter);
@@ -122,7 +121,11 @@ sub cb_role {
}
sub cb_promise {
- die;
+ my $promise_ref = shift;
+
+ $$promise_ref = Reflex::Callback::Promise->new();
+
+ return( on_promise => $$promise_ref );
}
sub cb_coderef (&) {
@@ -141,6 +144,10 @@ sub gather_cb {
my $callback = $arg->{$_};
if (blessed $callback) {
+ if ($callback->isa('Reflex::Callback::Promise')) {
+ return $callback;
+ }
+
if ($callback->isa('Reflex::Callback')) {
$return{$_} = $callback;
next;
@@ -168,7 +175,7 @@ sub send {
$event =~ s/^(on_)?/on_/;
- $self->callback_map()->{$event}->deliver($arg);
+ $self->callback_map()->{$event}->deliver($event, $arg);
}
1;

0 comments on commit 701249a

Please sign in to comment.