core/vgui/vgui_blackbox_tableau.cxx
Go to the documentation of this file.
00001 // This is core/vgui/vgui_blackbox_tableau.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \brief  See vgui_blackbox_tableau.h for a description of this file.
00008 // \author Philip C. Pritchett, RRG, University of Oxford
00009 // \date   13 Oct 99
00010 //
00011 // \verbatim
00012 //  Modifications
00013 //   13-OCT-1999 P.Pritchett - Initial version
00014 // \endverbatim
00015 
00016 #include "vgui_blackbox_tableau.h"
00017 
00018 #include <vcl_iostream.h>
00019 #include <vcl_cstdio.h>
00020 #include <vcl_fstream.h>
00021 
00022 #include <vpl/vpl.h>
00023 
00024 #include <vgui/vgui.h>
00025 #include <vgui/vgui_utils.h>
00026 
00027 vgui_blackbox_tableau::vgui_blackbox_tableau(vgui_tableau_sptr const& t) :
00028   vgui_wrapper_tableau(t),
00029   recording(false)
00030 {
00031 }
00032 
00033 vgui_blackbox_tableau::~vgui_blackbox_tableau()
00034 {
00035 }
00036 
00037 vcl_string vgui_blackbox_tableau::type_name() const { return "vgui_blackbox_tableau"; }
00038 
00039 
00040 static void help()
00041 {
00042   vcl_cerr << '\n'
00043            << "+- vgui_blackbox_tableau keys -+\n"
00044            << "|                              |\n"
00045            << "| `,'  start/stop record       |\n"
00046            << "| `.'           playback       |\n"
00047            << "| `s'   playback w. dump       |\n"
00048            << "| `/'       print events       |\n"
00049            << "| `#'       clear events       |\n"
00050            << "+------------------------------+\n\n";
00051 }
00052 
00053 
00054 bool vgui_blackbox_tableau::handle(const vgui_event& event)
00055 {
00056   // manage the recording and playback
00057   if (event.type == vgui_KEY_PRESS) {
00058     bool do_save= false;
00059     switch (event.key) {
00060     case ',':
00061       recording = !recording;
00062       if (recording) {
00063         vgui::out << "blackbox: starting record\n";
00064         //vgui_event start_e;
00065         //events.push_back(start_e);
00066       }
00067       else {
00068         vgui::out << "blackbox: ending record\n";
00069       }
00070       return true;
00071 
00072     case 's':
00073       // Play and save.
00074       do_save = true;
00075 
00076     case '.':
00077       if (recording) {
00078         vgui::out << "blackbox: stop recording before playback...\n";
00079       } else {
00080         vgui::out << "blackbox: starting playback\n";
00081         if (child) {
00082           vgui_event *old_e = 0;
00083           int frame_number = 0;
00084           int t = 0;
00085           vcl_ofstream story("/tmp/vgui_blackbox_tableau.story");
00086 
00087           for (vcl_vector<vgui_event>::iterator e_iter=events.begin();
00088                e_iter != events.end(); ++e_iter) {
00089 
00090             // if first event then don't wait
00091             int dt = 0;
00092             if (old_e) {
00093               dt = (e_iter->timestamp - old_e->timestamp);
00094               t += dt;
00095               vpl_usleep(dt * 1000);
00096             }
00097 
00098             if ((*e_iter).type == vgui_DRAW) {
00099               // Draw events are different: post a redraw and run_till_idle.
00100               child->post_redraw();
00101               vgui::run_till_idle();
00102               vgui::flush();
00103             } else {
00104               // Regular event, handle it
00105               child->handle(*e_iter);
00106             }
00107 
00108             // Remember this event, at least for timestamping.
00109             old_e = &(*e_iter);
00110 
00111             // Save frames
00112             {
00113               char buf[1024];
00114               vcl_sprintf(buf, "/tmp/vgui_blackbox_tableau.%03d.ppm", frame_number);
00115               if (do_save)  vgui_utils::dump_colour_buffer(buf);
00116               if (old_e) {
00117                 double d = (dt * 1e-3);
00118                 story << "delay " <<  d << vcl_endl
00119                       << "image " << buf << vcl_endl;
00120                 vgui::out << "blackbox: Saving frame " << buf << ", delay " << dt << vcl_endl;
00121               }
00122 
00123               ++frame_number;
00124             }
00125           }
00126         }
00127         vgui::out << "blackbox: ending playback\n";
00128       }
00129       return true;
00130 
00131     case '/':
00132       if (!recording) {
00133         vcl_cerr << "vgui_blackbox_tableau EVENTS\n";
00134         for (vcl_vector<vgui_event>::iterator e_iter=events.begin();
00135              e_iter != events.end(); ++e_iter) {
00136           vcl_cerr << *e_iter << vcl_endl;
00137         }
00138         return true;
00139       }
00140       break;
00141 
00142     case '#':
00143       if (!recording) {
00144         vgui::out << "blackbox: clearing events\n";
00145         events.clear();
00146         return true;
00147       }
00148       break;
00149 
00150     case '?':
00151       if (!recording) {
00152         ::help();
00153       }
00154       break;
00155     default:
00156       break;
00157     }
00158   }
00159 
00160   vgui_event copy = event;
00161   bool used = child && child->handle(event);
00162 
00163   if (recording) {
00164     if (used)
00165       events.push_back(copy);
00166     else
00167       vcl_cerr << "blackbox: Ignoring " << copy << vcl_endl;
00168   }
00169 
00170   return used;
00171 }