示例#1
0
        private void LoadSubMaps()
        {
            var builder = new SubMapBuilder();

            m_subMaps = builder.GenerateSubMaps(this);
        }
        private void GenerateSubMaps(ProgressionCounter progression)
        {
            double total = MapsManager.Instance.MapsCount;

            progression.UpdateValue(0, "Loading all maps ...");
            m_mapsPosition = MapsPositionManager.Instance.EnumerateAllMaps().ToDictionary(x => x.MapId);
            int counter = 0;

            Parallel.ForEach(MapsManager.Instance.EnumerateMaps(), map =>
            {
                var builder = new SubMapBuilder();
                AdjacentSubMap[] submaps = builder.GenerateBinders(map);

                m_submaps.TryAdd(map.Id, submaps);

                // update the counter (in percent)
                Interlocked.Increment(ref counter);
                if (counter % 30 == 0)
                {
                    lock (progression)
                    {
                        if (counter % 30 == 0)
                        {
                            progression.UpdateValue(total == 0 ? 100d : (counter / total) * 100d);
                        }
                    }
                }
            });

            progression.UpdateValue(0, "Binding submaps together ...");
            counter = 0;
            Parallel.ForEach(m_submaps, cacheEntry =>
            {
                var neighbours = new[]
                {
                    TryGetMapNeighbour(cacheEntry.Key, MapNeighbour.Right),
                    TryGetMapNeighbour(cacheEntry.Key, MapNeighbour.Top),
                    TryGetMapNeighbour(cacheEntry.Key, MapNeighbour.Left),
                    TryGetMapNeighbour(cacheEntry.Key, MapNeighbour.Bottom),
                };

                foreach (AdjacentSubMap submap in cacheEntry.Value)
                {
                    for (MapNeighbour neighbour = MapNeighbour.Right; neighbour <= MapNeighbour.Bottom; neighbour++)
                    {
                        int i = (int)neighbour - 1;

                        if (neighbours[i] == null)
                        {
                            continue;
                        }

                        MapNeighbour opposite = GetOppositeDirection(neighbour);
                        AdjacentSubMap[] submaps;
                        int mapChangeData         = Map.MapChangeDatas[neighbour];
                        int oppositeMapChangeData = Map.MapChangeDatas[neighbour];
                        int cellChangement        = Map.MapCellChangement[neighbour];

                        if (neighbours[i] != null && m_submaps.TryGetValue(neighbours[i].Value, out submaps))
                        {
                            lock (submaps)
                                foreach (AdjacentSubMap neighbourSubmap in submaps)
                                {
                                    // neighbor already set
                                    lock (submap.SubMap.Neighbours)
                                        if (submap.SubMap.Neighbours.Any(x => x.GlobalId == neighbourSubmap.SubMap.GlobalId))
                                        {
                                            continue;
                                        }

                                    // if any cell of the submaps is a transition to another submap
                                    AdjacentSubMap submap1 = neighbourSubmap;
                                    short[] links          = submap.ChangeCells.Where(x => (x.MapChangeData & mapChangeData) != 0 &&
                                                                                      submap1.ChangeCells.Any(y => y.Id == x.Id + cellChangement)).Select(x => x.Id).ToArray();
                                    if (links.Length > 0)
                                    {
                                        // set in the two ways
                                        lock (submap.SubMap.Neighbours)
                                            lock (neighbourSubmap.SubMap.Neighbours)
                                            {
                                                submap.SubMap.Neighbours.Add(new SubMapNeighbour(neighbourSubmap.SubMap.GlobalId, new MovementTransition(neighbour, links)));
                                                neighbourSubmap.SubMap.Neighbours.Add(new SubMapNeighbour(submap.SubMap.GlobalId,
                                                                                                          new MovementTransition(opposite, links.Select(x => (short)(x + cellChangement)).ToArray())));
                                            }
                                    }
                                }
                        }
                    }
                }

                // update the counter (in percent)
                Interlocked.Increment(ref counter);
                if (counter % 30 == 0)
                {
                    lock (progression)
                    {
                        if (counter % 30 == 0)
                        {
                            progression.UpdateValue(counter / (double)m_submaps.Count * 100d);
                        }
                    }
                }
            });


            using (IRedisClient client = m_clientManager.GetClient())
            {
                progression.UpdateValue(0, "Storing informations on Redis server...");

                IRedisTypedClient <SubMapBinder> typedClient1 = client.As <SubMapBinder>();
                typedClient1.SetRangeInHash(typedClient1.GetHash <long>(REDIS_KEY), m_submaps.Values.SelectMany(x => x).ToDictionary(x => x.SubMap.GlobalId, x => x.SubMap));
                progression.UpdateValue(50);

                IRedisTypedClient <long[]> typedClient2 = client.As <long[]>();
                typedClient2.SetRangeInHash(typedClient2.GetHash <int>(REDIS_MAPS), m_submaps.ToDictionary(x => x.Key, x => x.Value.Select(y => y.SubMap.GlobalId).ToArray()));
                progression.UpdateValue(100);

                client.Set(REDIS_VERSION, VERSION);
            }

            m_submaps.Clear();
            m_mapsPosition.Clear();

            progression.NotifyEnded();
        }