# Path: flexbe_mirror/src/flexbe_mirror/mirror_state.py
# class MirrorState(EventState):
#     '''
#     This state will display its possible outcomes as buttons in the GUI
#     and is designed in a way to be created dynamically.
#     '''
# 
#     def __init__(self, target_name, target_path, given_outcomes, outcome_autonomy):
#         super(MirrorState, self).__init__(outcomes=given_outcomes)
#         self.set_rate(100)
#         self._target_name = target_name
#         self._target_path = target_path
# 
#         self._outcome_topic = 'flexbe/mirror/outcome'
# 
#         self._pub = ProxyPublisher()
#         self._sub = ProxySubscriberCached({self._outcome_topic: UInt8})
# 
#     def execute(self, userdata):
#         if self._sub.has_buffered(self._outcome_topic):
#             msg = self._sub.get_from_buffer(self._outcome_topic)
#             if msg.data < len(self.outcomes):
#                 rospy.loginfo("State update: %s > %s", self._target_name, self.outcomes[msg.data])
#                 return self.outcomes[msg.data]
#         try:
#             self.sleep()
#         except ROSInterruptException:
#             print('Interrupted mirror sleep.')
# 
#     def on_enter(self, userdata):
#         self._pub.publish('flexbe/behavior_update', String("/" + "/".join(self._target_path.split("/")[1:])))


import rospy
import threading
import zlib
from flexbe_core.core import PreemptableState, PreemptableStateMachine, LockableStateMachine
from .mirror_state import MirrorState
from flexbe_core.proxy import ProxyPublisher, ProxySubscriberCached
from flexbe_msgs.msg import ContainerStructure, BehaviorSync, BEStatus
from std_msgs.msg import Empty, String, Int32, UInt8
        self._sub.subscribe('flexbe/status', BEStatus, self._status_callback)
        self._sub.subscribe('flexbe/mirror/sync', BehaviorSync, self._sync_callback)
        self._sub.subscribe('flexbe/mirror/preempt', Empty, self._preempt_callback)

    def _mirror_callback(self, msg):
        rate = rospy.Rate(10)
        while self._stopping:
            rate.sleep()

        if self._running:
            rospy.logwarn('Received a new mirror structure while mirror is already running, '
                          'adding to buffer (checksum: %s).' % str(msg.behavior_id))
        elif self._active_id != 0 and msg.behavior_id != self._active_id:
            rospy.logwarn('Checksum of received mirror structure (%s) does not match expected (%s), '
                          'will ignore.' % (str(msg.behavior_id), str(self._active_id)))
            return
        else:
            rospy.loginfo('Received a new mirror structure for checksum %s' % str(msg.behavior_id))

        self._struct_buffer.append(msg)

        if self._active_id == msg.behavior_id:
            self._struct_buffer = list()
            self._mirror_state_machine(msg)
            rospy.loginfo('Mirror built.')

            self._execute_mirror()

    def _status_callback(self, msg):
        if msg.code == BEStatus.STARTED:

# Path: flexbe_mirror/src/flexbe_mirror/mirror_state.py
# class MirrorState(EventState):
#     '''
#     This state will display its possible outcomes as buttons in the GUI
#     and is designed in a way to be created dynamically.
#     '''
# 
#     def __init__(self, target_name, target_path, given_outcomes, outcome_autonomy):
#         super(MirrorState, self).__init__(outcomes=given_outcomes)
#         self.set_rate(100)
#         self._target_name = target_name
#         self._target_path = target_path
# 
#         self._outcome_topic = 'flexbe/mirror/outcome'
# 
#         self._pub = ProxyPublisher()
#         self._sub = ProxySubscriberCached({self._outcome_topic: UInt8})
# 
#     def execute(self, userdata):
#         if self._sub.has_buffered(self._outcome_topic):
#             msg = self._sub.get_from_buffer(self._outcome_topic)
#             if msg.data < len(self.outcomes):
#                 rospy.loginfo("State update: %s > %s", self._target_name, self.outcomes[msg.data])
#                 return self.outcomes[msg.data]
#         try:
#             self.sleep()
#         except ROSInterruptException:
#             print('Interrupted mirror sleep.')
# 
#     def on_enter(self, userdata):
#         self._pub.publish('flexbe/behavior_update', String("/" + "/".join(self._target_path.split("/")[1:])))


# Path: flexbe_mirror/src/flexbe_mirror/flexbe_mirror.py
import rospy
import threading
import zlib
from flexbe_core.core import PreemptableState, PreemptableStateMachine, LockableStateMachine
from .mirror_state import MirrorState
from flexbe_core.proxy import ProxyPublisher, ProxySubscriberCached
from flexbe_msgs.msg import ContainerStructure, BehaviorSync, BEStatus
from std_msgs.msg import Empty, String, Int32, UInt8

        self._sub.subscribe('flexbe/status', BEStatus, self._status_callback)
        self._sub.subscribe('flexbe/mirror/sync', BehaviorSync, self._sync_callback)
        self._sub.subscribe('flexbe/mirror/preempt', Empty, self._preempt_callback)

    def _mirror_callback(self, msg):
        rate = rospy.Rate(10)
        while self._stopping:
            rate.sleep()

        if self._running:
            rospy.logwarn('Received a new mirror structure while mirror is already running, '
                          'adding to buffer (checksum: %s).' % str(msg.behavior_id))
        elif self._active_id != 0 and msg.behavior_id != self._active_id:
            rospy.logwarn('Checksum of received mirror structure (%s) does not match expected (%s), '
                          'will ignore.' % (str(msg.behavior_id), str(self._active_id)))
            return
        else:
            rospy.loginfo('Received a new mirror structure for checksum %s' % str(msg.behavior_id))

        self._struct_buffer.append(msg)

        if self._active_id == msg.behavior_id:
            self._struct_buffer = list()
            self._mirror_state_machine(msg)
            rospy.loginfo('Mirror built.')

            self._execute_mirror()

    def _status_callback(self, msg):
        if msg.code == BEStatus.STARTED:

            thread = threading.Thread(target=self._start_mirror, args=[msg])