public MHRoot FindObject(MHObjectRef oRef, bool failOnNotFound) { // It should match either the application or the scene. MHGroup pSearch = null; MHGroup pScene = CurrentScene(); MHGroup pApp = CurrentApp(); if (pScene != null && GetPathName(pScene.ObjectIdentifier.GroupId) == GetPathName(oRef.GroupId)) { pSearch = pScene; } else if (pApp != null && GetPathName(pApp.ObjectIdentifier.GroupId) == GetPathName(oRef.GroupId)) { pSearch = pApp; } if (pSearch != null) { MHRoot pItem = pSearch.FindByObjectNo(oRef.ObjectNo); if (pItem != null) { return(pItem); } } if (failOnNotFound) { // I've seen at least one case where MHEG code has quite deliberately referred to // an object that may or may not exist at a particular time. // Another case was a call to CallActionSlot with an object reference variable // that had been initialised to zero. Logging.Log(Logging.MHLogWarning, "Reference " + oRef.ObjectNo + " not found"); throw new MHEGException("FindObject failed"); } return(null); // If we don't generate an error. }
protected MHGroup ParseProgram(byte[] text) { if (text.Length == 0) { return(null); } IMHParser parser = null; MHParseNode pTree = null; MHGroup pRes = null; // Look at the first byte to decide whether this is text or binary. Binary // files will begin with 0xA0 or 0xA1, text files with white space, comment ('/') // or curly bracket. // This is only there for testing: all downloaded objects will be in ASN1 byte ch = text[0]; if (ch >= 128) { parser = new MHParseBinary(text); } else { parser = new MHParseText(text); } // Parse the binary or text. pTree = parser.Parse(); switch (pTree.GetTagNo()) { // The parse node should be a tagged item. case ASN1Codes.C_APPLICATION: pRes = new MHApplication(); break; case ASN1Codes.C_SCENE: pRes = new MHScene(); break; default: pTree.Failure("Expected Application or Scene"); break; // throws exception. } pRes.Initialise(pTree, this); // Convert the parse tree. return(pRes); }
public void TransitionToScene(MHObjectRef target) { int i; if (m_fInTransition) { // TransitionTo is not allowed in OnStartUp or OnCloseDown actions. Logging.Log(Logging.MHLogWarning, "TransitionTo during transition - ignoring"); return; } if (target.GroupId.Size == 0) { return; // No file name. } string csPath = GetPathName(target.GroupId); // Check that the file exists before we commit to the transition. byte[] text; if (!m_Context.GetCarouselData(csPath, out text)) { return; } // Parse and run the file. MHGroup pProgram = ParseProgram(text); if (pProgram.IsApp) { throw new MHEGException("Expected a scene"); } // Clear the action queue of anything pending. m_ActionStack.Clear(); // At this point we have managed to load the scene. // Deactivate any non-shared ingredients in the application. MHApplication pApp = CurrentApp(); for (i = pApp.Items.Size; i > 0; i--) { MHIngredient pItem = pApp.Items.GetAt(i - 1); if (!pItem.IsShared()) { pItem.Deactivation(this); // This does not remove them from the display stack. } } m_fInTransition = true; // TransitionTo etc are not allowed. if (pApp.CurrentScene != null) { pApp.CurrentScene.Deactivation(this); // This may involve a call to RunActions pApp.CurrentScene.Destruction(this); } // Everything that belongs to the previous scene should have been removed from the display stack. // At this point we may have added actions to the queue as a result of synchronous // events during the deactivation. // Remove any events from the asynch event queue unless they derive from // the application itself or a shared ingredient. List <MHAsynchEvent> removeEvents = new List <MHAsynchEvent>(); foreach (MHAsynchEvent e in m_EventQueue) { if (!e.EventSource.IsShared()) { removeEvents.Add(e); } } foreach (MHAsynchEvent e in removeEvents) { m_EventQueue.Remove(e); } // Can now actually delete the old scene. if (pApp.CurrentScene != null) { pApp.CurrentScene = null; } // Switch to the new scene. CurrentApp().CurrentScene = (MHScene)pProgram; SetInputRegister(CurrentScene().EventReg); m_redrawRegion = new Region(new Rectangle(0, 0, CurrentScene().SceneCoordX, CurrentScene().SceneCoordY)); // Redraw the whole screen if ((Logging.GetLoggingLevel() & Logging.MHLogScenes) != 0) { // Print it so we know what's going on. pProgram.Print(Logging.GetLoggingStream(), 0); } pProgram.Preparation(this); pProgram.Activation(this); m_fInTransition = false; // The transition is complete }