/// <summary> /// Initializes the mmus /// </summary> /// <param name="timeout"></param> /// <param name="initializationProperties"></param> public bool InitializeMMUs(TimeSpan timeout, string AvatarID, Dictionary <string, string> initializationProperties = null) { //Directly return if not loaded if (!this.IsLoaded) { return(false); } if (initializationProperties == null) { initializationProperties = new Dictionary <string, string>(); } //Initialize all mmus based on the specified timeout bool success = Threading.ExecuteTasksParallel(this.MotionModelUnits, (IMotionModelUnitAccess mmu, CancellationTokenSource tcs) => { mmu.Initialize(this.SkeletonAccess.GetAvatarDescription(AvatarID), initializationProperties); }, timeout); //Raise the event and set flag if successful if (success) { //Set initialized to true this.IsInitialized = true; this.OnInitialized?.Invoke(this, new EventArgs()); } return(success); }
/// <summary> /// Loads the defined MMUs in an async manner /// </summary> /// <param name="list"></param> /// <param name="timeout"></param> /// <param name="async">Defines whether the operation should be executed asynchonously</param> public bool LoadMMUs(List <MMUDescription> list, TimeSpan timeout) { //Create a concurrent dictionary for storing the createad MMUAccesses ConcurrentDictionary <IAdapter, List <MotionModelUnitAccess> > adapterMMUAccesses = new ConcurrentDictionary <IAdapter, List <MotionModelUnitAccess> >(); List <Task> tasks = new List <Task>(); //Execute the loading using different tasks bool allFinished = Threading.ExecuteTasksParallel(this.Adapters, (IAdapter adapter, CancellationTokenSource cts) => { //Load the mmus based on their id adapter.LoadMMUs(list.Select(s => s.ID).ToList(), this.SessionId); //Add the created connections to the concurrent dictionary adapterMMUAccesses.TryAdd(adapter, adapter.CreateMMUConnections(this.SessionId, this.MMUDescriptions)); }, timeout); //Check if all tasks have been finished if (allFinished) { //Add the MMU connections to the global list foreach (List <MotionModelUnitAccess> mmuAccesses in adapterMMUAccesses.Values) { this.MotionModelUnits.AddRange(mmuAccesses); } //raise event this.OnLoaded?.Invoke(this, new EventArgs()); return(true); } else { //throw new Exception("Timeout during establishing connections to MMUs"); return(false); } }
/// <summary> /// Connects to the given adapters /// </summary> /// <param name="adapterAddresses"></param> /// <param name="timeout">The timout in milliseconds</param> public bool Connect(MIPAddress mmiRegisterAddress, TimeSpan timeout, string AvatarID) { //Create a list representing the adapter descriptions List <MAdapterDescription> adapterDescriptions = new List <MAdapterDescription>(); //Create a concurrent dictionary for storing the createad MMUAccesses ConcurrentDictionary <IAdapter, List <MotionModelUnitAccess> > adapterMMUAccesses = new ConcurrentDictionary <IAdapter, List <MotionModelUnitAccess> >(); //Get all registered adapters -> Execute this task in background with the imposed timeout bool adapterDescriptionReceived = Threading.ExecuteTask((CancellationTokenSource cls) => { //The actual function which is executed in the background while (!cls.IsCancellationRequested) { try { //Get all adapter descriptions and create a client for this purpose using (MMIRegisterServiceClient client = new MMIRegisterServiceClient(mmiRegisterAddress.Address, mmiRegisterAddress.Port)) { adapterDescriptions = client.Access.GetRegisteredAdapters(SessionId); break; } } catch (Exception) { Thread.Sleep(100); } } }, timeout); //Directly return if no adapter description was received if (!adapterDescriptionReceived) { return(false); } //Create the service access this.ServiceAccess = new ServiceAccess(mmiRegisterAddress, SessionId); //Fetch all adapter descriptions and create a new adapter instance foreach (MAdapterDescription description in adapterDescriptions) { //Skip if adapter is already available if (this.Adapters.Exists(s => s.Description.Name == description.Name && description.Addresses[0] == description.Addresses[0] && s.Description.Addresses[0].Port == description.Addresses[0].Port)) { continue; } //Add a new remote adapter instance to the list this.Adapters.Add(new RemoteAdapterAccess(description.Addresses[0].Address, description.Addresses[0].Port, description, this)); } ///Dictionary which contains the connected adapters ConcurrentDictionary <IAdapter, bool> connectedAdapters = new ConcurrentDictionary <IAdapter, bool>(); //Create the sessions for each adapter in parallel bool success = Threading.ExecuteTasksParallel(this.Adapters, (IAdapter adapter, CancellationTokenSource cls) => { //Start the adapter adapter.Start(); //Create the session adapter.CreateSession(this.SessionId, this.SkeletonAccess.GetAvatarDescription(AvatarID)); //Add flag if finished connectedAdapters.TryAdd(adapter, true); }, timeout); //Remove all adapters not being connected (therfore iterate over all added adapters) for (int i = this.Adapters.Count - 1; i >= 0; i--) { //Remove the adapter if not connected if (!connectedAdapters.ContainsKey(this.Adapters[i])) { //Close the connection this.Adapters[i].CloseConnection(); this.Adapters.Remove(this.Adapters[i]); } } //Return true if at least one adapter is connected return(this.Adapters.Count > 0); }