// Send a message representing new page info to the controller. // Typically will be called when the user presses previous or next. // Sends until success, in a new thread. public void SendStorybookPageInfoAction(StorybookPageInfo pageInfo) { Thread thread = new Thread(() => { Dictionary <string, object> publish = new Dictionary <string, object>(); publish.Add("topic", Constants.STORYBOOK_PAGE_INFO_TOPIC); publish.Add("op", "publish"); Dictionary <string, object> data = new Dictionary <string, object>(); data.Add("header", RosbridgeUtilities.GetROSHeader()); data.Add("story_name", pageInfo.storyName); data.Add("page_number", pageInfo.pageNumber); data.Add("sentences", pageInfo.sentences); List <Dictionary <string, object> > tinkerTexts = new List <Dictionary <string, object> > (); foreach (StorybookTinkerText t in pageInfo.tinkerTexts) { Dictionary <string, object> tinkerText = new Dictionary <string, object>(); tinkerText.Add("has_scene_object", t.hasSceneObject); tinkerText.Add("scene_object_id", t.sceneObjectId); tinkerText.Add("word", t.word); tinkerTexts.Add(tinkerText); } data.Add("tinkertexts", tinkerTexts); List <Dictionary <string, object> > sceneObjects = new List <Dictionary <string, object> >(); foreach (StorybookSceneObject o in pageInfo.sceneObjects) { Dictionary <string, object> sceneObject = new Dictionary <string, object>(); sceneObject.Add("id", o.id); sceneObject.Add("label", o.label); sceneObject.Add("in_text", o.inText); sceneObjects.Add(sceneObject); } data.Add("scene_objects", sceneObjects); List <Dictionary <string, object> > prompts = new List <Dictionary <string, object> >(); foreach (JiboPrompt p in pageInfo.prompts) { Dictionary <string, object> prompt = new Dictionary <string, object>(); prompt.Add("question", p.question); prompt.Add("response", p.response); prompt.Add("hint", p.hint); prompts.Add(prompt); } data.Add("prompts", prompts); publish.Add("msg", data); Logger.Log("Sending page info ROS message: " + Json.Serialize(publish)); bool sent = false; while (!sent) { sent = this.rosClient.SendMessage(Json.Serialize(publish)); } Logger.Log("Successfully sent page info ROS message."); }); thread.Start(); }
// Helper function to wrap together two actions: // (1) loading a page and (2) sending the StorybookPageInfo message over ROS. private void loadPageAndSendRosMessage(SceneDescription sceneDescription) { // Load the page. this.storyManager.LoadPage(sceneDescription); // Send the ROS message to update the controller about what page we're on now. StorybookPageInfo updatedInfo = new StorybookPageInfo(); updatedInfo.storyName = this.currentStory.GetName(); updatedInfo.pageNumber = this.currentPageNumber; updatedInfo.sentences = this.storyManager.stanzaManager.GetAllSentenceTexts(); // Update state (will get automatically sent to the controller. StorybookStateManager.SetStorySelected(this.currentStory.GetName(), this.currentStory.GetNumPages()); // Gather information about scene objects. StorybookSceneObject[] sceneObjects = new StorybookSceneObject[sceneDescription.sceneObjects.Length]; for (int i = 0; i < sceneDescription.sceneObjects.Length; i++) { SceneObject so = sceneDescription.sceneObjects[i]; StorybookSceneObject sso = new StorybookSceneObject(); sso.id = so.id; sso.label = so.label; sso.inText = so.inText; sceneObjects[i] = sso; } updatedInfo.sceneObjects = sceneObjects; // Gather information about tinker texts. StorybookTinkerText[] tinkerTexts = new StorybookTinkerText[this.storyManager.tinkerTexts.Count]; for (int i = 0; i < this.storyManager.tinkerTexts.Count; i++) { TinkerText tt = this.storyManager.tinkerTexts[i].GetComponent <TinkerText>(); StorybookTinkerText stt = new StorybookTinkerText(); stt.word = tt.word; stt.hasSceneObject = false; stt.sceneObjectId = -1; tinkerTexts[i] = stt; } foreach (Trigger trigger in sceneDescription.triggers) { if (trigger.type == TriggerType.CLICK_TINKERTEXT_SCENE_OBJECT) { tinkerTexts[trigger.args.textId].hasSceneObject = true; tinkerTexts[trigger.args.textId].sceneObjectId = trigger.args.sceneObjectId; } } updatedInfo.tinkerTexts = tinkerTexts; // Send the message. if (Constants.USE_ROS) { this.rosManager.SendStorybookPageInfoAction(updatedInfo); } }