// Send a message representing storybook state to the controller, in a new thread.
    // Doesn't need to return Action because it's only used as a timer elapsed handler.
    private void sendStorybookState(object sender, System.Timers.ElapsedEventArgs e)
    {
        Thread t = new Thread(() => {
            Dictionary <string, object> publish = new Dictionary <string, object>();
            publish.Add("topic", Constants.STORYBOOK_STATE_TOPIC);
            publish.Add("op", "publish");

            Dictionary <string, object> data = new Dictionary <string, object>();

            // Note that this is protected by a lock, so although ROS messages could
            // send out of order, the information within them will be consistent.
            // And if the sending rate isn't too high, the likelihood of out of order messages
            // is low, and inconsequential for the controller anyway.
            // TODO: should devise a better scheme to make sure states are sent in order.
            // Can also use the sequence numbers provided in the header.
            // Or use a lock in this class so that only one state message can be sent at a time.
            StorybookState currentStorybookState = this.storybookStateManager.getCurrentState();
            data.Add("header", RosbridgeUtilities.GetROSHeader());
            data.Add("audio_playing", currentStorybookState.audioPlaying);
            // ROS freaks out if it gets a null value, so just fill it in with an empty string
            // if there is no provided audio file.
            string audioFile = currentStorybookState.audioFile;
            if (audioFile == null)
            {
                audioFile = "";
            }
            data.Add("audio_file", audioFile);
            data.Add("storybook_mode", (int)currentStorybookState.storybookMode);
            data.Add("current_story", currentStorybookState.currentStory);
            data.Add("num_pages", currentStorybookState.numPages);
            data.Add("evaluating_stanza_index", currentStorybookState.evaluatingStanzaIndex);

            publish.Add("msg", data);

            bool success = this.rosClient.SendMessage(Json.Serialize(publish));
            if (!success)
            {
                Logger.Log("Failed to send StorybookState message: " + Json.Serialize((publish)));
            }
        });

        t.Start();
    }
Beispiel #2
0
    public static void Init()
    {
        // Set default values for start of interaction.
        currentState = new StorybookState {
            audioPlaying            = false,
            audioFile               = "",
            storybookMode           = StorybookMode.NotReading,
            currentStory            = "",
            numPages                = 0,
            evaluatingSentenceIndex = -1, // Something that's not -1 or higher, but can't use null.
        };

        rosMessageData = new Dictionary <string, object>();
        rosMessageData.Add("audio_playing", currentState.audioPlaying);
        rosMessageData.Add("audio_file", currentState.audioFile);
        rosMessageData.Add("storybook_mode", (int)currentState.storybookMode);
        rosMessageData.Add("current_story", currentState.currentStory);
        rosMessageData.Add("num_pages", currentState.numPages);
        rosMessageData.Add("evaluating_sentence_index", currentState.evaluatingSentenceIndex);
    }
    public StorybookStateManager()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            throw new Exception("Cannot attempt to create multiple StorybookStateManagers");
        }

        this.stateLock = new Object();

        // Set default values for start of interaction.
        this.currentState = new StorybookState {
            audioPlaying          = false,
            audioFile             = "",
            storybookMode         = StorybookMode.NotReading,
            currentStory          = "",
            numPages              = 0,
            evaluatingStanzaIndex = -1,
        };
    }