<commit_before>'''
    This manages the active state of the robot
''' 

import sys
import threading

import fake_wpilib as wpilib
from .drive_train import DriveTrain

class RobotController(object):

    MODE_DISABLED = 0
    MODE_AUTONOMOUS = 1
    MODE_OPERATOR_CONTROL = 2
    
    def __init__(self, robot_module, myrobot):
    
        self.mode = RobotController.MODE_DISABLED
    
        self.robot_module = robot_module
        self.myrobot = myrobot
        self.drive_train = DriveTrain(DriveTrain.TANK_TREAD)
        
        # attach to the robot
        self.myrobot.on_IsEnabled = self.on_IsEnabled
        self.myrobot.on_IsAutonomous = self.on_IsAutonomous
        self.myrobot.on_IsOperatorControl = self.on_IsOperatorControl
        
        # any data shared with the snake board must be protected by
        # this since it's running in a different thread
        self._lock = threading.RLock()
        
        self.thread = threading.Thread(target=self._robot_thread)
        
    def run(self):
        self._run_code = True
        self.thread.start()
        
    def stop(self):
        with self._lock:
            self._run_code = False
        
            # if the robot code is spinning in any of the modes, then
            # we need to change the mode so it returns back to us
            if self.mode == RobotController.MODE_DISABLED:
                self.mode = RobotController.MODE_OPERATOR_CONTROL
            else:
                self.mode = RobotController.MODE_DISABLED
        
        try:
            self.thread.join(timeout=5.0)
        except RuntimeError:
            return False
        
        return not self.thread.is_alive()
        
    #
    # API used by the SnakeBoard class
    #
    
    def set_joystick(self, x, y):
        '''
            Receives joystick values from the SnakeBoard
        '''
        with self.driver_station.lock:
            drive_stick = self.driver_station.sticks[0]
            drive_stick[0] = x
            drive_stick[1] = y
            
    def set_mode(self, mode):
        
        if mode not in [RobotController.MODE_DISABLED, 
                        RobotController.MODE_AUTONOMOUS, 
                        RobotController.MODE_OPERATOR_CONTROL]:
            raise ValueError("Invalid value for mode: %s" % mode)
        
        with self._lock:
            self.mode = mode

    def get_mode(self):
        with self._lock:
            return self.mode

    #
    # Runs the code
    #
    
    def on_IsEnabled(self):
        with self._lock:
            return self.mode != RobotController.MODE_DISABLED
        
    def on_IsAutonomous(self, tm):
        with self._lock:
            if not self._run_code:
                return False
            return self.mode == RobotController.MODE_AUTONOMOUS
        
    def on_IsOperatorControl(self, tm):<commit_msg>Add callback function that gets called when the robot mode changes<commit_after>'''
    This manages the active state of the robot
''' 

import sys
import threading

import fake_wpilib as wpilib
from .drive_train import DriveTrain

class RobotController(object):

    MODE_DISABLED = 0
    MODE_AUTONOMOUS = 1
    MODE_OPERATOR_CONTROL = 2
    
    def __init__(self, robot_module, myrobot):
    
        self.mode = RobotController.MODE_DISABLED
        self.mode_callback = None
    
        self.robot_module = robot_module
        self.myrobot = myrobot
        self.drive_train = DriveTrain(DriveTrain.TANK_TREAD)
        
        # attach to the robot
        self.myrobot.on_IsEnabled = self.on_IsEnabled
        self.myrobot.on_IsAutonomous = self.on_IsAutonomous
        self.myrobot.on_IsOperatorControl = self.on_IsOperatorControl
        
        # any data shared with the snake board must be protected by
        # this since it's running in a different thread
        self._lock = threading.RLock()
        
        self.thread = threading.Thread(target=self._robot_thread)
        
    def run(self):
        self._run_code = True
        self.thread.start()
        
    def stop(self):
        with self._lock:
            self._run_code = False
        
            # if the robot code is spinning in any of the modes, then
            # we need to change the mode so it returns back to us
            if self.mode == RobotController.MODE_DISABLED:
                self.mode = RobotController.MODE_OPERATOR_CONTROL
            else:
                self.mode = RobotController.MODE_DISABLED
        
        try:
            self.thread.join(timeout=5.0)
        except RuntimeError:
            return False
        
        return not self.thread.is_alive()
        
    #
    # API used by the SnakeBoard class
    #
    
    def on_mode_change(self, callable):
        '''When the robot mode changes, call the function with the mode'''
        with self._lock:
            self.mode_callback = callable
    
    def set_joystick(self, x, y):
        '''
            Receives joystick values from the SnakeBoard
        '''
        with self.driver_station.lock:
            drive_stick = self.driver_station.sticks[0]
            drive_stick[0] = x
            drive_stick[1] = y
            
    def set_mode(self, mode):
        
        if mode not in [RobotController.MODE_DISABLED, 
                        RobotController.MODE_AUTONOMOUS, 
                        RobotController.MODE_OPERATOR_CONTROL]:
            raise ValueError("Invalid value for mode: %s" % mode)
        
        with self._lock:
            self.mode = mode
            callback = self.mode_callback
            
        # don't call from inside the lock
        callback(mode)

    def get_mode(self):
        with self._lock:
            return self.mode

    #
    # Runs the code
    #
    
    def on_IsEnabled(self):
        with self._lock:
            return self.mode != RobotController.MODE_DISABLED
        
    def on_IsAutonomous(self, tm):
        with self._lock:
            if not self._run_code:
                return False
            return self.mode == RobotController.MODE_AUTONOMOUS
        
    def on_IsOperatorControl(self, tm):
{'fraction_non_alphanumeric': 0.06548007838014369, 'fraction_numerical': 0.002612671456564337, 'mean_word_length': 1.759009009009009, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '7444612', 'n_tokens_mistral': 1765, 'n_tokens_neox': 1719, 'n_words': 444}