// Called from an ingredient to request a load of external content. public void RequestExternalContent(MHIngredient pRequester) { // It seems that some MHEG applications contain active ingredients with empty contents // This isn't correct but we simply ignore that. if (!pRequester.ContentRef.IsSet()) { return; } // Remove any existing content requests for this ingredient. CancelExternalContentRequest(pRequester); string csPath = GetPathName(pRequester.ContentRef.ContentRef); // Is this actually a carousel object? It could be a stream. We should deal // with that separately. if (csPath.Length == 0) { return; } byte[] text; if (m_Context.CheckCarouselObject(csPath) && m_Context.GetCarouselData(csPath, out text)) { // Available now - pass it to the ingredient. pRequester.ContentArrived(text, this); } else { // Need to record this and check later. MHExternContent pContent = new MHExternContent(); pContent.FileName = csPath; pContent.Requester = pRequester; m_ExternContentTable.Add(pContent); } }
// This isn't an MHEG action as such but is used as part of the implementation of "Clone" public override void MakeClone(MHRoot pTarget, MHRoot pRef, MHEngine engine) { MHIngredient pClone = pTarget.Clone(engine); // Clone it. pClone.ObjectIdentifier.GroupId.Copy(m_ObjectIdentifier.GroupId); // Group id is the same as this. pClone.ObjectIdentifier.ObjectNo = ++m_nLastId; // Create a new object id. m_Items.Append(pClone); // Set the object reference result to the newly constructed ref. pRef.SetVariableValue(new MHUnion(pClone.ObjectIdentifier)); pClone.Preparation(engine); // Prepare the clone. }
public void CancelExternalContentRequest(MHIngredient pRequester) { foreach (MHExternContent content in m_ExternContentTable) { if (content.Requester == pRequester) { m_ExternContentTable.Remove(content); return; } } }
public override void Preparation(MHEngine engine) { // Prepare the ingredients first if they are initially active or are initially available programs. for (int i = 0; i < m_Items.Size; i++) { MHIngredient pIngredient = m_Items.GetAt(i); if (pIngredient.InitiallyActive() || pIngredient.InitiallyAvailable()) { pIngredient.Preparation(engine); } } base.Preparation(engine); // Prepare the root object and send the IsAvailable event. }
public override void Activation(MHEngine engine) { if (RunningStatus) { return; } base.Activation(engine); // Run any start-up actions. engine.AddActions(m_StartUp); engine.RunActions(); // Activate the ingredients in order. for (int i = 0; i < m_Items.Size; i++) { MHIngredient pIngredient = m_Items.GetAt(i); if (pIngredient.InitiallyActive()) { pIngredient.Activation(engine); } } m_fRunning = true; // Record the time here. This is the basis for absolute times. m_StartTime = MHTimer.getCurrentTimeSpan(); // Don't generate IsRunning here - that's done by the sub-classes. }
// Set this up from the parse tree. public override void Initialise(MHParseNode p, MHEngine engine) { // Set to empty before we start (just in case). engine.GetGroupId().Copy(""); base.Initialise(p, engine); // Must be an external reference with an object number of zero. Logging.Assert(m_ObjectIdentifier.ObjectNo == 0 && m_ObjectIdentifier.GroupId.Size != 0); // Set the group id for the rest of the group to this. engine.GetGroupId().Copy(m_ObjectIdentifier.GroupId); // Some of the information is irrelevant. // MHParseNode pStdId = p.GetNamedArg(C_STANDARD_IDENTIFIER); // MHParseNode pStdVersion = p.GetNamedArg(C_STANDARD_VERSION); // MHParseNode pObjectInfo = p.GetNamedArg(C_OBJECT_INFORMATION); MHParseNode pOnStartUp = p.GetNamedArg(ASN1Codes.C_ON_START_UP); if (pOnStartUp != null) { m_StartUp.Initialise(pOnStartUp, engine); } MHParseNode pOnCloseDown = p.GetNamedArg(ASN1Codes.C_ON_CLOSE_DOWN); if (pOnCloseDown != null) { m_CloseDown.Initialise(pOnCloseDown, engine); } MHParseNode pOriginalGCPrio = p.GetNamedArg(ASN1Codes.C_ORIGINAL_GC_PRIORITY); if (pOriginalGCPrio != null) { m_nOrigGroupCachePriority = pOriginalGCPrio.GetArgN(0).GetIntValue(); } // Ignore the other stuff at the moment. MHParseNode pItems = p.GetNamedArg(ASN1Codes.C_ITEMS); if (pItems == null) { p.Failure("Missing :Items block"); } for (int i = 0; i < pItems.GetArgCount(); i++) { MHParseNode pItem = pItems.GetArgN(i); MHIngredient pIngredient = null; // Generate the particular kind of ingredient. switch (pItem.GetTagNo()) { case ASN1Codes.C_RESIDENT_PROGRAM: pIngredient = new MHResidentProgram(); break; // NOT UK case ASN1Codes.C_REMOTE_PROGRAM: pIngredient = new MHRemoteProgram(); break; // NOT UK case ASN1Codes.C_INTERCHANGED_PROGRAM: pIngredient = new MHInterChgProgram(); break; // NOT UK case ASN1Codes.C_PALETTE: pIngredient = new MHPalette(); break; // NOT UK case ASN1Codes.C_FONT: pIngredient = new MHFont(); break; // NOT UK case ASN1Codes.C_CURSOR_SHAPE: pIngredient = new MHCursorShape(); break; case ASN1Codes.C_BOOLEAN_VARIABLE: pIngredient = new MHBooleanVar(); break; case ASN1Codes.C_INTEGER_VARIABLE: pIngredient = new MHIntegerVar(); break; case ASN1Codes.C_OCTET_STRING_VARIABLE: pIngredient = new MHOctetStrVar(); break; case ASN1Codes.C_OBJECT_REF_VARIABLE: pIngredient = new MHObjectRefVar(); break; case ASN1Codes.C_CONTENT_REF_VARIABLE: pIngredient = new MHContentRefVar(); break; case ASN1Codes.C_LINK: pIngredient = new MHLink(); break; case ASN1Codes.C_STREAM: pIngredient = new MHStream(); break; case ASN1Codes.C_BITMAP: pIngredient = new MHBitmap(); break; case ASN1Codes.C_LINE_ART: pIngredient = new MHLineArt(); break; case ASN1Codes.C_DYNAMIC_LINE_ART: pIngredient = new MHDynamicLineArt(); break; case ASN1Codes.C_RECTANGLE: pIngredient = new MHRectangle(); break; // NOT UK case ASN1Codes.C_HOTSPOT: pIngredient = new MHHotSpot(); break; // NOT UK case ASN1Codes.C_SWITCH_BUTTON: pIngredient = new MHSwitchButton(); break; // NOT UK case ASN1Codes.C_PUSH_BUTTON: pIngredient = new MHPushButton(); break; case ASN1Codes.C_TEXT: pIngredient = new MHText(); break; case ASN1Codes.C_ENTRY_FIELD: pIngredient = new MHEntryField(); break; case ASN1Codes.C_HYPER_TEXT: pIngredient = new MHHyperText(); break; case ASN1Codes.C_SLIDER: pIngredient = new MHSlider(); break; case ASN1Codes.C_TOKEN_GROUP: pIngredient = new MHTokenGroup(); break; case ASN1Codes.C_LIST_GROUP: pIngredient = new MHListGroup(); break; default: // So we find out about these when debugging. Logging.Log(Logging.MHLogError, "'" + pItem.GetTagNo() + "' tag not in switch"); Logging.Assert(false); // Future proofing: ignore any ingredients that we don't know about. // Obviously these can only arise in the binary coding. break; } if (pIngredient != null) { // Initialise it from its argments. pIngredient.Initialise(pItem, engine); // Remember the highest numbered ingredient if (pIngredient.ObjectIdentifier.ObjectNo > m_nLastId) { m_nLastId = pIngredient.ObjectIdentifier.ObjectNo; } // Add it to the ingedients of this group. m_Items.Append(pIngredient); } } }
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 }