Пример #1
0
        private static void HandlePong(
            CommandResponseOp <PingResponder.Commands.Ping, Pong> response, Connection connection)
        {
            if (response.StatusCode != StatusCode.Success)
            {
                StringBuilder logMessageBuilder = new StringBuilder();
                logMessageBuilder.Append(
                    String.Format("Received invalid OnCommandResponse for request ID {0} with status code {1} to entity with ID {2}.", response.RequestId, response.StatusCode, response.EntityId));
                if (!string.IsNullOrEmpty(response.Message))
                {
                    logMessageBuilder.Append(String.Format("The message was \'{0}\'.", response.Message));
                }

                if (!response.Response.HasValue)
                {
                    logMessageBuilder.Append("The response was missing.");
                }
                else
                {
                    logMessageBuilder.Append(
                        String.Format("The EntityIdResponse ID value was {0}", response.Response.Value));
                }

                connection.SendLogMessage(LogLevel.Warn, LoggerName, logMessageBuilder.ToString());
            }
            else
            {
                var workerType    = response.Response.Value.workerType;
                var workerMessage = response.Response.Value.workerMessage;
                var logMessage    = String.Format("New Response: {0} says \"{1}\"", workerType, workerMessage);

                Console.WriteLine(logMessage);
                connection.SendLogMessage(LogLevel.Info, LoggerName, logMessage);
            }
        }
Пример #2
0
        /// <summary>
        /// Runs through the current view and creates updates for the entities it has write authority over
        /// Also fills in the list of all current sequence ids seen
        /// </summary>
        /// <param name="view"></param>
        /// <param name="connection">Pass the connection in to log messages, not to send updates</param>
        private static bool TryCreateEntitiesUpdatesAndSequenceIdList(Dictionary <EntityId, ViewEntity> view, Connection connection)
        {
            //WorkerConnection.SendLogMessage(LogLevel.Info, "LifeWorker", "Beginning Update Entities");

            int  liveNeighborCount  = 0;
            bool canGetAllNeighbors = false;

            //Run through every id/entity pair in the view
            foreach (var ve in view)
            {
                if (ve.Value.hasAuthority) //Only do this update if this worker has write access to the entity
                {
                    EntityId id = ve.Key;
                    Entity   e  = ve.Value.entity;

                    if (e == null)
                    {
                        throw new NullReferenceException("View Entities Enum has returned a null entity for EntityID " + ve.Key.ToString());
                    }

                    //Only do this if the entity is a Cell type (which should have a Life component)
                    var componentIdSet = e.GetComponentIds();
                    if (componentIdSet.Contains(Life.ComponentId))
                    {
                        // Add the current sequence id to the list of sequence ids for later selective updating
                        AddSequenceIdToList(GetLatestSequenceId(e));

                        //Get the number of live neighbors
                        canGetAllNeighbors = TryGetLiveNeighbors(id, e, view, out liveNeighborCount);

                        //Update the entity based on the live neighbor count
                        if (canGetAllNeighbors)
                        {
                            CreateEntityUpdates(id, e, liveNeighborCount, connection);
                        }
                        else
                        {
                            return(false); //If all neighbors can't be retrieved then the entity can't be updated. If one entity can't be updated then none can.
                        }
                    }
                    else
                    {
                        WorkerConnection.SendLogMessage(LogLevel.Info, "LifeWorker", "Life component not present on entity " + id.ToString() + ". update not done.");
                    }
                }
            }

            return(true); //All neighbors were successfully collected and updates successfully created
        }
