}//end constructor // // #endregion//Constructors #region no Properties // ***************************************************************** // **** Properties **** // ***************************************************************** // // #endregion//Properties #region Public Methods // ***************************************************************** // **** Public Methods **** // ***************************************************************** // // /// <summary> /// A new display is made and passed to this hub for management. /// Called by an external thread. /// </summary> /// <param name="aHub"></param> public void NewDisplay(ClusterDisplay newDisplay) { lock (NextClusterDisplayIDLock) { // Get next id number available. newDisplay.ID = m_NextClusterDisplayID; newDisplay.prevGuiTurns = currentClusterDisplayNumber; m_NextClusterDisplayID += 1; } newDisplay.FormClosing += new System.Windows.Forms.FormClosingEventHandler(Display_FormClosing); DisplayArgs args = new DisplayArgs(); args.display = newDisplay; args.Request = DisplayArgs.DisplayRequest.NewDisplay; HubEventEnqueue(args); }//NewDisplay().
} //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()
} //ProcessEngineEvents() // // // // ***************************************************************** // **** Process FrontEndRequest **** // ***************************************************************** /// <summary> /// These are my internal requests, used to create new GUI displays, etc. /// </summary> /// <param name="request"></param> private void ProcessFrontEndRequest(FrontEndRequest request) { EngineEventArgs e; Log.NewEntry(LogLevel.Minor, "FrontEndRequest {0}", request.ToString()); switch (request.Type) { case FrontEndRequest.Request.Start: // ************************************ // *** Start *** // ************************************ m_ServiceState = ServiceStates.Running; // We are ready to run. OnServiceStateChanged(); break; case FrontEndRequest.Request.Stop: // ************************************ // *** Stop *** // ************************************ if (m_ServiceState != ServiceStates.Stopping) { // Shut down displays m_ServiceState = ServiceStates.Stopping; // Trying to stop. OnServiceStateChanged(); // Tell displays to shut down. foreach (ClusterDisplay display in m_ClusterDisplays.Values) { if (display != null && (!display.IsDisposed)) { try { display.Invoke((System.Threading.ThreadStart) delegate() { display.Close(); }); } catch (Exception) { } } } } // Verify we can stop. if (m_ClusterDisplays.Count == 0) { // All displays are removed and shutdown. We can exit now. m_ServiceState = ServiceStates.Stopped; OnServiceStateChanged(); base.Stop(); } else { Log.NewEntry(LogLevel.Major, "Shutting down. {0} displays remaining.", m_ClusterDisplays.Count); m_PendingRequests.Enqueue(request); } break; case FrontEndRequest.Request.AddService: // ************************************ // *** Add Service *** // ************************************ // This is called internally, each time a new service is added // to the application. We attempt to get information about it. if (request.ObjectList == null) { return; } for (int i = 0; i < request.ObjectList.Count; ++i) { string serviceName = (string)request.ObjectList[i]; bool isGoodToAdd = true; // First check whether this type of engine is we want to ignore. foreach (string pattern in m_IgnoreEngineNamePatterns) { if (serviceName.Contains(pattern)) { isGoodToAdd = false; break; } } if (isGoodToAdd == false) { return; } IService iService; if (m_AppServices.TryGetService(serviceName, out iService) && iService is IEngineHub) { // We have discovered a new EngineHub if (!m_RemoteEngineHubs.ContainsKey(serviceName)) { // This new engineHub isunknown to us. IEngineHub iEngine = (IEngineHub)iService; m_RemoteEngineHubs.Add(serviceName, iEngine); Log.NewEntry(LogLevel.Major, "Adding new EngineHub {0}. Requesting all controls.", serviceName); iEngine.EngineChanged += new EventHandler(this.HubEventEnqueue); e = EngineEventArgs.RequestAllControls(serviceName); iEngine.HubEventEnqueue(e); } } } break; case FrontEndRequest.Request.AddDisplay: // ************************************ // *** Add Display *** // ************************************ // When a new display is requested, we search for the GuiTemplates already // stored for that new display, create the display and hand them to the display. List <string> engineHubNames = new List <string>(); if (request.ObjectList == null || (request.ObjectList.Count == 1 && request.ObjectList[0] == null)) { engineHubNames.AddRange(m_RemoteEngineHubs.Keys); } else { foreach (object o in request.ObjectList) { if (o is string) { engineHubNames.Add((string)o); } } } // Open displays for each hub name provided. foreach (string engineName in engineHubNames) { Dictionary <int, GuiTemplates.EngineContainerGui> engineHubTemplates = null; IEngineHub iEngineHub = null; if (m_RemoteEngineHubs.TryGetValue(engineName, out iEngineHub) && m_EngineHubTemplates.TryGetValue(engineName, out engineHubTemplates)) { Log.NewEntry(LogLevel.Major, "AddDisplay requesting new ClusterDisplay for {0}.", engineName); List <GuiTemplates.EngineContainerGui> templates = new List <GuiTemplates.EngineContainerGui>(engineHubTemplates.Values); Utilities.GuiCreator creator = Utilities.GuiCreator.Create(typeof(ClusterDisplay), this, iEngineHub, templates); creator.FormCreated += new EventHandler(this.HubEventEnqueue); // push created form on to my usual queue. creator.Start(); } else { Log.NewEntry(LogLevel.Major, "AddDisplay request rejected for {0}. No templates found.", engineName); } } break; case FrontEndRequest.Request.RemoveDisplay: // ************************************ // *** Remove Display *** // ************************************ ClusterDisplay display2 = (ClusterDisplay)request.ObjectList[0]; int n = display2.ID; if (m_ClusterDisplays.ContainsKey(n)) { m_ClusterDisplays.Remove(n); Log.NewEntry(LogLevel.Major, "RemoveDisplay id {1}. Remaining {0}.", m_ClusterDisplays.Count, n); } break; default: Log.NewEntry(LogLevel.Warning, "Unknown request."); break; } //requestType switch } //ProcessFrontEndRequest().
// // #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()