<commit_before>// During tests, we disable the renderer and that causes a bunch of warnings
// See Cargo.toml for an explanation of this attribute
#![cfg_attr(any(feature = "test", test), allow(dead_code, unused_variables, unused_imports))]

use std::env;
use std::thread;
use std::process::{self, Stdio};
use std::time::Instant;
use std::cell::RefCell;
use std::sync::mpsc;

use piston_window::math;

use client;
use canvas;
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path};
use query::{Query, Request, DrawingCommand, Response};
use radians::{self, Radians};
use {Point, Distance, Event};

use self::DrawingCommand::*;

#[cfg(any(feature = "test", test))]
fn renderer_client(_: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let command = if cfg!(windows) {
        "dir"
    } else {
        "ls"
    };
    let mut test_proc = process::Command::new(command)
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("test process failed to start");
    test_proc.kill().expect("test process could not be killed!");
    let handle = thread::spawn(move || {});
    (test_proc, handle)
}

#[cfg(not(any(feature = "test", test)))]
fn renderer_client(response_tx: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let current_exe = env::current_exe()
        .expect("Could not read path of the currently running executable")
        .into_os_string();
    let mut renderer_process = process::Command::new(current_exe)
        .env("RUN_TURTLE_CANVAS", "true")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("renderer process failed to start");

    let renderer_stdout = renderer_process.stdout.take()
        .expect("renderer process was not opened with stdout");
    let handle = thread::spawn(move || {
        client::run(renderer_stdout, response_tx);
    });

    (renderer_process, handle)
}

pub struct TurtleWindow {
    renderer: RefCell<process::Child>,
    thread_handle: RefCell<Option<thread::JoinHandle<()>>>,
    /// Channel for receiving responses from the rendering process
    response_channel: mpsc::Receiver<Response>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        // This needs to be called as close to the start of the program as possible
        // Since Turtle::new() is called at the beginning of many turtle programs, we do so here
        // to make sure this call occurs when it should.
        canvas::start();

        let (response_tx, response_rx) = mpsc::channel();
        let (renderer_process, handle) = renderer_client(response_tx);

        Self {
            renderer: RefCell::new(renderer_process),
            thread_handle: RefCell::new(Some(handle)),
            response_channel: response_rx,
        }
    }

    pub fn fetch_turtle(&self) -> TurtleState {
        self.send_query(Query::Request(Request::TurtleState));
        match self.wait_for_response() {
            Response::TurtleState(state) => {
                println!("{:?}", state);
                state
            },
            _ => panic!("bug: the renderer process did not sent back TurtleState"),
        }
    }

    pub fn update_turtle(&mut self, turtle: TurtleState) {
        unimplemented!();
    }

    pub fn fetch_drawing(&self) -> DrawingState {
        unimplemented!();
    }

    pub fn update_drawing(&mut self, drawing: DrawingState) {
        unimplemented!();
    }

    fn fetch_temporary_path(&self) -> Option<Path> {
        unimplemented!();
    }

    fn set_temporary_path(&mut self, path: Option<Path>) {<commit_msg>Removed println! leftover from debugging<commit_after>// During tests, we disable the renderer and that causes a bunch of warnings
// See Cargo.toml for an explanation of this attribute
#![cfg_attr(any(feature = "test", test), allow(dead_code, unused_variables, unused_imports))]

use std::env;
use std::thread;
use std::process::{self, Stdio};
use std::time::Instant;
use std::cell::RefCell;
use std::sync::mpsc;

use piston_window::math;

use client;
use canvas;
use animation::{Animation, MoveAnimation, RotateAnimation, AnimationStatus};
use state::{TurtleState, DrawingState, Path};
use query::{Query, Request, DrawingCommand, Response};
use radians::{self, Radians};
use {Point, Distance, Event};

use self::DrawingCommand::*;

#[cfg(any(feature = "test", test))]
fn renderer_client(_: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let command = if cfg!(windows) {
        "dir"
    } else {
        "ls"
    };
    let mut test_proc = process::Command::new(command)
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("test process failed to start");
    test_proc.kill().expect("test process could not be killed!");
    let handle = thread::spawn(move || {});
    (test_proc, handle)
}

#[cfg(not(any(feature = "test", test)))]
fn renderer_client(response_tx: mpsc::Sender<Response>) -> (process::Child, thread::JoinHandle<()>) {
    let current_exe = env::current_exe()
        .expect("Could not read path of the currently running executable")
        .into_os_string();
    let mut renderer_process = process::Command::new(current_exe)
        .env("RUN_TURTLE_CANVAS", "true")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::inherit())
        .spawn()
        .expect("renderer process failed to start");

    let renderer_stdout = renderer_process.stdout.take()
        .expect("renderer process was not opened with stdout");
    let handle = thread::spawn(move || {
        client::run(renderer_stdout, response_tx);
    });

    (renderer_process, handle)
}

pub struct TurtleWindow {
    renderer: RefCell<process::Child>,
    thread_handle: RefCell<Option<thread::JoinHandle<()>>>,
    /// Channel for receiving responses from the rendering process
    response_channel: mpsc::Receiver<Response>,
}

impl TurtleWindow {
    pub fn new() -> TurtleWindow {
        // This needs to be called as close to the start of the program as possible
        // Since Turtle::new() is called at the beginning of many turtle programs, we do so here
        // to make sure this call occurs when it should.
        canvas::start();

        let (response_tx, response_rx) = mpsc::channel();
        let (renderer_process, handle) = renderer_client(response_tx);

        Self {
            renderer: RefCell::new(renderer_process),
            thread_handle: RefCell::new(Some(handle)),
            response_channel: response_rx,
        }
    }

    pub fn fetch_turtle(&self) -> TurtleState {
        self.send_query(Query::Request(Request::TurtleState));
        match self.wait_for_response() {
            Response::TurtleState(state) => {
                state
            },
            _ => panic!("bug: the renderer process did not sent back TurtleState"),
        }
    }

    pub fn update_turtle(&mut self, turtle: TurtleState) {
        unimplemented!();
    }

    pub fn fetch_drawing(&self) -> DrawingState {
        unimplemented!();
    }

    pub fn update_drawing(&mut self, drawing: DrawingState) {
        unimplemented!();
    }

    fn fetch_temporary_path(&self) -> Option<Path> {
        unimplemented!();
    }

    fn set_temporary_path(&mut self, path: Option<Path>) {
{'fraction_non_alphanumeric': 0.13779317697228144, 'fraction_numerical': 0.0, 'mean_word_length': 3.2617830777967063, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 41, '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': '471662', 'n_tokens_mistral': 2292, 'n_tokens_neox': 2239, 'n_words': 578}