File Coverage

blib/lib/Decl/EventContext.pm
Criterion Covered Total %
statement 30 46 65.2
branch 2 12 16.6
condition 0 9 0.0
subroutine 10 12 83.3
pod 6 6 100.0
total 48 85 56.4


line stmt bran cond sub pod time code
1            
2             package Decl::EventContext;
3            
4 12     12   79 use warnings;
  12         25  
  12         323  
5 12     12   63 use strict;
  12         24  
  12         318  
6 12     12   7005 use Decl::Semantics::Code;
  12         43  
  12         550  
7 12     12   394 use Text::ParseWords;
  12         22  
  12         1131  
8 12     12   68 use Data::Dumper;
  12         24  
  12         7302  
9            
10             =head1 NAME
11            
12             Decl::EventContext - base class implementing an event context in a declarative structure.
13            
14             =head1 VERSION
15            
16             Version 0.01
17            
18             =cut
19            
20             our $VERSION = '0.01';
21            
22            
23             =head1 SYNOPSIS
24            
25             Each node in a C structure that can respond to events can inherit from this class to get the proper machinery in place.
26            
27             =head2 event_context_init()
28            
29             Called during object creation to set up fields and such.
30            
31             =cut
32            
33             sub event_context_init {
34 27     27 1 87 my $self = shift;
35            
36             }
37            
38            
39            
40             =head2 event_context()
41            
42             Returns $self.
43            
44             =cut
45            
46 61     61 1 1258 sub event_context { $_[0] }
47            
48             =head2 register_event($event, $closure), do ($event)
49            
50             Registers and fires closures by name. This is the mechanism used by the 'on' tag in the core semantics.
51             This is actually a command-line interface; C runs the L C function on its
52             input, and gives the event closure any list elements that come after the first word.
53            
54             =cut
55            
56             sub register_event {
57 4     4 1 14 my ($self, $event, $closure) = @_;
58            
59 4         21 $self->{e}->{$event} = $closure;
60             }
61             sub do {
62 8     8 1 20 my ($self, $command) = @_;
63            
64 8         33 my @words = parse_line ('\s+', 0, $command);
65 8         470 my $event = shift @words;
66            
67 8         27 my $e = $self->{e}->{$event};
68 8 50       24 if ($e) {
69 8         15 my $r = eval { &$e($self, @words) };
  8         253  
70 8 50       28 print STDERR $@ if $@; # TODO: centralized error handling.
71 8         55 return $r;
72             }
73 0 0       0 if ($self->parent) {
74 0         0 my $cx = $self->parent->event_context();
75 0         0 return ($cx->do($command));
76             }
77             }
78            
79             =head2 make_event
80            
81             Given the name of a C event, finds the code referred to in its callable closure.
82            
83             TODO: this is not covered by unit testing!
84            
85             =cut
86            
87             sub make_event {
88 0     0 1 0 my ($self, $item) = @_;
89            
90             # Does the item have a body or children? Then use Decl::Semantics::Code to build code for it.
91             # Note: the flag $is_event registers the item as a named event, if it has a name.
92 0         0 Decl::Semantics::Code::build_payload ($item, 1);
93 0 0       0 return $item->{sub} if $item->{callable};
94            
95             # Does the item have an appropriately named 'on' handler? Then build that and use it.
96             # Search up the tree to inherit parents' 'on' handlers.
97 0         0 for (my $cursor = $item; $cursor; $cursor = $cursor->parent()) {
98 0         0 foreach ($cursor->nodes) {
99 0 0       0 $_->build if $_->is('on');
100 0 0 0     0 if ($_->is('on') and ($_->name eq $item->name) and $_->can('build') and my $handler = $_->build) {
      0        
      0        
101 0         0 $self->register_event($item->name, $handler);
102 0         0 return $handler;
103             }
104             }
105             }
106            
107             # If all else fails, build a stub.
108 0     0   0 my $closure = sub { print "event " . $item->name . "\n"; };
  0         0  
109 0         0 $self->register_event($item->name, $closure);
110 0         0 return $closure;
111             }
112            
113            
114             =head2 semantics()
115            
116             Each event context can return a semantic handler. For example, a form knows that its core semantics are "wx"; a Word document knows that
117             its core semantics are "ms-word", and so on. The semantic handlers are a good place to put common functionality for a given semantic
118             domain, so they're useful in code snippets in a given context.
119            
120             The default is to return the core semantics.
121            
122             =cut
123            
124             sub semantics {
125 20     20 1 50 my $self = shift;
126 20         74 $self->root()->semantic_handler('core');
127             }
128            
129            
130             =head1 AUTHOR
131            
132             Michael Roberts, C<< >>
133            
134             =head1 BUGS
135            
136             Please report any bugs or feature requests to C, or through
137             the web interface at L. I will be notified, and then you'll
138             automatically be notified of progress on your bug as I make changes.
139            
140             =head1 LICENSE AND COPYRIGHT
141            
142             Copyright 2010 Michael Roberts.
143            
144             This program is free software; you can redistribute it and/or modify it
145             under the terms of either: the GNU General Public License as published
146             by the Free Software Foundation; or the Artistic License.
147            
148             See http://dev.perl.org/licenses/ for more information.
149            
150             =cut
151            
152             1; # End of Decl::EventContext