Beispiel #1
0
        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            var dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (Keyboard.GetState().IsKeyDown(Keys.S))
            {
                dt *= 10;
            }

            for (var i = 0; i < agents.Length; i++)
            {
                var agent = agents[i];
                agent.Position += agent.Velocity * dt;
                if (agent.Position.X < configuration.AgentRadius)
                {
                    agent.Velocity.X = Math.Abs(agent.Velocity.X);
                }
                if (agent.Position.X > configuration.FieldWidth - configuration.AgentRadius)
                {
                    agent.Velocity.X = -Math.Abs(agent.Velocity.X);
                }
                if (agent.Position.Y < configuration.AgentRadius)
                {
                    agent.Velocity.Y = Math.Abs(agent.Velocity.Y);
                }
                if (agent.Position.Y > configuration.FieldHeight - configuration.AgentRadius)
                {
                    agent.Velocity.Y = -Math.Abs(agent.Velocity.Y);
                }
                agent.BluetoothAdapter.Permit(dt);
            }

            int columns = 1 + (configuration.FieldWidth - 1) / SimulationBluetoothConstants.RANGE;
            int rows    = 1 + (configuration.FieldHeight - 1) / SimulationBluetoothConstants.RANGE;
            var bins    = Enumerable.Range(0, columns * rows).Select(i => new List <DeviceAgent>()).ToArray();

            foreach (var agent in agents)
            {
                var binX = ((int)agent.Position.X) / SimulationBluetoothConstants.RANGE;
                var binY = ((int)agent.Position.Y) / SimulationBluetoothConstants.RANGE;
                bins[binX + binY * columns].Add(agent);
            }

            var processAgentPair = new Action <DeviceAgent, DeviceAgent>((a, b) => {
                var distanceSquared = (a.Position - b.Position).LengthSquared();
                if (distanceSquared < SimulationBluetoothConstants.RANGE_SQUARED)
                {
                    if (!a.ActiveConnectionStates.ContainsKey(b))
                    {
                        var connectionState = new SimulationBluetoothConnectionState();

                        if (!a.BluetoothAdapter.NeighborsByAdapterId.ContainsKey(b.BluetoothAdapterId))
                        {
                            var connectionContext = new SimulationBluetoothAdapter.SimulationConnectionContext(a, b);
                            a.BluetoothAdapter.NeighborsByAdapterId[b.BluetoothAdapterId] = new SimulationBluetoothAdapter.SimulationBluetoothNeighbor(a, connectionContext);
                            b.BluetoothAdapter.NeighborsByAdapterId[a.BluetoothAdapterId] = new SimulationBluetoothAdapter.SimulationBluetoothNeighbor(b, connectionContext);
                            connectionContext.Start();
                        }

                        a.ActiveConnectionStates.AddOrThrow(b, connectionState);
                        b.ActiveConnectionStates.AddOrThrow(a, connectionState);
                    }
                }
            });

            var processBins = new Action <List <DeviceAgent>, List <DeviceAgent> >((a, b) => {
                if (a == null || b == null)
                {
                    return;
                }
                if (a == b)
                {
                    for (var i = 0; i < a.Count - 1; i++)
                    {
                        for (var j = i + 1; j < a.Count; j++)
                        {
                            processAgentPair(a[i], a[j]);
                        }
                    }
                }
                else
                {
                    for (var i = 0; i < a.Count; i++)
                    {
                        for (var j = 0; j < b.Count; j++)
                        {
                            processAgentPair(a[i], b[j]);
                        }
                    }
                }
            });

            for (var y = 0; y < rows; y++)
            {
                for (var x = 0; x < columns; x++)
                {
                    var a           = bins[x + y * columns];
                    var right       = x + 1 < columns ? bins[(x + 1) + y * columns] : null;
                    var bottom      = (y + 1 < rows) ? bins[x + (y + 1) * columns] : null;
                    var bottomRight = (x + 1 < columns && y + 1 < rows) ? bins[(x + 1) + (y + 1) * columns] : null;

                    processBins(a, a);
                    processBins(a, right);
                    processBins(a, bottom);
                    processBins(a, bottomRight);
                    processBins(right, bottom);
                }
            }

            var dConnectnessInRangeBase    = dt * 5.0f;
            var dConnectnessOutOfRangeBase = -dt * 50.0f;

            foreach (var agent in agents)
            {
                foreach (var pair in agent.ActiveConnectionStates)
                {
                    if (agent.BluetoothAdapterId.CompareTo(pair.Key.BluetoothAdapterId) < 0)
                    {
                        continue;
                    }

                    var other              = pair.Key;
                    var connectivity       = SimulationBluetoothCalculator.ComputeConnectivity(agent, other);
                    var deltaConnectedness = (connectivity.InRange ? connectivity.SignalQuality * dConnectnessInRangeBase : dConnectnessOutOfRangeBase);

                    var   connectionState   = pair.Value;
                    float nextConnectedness = Math.Max(0.0f, Math.Min(1.0f, connectionState.Connectedness + deltaConnectedness));

                    connectionState.Quality       = connectivity.SignalQuality;
                    connectionState.Connectedness = nextConnectedness;

                    if (nextConnectedness == 0.0f)
                    {
                        agent.ActiveConnectionStates.RemoveOrThrow(other);
                        other.ActiveConnectionStates.RemoveOrThrow(agent);
                    }
                }
            }