Пример #3
0
        private static System.Collections.Generic.List <ulong> sequenceIds = new System.Collections.Generic.List <ulong>(); //List of all current Sequence Ids, could probably split this out to a separate class with all the specific methods

        static int Main(string[] arguments)
        {
            //"${IMPROBABLE_RECEPTIONIST_HOST}", "${IMPROBABLE_RECEPTIONIST_PORT}", "${IMPROBABLE_WORKER_ID}" defined as passed in as part of config
            string hostName = arguments[0];
            ushort port     = Convert.ToUInt16(arguments[1]);
            string workerId = arguments[2];

            Assembly.Load("GeneratedCode");

            using (var connection = ConnectWorker(workerId, hostName, port))
            {
                using (var dispatcher = new Dispatcher())
                {
                    IsConnected = true;

                    dispatcher.OnDisconnect(op =>
                    {
                        Console.Error.WriteLine("[disconnect] {0}", op.Reason);
                        IsConnected = false;
                    });

                    dispatcher.OnLogMessage(op =>
                    {
                        connection.SendLogMessage(op.Level, LoggerName, op.Message);
                        Console.WriteLine("Log Message: {0}", op.Message);
                        if (op.Level == LogLevel.Fatal)
                        {
                            Console.Error.WriteLine("Fatal error: {0}", op.Message);
                            Environment.Exit(ErrorExitStatus);
                        }
                    });

                    dispatcher.OnAuthorityChange <Life>(op =>
                    {
                        ViewEntity entity;
                        if (EntityView.TryGetValue(op.EntityId, out entity))
                        {
                            if (op.Authority == Authority.Authoritative)
                            {
                                entity.hasAuthority = true;
                            }
                            else if (op.Authority == Authority.NotAuthoritative)
                            {
                                entity.hasAuthority = false;
                            }
                            else if (op.Authority == Authority.AuthorityLossImminent)
                            {
                                entity.hasAuthority = false;
                            }
                        }
                    });

                    dispatcher.OnAddComponent <Life>(op =>
                    {
                        ViewEntity entity;
                        if (EntityView.TryGetValue(op.EntityId, out entity))
                        {
                            entity.entity.Add <Life>(op.Data);
                        }
                        else
                        {
                            ViewEntity newEntity = new ViewEntity();
                            EntityView.Add(op.EntityId, newEntity);
                            newEntity.entity.Add <Life>(op.Data);
                        }
                    });

                    dispatcher.OnComponentUpdate <Life>(op =>
                    {
                        ViewEntity entity;
                        if (EntityView.TryGetValue(op.EntityId, out entity))
                        {
                            var update = op.Update.Get();
                            entity.entity.Update <Life>(update);
                        }
                    });
                    dispatcher.OnAddComponent <Neighbors>(op =>
                    {
                        ViewEntity entity;
                        if (EntityView.TryGetValue(op.EntityId, out entity))
                        {
                            entity.entity.Add <Neighbors>(op.Data);
                        }
                        else
                        {
                            ViewEntity newEntity = new ViewEntity();
                            EntityView.Add(op.EntityId, newEntity);
                            newEntity.entity.Add <Neighbors>(op.Data);
                        }
                    });

                    dispatcher.OnComponentUpdate <Neighbors>(op =>
                    {
                        ViewEntity entity;
                        if (EntityView.TryGetValue(op.EntityId, out entity))
                        {
                            var update = op.Update.Get();
                            entity.entity.Update <Neighbors>(update);
                        }
                    });
                    dispatcher.OnAddEntity(op =>
                    {
                        //AddEntity will always be followed by OnAddComponent
                        ViewEntity newEntity   = new ViewEntity();
                        newEntity.hasAuthority = true;
                        newEntity.entity       = new Entity();
                        ViewEntity oldEntity;
                        if (!EntityView.TryGetValue(op.EntityId, out oldEntity))
                        {
                            EntityView.Add(op.EntityId, newEntity);
                        }
                    });
                    dispatcher.OnRemoveEntity(op =>
                    {
                        EntityView.Remove(op.EntityId);
                    });

                    WorkerConnection = connection;
                    WorkerConnection.SendLogMessage(LogLevel.Info, "LifeWorker", "Worker Connected");
                    RunEventLoop(connection, dispatcher);
                }
            }
            return(0);
        }