BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Kinetic/IO/internal/GUI_base.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  Stanford University (USA).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kinetic_data_structures/include/CGAL/Kinetic/IO/internal/GUI_base.h $
00016 // $Id: GUI_base.h 40832 2007-11-08 00:27:20Z ameyer $
00017 // 
00018 //
00019 // Author(s)     : Daniel Russel <drussel@alumni.princeton.edu>
00020 
00021 #ifndef CGAL_KINETIC_CGAL_GRAPHICAL_SIMULATOR_BASE_H
00022 #define CGAL_KINETIC_CGAL_GRAPHICAL_SIMULATOR_BASE_H
00023 #include <CGAL/Kinetic/basic.h>
00024 #include <CGAL/Kinetic/Ref_counted.h>
00025 #include <CGAL/Kinetic/Listener.h>
00026 
00027 CGAL_KINETIC_BEGIN_NAMESPACE
00029 
00032 template <class Simulator_t, class Timer>
00033 class Gui_base: public CGAL::Kinetic::Ref_counted<Gui_base<Simulator_t, Timer> >
00034 {
00035 protected:
00036   typedef Simulator_t Simulator;
00037   typedef Gui_base<Simulator, Timer> This;
00038 
00039   typedef typename Simulator::Time TT;
00040 
00041 public:
00042   //typedef CGAL::Ref_counted_pointer<This> Pointer;
00043 
00045 
00056   typedef enum Mode {RUNNING, RUNNING_TO_EVENT, RUNNING_THROUGH_EVENT, PAUSED, STOPPED}
00057     Mode;
00058 
00060   Gui_base(typename Simulator::Handle sh): mode_(STOPPED), paused_mode_(STOPPED),
00061                                             fps_(60), speed_log_(0),
00062                                             dir_of_time_(1), timer_(new Timer()),
00063                                            //timer_callback_(timer_,const_cast<This*>(this)),
00064                                            /*drawable_(NULL),*/ processing_(false) {
00065     sim_= sh;
00066     target_cur_time_= CGAL::to_interval(sim_->current_time()).first;
00067     CGAL_KINETIC_INIT_LISTEN(Timer, timer_.get());
00068   }
00069 
00070   virtual ~Gui_base() {
00071    
00072   }
00073 
00075   Mode mode() {
00076     return mode_;
00077   }
00078 
00080   void set_mode(Mode mode) {
00081     if (mode== PAUSED) {
00082       if (mode_ == PAUSED) {
00083         unpause();
00084       }
00085       else {
00086         pause();
00087       }
00088     } else if ((mode==RUNNING_TO_EVENT || mode==RUNNING_THROUGH_EVENT)
00089                && sim_->empty()) {
00090       std::cout << "No more events.\n";
00091       return;
00092     }
00093     else {
00094       mode_= mode;
00095     }
00096 
00097     CGAL_LOG(Log::SOME, "Mode changed to " << mode_string(this->mode()) << std::endl);
00098     timer_->clear();
00099     switch(this->mode()) {
00100     case RUNNING_TO_EVENT:
00101     case RUNNING_THROUGH_EVENT:
00102     case RUNNING:
00103       //std::cout << "Starting timer with time " << Parent::step_length_real_time() << std::endl;
00104       timer_->run(step_length_real_time());
00105       break;
00106     case STOPPED:
00107     case PAUSED:
00108       break;
00109     default:
00110       std::cerr << "Invalid case: " << this->mode() << std::endl;
00111       CGAL_error();
00112     }
00113   }
00114 
00115   CGAL_KINETIC_LISTENER1(CURRENT_TIME);
00116 public:
00118   typename Simulator::Handle& simulator() {
00119     return sim_;
00120   }
00121 
00123   typename Simulator::Const_handle simulator()const
00124   {
00125     return sim_;
00126   }
00127 
00129   double current_time() const
00130   {
00131     return target_cur_time_;
00132   }
00133 
00135   double speed() const
00136   {
00137     return speed_log_;
00138   }
00140   void set_speed(double s) {
00141     speed_log_=s;
00142   }
00143 
00144 protected:
00145 
00146   const char * mode_string(Mode m) const
00147   {
00148     switch (m) {
00149     case RUNNING:
00150       return "<Run>";
00151       break;
00152     case RUNNING_TO_EVENT:
00153       return  "<Run to>";
00154       break;
00155     case RUNNING_THROUGH_EVENT:
00156       return "<Run through>";
00157       break;
00158     case PAUSED:
00159       return "<Pause>";
00160       break;
00161     case STOPPED:
00162       return "<Stop>";
00163       break;
00164     default:
00165       return "<Unknown>";
00166     }
00167   }
00168 
00169   
00170 
00171   CGAL_KINETIC_LISTEN1(Timer, TICKS, timer_rang());
00172   /*class Timer_listener: public Timer::Listener
00173   {
00174   public:
00175     Timer_listener(Timer *tm, This *t):Timer::Listener(tm),  t_(t) {
00176     }
00177     void new_notification(typename Timer::Listener::Notification_type) {
00178       t_->timer_rang();
00179     }
00180   protected:
00181     This *t_;
00182   };
00183 
00184   friend class Timer_listener;*/
00185 
00186   void timer_rang() {
00187     // do something here
00188     if (increment_time()) {
00189       timer_->run(step_length_real_time());
00190     }
00191   }
00192 
00193   bool increment_target_time() {
00194     double nt= target_cur_time_+ step_length_kds_time();
00195     if (CGAL::compare(nt, target_cur_time_) == CGAL::EQUAL) {
00196       std::cerr << "Time failed to advance due to roundoff. This is bad.\n";
00197     }
00198     target_cur_time_= nt;
00199     if (CGAL::compare(TT(nt), sim_->next_event_time()) == CGAL::LARGER) {
00200       return true;
00201     } else {
00202       return false;
00203     }
00204   }
00205 
00206   /*TT compute_next_timestep() const
00207   {
00208     return compute_next_timestep(sim_->end_time());
00209     }*/
00210 
00211   double step_length_real_time() const
00212   {
00213     return 1/fps_;
00214   }
00215 
00216   double step_length_kds_time() const
00217   {
00218     return  std::exp(speed_log_)/fps_;
00219   }
00220 
00221   bool increment_time() {
00222     CGAL_precondition(!is_processing());
00223     set_is_processing(true);
00224     //typename Parent::Time t= do_timestep(Parent::_end_time);
00225     bool ret(true);                       // to satisfy compiler
00226     switch (mode_) {
00227     case RUNNING:
00228       {
00229         increment_target_time();
00230         TT tt(target_cur_time_);
00231         CGAL::Comparison_result cmp=CGAL::compare(tt, sim_->end_time());
00232         if (cmp == CGAL::LARGER) {
00233           target_cur_time_ = CGAL::to_interval(sim_->end_time()).second;
00234           ret=false;
00235         } else if (cmp== CGAL::EQUAL) {
00236           ret= false;
00237         }
00238         
00239         if (!ret) {
00240           sim_->set_current_time(sim_->end_time());
00241           std::cout << "Simulation reached end of time. "
00242                     << "Press \"step over\" to process the next final event (if any)." << std::endl;
00243           set_mode(STOPPED);
00244         } else {
00245           sim_->set_current_time(tt);
00246         }
00247         break;
00248       }
00249     case RUNNING_TO_EVENT:
00250       {
00251         TT ct(target_cur_time_);
00252         if (CGAL::compare(ct, sim_->next_event_time())== CGAL::SMALLER) {
00253           increment_target_time();
00254           TT tt(target_cur_time_);
00255           CGAL::Comparison_result cmp=CGAL::compare(tt, sim_->next_event_time());
00256           if (cmp != CGAL::SMALLER) {
00257             //target_cur_time_ = CGAL::to_interval(sim_->next_event_time()).second;
00258             ret=false;
00259           } 
00260           
00261           if (!ret) {
00262             sim_->set_current_time(sim_->next_event_time());
00263             set_mode(STOPPED);
00264           }
00265         } else {
00266           ret=false;
00267         }
00268         break;
00269       }
00270     case RUNNING_THROUGH_EVENT:
00271       {
00272         TT ct(target_cur_time_);
00273         if (CGAL::compare(ct, sim_->next_event_time())== CGAL::SMALLER) {
00274           increment_target_time();
00275           TT tt(target_cur_time_);
00276           CGAL::Comparison_result cmp=CGAL::compare(tt, sim_->next_event_time());
00277           if (cmp != CGAL::SMALLER) {
00278             //target_cur_time_ = CGAL::to_interval(sim_->next_event_time()).second;
00279             ret=false;
00280           } 
00281         } else {
00282           ret=false;
00283         }
00284           
00285         if (!ret) {
00286           //sim_->set_current_time(sim_->next_event_time());
00287           sim_->set_current_event_number(sim_->current_event_number()+1);
00288           set_mode(STOPPED);
00289         }
00290         break;
00291       }
00292     default:
00293       std::cerr << "Run callback in invalid mode." << std::endl;
00294     }
00295     CGAL_KINETIC_NOTIFY(CURRENT_TIME);
00296     //if (drawable_ != NULL) drawable_->new_notification(Listener::CURRENT_TIME);
00297 
00298     set_is_processing(false);
00299 
00300     return ret;
00301   }
00302 
00303   void pause() {
00304     paused_mode_= mode_;
00305     mode_=PAUSED;
00306   }
00307   void unpause() {
00308     mode_=paused_mode_;
00309   }
00310 
00311   bool is_processing() const
00312   {
00313     return processing_;
00314   }
00315   void set_is_processing(bool tf) {
00316     processing_=tf;
00317   }
00318 
00319   Mode mode_;
00320   Mode paused_mode_;
00321   double fps_;
00322   double speed_log_;
00323   double target_cur_time_;
00324   int dir_of_time_;
00325   typename Simulator::Handle sim_;
00326   std::auto_ptr<Timer> timer_;
00327   //Timer_listener timer_callback_;
00328   //Listener *drawable_;
00329   bool processing_;
00330 };
00331 CGAL_KINETIC_END_NAMESPACE;
00332 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines