/// <summary>
        /// Destroys the traffic light and removes it
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="destroyGroup"></param>
        public void RemoveNodeFromSimulation(ushort nodeId, bool destroyGroup, bool removeTrafficLight)
        {
#if DEBUG
            Log.Warning($"TrafficLightSimulationManager.RemoveNodeFromSimulation({nodeId}, {destroyGroup}, {removeTrafficLight}) called.");
#endif

            TrafficLightSimulation sim = TrafficLightSimulations[nodeId];
            if (sim == null)
            {
                return;
            }
            TrafficLightManager tlm = TrafficLightManager.Instance;

            if (sim.TimedLight != null)
            {
                // remove/destroy all timed traffic lights in group
                List <ushort> oldNodeGroup = new List <ushort>(sim.TimedLight.NodeGroup);
                foreach (var timedNodeId in oldNodeGroup)
                {
                    var otherNodeSim = GetNodeSimulation(timedNodeId);
                    if (otherNodeSim == null)
                    {
                        continue;
                    }

                    if (destroyGroup || timedNodeId == nodeId)
                    {
                        //Log._Debug($"Slave: Removing simulation @ node {timedNodeId}");
                        otherNodeSim.DestroyTimedTrafficLight();
                        otherNodeSim.DestroyManualTrafficLight();
                        ((TrafficLightSimulation)otherNodeSim).NodeGeoUnsubscriber?.Dispose();
                        RemoveNodeFromSimulation(timedNodeId);
                        if (removeTrafficLight)
                        {
                            Constants.ServiceFactory.NetService.ProcessNode(timedNodeId, delegate(ushort nId, ref NetNode node) {
                                tlm.RemoveTrafficLight(timedNodeId, ref node);
                                return(true);
                            });
                        }
                    }
                    else
                    {
                        otherNodeSim.TimedLight.RemoveNodeFromGroup(nodeId);
                    }
                }
            }

            //Flags.setNodeTrafficLight(nodeId, false);
            //sim.DestroyTimedTrafficLight();
            sim.DestroyManualTrafficLight();
            sim.NodeGeoUnsubscriber?.Dispose();
            RemoveNodeFromSimulation(nodeId);
            if (removeTrafficLight)
            {
                Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate(ushort nId, ref NetNode node) {
                    tlm.RemoveTrafficLight(nodeId, ref node);
                    return(true);
                });
            }
        }
