Differences From Artifact [1b458d7cd25e92dc]:
- File        
output.d
- 2012-07-14 08:31:35 - part of checkin [a5e6c99b3d] on branch trunk - Guarded. (user: kinaba) [annotate]
 
- File        
src/output.d
- 2012-07-14 09:16:47 - part of checkin [6293256fec] on branch trunk - Preparing for submission... (user: kinaba) [annotate]
 
To Artifact [2ca374354297c908]:
- File        
src/output.d
- 2012-07-14 11:24:30 - part of checkin [bee0596f0f] on branch trunk - Refactoring. (user: kinaba) [annotate]
 
    1  import util;                                                                           1  import util;
    2  import game;                                                                           2  import game;
    3  import core.stdc.signal;                                                         |     3  import driver;
    4  import std.c.stdlib;                                                                   4  import std.c.stdlib;
                                                                                        >     5  import core.stdc.signal;
    5                                                                                         6  
    6  abstract class Output                                                            |     7  class NilOutput : GameObserver
    7  {                                                                                      8  {
    8          void command(char c);                                                    |     9          this(const(Game) g) {}
    9          void flush();                                                            |    10          override bool on_game_changed(char c, const(Game) g, bool finished) {ret
   10  }                                                                                     11  }
   11                                                                                        12  
   12  class NilOutput : Output                                                         |    13  class StdOutput : GameObserver
   13  {                                                                                     14  {
   14          override void command(char c) {}                                         |    15          this(const(Game) g) {}
   15          override void flush() {}                                                 |    16          override bool on_game_changed(char c, const(Game) g, bool finished)
   16  }                                                                                <
   17                                                                                   <
   18  class StdOutput : Output                                                         <
   19  {                                                                                <
   20          override void command(char c)                                            <
   21          {                                                                             17          {
   22                  write(c);                                                        |    18                  stdout.write(c);
   23                  stdout.flush();                                                       19                  stdout.flush();
                                                                                        >    20                  return false;
   24          }                                                                             21          }
   25          override void flush() {}                                                 <
   26  }                                                                                     22  }
   27                                                                                        23  
   28  // TODO: clean it up.                                                            <
   29  __gshared Output g_output;                                                       <
   30                                                                                   <
   31  class GuardedOutput : StdOutput                                                  |    24  class GuardedOutput : GameObserver
   32  {                                                                                     25  {
   33          // Handle SIGINT: force abort and exit.                                  |    26          this(const(Game) g)
   34          static this()                                                            <
                                                                                        >    27          {
                                                                                        >    28                  setup_sigint_handling();
                                                                                        >    29                  ideal_log ~= g.score_if_abort_now;
                                                                                        >    30          }
                                                                                        >    31  
                                                                                        >    32          override bool on_game_changed(char c, const(Game) g, bool finished)
   35          {                                                                             33          {
   36                  signal(SIGINT, &sigint);                                         |    34                  log ~= c;
                                                                                        >    35                  score_log ~= g.score;
                                                                                        >    36                  ideal_log ~= g.score_if_abort_now;
                                                                                        >    37                  if(finished)
                                                                                        >    38                          flush();
                                                                                        >    39                  return false;
   37          }                                                                             40          }
   38                                                                                        41  
   39          extern(C) static void sigint(int)                                        |    42  private:
   40          {                                                                        <
   41                  if(g_output !is null)                                            <
   42                          g_output.flush();                                        <
   43                  else {                                                           <
   44                          write("A");                                              <
   45                          stdout.flush();                                          <
   46                  }                                                                <
   47                  exit(0);                                                         <
   48          }                                                                        <
   49                                                                                   <
   50          Game g;                                                                  <
   51          this(Game ini) { this.g = ini.clone(); ideal_log ~= g.score_if_abort_now <
   52                                                                                   <
   53          string log;                                                                   43          string log;
   54          long[] score_log;                                                             44          long[] score_log;
   55          long[] ideal_log;                                                             45          long[] ideal_log;
   56                                                                                        46  
   57          override void command(char c)                                            <
   58          {                                                                        <
   59                  g.command(c);                                                    <
   60                  log ~= c;                                                        <
   61                  score_log ~= g.score;                                            <
   62                  ideal_log ~= g.score_if_abort_now;                               <
   63          }                                                                        <
   64          override void flush()                                                    |    47          void flush()
   65          {                                                                             48          {
   66                  Tuple!(long, int, int) cand;                                          49                  Tuple!(long, int, int) cand;
   67                  cand[0] = long.min;                                                   50                  cand[0] = long.min;
   68                  foreach(int i, long s; score_log)                                <
                                                                                        >    51  
                                                                                        >    52                  for(int i=0; i<score_log.length; ++i)
   69                          if(cand[0] < s)                                          |    53                          if(cand[0] < score_log[i])
   70                                  cand = tuple(s,i,0);                             |    54                                  cand = tuple(score_log[i],i,0);
   71                  foreach(int i, long s; ideal_log)                                <
                                                                                        >    55                  for(int i=0; i<ideal_log.length; ++i)
   72                          if(cand[0] < s)                                          |    56                          if(cand[0] < ideal_log[i])
   73                                  cand = tuple(s,i,1);                             |    57                                  cand = tuple(ideal_log[i],i,1);
                                                                                        >    58  
   74                  if(cand[2]==0)                                                   |    59                  if(cand[2]==0) {
   75                          writeln(log[0..cand[1]+1]);                              |    60                          string str = log[0..cand[1]+1];
                                                                                        >    61                          std.c.stdio.printf("%.*s\n", str.length, str.ptr);
   76                  else                                                             |    62                  } else {
   77                          writeln(log[0..cand[1]]~"A");                            |    63                          string str = log[0..cand[1]];
   78                  stdout.flush();                                                  <
                                                                                        >    64                          std.c.stdio.printf("%.*sA\n", str.length, str.ptr);
                                                                                        >    65                  }
                                                                                        >    66                  std.c.stdio.fflush(std.c.stdio.stdout);
                                                                                        >    67          }
                                                                                        >    68  
                                                                                        >    69  private:
                                                                                        >    70          static __gshared GuardedOutput g_output;
                                                                                        >    71  
                                                                                        >    72          void setup_sigint_handling()
                                                                                        >    73          {
                                                                                        >    74                  assert(g_output is null);
                                                                                        >    75                  g_output = this;
                                                                                        >    76                  extern(C) static void catch_sigint(int) { g_output.flush(); appl
                                                                                        >    77                  core.stdc.signal.signal(SIGINT, &catch_sigint);
   79          }                                                                             78          }
   80  }                                                                                     79  }