//         for (var i = 0; i < agents.Length - 1; i++) {
//            var a = agents[i];
//            var aConnectionStates = a.BluetoothState.ConnectionStates;
//            for (var j = i + 1; j < agents.Length; j++) {
//               var b = agents[j];
//               var bConnectionStates = b.BluetoothState.ConnectionStates;
//            }
//         }

            if (Keyboard.GetState().IsKeyDown(Keys.A))
            {
                epoch++;
                epochAgentIndex = (int)(new Random(epochAgentIndex + 5).Next(0, agents.Length));
                agents[epochAgentIndex].Client.BroadcastAsync(BitConverter.GetBytes(epoch)).Forget();
            }

            if (Keyboard.GetState().IsKeyDown(Keys.Z))
            {
                while (epoch < 5)
                {
                    epoch++;
                    epochAgentIndex = (int)(new Random(epochAgentIndex + 5).Next(0, agents.Length));
                    agents[epochAgentIndex].Client.BroadcastAsync(BitConverter.GetBytes(epoch)).Forget();
                }
            }

            if (Keyboard.GetState().IsKeyDown(Keys.X))
            {
                while (epoch < 10)
                {
                    epoch++;
                    epochAgentIndex = (int)(new Random(epochAgentIndex + 5).Next(0, agents.Length));
                    agents[epochAgentIndex].Client.BroadcastAsync(BitConverter.GetBytes(epoch)).Forget();
                }
            }
        }
Beispiel #2
0
            private async Task RunAsync()
            {
                var pendingBeginConnect = (BeginConnectEvent)null;

                while (true)
                {
                    var adapterEvent = await adapterEventQueueChannel.ReadAsync(CancellationToken.None, x => true).ConfigureAwait(false);

                    switch (adapterEvent.GetType().Name)
                    {
                    case nameof(BeginConnectEvent):
                        var beginConnect = (BeginConnectEvent)adapterEvent;
                        if (pendingBeginConnect == null)
                        {
                            pendingBeginConnect = beginConnect;
                        }
                        else
                        {
                            firstDisconnectChannel.SetIsClosed(false);
                            secondDisconnectChannel.SetIsClosed(false);

                            var pendingBeginConnectCapture = pendingBeginConnect;
                            pendingBeginConnect = null;

                            pendingBeginConnectCapture.ResultBox.SetResult(true);
                            beginConnect.ResultBox.SetResult(true);
                        }
                        break;

                    case nameof(TimeoutConnectEvent):
                        var timeout = (TimeoutConnectEvent)adapterEvent;
                        if (timeout.BeginEvent == pendingBeginConnect)
                        {
                            pendingBeginConnect.ResultBox.SetException(new TimeoutException());
                            pendingBeginConnect = null;
                        }
                        break;

                    case nameof(SendEvent):
                        var send = (SendEvent)adapterEvent;
                        if (!GetIsConnected(send.Initiator))
                        {
                            send.CompletionBox.SetException(new NotConnectedException());
                            break;
                        }

                        var connectivity = SimulationBluetoothCalculator.ComputeConnectivity(firstAgent, secondAgent);
                        if (!connectivity.InRange)
                        {
                            firstDisconnectChannel.SetIsClosed(true);
                            secondDisconnectChannel.SetIsClosed(true);

                            send.CompletionBox.SetException(new NotConnectedException());
                            break;
                        }

                        var deltaBytesSent = (int)Math.Ceiling(connectivity.SignalQuality * send.Interval.TotalSeconds * SimulationBluetoothConstants.MAX_OUTBOUND_BYTES_PER_SECOND);
                        var bytesSent      = send.BytesSent + deltaBytesSent;
                        if (bytesSent >= send.Payload.Length)
                        {
                            await ChannelsExtensions.WriteAsync(GetOtherInboundChannelInternal(send.Initiator), send.Payload).ConfigureAwait(false);

                            send.CompletionBox.SetResult(true);
                            break;
                        }

                        var nextEvent = new SendEvent(DateTime.Now + send.Interval, send.Interval, send.Initiator, send.CompletionBox, send.Payload, bytesSent);
                        await adapterEventQueueChannel.WriteAsync(nextEvent, CancellationToken.None).ConfigureAwait(false);

                        break;
                    }
                }
            }