# Copyright (c) 2017 Timm Murray
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package Graphics::GVG::Renderer;
$Graphics::GVG::Renderer::VERSION = '0.92';
use strict;
use warnings;
use Data::UUID;
use Moose::Role;
requires 'class_suffix';
requires 'make_line';
requires 'make_rect';
requires 'make_poly';
requires 'make_circle';
requires 'make_ellipse';
has 'glow_count' => (
traits => ['Counter'],
is => 'ro',
isa => 'Int',
default => 0,
handles => {
'_increment_glow' => 'inc',
'_decrement_glow' => 'dec',
},
);
sub make_pack
{
my ($self, $ast) = @_;
my $class_suffix = $self->class_suffix;
my $class_prefix = $ast->meta_data->{class_prefix};
if(! defined $class_prefix ) {
my $uuid = Data::UUID->new->create_hex;
$class_prefix = __PACKAGE__ . '::' . $uuid;
}
$class_suffix =~ s/\A :://x;
$class_prefix =~ s/:: \z//x;
my $pack = $class_prefix . '::' . $class_suffix;
return $pack;
}
sub make_obj
{
my ($self, $ast, $args) = @_;
my $pack = $self->make_class( $ast );
my $obj = $pack->new( $args );
return $obj;
}
sub make_class
{
my ($self, $ast) = @_;
my ($code, $pack) = $self->make_code( $ast );
eval $code or die $@;
return $pack;
}
sub make_code
{
my ($self, $ast, $target_class) = @_;
my $pack = $target_class
// $self->make_pack( $ast );
my $code = $self->make_opening_code( $pack, $ast );
$code .= $self->_walk_ast( $pack, $ast, $ast );
$code .= $self->make_closing_code( $pack, $ast );
return ($code, $pack);
}
sub make_opening_code
{
return '';
}
sub make_closing_code
{
return '';
}
sub _walk_ast
{
my ($self, $pack, $root_ast, $ast) = @_;
my $code = join( "\n", map {
my $ret = '';
if(! ref $_ ) {
warn "Not a ref, don't know what to do with '$_'\n";
}
elsif( $_->isa( 'Graphics::GVG::AST::Line' ) ) {
$ret = $self->make_line( $_, $root_ast );
}
elsif( $_->isa( 'Graphics::GVG::AST::Rect' ) ) {
$ret = $self->make_rect( $_, $root_ast );
}
elsif( $_->isa( 'Graphics::GVG::AST::Polygon' ) ) {
$ret = $self->make_poly( $_, $root_ast );
}
elsif( $_->isa( 'Graphics::GVG::AST::Circle' ) ) {
$ret = $self->make_circle( $_, $root_ast );
}
elsif( $_->isa( 'Graphics::GVG::AST::Ellipse' ) ) {
$ret = $self->make_ellipse( $_, $root_ast );
}
elsif( $_->isa( 'Graphics::GVG::AST::Glow' ) ) {
$self->_increment_glow;
$ret = $self->_walk_ast( $pack, $root_ast, $_ );
$self->_decrement_glow;
}
else {
warn "Don't know what to do with " . ref($_) . "\n";
}
$ret;
} @{ $ast->commands });
return $code;
}
1;
__END__