コード例 #2
0
        /// <summary>
        /// Destroys the traffic light and removes it
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="destroyGroup"></param>
        public void RemoveNodeFromSimulation(ushort nodeId, bool destroyGroup, bool removeTrafficLight)
        {
#if DEBUG
            Log._Debug($"TrafficLightSimulationManager.RemoveNodeFromSimulation({nodeId}, {destroyGroup}, {removeTrafficLight}) called.");
#endif

            if (!TrafficLightSimulations[nodeId].HasSimulation())
            {
                return;
            }
            TrafficLightManager tlm = TrafficLightManager.Instance;

            if (TrafficLightSimulations[nodeId].IsTimedLight())
            {
                // remove/destroy all timed traffic lights in group
                List <ushort> oldNodeGroup = new List <ushort>(TrafficLightSimulations[nodeId].TimedLight.NodeGroup);
                foreach (var timedNodeId in oldNodeGroup)
                {
                    if (!TrafficLightSimulations[timedNodeId].HasSimulation())
                    {
                        continue;
                    }

                    if (destroyGroup || timedNodeId == nodeId)
                    {
                        //Log._Debug($"Slave: Removing simulation @ node {timedNodeId}");
                        //TrafficLightSimulations[timedNodeId].Destroy();
                        RemoveNodeFromSimulation(timedNodeId);
                        if (removeTrafficLight)
                        {
                            Constants.ServiceFactory.NetService.ProcessNode(timedNodeId, delegate(ushort nId, ref NetNode node) {
                                tlm.RemoveTrafficLight(timedNodeId, ref node);
                                return(true);
                            });
                        }
                    }
                    else
                    {
                        if (TrafficLightSimulations[timedNodeId].IsTimedLight())
                        {
                            TrafficLightSimulations[timedNodeId].TimedLight.RemoveNodeFromGroup(nodeId);
                        }
                    }
                }
            }

            //Flags.setNodeTrafficLight(nodeId, false);
            //sim.DestroyTimedTrafficLight();
            //TrafficLightSimulations[nodeId].DestroyManualTrafficLight();
            RemoveNodeFromSimulation(nodeId);
            if (removeTrafficLight)
            {
                Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate(ushort nId, ref NetNode node) {
                    tlm.RemoveTrafficLight(nodeId, ref node);
                    return(true);
                });
            }
        }
        /// <summary>
        /// Destroys the traffic light and removes it
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="destroyGroup"></param>
        public void RemoveNodeFromSimulation(ushort nodeId,
                                             bool destroyGroup,
                                             bool removeTrafficLight)
        {
            Log._Debug($"TrafficLightSimulationManager.RemoveNodeFromSimulation({nodeId}, " +
                       $"{destroyGroup}, {removeTrafficLight}) called.");

            if (!TrafficLightSimulations[nodeId].HasSimulation())
            {
                return;
            }

            TrafficLightManager tlm = TrafficLightManager.Instance;

            if (TrafficLightSimulations[nodeId].IsTimedLight())
            {
                // remove/destroy all timed traffic lights in group
                var oldNodeGroup = new List <ushort>(TrafficLightSimulations[nodeId].timedLight.NodeGroup);

                foreach (ushort timedNodeId in oldNodeGroup)
                {
                    if (!TrafficLightSimulations[timedNodeId].HasSimulation())
                    {
                        continue;
                    }

                    if (destroyGroup || timedNodeId == nodeId)
                    {
                        // Log._Debug($"Slave: Removing simulation @ node {timedNodeId}");
                        // TrafficLightSimulations[timedNodeId].Destroy();
                        RemoveNodeFromSimulation(timedNodeId);
                        if (removeTrafficLight)
                        {
                            tlm.RemoveTrafficLight(timedNodeId, ref timedNodeId.ToNode());
                        }
                    }
                    else
                    {
                        if (TrafficLightSimulations[timedNodeId].IsTimedLight())
                        {
                            TrafficLightSimulations[timedNodeId].timedLight.RemoveNodeFromGroup(nodeId);
                        }
                    }
                }
            }

            // Flags.setNodeTrafficLight(nodeId, false);
            // sim.DestroyTimedTrafficLight();
            // TrafficLightSimulations[nodeId].DestroyManualTrafficLight();
            RemoveNodeFromSimulation(nodeId);

            if (removeTrafficLight)
            {
                tlm.RemoveTrafficLight(nodeId, ref nodeId.ToNode());
            }
        }
        public bool LoadData(List <Configuration.TimedTrafficLights> data)
        {
            bool success = true;

            Log.Info($"Loading {data.Count} timed traffic lights (new method)");

            TrafficLightManager tlm = TrafficLightManager.Instance;

            HashSet <ushort> nodesWithSimulation = new HashSet <ushort>();

            foreach (Configuration.TimedTrafficLights cnfTimedLights in data)
            {
                nodesWithSimulation.Add(cnfTimedLights.nodeId);
            }

            Dictionary <ushort, ushort>         masterNodeIdBySlaveNodeId = new Dictionary <ushort, ushort>();
            Dictionary <ushort, List <ushort> > nodeGroupByMasterNodeId   = new Dictionary <ushort, List <ushort> >();

            foreach (Configuration.TimedTrafficLights cnfTimedLights in data)
            {
                try {
                    // TODO most of this should not be necessary at all if the classes around TimedTrafficLights class were properly designed
                    List <ushort> currentNodeGroup = cnfTimedLights.nodeGroup.Distinct().ToList();                    // enforce uniqueness of node ids
                    if (!currentNodeGroup.Contains(cnfTimedLights.nodeId))
                    {
                        currentNodeGroup.Add(cnfTimedLights.nodeId);
                    }
                    // remove any nodes that are not configured to have a simulation
                    currentNodeGroup = new List <ushort>(currentNodeGroup.Intersect(nodesWithSimulation));

                    // remove invalid nodes from the group; find if any of the nodes in the group is already a master node
                    ushort masterNodeId     = 0;
                    int    foundMasterNodes = 0;
                    for (int i = 0; i < currentNodeGroup.Count;)
                    {
                        ushort nodeId = currentNodeGroup[i];
                        if (!Services.NetService.IsNodeValid(currentNodeGroup[i]))
                        {
                            currentNodeGroup.RemoveAt(i);
                            continue;
                        }
                        else if (nodeGroupByMasterNodeId.ContainsKey(nodeId))
                        {
                            // this is a known master node
                            if (foundMasterNodes > 0)
                            {
                                // we already found another master node. ignore this node.
                                currentNodeGroup.RemoveAt(i);
                                continue;
                            }
                            // we found the first master node
                            masterNodeId = nodeId;
                            ++foundMasterNodes;
                        }
                        ++i;
                    }

                    if (masterNodeId == 0)
                    {
                        // no master node defined yet, set the first node as a master node
                        masterNodeId = currentNodeGroup[0];
                    }

                    // ensure the master node is the first node in the list (TimedTrafficLights depends on this at the moment...)
                    currentNodeGroup.Remove(masterNodeId);
                    currentNodeGroup.Insert(0, masterNodeId);

                    // update the saved node group and master-slave info
                    nodeGroupByMasterNodeId[masterNodeId] = currentNodeGroup;
                    foreach (ushort nodeId in currentNodeGroup)
                    {
                        masterNodeIdBySlaveNodeId[nodeId] = masterNodeId;
                    }
                } catch (Exception e) {
                    Log.Warning($"Error building timed traffic light group for TimedNode {cnfTimedLights.nodeId} (NodeGroup: {string.Join(", ", cnfTimedLights.nodeGroup.Select(x => x.ToString()).ToArray())}): " + e.ToString());
                    success = false;
                }
            }

            foreach (Configuration.TimedTrafficLights cnfTimedLights in data)
            {
                try {
                    if (!masterNodeIdBySlaveNodeId.ContainsKey(cnfTimedLights.nodeId))
                    {
                        continue;
                    }
                    ushort        masterNodeId = masterNodeIdBySlaveNodeId[cnfTimedLights.nodeId];
                    List <ushort> nodeGroup    = nodeGroupByMasterNodeId[masterNodeId];

                    Log._Debug($"Adding timed light at node {cnfTimedLights.nodeId}. NodeGroup: {string.Join(", ", nodeGroup.Select(x => x.ToString()).ToArray())}");

                    ITrafficLightSimulation sim = AddNodeToSimulation(cnfTimedLights.nodeId);
                    sim.SetupTimedTrafficLight(nodeGroup);
                    var timedNode = sim.TimedLight;

                    int j = 0;
                    foreach (Configuration.TimedTrafficLightsStep cnfTimedStep in cnfTimedLights.timedSteps)
                    {
                        Log._Debug($"Loading timed step {j} at node {cnfTimedLights.nodeId}");
                        ITimedTrafficLightsStep step = timedNode.AddStep(cnfTimedStep.minTime, cnfTimedStep.maxTime, (TrafficLight.StepChangeMetric)cnfTimedStep.changeMetric, cnfTimedStep.waitFlowBalance);

                        foreach (KeyValuePair <ushort, Configuration.CustomSegmentLights> e in cnfTimedStep.segmentLights)
                        {
                            if (!Services.NetService.IsSegmentValid(e.Key))
                            {
                                continue;
                            }
                            e.Value.nodeId = cnfTimedLights.nodeId;

                            Log._Debug($"Loading timed step {j}, segment {e.Key} at node {cnfTimedLights.nodeId}");
                            ICustomSegmentLights lights = null;
                            if (!step.CustomSegmentLights.TryGetValue(e.Key, out lights))
                            {
                                Log._Debug($"No segment lights found at timed step {j} for segment {e.Key}, node {cnfTimedLights.nodeId}");
                                continue;
                            }
                            Configuration.CustomSegmentLights cnfLights = e.Value;

                            Log._Debug($"Loading pedestrian light @ seg. {e.Key}, step {j}: {cnfLights.pedestrianLightState} {cnfLights.manualPedestrianMode}");

                            lights.ManualPedestrianMode = cnfLights.manualPedestrianMode;
                            lights.PedestrianLightState = cnfLights.pedestrianLightState;

                            foreach (KeyValuePair <ExtVehicleType, Configuration.CustomSegmentLight> e2 in cnfLights.customLights)
                            {
                                Log._Debug($"Loading timed step {j}, segment {e.Key}, vehicleType {e2.Key} at node {cnfTimedLights.nodeId}");
                                ICustomSegmentLight light = null;
                                if (!lights.CustomLights.TryGetValue(e2.Key, out light))
                                {
                                    Log._Debug($"No segment light found for timed step {j}, segment {e.Key}, vehicleType {e2.Key} at node {cnfTimedLights.nodeId}");
                                    continue;
                                }
                                Configuration.CustomSegmentLight cnfLight = e2.Value;

                                light.InternalCurrentMode = (TrafficLight.LightMode)cnfLight.currentMode;                                 // TODO improve & remove
                                light.SetStates(cnfLight.mainLight, cnfLight.leftLight, cnfLight.rightLight, false);
                            }
                        }
                        ++j;
                    }
                } catch (Exception e) {
                    // ignore, as it's probably corrupt save data. it'll be culled on next save
                    Log.Warning("Error loading data from TimedNode (new method): " + e.ToString());
                    success = false;
                }
            }

            foreach (Configuration.TimedTrafficLights cnfTimedLights in data)
            {
                try {
                    ITrafficLightSimulation sim = GetNodeSimulation(cnfTimedLights.nodeId);
                    if (sim == null || sim.TimedLight == null)
                    {
                        continue;
                    }

                    var timedNode = sim.TimedLight;

                    timedNode.Housekeeping();
                    if (cnfTimedLights.started)
                    {
                        timedNode.Start(cnfTimedLights.currentStep);
                    }
                } catch (Exception e) {
                    Log.Warning($"Error starting timed light @ {cnfTimedLights.nodeId}: " + e.ToString());
                    success = false;
                }
            }

            return(success);
        }