<commit_before>#include <chrono>
#include <thread>
//#include <iostream>
#include <stdexcept>

#include "simulator.hpp"
#include "event.hpp"

#define LOGURU_WITH_STREAMS 1
#include "loguru.hpp"


namespace config  // some of these may later be read from config files
{

const float threshold = 0.01;

}


namespace sim
{

Simulator::Simulator( std::string _scenario_fname ) 
{
  scenario_fname = _scenario_fname;
  user_command_received = false;
  quit_now = false;
  restart = false;
}

void 
Simulator::run()
{  
  using namespace std::chrono_literals;
  
  loguru::set_thread_name("sim manager");
  
  Scenario scenario( scenario_fname );
  for( ;; )
  {
    if( scenario.requires_recompute() ) { recompute_with( scenario ); }

    std::unique_lock<std::mutex> lk( user_command_mutex );
    cv.wait_for( lk, 500ms ); 
    // Spurious wake ups are not a problem here
    if( quit_now ) break;

    scenario.reload_changes(); 
  }
   
  if( compute_thread.joinable() ) compute_thread.join();  
}


void
Simulator::recompute_with( const Scenario& new_scenario )
{
  restart = true;
  if( compute_thread.joinable() ) compute_thread.join();

  // once more unto the breach
  compute_thread = std::thread( 
    &sim::Simulator::compute,
    std::ref( *this ),
    new_scenario
  );
}

void
Simulator::wait()
{
  std::unique_lock<std::mutex> lk( user_command_mutex );
  cv.wait(lk, [this](){ return user_command_received; });  // protects against spurious unblocks
  user_command_received = false;
}

void
Simulator::quit()
{ 
  std::lock_guard<std::mutex> lk( user_command_mutex );
  user_command_received = true;
  quit_now = true;
  cv.notify_one();
}

void 
Simulator::compute( Scenario scenario )
{
  loguru::set_thread_name("compute");
 
  load( scenario );
  
  restart = false;  
  DLOG_S(INFO) << "Starting Simulator: " << scenario.start_jd << " - " << scenario.stop_jd;  

  int simulator_steps = 0;
  double jd = scenario.start_jd;
  while( !restart & !quit_now & ( jd < scenario.stop_jd ) ) 
  { 
    step( jd, scenario.dt );
    jd += scenario.step_jd;
    simulator_steps++;
  }

  DLOG_S(INFO) << "Stopping Simulator: " << jd << " (" << simulator_steps << " steps)";    
}
 
void
Simulator::step( double jd, double dt )
{
  for( auto& s : simulation->space_ships ) { s->update_pos( jd, dt ); }

  for( auto& b : simulation->orrery_bodies ) { b->update_pos( jd ); }

  for( auto& s : simulation->space_ships ) 
  {
    Vector g;
    for( auto& b : simulation->orrery_bodies ) {
      Vector R = b->pos - s->pos;
      // Good time to check for collisions too! TODO
      g += (b->GM / R.norm_sq()) * R.normed();
    }
    s->update_acc_and_vel( g, jd, dt );
  }
  resolve_actions( jd );

  simulation->set_last_jd( jd );
}

void
Simulator::resolve_actions( double jd )
{

}

// OrreryBody& 
// Simulator::get_orrery_body( std::string name )
// {
//   for( auto& b : orrery_bodies ) {
//     if( b.name == name ) return b;<commit_msg>bugfix: g should be initialized to zero<commit_after>#include <chrono>
#include <thread>
//#include <iostream>
#include <stdexcept>

#include "simulator.hpp"
#include "event.hpp"

#define LOGURU_WITH_STREAMS 1
#include "loguru.hpp"


namespace config  // some of these may later be read from config files
{

const float threshold = 0.01;

}


namespace sim
{

Simulator::Simulator( std::string _scenario_fname ) 
{
  scenario_fname = _scenario_fname;
  user_command_received = false;
  quit_now = false;
  restart = false;
}

void 
Simulator::run()
{  
  using namespace std::chrono_literals;
  
  loguru::set_thread_name("sim manager");
  
  Scenario scenario( scenario_fname );
  for( ;; )
  {
    if( scenario.requires_recompute() ) { recompute_with( scenario ); }

    std::unique_lock<std::mutex> lk( user_command_mutex );
    cv.wait_for( lk, 500ms ); 
    // Spurious wake ups are not a problem here
    if( quit_now ) break;

    scenario.reload_changes(); 
  }
   
  if( compute_thread.joinable() ) compute_thread.join();  
}


void
Simulator::recompute_with( const Scenario& new_scenario )
{
  restart = true;
  if( compute_thread.joinable() ) compute_thread.join();

  // once more unto the breach
  compute_thread = std::thread( 
    &sim::Simulator::compute,
    std::ref( *this ),
    new_scenario
  );
}

void
Simulator::wait()
{
  std::unique_lock<std::mutex> lk( user_command_mutex );
  cv.wait(lk, [this](){ return user_command_received; });  // protects against spurious unblocks
  user_command_received = false;
}

void
Simulator::quit()
{ 
  std::lock_guard<std::mutex> lk( user_command_mutex );
  user_command_received = true;
  quit_now = true;
  cv.notify_one();
}

void 
Simulator::compute( Scenario scenario )
{
  loguru::set_thread_name("compute");
 
  load( scenario );
  
  restart = false;  
  DLOG_S(INFO) << "Starting Simulator: " << scenario.start_jd << " - " << scenario.stop_jd;  

  int simulator_steps = 0;
  double jd = scenario.start_jd;
  while( !restart & !quit_now & ( jd < scenario.stop_jd ) ) 
  { 
    step( jd, scenario.dt );
    jd += scenario.step_jd;
    simulator_steps++;
  }

  DLOG_S(INFO) << "Stopping Simulator: " << jd << " (" << simulator_steps << " steps)";    
}
 
void
Simulator::step( double jd, double dt )
{
  for( auto& s : simulation->space_ships ) { s->update_pos( jd, dt ); }

  for( auto& b : simulation->orrery_bodies ) { b->update_pos( jd ); }

  for( auto& s : simulation->space_ships ) 
  {
    Vector g = { 0, 0, 0 };
    for( auto& b : simulation->orrery_bodies ) {
      Vector R = b->pos - s->pos;
      // Good time to check for collisions too! TODO
      g += (b->GM / R.norm_sq()) * R.normed();
    }
    s->update_acc_and_vel( g, jd, dt );
  }
  resolve_actions( jd );

  simulation->set_last_jd( jd );
}

void
Simulator::resolve_actions( double jd )
{

}

// OrreryBody& 
// Simulator::get_orrery_body( std::string name )
// {
//   for( auto& b : orrery_bodies ) {
//     if( b.name == name ) return b;
{'fraction_non_alphanumeric': 0.1451231859601755, 'fraction_numerical': 0.00320620992237597, 'mean_word_length': 3.4799697656840514, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2082898', 'n_tokens_mistral': 2225, 'n_tokens_neox': 2140, 'n_words': 478}