function initMemory() {
memory.counter = 0;
}
function incCounter(amount) {
memory.counter = memory.counter + amount;
}
function printCounter() {
log("Current count is " + memory.counter);
}
####
#!/usr/bin/env perl
package ReportingHandler;
use strict;
use warnings;
sub new {
my ($proto, %config) = @_;
my $class = ref($proto) || $proto;
my $self = bless \%config, $class;
return $self;
}
sub debuglog {
my ($self, @debugtext) = @_;
print "DEBUG: ", join(' ', @debugtext), "\n";
}
package main;
use strict;
use warnings;
use PageCamel::Helpers::JavaScript;
use Data::Dumper;
my $reph = ReportingHandler->new();
my $memory;
#print Dumper($reph);
my $jscode = qq{
function initMemory() {
memory.counter = 0;
}
function incCounter(amount) {
memory.counter = memory.counter + amount;
}
function printCounter() {
log("Current count is " + memory.counter);
}
};
{ # First run
print "First run\n";
my $jsh = PageCamel::Helpers::JavaScript->new(reph => $reph, timeout => 10, code => $jscode);
$jsh->initMemory();
$jsh->call('printCounter');
$jsh->call('incCounter', 42);
$jsh->call('printCounter');
$memory = $jsh->getMemory();
}
print "Memory contents: ", $memory, "\n";
{ # Second run
print "Second run\n";
my $jsh = PageCamel::Helpers::JavaScript->new(reph => $reph, timeout => 10, code => $jscode);
$jsh->setMemory($memory);
$jsh->call('printCounter');
$jsh->call('incCounter', 23);
$jsh->call('printCounter');
}
##
##
package PageCamel::Helpers::JavaScript;
#---AUTOPRAGMASTART---
use 5.030;
use strict;
use warnings;
use diagnostics;
use mro 'c3';
use English;
use Carp qw[carp croak confess cluck longmess shortmess];
our $VERSION = 4.0;
use autodie qw( close );
use Array::Contains;
use utf8;
use Data::Dumper;
use PageCamel::Helpers::UTF;
#---AUTOPRAGMAEND---
BEGIN {
mkdir '/tmp/pagecamel_helpers_javascript_inline';
$ENV{PERL_INLINE_DIRECTORY} = '/tmp/pagecamel_helpers_javascript_inline';
};
use JavaScript::Duktape;
use JSON::XS;
sub new {
my ($class, %config) = @_;
my $self = bless \%config, $class;
if(!defined($self->{reph})) {
croak('PageCamel::Helpers::JavaScript needs reph reporting handler');
}
if(!defined($self->{timeout})) {
croak('PageCamel::Helpers::JavaScript needs timeout (default timeout value)');
}
my $js = JavaScript::Duktape->new(timeout => $self->{timeout});
$self->{js} = $js;
$self->{js}->set('log' => sub {
$self->_logfromjs($_[0]);
});
$self->{js}->eval(qq{
var memory = new Object;
function __encode(obj) {
return JSON.stringify(obj);
}
function __decode(txt) {
return JSON.parse(txt);
}
function __setmemory(txt) {
memory = __decode(txt);
}
function __getmemory() {
return __encode(memory);
}
function __getKeys(obj) {
var keys = Object.keys(obj);
return keys;
}
});
if(defined($self->{code})) {
$self->load();
}
return $self;
}
sub _logfromjs {
my ($self, $text) = @_;
$self->{reph}->debuglog($text);
return;
}
sub load {
my ($self, $code) = @_;
if(defined($code)) {
$self->{code} = $code;
}
$self->{js}->eval($self->{code});
return;
}
sub call {
my ($self, $name, @arguments) = @_;
my $func = $self->{js}->get_object($name);
if(!defined($func)) {
print STDERR "Function $func does not exist!\n";
return;
}
return $func->(@arguments);
}
sub registerCallback {
my ($self, $name, $func) = @_;
$self->{js}->set($name, $func);
return;
}
sub encode {
my ($self, $data) = @_;
return encode_json $data;
}
sub decode {
my ($self, $json) = @_;
return decode_json $json;
}
sub toArray {
my ($self, $object) = @_;
my @arr;
$object->forEach(sub {
my ($value, $index, $ar) = @_;
push @arr, $value;
});
return @arr;
}
sub getKeys {
my ($self, $object) = @_;
my $rval = $self->call('__getKeys', $object);
return $self->toArray($rval);
}
sub toHash {
my ($self, $object) = @_;
my @keys = $self->getKeys($object);
my %hash;
foreach my $key (@keys) {
$hash{$key} = $object->$key;
}
return %hash;
}
sub setMemory {
my ($self, $memory) = @_;
$self->call('__setmemory', $memory);
return;
}
sub getMemory {
my ($self) = @_;
return $self->call('__getmemory');
}
sub initMemory {
my ($self) = @_;
$self->call('initMemory');
return;
}
1;
##
##
First run
DEBUG: Current count is 0
DEBUG: Current count is 42
Memory contents: {"counter":42}
Second run
DEBUG: Current count is 42
DEBUG: Current count is 65