protected void CheckLinks(MHObjectRef sourceRef, int eventType, MHUnion un) { for (int i = 0; i < (int)m_LinkTable.Count; i++) { m_LinkTable[i].MatchEvent(sourceRef, eventType, un, this); } }
public MHUnion() { m_Type = U_None; m_StrVal = new MHOctetString(); m_ObjRefVal = new MHObjectRef(); m_ContentRefVal = new MHContentRef(); }
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. }
// Return the value, looking up any indirect ref. public void GetValue(MHObjectRef reference, MHEngine engine) { if (m_fIsDirect) { reference.Copy(m_ObjRef); } else { MHUnion result = new MHUnion(); MHRoot pBase = engine.FindObject(m_Indirect); pBase.GetVariableValue(result, engine); result.CheckType(MHUnion.U_ObjRef); reference.Copy(result.ObjRef); } }
public bool Equal(MHObjectRef objr, MHEngine engine) { return(m_nObjectNo == objr.m_nObjectNo && engine.GetPathName(m_GroupId) == engine.GetPathName(objr.m_GroupId)); }
public MHUnion(MHObjectRef objVal) { m_Type = U_ObjRef; m_ObjRefVal = new MHObjectRef(); m_ObjRefVal.Copy(objVal); }
public int RunAll() { // Request to boot or reboot if (m_fBooting) { // Reset everything m_ApplicationStack.Clear(); m_EventQueue.Clear(); m_ExternContentTable.Clear(); m_LinkTable.Clear(); // UK MHEG applications boot from ~//a or ~//startup. Actually the initial // object can also be explicitly given in the MHObjectRef startObj = new MHObjectRef(); startObj.ObjectNo = 0; startObj.GroupId.Copy(new MHOctetString("~//a")); // Launch will block until either it finds the appropriate object and // begins the application or discovers that the file definitely isn't // present in the carousel. It is possible that the object might appear // if one of the containing directories is updated. if (!Launch(startObj)) { startObj.GroupId.Copy(new MHOctetString("~//startup")); if (!Launch(startObj)) { //Logging.Log(Logging.MHLogError, "Unable to launch application"); return(-1); } } m_fBooting = false; } int nNextTime = 0; do { // Check to see if we need to close. if (m_Context.CheckStop()) { return(0); } // Run queued actions. RunActions(); // Now the action stack is empty process the next asynchronous event. // Processing one event may affect how subsequent events are handled. // Check to see if some files we're waiting for have arrived. // This could result in ContentAvailable events. CheckContentRequests(); // Check the timers. This may result in timer events being raised. if (CurrentScene() != null) { int next = CurrentScene().CheckTimers(this); if (nNextTime == 0 || nNextTime > next) { nNextTime = next; } } if (CurrentApp() != null) { // The UK MHEG profile allows applications to have timers. int nAppTime = CurrentApp().CheckTimers(this); if (nAppTime != 0 && (nNextTime == 0 || nAppTime < nNextTime)) { nNextTime = nAppTime; } } if (m_ExternContentTable.Count != 0) { // If we have an outstanding request for external content we need to set a timer. if (nNextTime == 0 || nNextTime > CONTENT_CHECK_TIME) { nNextTime = CONTENT_CHECK_TIME; } } if (m_EventQueue.Count != 0) { MHAsynchEvent pEvent = m_EventQueue[0]; Logging.Log(Logging.MHLogLinks, "Asynchronous event dequeued - " + MHLink.EventTypeToString(pEvent.EventType) + " from " + pEvent.EventSource.ObjectIdentifier.Printable()); CheckLinks(pEvent.EventSource.ObjectIdentifier, pEvent.EventType, pEvent.EventData); m_EventQueue.Remove(pEvent); } } while (m_EventQueue.Count != 0 || m_ActionStack.Count != 0); // Redraw the display if necessary. if (!IsRegionEmpty(m_redrawRegion)) { m_Context.RequireRedraw(m_redrawRegion); m_redrawRegion = new Region(); m_redrawRegion.MakeEmpty(); } return(nNextTime); }
public MHGenericBase() { m_Indirect = new MHObjectRef(); }
public virtual void SetPaletteRef(MHObjectRef newPalette, MHEngine engine) { InvalidAction("SetPaletteRef"); }
public virtual void GetListItem(int nCell, MHObjectRef itemDest, MHEngine engine) { InvalidAction("GetCellItem"); }
public bool Launch(MHObjectRef target) { return(Launch(target, false)); }
public bool Launch(MHObjectRef target, bool fIsSpawn) { string csPath = GetPathName(target.GroupId); // Get path relative to root. if (csPath.Length == 0) { return(false); // No file name. } if (m_fInTransition) { Logging.Log(Logging.MHLogWarning, "Launch during transition - ignoring"); return(false); } // Check that the file exists before we commit to the transition. // This may block if we cannot be sure whether the object is present. byte[] text; if (!m_Context.GetCarouselData(csPath, out text)) { return(false); } m_fInTransition = true; // Starting a transition try { if (CurrentApp() != null) { if (fIsSpawn) { // Run the CloseDown actions. AddActions(CurrentApp().CloseDown); RunActions(); } if (CurrentScene() != null) { CurrentScene().Destruction(this); } CurrentApp().Destruction(this); if (!fIsSpawn) { m_ApplicationStack.Pop(); // Pop and delete the current app. } } MHApplication pProgram = (MHApplication)ParseProgram(text); if ((Logging.GetLoggingLevel() & Logging.MHLogScenes) != 0) // Print it so we know what's going on. { pProgram.Print(Logging.GetLoggingStream(), 0); } if (!pProgram.IsApp) { throw new MHEGException("Expected an application"); } // Save the path we use for this app. pProgram.Path = csPath; // Record the path int nPos = pProgram.Path.LastIndexOf('/'); if (nPos < 0) { pProgram.Path = ""; } else { pProgram.Path = pProgram.Path.Substring(0, nPos); } // Have now got the application. m_ApplicationStack.Push(pProgram); // This isn't in the standard as far as I can tell but we have to do this because // we may have events referring to the old application. m_EventQueue.Clear(); // Activate the application. .... CurrentApp().Activation(this); m_fInTransition = false; // The transition is complete return(true); } catch (MHEGException) { m_fInTransition = false; // The transition is complete return(false); } }
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 }
public MHGenericObjectRef() : base() { m_ObjRef = new MHObjectRef(); }
public void Copy(MHObjectRef objr) { m_nObjectNo = objr.m_nObjectNo; m_GroupId.Copy(objr.m_GroupId); }
// Actions on Programs. public virtual void CallProgram(bool fIsFork, MHObjectRef success, MHSequence <MHParameter> args, MHEngine engine) { InvalidAction("CallProgram"); }
public void Spawn(MHObjectRef target) { Launch(target, true); }
public virtual void GetItemStatus(int nCell, MHObjectRef itemDest, MHEngine engine) { InvalidAction("GetItemStatus"); }
// Look up an object by its object reference. In nearly all cases we want to throw // an exception if it isn't found. In a very few cases where we don't fail this // returns NULL if it isn't there. public MHRoot FindObject(MHObjectRef objr) { return(FindObject(objr, true)); }
protected MHObjectRef m_ObjectIdentifier; // Identifier of this object. public MHRoot() { m_fAvailable = false; m_fRunning = false; m_ObjectIdentifier = new MHObjectRef(); }
public MHFontBody() { m_DirFont = new MHOctetString(); m_IndirFont = new MHObjectRef(); }