示例#1
0
 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);
     }
 }
示例#2
0
 public MHUnion()
 {
     m_Type          = U_None;
     m_StrVal        = new MHOctetString();
     m_ObjRefVal     = new MHObjectRef();
     m_ContentRefVal = new MHContentRef();
 }
示例#3
0
        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.
        }
示例#4
0
 // 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);
     }
 }
示例#5
0
 public bool Equal(MHObjectRef objr, MHEngine engine)
 {
     return(m_nObjectNo == objr.m_nObjectNo && engine.GetPathName(m_GroupId) == engine.GetPathName(objr.m_GroupId));
 }
示例#6
0
 public MHUnion(MHObjectRef objVal)
 {
     m_Type      = U_ObjRef;
     m_ObjRefVal = new MHObjectRef();
     m_ObjRefVal.Copy(objVal);
 }
示例#7
0
        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);
        }
示例#8
0
 public MHGenericBase()
 {
     m_Indirect = new MHObjectRef();
 }
示例#9
0
 public virtual void SetPaletteRef(MHObjectRef newPalette, MHEngine engine)
 {
     InvalidAction("SetPaletteRef");
 }
示例#10
0
 public virtual void GetListItem(int nCell, MHObjectRef itemDest, MHEngine engine)
 {
     InvalidAction("GetCellItem");
 }
示例#11
0
 public bool Launch(MHObjectRef target)
 {
     return(Launch(target, false));
 }
示例#12
0
        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);
            }
        }
示例#13
0
        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
        }
示例#14
0
 public MHGenericObjectRef() : base()
 {
     m_ObjRef = new MHObjectRef();
 }
示例#15
0
 public void Copy(MHObjectRef objr)
 {
     m_nObjectNo = objr.m_nObjectNo;
     m_GroupId.Copy(objr.m_GroupId);
 }
示例#16
0
 // Actions on Programs.
 public virtual void CallProgram(bool fIsFork, MHObjectRef success, MHSequence <MHParameter> args, MHEngine engine)
 {
     InvalidAction("CallProgram");
 }
示例#17
0
 public void Spawn(MHObjectRef target)
 {
     Launch(target, true);
 }
示例#18
0
 public virtual void GetItemStatus(int nCell, MHObjectRef itemDest, MHEngine engine)
 {
     InvalidAction("GetItemStatus");
 }
示例#19
0
 // 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));
 }
示例#20
0
        protected MHObjectRef m_ObjectIdentifier; // Identifier of this object.

        public MHRoot()
        {
            m_fAvailable       = false;
            m_fRunning         = false;
            m_ObjectIdentifier = new MHObjectRef();
        }
示例#21
0
 public MHFontBody()
 {
     m_DirFont   = new MHOctetString();
     m_IndirFont = new MHObjectRef();
 }