line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Valence; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
30656
|
use common::sense; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
11
|
|
4
|
|
|
|
|
|
|
|
5
|
2
|
|
|
2
|
|
858
|
use AnyEvent; |
|
2
|
|
|
|
|
3405
|
|
|
2
|
|
|
|
|
36
|
|
6
|
2
|
|
|
2
|
|
961
|
use AnyEvent::Util; |
|
2
|
|
|
|
|
16294
|
|
|
2
|
|
|
|
|
166
|
|
7
|
2
|
|
|
2
|
|
1255
|
use AnyEvent::Handle; |
|
2
|
|
|
|
|
10287
|
|
|
2
|
|
|
|
|
66
|
|
8
|
2
|
|
|
2
|
|
1206
|
use Callback::Frame; |
|
2
|
|
|
|
|
2016
|
|
|
2
|
|
|
|
|
114
|
|
9
|
2
|
|
|
2
|
|
1029
|
use JSON::XS; |
|
2
|
|
|
|
|
11283
|
|
|
2
|
|
|
|
|
121
|
|
10
|
2
|
|
|
2
|
|
11
|
use File::Spec; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
28
|
|
11
|
2
|
|
|
2
|
|
812
|
use File::ShareDir; |
|
2
|
|
|
|
|
8726
|
|
|
2
|
|
|
|
|
108
|
|
12
|
|
|
|
|
|
|
|
13
|
2
|
|
|
2
|
|
1776
|
use Alien::Electron; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use Valence::Object; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our $VERSION = '0.100'; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub new { |
21
|
|
|
|
|
|
|
my ($class, %args) = @_; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my $electron_binary = $args{electron_binary} || |
24
|
|
|
|
|
|
|
$ENV{ELECTRON_BINARY} || |
25
|
|
|
|
|
|
|
$Alien::Electron::electron_binary; |
26
|
|
|
|
|
|
|
debug(1, sub { "Electron binary location: $electron_binary" }); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
my $valence_dir = $args{valence_dir} || |
29
|
|
|
|
|
|
|
$ENV{VALENCE_DIR} || |
30
|
|
|
|
|
|
|
File::ShareDir::dist_dir('Valence'); |
31
|
|
|
|
|
|
|
debug(1, sub { "Valence JS directory: $valence_dir" }); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my $self = { |
34
|
|
|
|
|
|
|
next_object_id => 1, |
35
|
|
|
|
|
|
|
object_map => {}, |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
next_callback_id => 1, |
38
|
|
|
|
|
|
|
callback_map => {}, |
39
|
|
|
|
|
|
|
}; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
bless $self, $class; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
my ($fh1, $fh2) = portable_socketpair(); |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
$self->{cv} = run_cmd [ $electron_binary, $valence_dir ], |
46
|
|
|
|
|
|
|
close_all => 1, |
47
|
|
|
|
|
|
|
'>' => $fh2, |
48
|
|
|
|
|
|
|
'<' => $fh2, |
49
|
|
|
|
|
|
|
'2>' => $ENV{VALENCE_DEBUG} >= 2 ? \*STDERR : File::Spec->devnull(), |
50
|
|
|
|
|
|
|
'$$' => \$self->{pid}; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
close $fh2; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
$self->{fh} = $fh1; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
$self->{hdl} = AnyEvent::Handle->new(fh => $self->{fh}); |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
my $line_handler; $line_handler = sub { |
59
|
|
|
|
|
|
|
my ($hdl, $line) = @_; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
my $msg = eval { decode_json($line) }; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
if ($@) { |
64
|
|
|
|
|
|
|
warn "error decoding JSON from electron: $@: $line"; |
65
|
|
|
|
|
|
|
} else { |
66
|
|
|
|
|
|
|
debug(1, sub { "<<<<<<<<<<<<<<<<< Message from electron" }, $msg, 1); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
$self->_handle_msg($msg); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
$self->{hdl}->push_read(line => $line_handler); |
72
|
|
|
|
|
|
|
}; |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
$self->{hdl}->push_read(line => $line_handler); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
return $self; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub _handle_msg { |
82
|
|
|
|
|
|
|
my ($self, $msg) = @_; |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
if ($msg->{cmd} eq 'cb') { |
85
|
|
|
|
|
|
|
$self->{callback_map}->{$msg->{cb}}->(@{ $msg->{args} }); |
86
|
|
|
|
|
|
|
} else { |
87
|
|
|
|
|
|
|
warn "unknown cmd: '$msg->{cmd}'"; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub run { |
93
|
|
|
|
|
|
|
my ($self) = @_; |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
$self->{cv} = AE::cv; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
$self->{cv}->recv; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub _send { |
104
|
|
|
|
|
|
|
my ($self, $msg) = @_; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
debug(1, sub { "Sending to electron >>>>>>>>>>>>>>>>>" }, $msg); |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
$self->{hdl}->push_write(json => $msg); |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
$self->{hdl}->push_write("\n"); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub _call_method { |
115
|
|
|
|
|
|
|
my ($self, $msg) = @_; |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
## Manipulate arguments |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
for (my $i=0; $i < @{ $msg->{args} }; $i++) { |
120
|
|
|
|
|
|
|
if (ref $msg->{args}->[$i] eq 'CODE') { |
121
|
|
|
|
|
|
|
my $callback_id = $self->{next_callback_id}++; |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
push @{ $msg->{args_cb} }, [$i, $callback_id]; |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
$self->{callback_map}->{$callback_id} = $msg->{args}->[$i]; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
$msg->{args}->[$i] = undef; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
## Send msg |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
$msg->{cmd} = 'call'; |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
my $obj = Valence::Object->_valence_new(valence => $self); |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
$msg->{save} = $obj->{id}; |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
$self->_send($msg); |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
return $obj; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub _get_attr { |
146
|
|
|
|
|
|
|
my ($self, $msg) = @_; |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
## Send msg |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
$msg->{cmd} = 'attr'; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
my $obj = Valence::Object->_valence_new(valence => $self); |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
$msg->{save} = $obj->{id}; |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
$self->_send($msg); |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
return $obj; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub require { |
163
|
|
|
|
|
|
|
my ($self) = shift; |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
return $self->_call_method({ method => 'require', args => \@_, }); |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
my $pretty_js_ctx; |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub debug { |
174
|
|
|
|
|
|
|
my ($level, $msg_cb, $to_dump, $indent) = @_; |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
return if $level > $ENV{VALENCE_DEBUG}; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
$pretty_js_ctx ||= JSON::XS->new->pretty->canonical; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
my $out = "\n" . $msg_cb->() . "\n"; |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
$out .= $pretty_js_ctx->encode($to_dump) . "\n" if $to_dump; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
$out =~ s/\n/\n /g if $indent; |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
print STDERR $out; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub DESTROY { |
192
|
|
|
|
|
|
|
my ($self) = @_; |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
kill 'KILL', $self->{pid}; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
1; |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
__END__ |