Store given transition in the backend

def store_transition(self, frame, action, reward, done, extra_info=None):
        """ Store given transition in the backend """
        self.current_idx = (self.current_idx + 1) % self.buffer_capacity

        if self.frame_stack_compensation:
            # Compensate for frame stack built into the environment
            idx_range = np.arange(-frame.shape[-1] // self.frame_history, 0)
            frame = np.take(frame, indices=idx_range, axis=-1)

        self.state_buffer[self.current_idx] = frame

        self.action_buffer[self.current_idx] = action
        self.reward_buffer[self.current_idx] = reward
        self.dones_buffer[self.current_idx] = done

        if extra_info is not None:
            for name in extra_info:
                if name not in self.extra_data:
                    assert self.current_size == 0, f"New data {name} encountered in the middle of the training"
                    array = extra_info[name]

                    self.extra_data[name] = np.zeros([self.buffer_capacity] + list(array.shape), dtype=array.dtype)

                self.extra_data[name][self.current_idx] = extra_info[name]

        if self.current_size < self.buffer_capacity:
            self.current_size += 1

        return self.current_idx