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(); }