# # $Id: Undo.pm,v 4.7 2002/07/21 06:49:53 kono Exp $ # package CardPlay::Undo; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK ); require Exporter; require AutoLoader; @ISA = qw(Exporter AutoLoader); @EXPORT = qw( ); $VERSION = "0.2"; use Carp; # class method sub new { my ($types) = shift; my $self; %$self = @_; undo_init($self); bless $self; } sub undo_init { my $self = shift; $self->{'-undo'}=[]; $self->{'-undo_index'}=0; $self; } sub undo_restart { my $self = shift; $self->{'-undo_index'}=0; $self; } # instance method # undo buffer processing # log_commit(0) commit # log_commit(-1) point of no return, end of initialzation sub log_move { my ($self) = shift; my ($undo) = @_; return if ($self->{'-undoing'}==1); return if ($undo==0); $self->{'-undo'}->[$self->{'-undo_index'}]=$undo; $#{$self->{'-undo'}} = $self->{'-undo_index'}++; # print STDERR "log_move: "; $undo->print(); } sub log_commit { my ($self,$mode) = @_; return if ($self->{'-undoing'}==1); return if ($self->{'-undo'}->[$self->{'-undo_index'}-1]==$mode); $self->{'-undo'}->[$self->{'-undo_index'}]=$mode; $#{$self->{'-undo'}} = $self->{'-undo_index'}++; # print STDERR "\nlog cdommit ",$self->{'-undo_index'},"\n"; # $self->log_print; } sub log_print { my ($self) = shift; my (@list) = @{$self->{'-undo'}}; foreach my $undo ( @list ) { next if ($undo == 0 || $undo == -1); $undo->print(); } } sub disable_undo { } sub enable_undo { } sub enable_log { my ($self) = shift; $self->{'-undoing'}=0; } sub disable_log { my ($self) = shift; $self->{'-undoing'}=1; } sub undo { my ($self) = shift; my ($undo); return if ($self->{'-undo_index'}==0); return if ($self->{'-undoing'}++>0); return if ($self->{'-undoing'}!=1); $self->disable_undo; while ( $self->{'-undo_index'} > 0 ) { $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1]; last if ($undo==-1); last if ($undo!=0); $self->{'-undo_index'} --; } while ( $self->{'-undo_index'} > 0 ) { $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1]; last if ($undo== -1); $self->{'-undo_index'} --; last if ($undo==0); $undo->undo(); } $self->{'-undoing'}=0; $self->enable_undo; } sub redo { my ($self) = shift; my ($undo); return if ($self->{'-undo_index'}==$#{$self->{'-undo'}}); return if ($self->{'-undoing'}++>0); return if ($self->{'-undoing'}!=1); $self->disable_undo; while ( $self->{'-undo_index'} <= $#{$self->{'-undo'}} ) { $undo = $self->{'-undo'}->[$self->{'-undo_index'}]; next if ($undo==-1); last if ($undo!=0); $self->{'-undo_index'} ++; } while ( $self->{'-undo_index'} <= $#{$self->{'-undo'}} ) { $self->{'-undo_index'} ++; # print STDERR "Redoing ",$self->{'-undo_index'},"\n"; $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1]; last if ($undo==0); next if ($undo==-1); $undo->redo(); } $self->{'-undoing'}=0; $self->enable_undo; } 1; # end