Commit 701249a5d5afa35ad9bcf0fe998dcdaf8aba4177

Initial implementation of promises, completing the callback types.
  
1#!/usr/bin/env perl
2
3# This example illustrates explicit a promise-like form of callback.
4# The promise acts as an event pipeline. Events emitted from the
5# object are available one at a time from a promise method.
6#
7# Promises require some form of asynchrony. This example is larger
8# than the others because it includes some custom mock-up code to
9# stand in for the rest of Reflex.
10
11# Reflex::Callbacks and the Reflex::Callback helper classes will
12# abstract callbacks to fulfill a number of goals. The goals are
13# detailed in docs/requirements.otl and summarized in
14# eg/eg-20-rcb-callback.pl
15
16use warnings;
17use strict;
18use lib qw(../lib);
19
20# Create a thing that will invoke callbacks.
21
22{
23 package PromiseThing;
24 use Moose;
25 extends 'Reflex::Object';
26 use Reflex::Timer;
27 use Reflex::Callbacks qw(gather_cb);
28
29 has ticker => (
30 isa => 'Reflex::Timer',
31 is => 'rw',
32 setup => { interval => 1, auto_repeat => 1 },
33 traits => [ 'Reflex::Trait::Observer' ],
34 );
35
36 has cb => ( is => 'rw', isa => 'Reflex::Callbacks' );
37
38 sub BUILD {
39 my ($self, $arg) = @_;
40 $self->cb(gather_cb($arg));
41 }
42
43 sub on_ticker_tick {
44 my $self = shift;
45 $self->cb()->send( event => {} );
46 }
47}
48
49use Reflex::Callbacks qw(cb_promise);
50use ExampleHelpers qw(eg_say);
51
52my $promise;
53my $pt = PromiseThing->new( cb_promise(\$promise) );
54
55while (my $event = $promise->wait()) {
56 eg_say("wait() returned an event (@$event)");
57}
  
1010);
1111
1212sub deliver {
13 my $self = shift;
14 $self->code_ref()->(@_);
13 my ($self, $event, $arg) = @_;
14 $self->code_ref()->($arg);
1515}
1616
1717
  
1717);
1818
1919sub deliver {
20 my $self = shift;
20 my ($self, $event, $arg) = @_;
2121 my $method_name = $self->method_name();
22 $self->object()->$method_name(@_);
22 $self->object()->$method_name($arg);
2323}
2424
25251;
  
1package Reflex::Callback::Promise;
2
3use Moose;
4extends 'Reflex::Callback';
5extends 'Reflex::Callbacks';
6
7has queue => (
8 is => 'rw',
9 isa => 'ArrayRef[ArrayRef]',
10 default => sub { [] },
11);
12
13# Delivering to a promise enqueues the message.
14sub send {
15 my ($self, $event, $arg) = @_;
16 push @{$self->queue()}, [ $event, $arg ];
17}
18
19sub wait {
20 my $self = shift;
21
22 my $queue = $self->queue();
23
24 # TODO - Probably should bail out if the event loop ends.
25 $POE::Kernel::poe_kernel->run_one_timeslice() while @$queue < 1;
26
27 return shift @$queue;
28}
29
301;
  
1818use Reflex::Callback::CodeRef;
1919#use Reflex::Callback::Emit; # For current Reflex compatibility
2020use Reflex::Callback::Method;
21#use Reflex::Callback::Promise;
22#use Reflex::Callback::Role;
21use Reflex::Callback::Promise;
2322
2423use Exporter;
2524use base qw(Exporter);
121121}
122122
123123sub cb_promise {
124 die;
124 my $promise_ref = shift;
125
126 $$promise_ref = Reflex::Callback::Promise->new();
127
128 return( on_promise => $$promise_ref );
125129}
126130
127131sub cb_coderef (&) {
144144 my $callback = $arg->{$_};
145145
146146 if (blessed $callback) {
147 if ($callback->isa('Reflex::Callback::Promise')) {
148 return $callback;
149 }
150
147151 if ($callback->isa('Reflex::Callback')) {
148152 $return{$_} = $callback;
149153 next;
175175
176176 $event =~ s/^(on_)?/on_/;
177177
178 $self->callback_map()->{$event}->deliver($arg);
178 $self->callback_map()->{$event}->deliver($event, $arg);
179179}
180180
1811811;