New cache mechanism and thread overload fixed
This commit is contained in:
145
PBMap.pb
145
PBMap.pb
@@ -303,7 +303,7 @@ Module PBMap
|
|||||||
;-*** Global variables
|
;-*** Global variables
|
||||||
|
|
||||||
;-Show debug infos
|
;-Show debug infos
|
||||||
Global MyDebugLevel = 0
|
Global MyDebugLevel = 5
|
||||||
|
|
||||||
Global PBMap.PBMap, Null.i, NullPtrMem.i, *NullPtr = @NullPtrMem
|
Global PBMap.PBMap, Null.i, NullPtrMem.i, *NullPtr = @NullPtrMem
|
||||||
Global slash.s
|
Global slash.s
|
||||||
@@ -1063,17 +1063,17 @@ Module PBMap
|
|||||||
ProcedureReturn 0
|
ProcedureReturn 0
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
Procedure.i GetTileFromWeb(TileURL.s, CacheFile.s)
|
; Procedure.i GetTileFromWeb(TileURL.s, CacheFile.s)
|
||||||
;Debug TileURL
|
; ;Debug TileURL
|
||||||
If ReceiveHTTPFile(TileURL, CacheFile)
|
; If ReceiveHTTPFile(TileURL, CacheFile, #PB_HTTP_Asynchronous)
|
||||||
MyDebug(" Loaded from web " + TileURL + " as CacheFile " + CacheFile, 3)
|
; MyDebug(" Loaded from web " + TileURL + " as CacheFile " + CacheFile, 3)
|
||||||
; Debug TileURL + " OK"
|
; ; Debug TileURL + " OK"
|
||||||
ProcedureReturn GetTileFromHDD(CacheFile)
|
; ProcedureReturn GetTileFromHDD(CacheFile)
|
||||||
Else
|
; Else
|
||||||
MyDebug(" Problem receving from web " + TileURL + " as CacheFile " + CacheFile, 3)
|
; MyDebug(" Problem receving from web " + TileURL + " as CacheFile " + CacheFile, 3)
|
||||||
; Debug TileURL + " NOT OK"
|
; ; Debug TileURL + " NOT OK"
|
||||||
ProcedureReturn -1
|
; ProcedureReturn -1
|
||||||
EndIf
|
; EndIf
|
||||||
; **** (OLD) IMPORTANT NOTICE (please not remove)
|
; **** (OLD) IMPORTANT NOTICE (please not remove)
|
||||||
; I'm (djes) now using Curl (actually, just normal pb) only, as this original catchimage/saveimage method is a double operation (uncompress/recompress PNG)
|
; I'm (djes) now using Curl (actually, just normal pb) only, as this original catchimage/saveimage method is a double operation (uncompress/recompress PNG)
|
||||||
; and is modifying the original PNG image which could lead to PNG error (Idle has spent hours debunking the 1 bit PNG bug)
|
; and is modifying the original PNG image which could lead to PNG error (Idle has spent hours debunking the 1 bit PNG bug)
|
||||||
@@ -1099,22 +1099,47 @@ Module PBMap
|
|||||||
; MyDebug(" Problem loading from web " + TileURL, 3)
|
; MyDebug(" Problem loading from web " + TileURL, 3)
|
||||||
; EndIf
|
; EndIf
|
||||||
; ****
|
; ****
|
||||||
EndProcedure
|
; EndProcedure
|
||||||
|
|
||||||
Procedure GetImageThread(*Tile.Tile)
|
Procedure GetImageThread(*Tile.Tile)
|
||||||
MyDebug("Thread for image key " + *Tile\key, 3)
|
Protected Download, Progress, Size
|
||||||
Repeat
|
MyDebug("Thread starting for image " + *Tile\CacheFile + "(" + *Tile\key + ")", 3)
|
||||||
*Tile\nImage = GetTileFromWeb(*Tile\URL, *Tile\CacheFile)
|
Download = ReceiveHTTPFile(*Tile\URL, *Tile\CacheFile, #PB_HTTP_Asynchronous)
|
||||||
If *Tile\nImage <> -1
|
If Download
|
||||||
*Tile\RetryNb = 0
|
Repeat
|
||||||
Else
|
Progress = HTTPProgress(Download)
|
||||||
Delay(2000)
|
Select Progress
|
||||||
*Tile\RetryNb - 1
|
Case #PB_Http_Success
|
||||||
EndIf
|
Size = FinishHTTP(Download)
|
||||||
Until *Tile\RetryNb <= 0
|
MyDebug(" Thread for image " + *Tile\CacheFile + " finished. Size : " + Str(Size), 3)
|
||||||
MyDebug(" Thread for image key " + *Tile\key + " finished", 3)
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ;To free memory outside the thread
|
||||||
*Tile\RetryNb = -2 ;End of the thread
|
ProcedureReturn
|
||||||
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ;To free memory outside the thread
|
Case #PB_Http_Failed
|
||||||
|
MyDebug(" Thread for image " + *Tile\CacheFile + " failed.", 3)
|
||||||
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ;To free memory outside the thread
|
||||||
|
ProcedureReturn
|
||||||
|
Case #PB_Http_Aborted
|
||||||
|
MyDebug(" Thread for image " + *Tile\CacheFile + " aborted.", 3)
|
||||||
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ;To free memory outside the thread
|
||||||
|
ProcedureReturn
|
||||||
|
Default
|
||||||
|
MyDebug(" Thread for image " + *Tile\CacheFile + " downloading " + Str(Progress) + " bytes", 3)
|
||||||
|
EndSelect
|
||||||
|
Delay(500) ; Frees CPU
|
||||||
|
ForEver
|
||||||
|
EndIf
|
||||||
|
; Repeat
|
||||||
|
; *Tile\nImage = GetTileFromWeb(*Tile\URL, *Tile\CacheFile)
|
||||||
|
; If *Tile\nImage <> -1
|
||||||
|
; *Tile\RetryNb = 0
|
||||||
|
; Else
|
||||||
|
; Delay(2000)
|
||||||
|
; *Tile\RetryNb - 1
|
||||||
|
; EndIf
|
||||||
|
; Until *Tile\RetryNb <= 0
|
||||||
|
; MyDebug(" Thread for image key " + *Tile\key + " finished", 3)
|
||||||
|
; *Tile\RetryNb = -2 ;End of the thread
|
||||||
|
; PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ;To free memory outside the thread
|
||||||
EndProcedure
|
EndProcedure
|
||||||
;-***
|
;-***
|
||||||
|
|
||||||
@@ -1136,35 +1161,37 @@ Module PBMap
|
|||||||
EndIf
|
EndIf
|
||||||
Else
|
Else
|
||||||
;*** Cache management
|
;*** Cache management
|
||||||
; if cache size exceeds limit, try to delete the oldest tiles used (first in the time stack)
|
; If cache size exceeds limit, try to delete the oldest tiles used (first in the time stack)
|
||||||
Protected CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 4 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
Protected CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 5 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
||||||
Protected CacheLimit = PBMap\Options\MaxMemCache * 1024
|
Protected CacheLimit = PBMap\Options\MaxMemCache * 1024
|
||||||
MyDebug("Cache size : " + Str(CacheSize/1024) + " / CacheLimit : " + Str(CacheLimit/1024), 3)
|
MyDebug("Cache size : " + Str(CacheSize/1024) + " / CacheLimit : " + Str(CacheLimit/1024), 5)
|
||||||
If CacheSize > CacheLimit
|
If CacheSize > CacheLimit
|
||||||
MyDebug(" Cache full. Trying cache cleaning", 3)
|
MyDebug(" Cache full. Trying cache cleaning", 5)
|
||||||
ResetList(PBMap\MemCache\ImagesTimeStack())
|
ResetList(PBMap\MemCache\ImagesTimeStack())
|
||||||
; Try to free half the cache memory (one pass)
|
; Try to free half the cache memory (one pass)
|
||||||
While NextElement(PBMap\MemCache\ImagesTimeStack()) And CacheSize > (CacheLimit / 2) ; /2 = half
|
While NextElement(PBMap\MemCache\ImagesTimeStack()) And CacheSize > (CacheLimit / 2) ; /2 = half
|
||||||
Protected CacheMapKey.s = PBMap\MemCache\ImagesTimeStack()\MapKey
|
Protected CacheMapKey.s = PBMap\MemCache\ImagesTimeStack()\MapKey
|
||||||
Protected Image = PBMap\MemCache\Images(CacheMapKey)\nImage
|
Protected Image = PBMap\MemCache\Images(CacheMapKey)\nImage
|
||||||
If IsImage(Image) ; Check if the image is valid (is a loading thread running ?)
|
If PBMap\MemCache\Images(CacheMapKey)\Tile = 0 ; Check if a loading thread is not already running
|
||||||
FreeImage(Image)
|
If IsImage(Image) ; Check if the image is valid
|
||||||
DeleteMapElement(PBMap\MemCache\Images(), CacheMapKey)
|
FreeImage(Image)
|
||||||
DeleteElement(PBMap\MemCache\ImagesTimeStack())
|
EndIf
|
||||||
MyDebug(" Delete " + CacheMapKey + " as image nb " + Str(Image), 3)
|
DeleteMapElement(PBMap\MemCache\Images(), CacheMapKey)
|
||||||
EndIf
|
DeleteElement(PBMap\MemCache\ImagesTimeStack())
|
||||||
CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 4 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
MyDebug(" Delete " + CacheMapKey + " as image nb " + Str(Image), 5)
|
||||||
Wend
|
EndIf
|
||||||
MyDebug(" New cache size : " + Str(CacheSize/1024) + " / CacheLimit : " + Str(CacheLimit/1024), 3)
|
CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 4 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
||||||
If CacheSize > CacheLimit
|
Wend
|
||||||
MyDebug(" Cache cleaning unsuccessfull, can't add new tiles.", 3)
|
MyDebug(" New cache size : " + Str(CacheSize/1024) + " / CacheLimit : " + Str(CacheLimit/1024), 5)
|
||||||
ProcedureReturn 0
|
If CacheSize > CacheLimit
|
||||||
EndIf
|
MyDebug(" Cache cleaning unsuccessfull, can't add new tiles.", 5)
|
||||||
|
ProcedureReturn 0
|
||||||
|
EndIf
|
||||||
EndIf
|
EndIf
|
||||||
; Creates a new cache element
|
; Creates a new cache element
|
||||||
*timg = AddMapElement(PBMap\MemCache\Images(), key)
|
*timg = AddMapElement(PBMap\MemCache\Images(), key)
|
||||||
If *timg = 0
|
If *timg = 0
|
||||||
MyDebug(" Can't add a new cache element.", 3)
|
MyDebug(" Can't add a new cache element.", 5)
|
||||||
ProcedureReturn 0
|
ProcedureReturn 0
|
||||||
EndIf
|
EndIf
|
||||||
; add a new time stack element at the End
|
; add a new time stack element at the End
|
||||||
@@ -1172,16 +1199,16 @@ Module PBMap
|
|||||||
; Stores the time stack ptr
|
; Stores the time stack ptr
|
||||||
*timg\TimeStackPtr = AddElement(PBMap\MemCache\ImagesTimeStack())
|
*timg\TimeStackPtr = AddElement(PBMap\MemCache\ImagesTimeStack())
|
||||||
If *timg\TimeStackPtr = 0
|
If *timg\TimeStackPtr = 0
|
||||||
MyDebug(" Can't add a new time stack element.", 3)
|
MyDebug(" Can't add a new time stack element.", 5)
|
||||||
DeleteMapElement(PBMap\MemCache\Images())
|
DeleteMapElement(PBMap\MemCache\Images())
|
||||||
ProcedureReturn 0
|
ProcedureReturn 0
|
||||||
EndIf
|
EndIf
|
||||||
; Associates the time stack element to the cache element
|
; Associates the time stack element to the cache element
|
||||||
PBMap\MemCache\ImagesTimeStack()\MapKey = MapKey(PBMap\MemCache\Images())
|
PBMap\MemCache\ImagesTimeStack()\MapKey = MapKey(PBMap\MemCache\Images())
|
||||||
MyDebug("Key : " + key + " added in memory cache", 3)
|
MyDebug("Key : " + key + " added in memory cache", 5)
|
||||||
;***
|
;***
|
||||||
EndIf
|
EndIf
|
||||||
If *timg\Tile = 0 ; Check if a loading thread is not already running
|
If *timg\Tile = 0 ; Checks if a loading thread is not already running
|
||||||
; Is the file image on HDD ?
|
; Is the file image on HDD ?
|
||||||
*timg\nImage = GetTileFromHDD(CacheFile.s)
|
*timg\nImage = GetTileFromHDD(CacheFile.s)
|
||||||
If *timg\nImage
|
If *timg\nImage
|
||||||
@@ -1202,7 +1229,7 @@ Module PBMap
|
|||||||
\URL = URL
|
\URL = URL
|
||||||
\CacheFile = CacheFile
|
\CacheFile = CacheFile
|
||||||
\RetryNb = 5
|
\RetryNb = 5
|
||||||
\nImage = -1
|
\nImage = 0
|
||||||
\GetImageThread = CreateThread(@GetImageThread(), *NewTile)
|
\GetImageThread = CreateThread(@GetImageThread(), *NewTile)
|
||||||
If \GetImageThread
|
If \GetImageThread
|
||||||
MyDebug(" Creating get image thread nb " + Str(\GetImageThread) + " to get " + CacheFile, 3)
|
MyDebug(" Creating get image thread nb " + Str(\GetImageThread) + " to get " + CacheFile, 3)
|
||||||
@@ -2630,8 +2657,8 @@ CompilerIf #PB_Compiler_IsMainFile
|
|||||||
;Our main gadget
|
;Our main gadget
|
||||||
PBMap::InitPBMap(#Window_0)
|
PBMap::InitPBMap(#Window_0)
|
||||||
PBMap::SetOption("ShowDegrees", "1") : Degrees = 0
|
PBMap::SetOption("ShowDegrees", "1") : Degrees = 0
|
||||||
PBMap::SetOption("ShowDebugInfos", "1")
|
PBMap::SetOption("ShowDebugInfos", "0")
|
||||||
PBMap::SetOption("Verbose", "1")
|
PBMap::SetOption("Verbose", "0")
|
||||||
PBMap::SetOption("ShowScale", "1")
|
PBMap::SetOption("ShowScale", "1")
|
||||||
PBMap::SetOption("Warning", "1")
|
PBMap::SetOption("Warning", "1")
|
||||||
PBMap::SetOption("ShowMarkersLegend", "1")
|
PBMap::SetOption("ShowMarkersLegend", "1")
|
||||||
@@ -2774,8 +2801,8 @@ CompilerIf #PB_Compiler_IsMainFile
|
|||||||
CompilerEndIf
|
CompilerEndIf
|
||||||
|
|
||||||
; IDE Options = PureBasic 5.60 (Windows - x64)
|
; IDE Options = PureBasic 5.60 (Windows - x64)
|
||||||
; CursorPosition = 1067
|
; CursorPosition = 871
|
||||||
; FirstLine = 1055
|
; FirstLine = 858
|
||||||
; Folding = -------------------
|
; Folding = -------------------
|
||||||
; EnableThread
|
; EnableThread
|
||||||
; EnableXP
|
; EnableXP
|
||||||
|
Reference in New Issue
Block a user