Ejemplo n.º 1
0
        public ILandChunk GetLandChunkAt(int x, int y)
        {
            ILandChunk result = null;

            int offsetX = x - this.currentChunksArea.Left;
            int offsetY = y - this.currentChunksArea.Top;

            if (offsetX >= 0 && offsetY >= 0)
            {
                int chunkX = offsetX / CHUNK_SIZE;
                int chunkY = offsetY / CHUNK_SIZE;

                if (chunkY < this.landChunkArea.Count &&
                    chunkX < this.landChunkArea[0].Count)
                {
                    offsetX %= CHUNK_SIZE;
                    offsetY %= CHUNK_SIZE;

                    LandChunkContainer container = this.landChunkArea[chunkY][chunkX];

                    if (container.LandChunk != null)
                    {
                        result = container.LandChunk;
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        private void PrepareChunksUpdated(List <LandChunkContainer> chunksRemoved, List <LandChunkContainer> chunksAdded)
        {
            foreach (LandChunkContainer container in chunksRemoved)
            {
                this.landChunksToRemove.Add(container.Area);

                /*if (container.LandChunk != null
                 *  && this.currentLoadedLandChunks.ContainsKey(container.Area)
                 *  && this.landChunksCache.Contains(container.LandChunk) == false)
                 * {
                 *  this.landChunksToRemove.Add(container.Area);
                 * }
                 * else if(this.landChunkLoader.IsLandChunkLoading(container.Area) || this.pendingLandChunksImported.ContainsKey(container.Area) == false)
                 * {
                 *  this.landChunksToRemove.Add(container.Area);
                 * }*/
            }

            List <LandChunkContainer> subChunksAddedList = new List <LandChunkContainer>();

            foreach (LandChunkContainer container in chunksAdded)
            {
                this.mainMutex.WaitOne();

                // Order is important
                if (this.landChunkLoader.IsLandChunkLoading(container.Area) == false &&
                    this.pendingLandChunksImported.ContainsKey(container.Area) == false)
                {
                    this.mainMutex.ReleaseMutex();

                    if (this.currentLoadedLandChunks.ContainsKey(container.Area))
                    {
                        LandChunkContainer landChunkContainer = this.currentLoadedLandChunks[container.Area];
                        ILandChunk         landChunkCache     = this.landChunksCache.FirstOrDefault(pElem => pElem.Area == container.Area);
                        if (landChunkCache != null)
                        {
                            this.landChunksCache.Remove(landChunkCache);

                            container.LandChunk          = landChunkContainer.LandChunk;
                            landChunkContainer.LandChunk = null;
                            this.currentLoadedLandChunks[container.Area] = container;
                        }
                    }
                    else
                    {
                        subChunksAddedList.Add(container);
                    }
                }
                else
                {
                    this.mainMutex.ReleaseMutex();
                }

                this.landChunksToRemove.Remove(container.Area);
            }

            this.landChunkLoader.RequestChunk(subChunksAddedList);
        }
Ejemplo n.º 3
0
        private void UpdateLandChunks()
        {
            this.mainMutex.WaitOne();

            IEnumerable <Tuple <LandChunkContainer, ILandChunk> > tuplesImported = this.pendingLandChunksImported.Values.ToList();

            this.mainMutex.ReleaseMutex();

            List <ILandChunk>    realLandChunksToRemove  = new List <ILandChunk>();
            List <IntRect>       firstLandChunksToRemove = this.landChunksToRemove.ToList();
            HashSet <ILandChunk> realLandChunksToImport  = new HashSet <ILandChunk>();

            foreach (Tuple <LandChunkContainer, ILandChunk> tupleImported in tuplesImported)
            {
                tupleImported.Item1.LandChunk = tupleImported.Item2;

                this.currentLoadedLandChunks.Add(tupleImported.Item1.Area, tupleImported.Item1);

                realLandChunksToImport.Add(tupleImported.Item2);

                this.mainMutex.WaitOne();

                this.pendingLandChunksImported.Remove(tupleImported.Item1.Area);

                this.mainMutex.ReleaseMutex();
            }


            foreach (IntRect areaToRemove in firstLandChunksToRemove)
            {
                if (this.currentLoadedLandChunks.ContainsKey(areaToRemove))
                {
                    LandChunkContainer containerToRemove = this.currentLoadedLandChunks[areaToRemove];

                    ILandChunk landChunkToRemove;

                    this.landChunksCache.Add(containerToRemove.LandChunk);
                    if (this.landChunksCache.Count > NB_MAX_CACHE_CHUNK)
                    {
                        ILandChunk landChunkFront = this.landChunksCache.ElementAt(0);
                        this.landChunksCache.RemoveAt(0);

                        this.currentLoadedLandChunks.Remove(landChunkFront.Area);

                        landChunkToRemove = landChunkFront;
                    }
                    else
                    {
                        landChunkToRemove = null;
                    }

                    this.landChunksToRemove.Remove(containerToRemove.LandChunk.Area);

                    if (landChunkToRemove != null)
                    {
                        if (realLandChunksToImport.Contains(landChunkToRemove))
                        {
                            realLandChunksToImport.Remove(landChunkToRemove);
                        }
                        else
                        {
                            realLandChunksToRemove.Add(landChunkToRemove);
                        }
                    }
                }
            }

            foreach (ILandChunk landChunkReleased in realLandChunksToRemove)
            {
                this.NotifyChunkRemoved(landChunkReleased);
            }

            foreach (ILandChunk landChunkImported in realLandChunksToImport)
            {
                this.NotifyChunkAdded(landChunkImported);
            }

            if (realLandChunksToImport.Count > 0 || realLandChunksToRemove.Count > 0)
            {
                this.NotifyAllChunksUpdated();
            }
        }
Ejemplo n.º 4
0
        public void OnFocusAreaChanged(Vector2f areaPosition, Vector2f areaSize)
        {
            List <LandChunkContainer> removedChunk = new List <LandChunkContainer>();
            List <LandChunkContainer> addedChunk   = new List <LandChunkContainer>();

            IntRect newArea = new IntRect(
                (int)(areaPosition.X - areaSize.X / 2 + 1),
                (int)(areaPosition.Y - areaSize.Y / 2 + 1),
                (int)(areaSize.X + 1),
                (int)(areaSize.Y + 1));

            IntRect newChunksArea = new IntRect(
                (int)Math.Floor(((double)newArea.Left) / CHUNK_SIZE) - 1,
                (int)Math.Floor(((double)newArea.Top) / CHUNK_SIZE) - 1,
                newArea.Width / CHUNK_SIZE + 4,
                newArea.Height / CHUNK_SIZE + 4);

            // Remove out bounds chunks
            int minNbRemove = Math.Min(newChunksArea.Top - this.currentChunksArea.Top, this.currentChunksArea.Height);
            int maxNbRemove = Math.Min((this.currentChunksArea.Top + this.currentChunksArea.Height) - (newChunksArea.Top + newChunksArea.Height), this.currentChunksArea.Height);

            if (minNbRemove > 0)
            {
                List <List <LandChunkContainer> > subLandChunkList = this.landChunkArea.GetRange(0, minNbRemove);
                foreach (List <LandChunkContainer> row in subLandChunkList)
                {
                    removedChunk.AddRange(row);

                    Console.WriteLine(row.Count + " up chunk removed");
                }
                landChunkArea.RemoveRange(0, minNbRemove);
            }

            if (maxNbRemove > 0)
            {
                List <List <LandChunkContainer> > subLandChunkList = this.landChunkArea.GetRange(landChunkArea.Count - maxNbRemove, maxNbRemove);
                foreach (List <LandChunkContainer> row in subLandChunkList)
                {
                    removedChunk.AddRange(row);

                    Console.WriteLine(row.Count + " down chunk removed");
                }
                landChunkArea.RemoveRange(landChunkArea.Count - maxNbRemove, maxNbRemove);
            }

            minNbRemove = Math.Min(newChunksArea.Left - this.currentChunksArea.Left, this.currentChunksArea.Width);
            maxNbRemove = Math.Min((this.currentChunksArea.Left + this.currentChunksArea.Width) - (newChunksArea.Left + newChunksArea.Width), this.currentChunksArea.Width);

            foreach (List <LandChunkContainer> row in this.landChunkArea)
            {
                if (minNbRemove > 0)
                {
                    removedChunk.AddRange(row.GetRange(0, minNbRemove));
                    row.RemoveRange(0, minNbRemove);

                    Console.WriteLine("left chunk removed");
                }

                if (maxNbRemove > 0)
                {
                    removedChunk.AddRange(row.GetRange(landChunkArea.Count - maxNbRemove, maxNbRemove));
                    row.RemoveRange(landChunkArea.Count - maxNbRemove, maxNbRemove);

                    Console.WriteLine("right chunk removed");
                }
            }

            // Add new chunks
            int minNbAdd = Math.Min(this.currentChunksArea.Left - newChunksArea.Left, newChunksArea.Width);
            int maxNbAdd = Math.Min((newChunksArea.Left + newChunksArea.Width) - (this.currentChunksArea.Left + this.currentChunksArea.Width), newChunksArea.Width);

            int i = 0;

            if (minNbAdd > 0)
            {
                foreach (List <LandChunkContainer> row in this.landChunkArea)
                {
                    List <LandChunkContainer> chunksAdded = new List <LandChunkContainer>();
                    for (int j = 0; j < minNbAdd; j++)
                    {
                        IntRect area = new IntRect((newChunksArea.Left + j) * CHUNK_SIZE, (newChunksArea.Top + i) * CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE);

                        LandChunkContainer container = new LandChunkContainer(area);

                        chunksAdded.Add(container);
                    }
                    addedChunk.AddRange(chunksAdded);

                    row.InsertRange(0, chunksAdded);

                    Console.WriteLine(chunksAdded.Count + " left chunk added");

                    i++;
                }
            }

            i = 0;
            if (maxNbAdd > 0)
            {
                foreach (List <LandChunkContainer> row in this.landChunkArea)
                {
                    List <LandChunkContainer> chunksAdded = new List <LandChunkContainer>();
                    for (int j = 0; j < maxNbAdd; j++)
                    {
                        IntRect area = new IntRect((newChunksArea.Left + row.Count + j) * CHUNK_SIZE, (newChunksArea.Top + i) * CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE);

                        LandChunkContainer container = new LandChunkContainer(area);

                        chunksAdded.Add(container);
                    }

                    addedChunk.AddRange(chunksAdded);

                    row.InsertRange(row.Count, chunksAdded);

                    Console.WriteLine(chunksAdded.Count + " right chunk added");

                    i++;
                }
            }

            minNbAdd = Math.Min(currentChunksArea.Top - newChunksArea.Top, newChunksArea.Height);
            maxNbAdd = Math.Min((newChunksArea.Top + newChunksArea.Height) - (currentChunksArea.Top + currentChunksArea.Height), newChunksArea.Height);

            if (minNbAdd > 0)
            {
                for (i = minNbAdd - 1; i >= 0; i--)
                {
                    List <LandChunkContainer> chunksAdded = new List <LandChunkContainer>();

                    for (int j = 0; j < newChunksArea.Width; j++)
                    {
                        IntRect area = new IntRect((newChunksArea.Left + j) * CHUNK_SIZE, (newChunksArea.Top + i) * CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE);

                        LandChunkContainer container = new LandChunkContainer(area);

                        chunksAdded.Add(container);
                    }
                    addedChunk.AddRange(chunksAdded);

                    this.landChunkArea.Insert(0, chunksAdded);

                    Console.WriteLine(chunksAdded.Count + " top chunk added");
                }
            }

            if (maxNbAdd > 0)
            {
                for (i = 0; i < maxNbAdd; i++)
                {
                    List <LandChunkContainer> chunksAdded = new List <LandChunkContainer>();

                    for (int j = 0; j < newChunksArea.Width; j++)
                    {
                        IntRect area = new IntRect((newChunksArea.Left + j) * CHUNK_SIZE, (newChunksArea.Top + (newChunksArea.Height - maxNbAdd) + i) * CHUNK_SIZE, CHUNK_SIZE, CHUNK_SIZE);

                        LandChunkContainer container = new LandChunkContainer(area);

                        chunksAdded.Add(container);
                    }
                    addedChunk.AddRange(chunksAdded);

                    this.landChunkArea.Insert(this.landChunkArea.Count, chunksAdded);

                    Console.WriteLine(chunksAdded.Count + " down chunk added");
                }
            }

            this.PrepareChunksUpdated(removedChunk, addedChunk);

            this.currentChunksArea = newChunksArea;
        }