Пример #1
0
        void ProcessLoadTask()
        {
            bool     invalidate = false;
            LoadTask?task       = null;
            long     lastTileLoadTimeMs;
            bool     stop = false;

#if !PocketPC
            Thread ct   = Thread.CurrentThread;
            string ctid = "Thread[" + ct.ManagedThreadId + "]";
#else
            int ctid = 0;
#endif
            while (!stop)
            {
                invalidate = false;
                task       = null;

                lock (tileLoadQueue)
                {
                    while (tileLoadQueue.Count == 0)
                    {
                        Debug.WriteLine(ctid + " - Wait " + loadWaitCount + " - " + DateTime.Now.TimeOfDay);

                        if (++loadWaitCount >= GThreadPoolSize)
                        {
                            loadWaitCount = 0;

                            lock (LastInvalidationLock)
                            {
                                LastInvalidation = DateTime.Now;
                            }

                            if (OnNeedInvalidation != null)
                            {
                                OnNeedInvalidation();
                            }

                            lock (LastTileLoadStartEndLock)
                            {
                                LastTileLoadEnd    = DateTime.Now;
                                lastTileLoadTimeMs = (long)(LastTileLoadEnd - LastTileLoadStart).TotalMilliseconds;
                            }

                            #region -- clear stuff--
                            {
                                GMaps.Instance.kiberCacheLock.AcquireWriterLock();
                                try
                                {
                                    GMaps.Instance.TilesInMemory.RemoveMemoryOverload();
                                }
                                finally
                                {
                                    GMaps.Instance.kiberCacheLock.ReleaseWriterLock();
                                }

                                tileDrawingListLock.AcquireReaderLock();
                                try
                                {
                                    Matrix.ClearLevelAndPointsNotIn(Zoom, tileDrawingList);
                                }
                                finally
                                {
                                    tileDrawingListLock.ReleaseReaderLock();
                                }
                            }
                            #endregion

                            UpdateGroundResolution();
#if UseGC
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                            GC.Collect();
#endif

                            Debug.WriteLine(ctid + " - OnTileLoadComplete: " + lastTileLoadTimeMs + "ms, MemoryCacheSize: " + GMaps.Instance.MemoryCacheSize + "MB");

                            if (OnTileLoadComplete != null)
                            {
                                OnTileLoadComplete(lastTileLoadTimeMs);
                            }
                        }
#if !PocketPC
                        if (false == Monitor.Wait(tileLoadQueue, WaitForTileLoadThreadTimeout, false))
                        {
                            stop = true;
                            break;
                        }
#else
                        wait.Wait();
#endif
                    }

                    if (!stop || tileLoadQueue.Count > 0)
                    {
                        task = tileLoadQueue.Dequeue();
                    }
                }

                if (task.HasValue)
                {
                    try
                    {
                        #region -- execute --
                        var m = Matrix.GetTileWithReadLock(task.Value.Zoom, task.Value.Pos);

                        if (m == null || m.Overlays.Count == 0)
                        {
                            Debug.WriteLine(ctid + " - Fill empty TileMatrix: " + task);

                            Tile t      = new Tile(task.Value.Zoom, task.Value.Pos);
                            var  layers = GMaps.Instance.GetAllLayersOfType(MapType);

                            foreach (MapType tl in layers)
                            {
                                int retry = 0;
                                do
                                {
                                    PureImage img;
                                    Exception ex;

                                    // tile number inversion(BottomLeft -> TopLeft) for pergo maps
                                    if (tl == MapType.PergoTurkeyMap)
                                    {
                                        img = GMaps.Instance.GetImageFrom(tl, new Point(task.Value.Pos.X, maxOfTiles.Height - task.Value.Pos.Y), task.Value.Zoom, out ex);
                                    }
                                    else // ok
                                    {
                                        img = GMaps.Instance.GetImageFrom(tl, task.Value.Pos, task.Value.Zoom, out ex);
                                    }

                                    if (img != null)
                                    {
                                        lock (t.Overlays)
                                        {
                                            t.Overlays.Add(img);
                                        }
                                        break;
                                    }
                                    else
                                    {
                                        if (ex != null)
                                        {
                                            lock (FailedLoads)
                                            {
                                                if (!FailedLoads.ContainsKey(task.Value))
                                                {
                                                    FailedLoads.Add(task.Value, ex);

                                                    if (OnEmptyTileError != null)
                                                    {
                                                        if (!RaiseEmptyTileError)
                                                        {
                                                            RaiseEmptyTileError = true;
                                                            OnEmptyTileError(task.Value.Zoom, task.Value.Pos);
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        if (RetryLoadTile > 0)
                                        {
                                            Debug.WriteLine(ctid + " - ProcessLoadTask: " + task + " -> empty tile, retry " + retry);
                                            {
                                                Thread.Sleep(1111);
                                            }
                                        }
                                    }
                                }while(++retry < RetryLoadTile);
                            }

                            if (t.Overlays.Count > 0)
                            {
                                Matrix.SetTile(t);
                            }
                            else
                            {
                                t.Clear();
                                t = null;
                            }

                            layers = null;
                        }
                        #endregion
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ctid + " - ProcessLoadTask: " + ex.ToString());
                    }
                    finally
                    {
                        lock (LastInvalidationLock)
                        {
                            invalidate = ((DateTime.Now - LastInvalidation).TotalMilliseconds > 111);
                            if (invalidate)
                            {
                                LastInvalidation = DateTime.Now;
                            }
                        }

                        if (invalidate)
                        {
                            if (OnNeedInvalidation != null)
                            {
                                OnNeedInvalidation();
                            }
                        }
#if DEBUG
                        //else
                        //{
                        //   lock(LastInvalidationLock)
                        //   {
                        //      Debug.WriteLine(ctid + " - SkipInvalidation, Delta: " + (DateTime.Now - LastInvalidation).TotalMilliseconds + "ms");
                        //   }
                        //}
#endif
                    }
                }
            }

#if !PocketPC
            lock (tileLoadQueue)
            {
                Debug.WriteLine("Quit - " + ct.Name);
                GThreadPool.Remove(ct);
            }
#endif
        }
Пример #2
0
        /// <summary>
        /// updates map bounds
        /// </summary>
        void UpdateBounds()
        {
            if (MapType == NET.MapType.None)
            {
                return;
            }

            lock (tileLoadQueue)
            {
                tileDrawingListLock.AcquireWriterLock();
                try
                {
                    #region -- find tiles around --
                    tileDrawingList.Clear();

                    for (int i = -sizeOfMapArea.Width; i <= sizeOfMapArea.Width; i++)
                    {
                        for (int j = -sizeOfMapArea.Height; j <= sizeOfMapArea.Height; j++)
                        {
                            Point p = centerTileXYLocation;
                            p.X += i;
                            p.Y += j;

#if ContinuesMap
                            // ----------------------------
                            if (p.X < minOfTiles.Width)
                            {
                                p.X += (maxOfTiles.Width + 1);
                            }

                            if (p.X > maxOfTiles.Width)
                            {
                                p.X -= (maxOfTiles.Width + 1);
                            }
                            // ----------------------------
#endif

                            if (p.X >= minOfTiles.Width && p.Y >= minOfTiles.Height && p.X <= maxOfTiles.Width && p.Y <= maxOfTiles.Height)
                            {
                                if (!tileDrawingList.Contains(p))
                                {
                                    tileDrawingList.Add(p);
                                }
                            }
                        }
                    }

                    if (GMaps.Instance.ShuffleTilesOnLoad)
                    {
                        Stuff.Shuffle <Point>(tileDrawingList);
                    }
                    #endregion

                    foreach (Point p in tileDrawingList)
                    {
                        LoadTask task = new LoadTask(p, Zoom);
                        {
                            if (!tileLoadQueue.Contains(task))
                            {
                                tileLoadQueue.Enqueue(task);
                            }
                        }
                    }
                }
                finally
                {
                    tileDrawingListLock.ReleaseWriterLock();
                }

                #region -- starts loader threads if needed --
#if !PocketPC
                while (GThreadPool.Count < GThreadPoolSize)
#else
                while (GThreadPool.Count < GThreadPoolSize)
#endif
                {
                    Thread t = new Thread(new ThreadStart(ProcessLoadTask));
                    {
                        t.Name         = "GMap.NET TileLoader: " + GThreadPool.Count;
                        t.IsBackground = true;
                        t.Priority     = ThreadPriority.BelowNormal;
                    }
                    GThreadPool.Add(t);

                    Debug.WriteLine("add " + t.Name + " to GThreadPool");

                    t.Start();
                }
                #endregion

                lock (LastTileLoadStartEndLock)
                {
                    LastTileLoadStart = DateTime.Now;
                    Debug.WriteLine("OnTileLoadStart - at zoom " + Zoom + ", time: " + LastTileLoadStart.TimeOfDay);
                }

                loadWaitCount = 0;

#if !PocketPC
                Monitor.PulseAll(tileLoadQueue);
#else
                wait.PulseAll();
#endif
            }

            if (OnTileLoadStart != null)
            {
                OnTileLoadStart();
            }
        }