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
|