} //ProcessFrontEndRequest(). // // // // // ********************************************************* // **** ProcessCreatedForm() **** // ********************************************************* /// <summary> /// A new Form has been created by the GUI thread, and is now ready to /// be employed. We request all controls for this display (based on the type /// of display it is). /// </summary> /// <param name="anEventArg"></param> private void ProcessCreatedForm(Utilities.GuiCreator.CreateFormEventArgs anEventArg) { // if (anEventArg.CreatedForm is ClusterDisplay) { // We have created a new ClusterDisplay. ClusterDisplay display = (ClusterDisplay)anEventArg.CreatedForm; IEngineHub iengineHub = display.AssocEngineHub; // EngineHub associated with this display. display.FormClosing += new System.Windows.Forms.FormClosingEventHandler(ClusterDisplay_FormClosing); display.ID = System.Threading.Interlocked.Increment(ref m_NextClusterDisplayID); // create a unique ID for this display. m_ClusterDisplays.Add(display.ID, display); // Create quick lookup tables for engine event arg processing. // We create a list of display IDs that contain the controls once given the IEngineHub name // and IEngineContainerID. Dictionary <int, List <int> > clusterIdsToDislayIds = null; if (!m_ClusterDisplayIds.TryGetValue(iengineHub.ServiceName, out clusterIdsToDislayIds)) { // First form created for this engineHub. Add entry for it. clusterIdsToDislayIds = new Dictionary <int, List <int> >(); m_ClusterDisplayIds.Add(iengineHub.ServiceName, clusterIdsToDislayIds); } int displayID = display.ID; foreach (IEngineContainer iengContainer in display.GetEngineContainers()) { List <int> clusterIdList; if (!clusterIdsToDislayIds.TryGetValue(iengContainer.EngineContainerID, out clusterIdList)) { clusterIdList = new List <int>(); clusterIdsToDislayIds.Add(iengContainer.EngineContainerID, clusterIdList); } clusterIdList.Add(displayID); // For each list add this displayID. } Log.NewEntry(LogLevel.Major, "ProcessCreatedForm: ClusterDisplay created. Requesting parameter values."); // Request all parameter values for my new display. // Since Display exists now, when response comes back, we have this display in the display list. foreach (IEngineContainer iEngineContainer in display.GetEngineContainers()) { string engineHubName = iengineHub.ServiceName; // name of StrategyHub I am associated with. foreach (EngineEventArgs e in EngineEventArgs.RequestAllParameters(engineHubName, iEngineContainer)) { // TODO: Throttle requests we will make to StrategyHubs. // display.AssocEngineHub.HubEventEnqueue(e); } } } }//ProcessCreatedForm()
// // // // #endregion//Public Methods #region Private Methods // ***************************************************************** // **** Private Methods **** // ***************************************************************** // // // // ***************************************************** // **** Process Remote Engine Events **** // ***************************************************** /// <summary> /// This is called by the StrategyHub thread whenever it receives events /// from the remote engineHub/engine that we are subscribed to. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> protected void ProcessRemoteEngineEvents(object sender, EventArgs eventArgs) { if (eventArgs is EngineEventArgs) { EngineEventArgs eventArg = (EngineEventArgs)eventArgs; switch (eventArg.MsgType) { // ***************************** // **** New Engine **** // ***************************** case EngineEventArgs.EventType.NewEngine: int ptr = 0; m_EngineGuis = new List <EngineGui>(); while (eventArg.DataObjectList.Count > ptr) { if (eventArg.DataObjectList[ptr] is EngineGui) { m_EngineGuis.Add((EngineGui)eventArg.DataObjectList[ptr]); // extract engine guis from remote engine } else { } ptr++; } // Request parameter values from the new engine. m_RemoteEngineHub.HubEventEnqueue(EngineEventArgs.RequestAllParameters(m_RemoteEngineHub.ServiceName, m_EngineContainerId, m_EngineID)); break; // ***************************************** // **** ParameterChange **** // ***************************************** case EngineEventArgs.EventType.ParameterChange: if (eventArg.Status == EngineEventArgs.EventStatus.Confirm || eventArg.Status == EngineEventArgs.EventStatus.Failed) { // Update my internal values for this parameter. for (int i = 0; i < eventArg.DataIntA.Length; ++i) { int paramId = eventArg.DataIntA[i]; m_ParameterValueTable[paramId] = eventArg.DataObjectList[i]; } // Broadcast the parameter change value EngineEventArgs outEventArg = eventArg.Copy(); outEventArg.EngineHubName = m_LocalEngineHubName; // only hub name differs, so change it. ((StrategyHub)m_LocalEngineHub).OnEngineChanged(outEventArg); } break; // ***************************************** // **** ParameterValue **** // ***************************************** case EngineEventArgs.EventType.ParameterValue: // When I receive parameter change confirmations, I broadcast them as if they originated from me. if (eventArg.Status == EngineEventArgs.EventStatus.Confirm || eventArg.Status == EngineEventArgs.EventStatus.Failed) { // Update my internal values for this parameter. for (int i = 0; i < eventArg.DataIntA.Length; ++i) { int paramId = eventArg.DataIntA[i]; m_ParameterValueTable[paramId] = eventArg.DataObjectList[i]; } // Broadcast the parameter change value EngineEventArgs outEventArg = eventArg.Copy(); outEventArg.EngineHubName = m_LocalEngineHubName; // only hub name differs, so change it. ((StrategyHub)m_LocalEngineHub).OnEngineChanged(outEventArg); // Inform strategy we are ready to complete setup after first ParameterValue callback. // Criteria: 1) Loaded engine guis from NewEngine call back, 2) got parameter values. if (this.IsReadyForSetup == false) { if (m_EngineGuis != null) { this.IsReadyForSetup = true; ((StrategyHub)m_LocalEngineHub).RequestSetupComplete(m_EngineContainerId); } } } break; // ***************************************** // **** default **** // ***************************************** default: // Whenever I receive other events from the remote engine, // I will broadcast them as if they originated from me. if (eventArg.Status == EngineEventArgs.EventStatus.Confirm || eventArg.Status == EngineEventArgs.EventStatus.Failed) { EngineEventArgs outEventArg = eventArg.Copy(); outEventArg.EngineHubName = m_LocalEngineHubName; // only hub name differs, so change it. ((StrategyHub)m_LocalEngineHub).OnEngineChanged(outEventArg); } break; } } else { Log.NewEntry(LogLevel.Error, "ProcessRemoteEvents: Unknown event {0}", eventArgs); } }//ProcessRemoteEngineHubEvents
// // #endregion//Public Methods #region HubEvent Handler // ***************************************************************** // **** Private HubEvent Methods **** // ***************************************************************** // // // **** Hub Event Handler **** // /// <summary> /// Main request handling routine. /// Called only by the internal hub thread. /// </summary> /// <param name="e"></param> protected override void HubEventHandler(EventArgs[] eArgList) { foreach (EventArgs eArg in eArgList) // process each event { Log.NewEntry(LogLevel.Minor, eArg.ToString()); Type eArgType = eArg.GetType(); if (eArgType == typeof(FrontEndHub.DisplayArgs)) { // **************************************** // **** Display Events **** // **************************************** // These are my internal requests, used to create new GUI displays, etc. FrontEndHub.DisplayArgs e = (FrontEndHub.DisplayArgs)eArg; switch (e.Request) { case DisplayArgs.DisplayRequest.NewDisplay: // // *** New Display *** // // When a new display is requested (to be displayed from this hub), a request is pushed // onto the queue and comes here. this way the new ClusterDisplay can be created and // added to the list without the need to lock the list (only the hub thread ever touches // this list.) IEngineHub engineHub = e.display.AssocEngineHub; // hub whose elements we want to display List <ClusterDisplay> displayList; // displays already associated with element hub if (!m_EngineSubscriptions.TryGetValue(engineHub, out displayList)) { // First time we are creating a display for this hub. There is no existing list. displayList = new List <ClusterDisplay>(); // create new list. m_EngineSubscriptions.Add(engineHub, displayList); engineHub.EngineChanged += new EventHandler(this.HubEventEnqueue); } ClusterDisplay newDisplay = e.display; // display created by event creator. displayList.Add(newDisplay); m_ClusterDisplay.Add(newDisplay.ID, newDisplay); // the ID is made by original caller // Now request a complete list of the controls for engines from hub. engineHub.HubEventEnqueue(Engines.EngineEventArgs.RequestAllControls(newDisplay.ID - newDisplay.prevGuiTurns)); //newDisplay.ID)); break; case DisplayArgs.DisplayRequest.RemoveDisplay: // // *** Remove Display *** // ClusterDisplay displayToRemove = e.display; if (displayToRemove != null) { // Remove any book subscriptions List <object> hubsToRemove = new List <object>(); foreach (BookHub hub in m_Subscriptions.Keys) { if (m_Subscriptions[hub].Contains(displayToRemove)) { m_Subscriptions[hub].Remove(displayToRemove); if (m_Subscriptions[hub].Count == 0) { hub.InstrumentChanged -= this.HubEventEnqueue; hubsToRemove.Add(hub); } } } foreach (object hub in hubsToRemove) { m_Subscriptions.Remove((BookHub)hub); } // Remove engine subscriptions foreach (IEngineHub hub in m_EngineSubscriptions.Keys) { if (m_EngineSubscriptions[hub].Contains(displayToRemove)) { m_EngineSubscriptions[hub].Remove(displayToRemove); if (m_EngineSubscriptions[hub].Count == 0) { hub.EngineChanged -= this.HubEventEnqueue; hubsToRemove.Add(hub); } } } foreach (object hub in hubsToRemove) { m_EngineSubscriptions.Remove((IEngineHub)hub); } m_ClusterDisplay[displayToRemove.ID] = null; // dump my pointer to it. } break; default: // // *** default error *** // Log.NewEntry(LogLevel.Error, "Unknown DisplayArg Request."); break; } } else if (eArgType == typeof(EngineEventArgs)) { // ***************************************************** // ***** Process Engine Events **** // ***************************************************** EngineEventArgs e = (EngineEventArgs)eArg; // Pass event to all ClusterDisplays subscribed to event-generating hub. // List <ClusterDisplay> clusterDisplayList; if (m_EngineSubscriptions.TryGetValue(e.EngineHubResponding, out clusterDisplayList)) { // at least some displays are subscribed to this hub. for (int i = 0; i < clusterDisplayList.Count; ++i) { ClusterDisplay display = clusterDisplayList[i]; //List<IEngineContainer> containers = display.GetEngineContainers(); // get containers in this hub. //Dictionary<int, IEngineContainer> containersDict = display.GetEngineContainersDictionary(); //IEngineContainer engineContainer11; if (e.EngineContainerID < 0) { // EngineContainer ID < 0 => event is meant for all containers in hub. // Such events are passed to all Stratgies or Clusters, etc. if (e.MsgType == EngineEventArgs.EventType.GetControls) { // Create the cluster controls for this display. // This request is made by ClusterDisplays (to the Hub they are displaying) after // they have been created, but not completely initialized. // Now proceed through our list of ClusterDisplays and only the first uninitialized // display we find will have the controls inside this eventarg passed to it. bool isNewDisplay = (e.Status == EngineEventArgs.EventStatus.Confirm) && (!display.IsInitialized); if (isNewDisplay) { display.HubEventEnqueue(e); // This is a non-asynchronous call, display is initialized immediately. // Now request all parameter updates for new display. List <EngineEventArgs> newRequestList = EngineEventArgs.RequestAllParameters((display.ID - display.prevGuiTurns), display); //(i,display); foreach (EngineEventArgs newRequest in newRequestList) { e.EngineHubResponding.HubEventEnqueue(newRequest); } break; // only initialize one display per GetControls event. The first uninitialized display gets initialized. } } else { // Every other non-GetControls event for "all clusters" processed here. // Right now, there are none of such terms. List <IEngineContainer> containers = display.GetEngineContainers(); // get containers in this hub. foreach (IEngineContainer container in containers) { container.ProcessEngineEvent(e); } } } else { // A specific containerID was provided. // Pass along this event directly to the specific engineContainer. Dictionary <int, IEngineContainer> containersDict = display.GetEngineContainersDictionary(); IEngineContainer engineContainer; if (containersDict.TryGetValue(e.EngineContainerID, out engineContainer)) { engineContainer.ProcessEngineEvent(e); } else { // Failed to find enginecontainer! Log.NewEntry(LogLevel.Error, "Received event for unknown engineContainerID={0}.", e.EngineContainerID); } } display.RegenerateNow(this, null); // tells the display to repaint, if needed. } } } else { // // **** Unrecognized Event **** // Log.NewEntry(LogLevel.Error, "Unknown event type: {0}", eArgType.ToString()); eArg.GetType(); } } //next event arg } //HubEventHandler()