package Test; 1; package Blacknote::System::Shell; use strict; use warnings FATAL => qw(all); use Curses; use File::Spec::Functions qw(catfile); use Blacknote::Logging; use Blacknote::System::State qw( bnsm_get_log bnsm_request_quit bnsm_get_player ); use Exporter qw(import); # prefix = bnsh_ = blacknote shell our @EXPORT = grep { /^bnsh_.*/ and $_ } keys %Blacknote::System::Shell::; my @orig_curpos = (); sub bnsh_open { # Switch to normal typing mode curs_set 1; my ($x,$y); getsyx $y,$x; @orig_curpos = ($y,$x); nocbreak; echo; move $LINES-1,0; addstring " " x ($COLS-1); move $LINES-1,0; setsyx $LINES-1,0; addch ":"; my $cmd = getstring(); goto RESTORE if not defined $cmd or not $cmd; my @params = split / /,$cmd; $cmd = shift @params; DEBUG "Got command $cmd"; if(exists $Blacknote::System::Shell::{"cmd_".$cmd}){ my $func = $Blacknote::System::Shell::{"cmd_".$cmd}; DEBUG "Running command: $cmd"; $func->(@params); }else{ if($cmd eq "e"){ eval "$cmd " . join(" ",@params); goto RESTORE; }elsif($cmd eq "!"){ #shell escape my $fullcmd = join " ",@params; my $result = qx/$fullcmd/; bnsm_get_log->push(reverse split /\n/, $result); goto RESTORE; }elsif($cmd eq "q"){ move $LINES-1, 0; addstring "Really quit? [y/N]: "; my $yn = getch; if($yn eq "y"){ DEBUG "Quit requested. Exiting gracefully"; bnsm_request_quit; }else{ DEBUG "Quit aborted. Continuing game"; } goto RESTORE; } my $errmsg = "Uknown command '$cmd'"; WARN $errmsg; bnsm_get_log->push($errmsg); } RESTORE: # Restore cursor state after command processing bnsh_restore(); } sub bnsh_restore { move $LINES-1, 0; addstring " " x ($COLS-1); # Clear one line cbreak; noecho; move @orig_curpos; setsyx @orig_curpos; curs_set 0; } # === Commands === sub cmd_echo { DEBUG "Params: @_"; bnsm_get_log->push(join " ",@_); } sub cmd_loadmod { my $modname = shift; my $target = catfile("Mods/", $modname . ".pm"); DEBUG "Live loading: " . $target; no warnings 'redefine'; no warnings 'closure'; push @INC, "."; my $pkg = do $target; ERROR "Error during compilation of module $target: " . $@ . "|" . $! && die $! if not defined $pkg; DEBUG "Loaded: $pkg"; # NOTE: This is better, people might deploy casual/standard OOP # We do, however, expect this to be at least a singleton my $module = bless {}, $pkg; $module->init; pop @INC; } sub cmd_script { my @params = @_; my $subcmd = shift @params; my %funcs = ( attach => sub { DEBUG "Attaching script to " . shift@params; }, detach => sub { DEBUG "Detaching script from " . shift@params; }, info => sub { DEBUG "Showing scripts of " . shift@params; } ); &{$funcs{$subcmd}}(); } sub cmd_turns { bnsm_get_log->push("Total game turns:".$Blacknote::System::State::GAME_TURNS); } sub cmd_player_turns { #FIXME: Crashes when turns aren't initialized in player bnsm_get_log->push("Total player turns: " . bnsm_get_player->turns); } 1; .