Example #1
0
 public virtual void Dispose()
 {
     Worker?.Dispose();
     Worker = null;
     Destroy(this);
 }
Example #2
0
        /// <summary>
        ///     Asynchronously connects a worker to the SpatialOS runtime.
        /// </summary>
        /// <remarks>
        ///     Uses the global position of this GameObject as the worker origin.
        ///     Uses <see cref="ShouldUseLocator"/> to determine whether to connect via the Locator.
        /// </remarks>
        /// <param name="workerType">The type of the worker to connect as</param>
        /// <param name="logger">The logger for the worker to use.</param>
        /// <returns></returns>
        public async Task Connect(string workerType, ILogDispatcher logger)
        {
            // Check that other workers have finished trying to connect before this one starts.
            // This prevents races on the workers starting and races on when we start ticking systems.
            await WorkerConnectionSemaphore.WaitAsync();

            try
            {
                // A check is needed for the case that play mode is exited before the semaphore was released.
                if (!Application.isPlaying)
                {
                    return;
                }

                var origin = transform.position;
                ConnectionDelegate connectionDelegate;
                var chosenService        = GetConnectionService();
                var connectionParameters = GetConnectionParameters(workerType, chosenService);
                switch (chosenService)
                {
                case ConnectionService.Receptionist:
                    connectionDelegate = async() =>
                                         await Worker.CreateWorkerAsync(GetReceptionistConfig(workerType), connectionParameters, logger, origin)
                                         .ConfigureAwait(false);

                    break;

                case ConnectionService.Locator:
                    connectionDelegate = async() =>
                                         await Worker
                                         .CreateWorkerAsync(GetLocatorConfig(), connectionParameters, logger, origin)
                                         .ConfigureAwait(false);

                    break;

                case ConnectionService.AlphaLocator:
                    connectionDelegate = async() =>
                                         await Worker.CreateWorkerAsync(GetAlphaLocatorConfig(), connectionParameters, logger, origin)
                                         .ConfigureAwait(false);

                    break;

                default:
                    throw new Exception("No valid connection flow type selected");
                }

                Worker = await ConnectWithRetries(connectionDelegate, MaxConnectionAttempts, logger, workerType);

                Worker.OnDisconnect += OnDisconnected;

                HandleWorkerConnectionEstablished();

                World.Active = World.Active ?? Worker.World;
                ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.AllWorlds.ToArray());
            }
            catch (Exception e)
            {
                logger.HandleLog(LogType.Error, new LogEvent("Failed to create worker")
                                 .WithException(e)
                                 .WithField("WorkerType", workerType)
                                 .WithField("Message", e.Message));
#if UNITY_EDITOR
                // Temporary warning to be replaced when we can reliably detect if a local runtime is running, or not.
                logger.HandleLog(LogType.Warning,
                                 new LogEvent(
                                     "Is a local runtime running? If not, you can start one from 'SpatialOS -> Local launch' or by pressing Cmd/Ctrl-L")
                                 .WithField("Reason", "A worker running in the Editor failed to connect"));
#endif
                // A check is needed for the case that play mode is exited before the connection can complete.
                if (Application.isPlaying)
                {
                    HandleWorkerConnectionFailure(e.Message);
                    Dispose();
                }
            }
            finally
            {
                WorkerConnectionSemaphore.Release();
            }

            foreach (var callback in workerConnectedCallbacks)
            {
                callback(Worker);
            }
        }
Example #3
0
 public WorkerSystem(Worker worker)
 {
     Worker = worker;
 }