1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
# Go to a requested generation. The given generation can be an
# absolute number like 1,000,000 (commas are optional) or a number
# relative to the current generation like +9 or -6. If the target
# generation is less than the current generation then we go back
# to the starting generation (normally 0) and advance to the target.
# Authors: Andrew Trevorrow and Dave Greene, June 2007.
use strict;
use Time::HiRes qw ( time );
# --------------------------------------------------------------------
sub go_to {
my $gen = shift;
my $currgen = g_getgen();
my $newgen = $gen;
if (substr($gen,0,1) eq '+') {
$newgen = $currgen + $gen;
} elsif (substr($gen,0,1) eq '-') {
my $n = -$gen;
if ($currgen > $n) {
$newgen = $currgen - $n;
} else {
$newgen = 0;
}
}
if ($newgen < $currgen) {
# try to go back to starting gen (not necessarily 0) and
# then forwards to newgen; note that reset() also restores
# algorithm and/or rule, so too bad if user changed those
# after the starting info was saved;
# first save current location and scale
my ($midx, $midy) = g_getpos();
my $mag = g_getmag();
g_reset();
# restore location and scale
g_setpos($midx, $midy);
g_setmag($mag);
# current gen might be > 0 if user loaded a pattern file
# that set the gen count
$currgen = g_getgen();
if ($newgen < $currgen) {
g_error("Can't go back any further; pattern was saved ".
"at generation $currgen.");
return;
}
}
return if $newgen == $currgen;
g_show("Hit escape to abort...");
my $oldsecs = time;
# do 1 step first, to ensure a reasonable value is saved for the step size:
g_run(1);
++$currgen;
my $base = g_getbase();
my $todo = $newgen - $currgen;
my $exp = 0;
while ($todo > 0) {
my $num_steps = $todo % $base;
g_setstep($exp++);
$todo = ($todo - $num_steps)/$base;
while ($num_steps-- > 0) {
if (g_empty()) {
g_show("Pattern is empty.");
return;
}
g_step();
my $newsecs = time;
if ($newsecs - $oldsecs >= 1.0) { # do an update every sec
$oldsecs = $newsecs;
g_update();
}
}
}
g_show("");
}
# --------------------------------------------------------------------
sub savegen {
my ($filename, $gen) = @_;
if (not open(OUTFILE, ">".$filename)) {
g_warn("Can't save gen in $filename:\n$!");
} else {
print OUTFILE $gen;
close OUTFILE;
}
}
# --------------------------------------------------------------------
# use same file name as in goto.py
my $GotoINIFileName = g_getdir("data")."goto.ini";
my $previousgen = "";
if (open(INFILE, $GotoINIFileName)) {
$previousgen = <INFILE>;
close INFILE;
}
my $gen = g_getstring("Enter the desired generation number,\n".
"or -n/+n to go back/forwards by n:",
$previousgen, "Go to generation");
if ($gen eq "") {
g_exit();
} elsif ($gen eq '+' or $gen eq '-') {
# clear the default
savegen($GotoINIFileName, "");
} elsif ($gen !~ /^[+-]?\d[\d,]*$/) {
g_exit("Sorry, but \"$gen\" is not a valid integer.");
} else {
# best to save given gen now in case user aborts script
savegen($GotoINIFileName, $gen);
$gen =~ s/,//g;
my $oldstep = g_getstep();
go_to($gen);
g_setstep($oldstep);
}
|