1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
PBMap.pb.bak
|
PBMap.pb.bak
|
||||||
|
*.exe
|
||||||
|
413
PBMap.pb
413
PBMap.pb
@@ -47,6 +47,7 @@ DeclareModule PBMap
|
|||||||
#PB_MAP_TILE_CLEANUP = #PB_EventType_FirstCustomValue + 3
|
#PB_MAP_TILE_CLEANUP = #PB_EventType_FirstCustomValue + 3
|
||||||
|
|
||||||
Declare InitPBMap(window)
|
Declare InitPBMap(window)
|
||||||
|
Declare SetDebugLevel(level.i)
|
||||||
Declare SetOption(Option.s, Value.s)
|
Declare SetOption(Option.s, Value.s)
|
||||||
Declare.s GetOption(Option.s)
|
Declare.s GetOption(Option.s)
|
||||||
Declare LoadOptions(PreferencesFile.s = "PBMap.prefs")
|
Declare LoadOptions(PreferencesFile.s = "PBMap.prefs")
|
||||||
@@ -124,7 +125,10 @@ Module PBMap
|
|||||||
URL.s
|
URL.s
|
||||||
CacheFile.s
|
CacheFile.s
|
||||||
GetImageThread.i
|
GetImageThread.i
|
||||||
RetryNb.i
|
Download.i
|
||||||
|
Time.i
|
||||||
|
Size.i
|
||||||
|
Mutex.i
|
||||||
EndStructure
|
EndStructure
|
||||||
|
|
||||||
Structure BoundingBox
|
Structure BoundingBox
|
||||||
@@ -152,8 +156,9 @@ Module PBMap
|
|||||||
|
|
||||||
Structure ImgMemCach
|
Structure ImgMemCach
|
||||||
nImage.i
|
nImage.i
|
||||||
|
Size.i
|
||||||
*Tile.Tile
|
*Tile.Tile
|
||||||
TimeStackPosition.i
|
*TimeStackPtr
|
||||||
Alpha.i
|
Alpha.i
|
||||||
EndStructure
|
EndStructure
|
||||||
|
|
||||||
@@ -197,6 +202,8 @@ Module PBMap
|
|||||||
ShowPointer.i
|
ShowPointer.i
|
||||||
TimerInterval.i
|
TimerInterval.i
|
||||||
MaxMemCache.i ; in MiB
|
MaxMemCache.i ; in MiB
|
||||||
|
MaxThreads.i ; Maximum simultaneous web loading threads
|
||||||
|
MaxDownloadSlots.i ; Maximum simultaneous download slots
|
||||||
TileLifetime.i
|
TileLifetime.i
|
||||||
Verbose.i ; Maximum debug informations
|
Verbose.i ; Maximum debug informations
|
||||||
Warning.i ; Warning requesters
|
Warning.i ; Warning requesters
|
||||||
@@ -281,11 +288,16 @@ Module PBMap
|
|||||||
|
|
||||||
MemCache.TileMemCach ; Images in memory cache
|
MemCache.TileMemCach ; Images in memory cache
|
||||||
|
|
||||||
|
ThreadsNB.i ; Current web threads nb
|
||||||
|
|
||||||
Mode.i ; User mode : 0 (default)->hand (moving map) and select markers, 1->hand, 2->select only (moving objects), 3->drawing (todo)
|
Mode.i ; User mode : 0 (default)->hand (moving map) and select markers, 1->hand, 2->select only (moving objects), 3->drawing (todo)
|
||||||
Redraw.i
|
Redraw.i
|
||||||
Dragging.i
|
Dragging.i
|
||||||
Dirty.i ; To signal that drawing need a refresh
|
Dirty.i ; To signal that drawing need a refresh
|
||||||
|
|
||||||
|
MemoryCacheAccessMutex.i ; Memorycache access variable mutual exclusion
|
||||||
|
DownloadSlots.i ; Actual nb of used download slots
|
||||||
|
|
||||||
List TracksList.Tracks() ; To display a GPX track
|
List TracksList.Tracks() ; To display a GPX track
|
||||||
List Markers.Marker() ; To diplay marker
|
List Markers.Marker() ; To diplay marker
|
||||||
EditMarker.l
|
EditMarker.l
|
||||||
@@ -300,7 +312,7 @@ Module PBMap
|
|||||||
;-*** Global variables
|
;-*** Global variables
|
||||||
|
|
||||||
;-Show debug infos
|
;-Show debug infos
|
||||||
Global MyDebugLevel = 3
|
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
|
||||||
@@ -344,9 +356,14 @@ Module PBMap
|
|||||||
EndIf
|
EndIf
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
|
; Set the debug level allowing more or less debug infos
|
||||||
|
Procedure SetDebugLevel(level.i)
|
||||||
|
MyDebugLevel = level
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
; Send debug infos to stdout (allowing mixed debug infos with curl or other libs)
|
; Send debug infos to stdout (allowing mixed debug infos with curl or other libs)
|
||||||
Procedure MyDebug(msg.s, DbgLevel = 0)
|
Procedure MyDebug(msg.s, DbgLevel = 0)
|
||||||
If PBMap\Options\Verbose And DbgLevel >= MyDebugLevel
|
If PBMap\Options\Verbose And DbgLevel <= MyDebugLevel
|
||||||
PrintN(msg)
|
PrintN(msg)
|
||||||
; Debug msg
|
; Debug msg
|
||||||
EndIf
|
EndIf
|
||||||
@@ -681,6 +698,10 @@ Module PBMap
|
|||||||
PBMap\Options\HDDCachePath = Value
|
PBMap\Options\HDDCachePath = Value
|
||||||
Case "maxmemcache"
|
Case "maxmemcache"
|
||||||
PBMap\Options\MaxMemCache = Val(Value)
|
PBMap\Options\MaxMemCache = Val(Value)
|
||||||
|
Case "maxthreads"
|
||||||
|
PBMap\Options\MaxThreads = Val(Value)
|
||||||
|
Case "maxdownloadslots"
|
||||||
|
PBMap\Options\MaxDownloadSlots = Val(Value)
|
||||||
Case "tilelifetime"
|
Case "tilelifetime"
|
||||||
PBMap\Options\TileLifetime = Val(Value)
|
PBMap\Options\TileLifetime = Val(Value)
|
||||||
Case "verbose"
|
Case "verbose"
|
||||||
@@ -748,6 +769,10 @@ Module PBMap
|
|||||||
ProcedureReturn \HDDCachePath
|
ProcedureReturn \HDDCachePath
|
||||||
Case "maxmemcache"
|
Case "maxmemcache"
|
||||||
ProcedureReturn StrU(\MaxMemCache)
|
ProcedureReturn StrU(\MaxMemCache)
|
||||||
|
Case "maxthreads"
|
||||||
|
ProcedureReturn StrU(\MaxThreads)
|
||||||
|
Case "maxdownloadslots"
|
||||||
|
ProcedureReturn StrU(\MaxDownloadSlots)
|
||||||
Case "tilelifetime"
|
Case "tilelifetime"
|
||||||
ProcedureReturn StrU(\TileLifetime)
|
ProcedureReturn StrU(\TileLifetime)
|
||||||
Case "verbose"
|
Case "verbose"
|
||||||
@@ -809,6 +834,8 @@ Module PBMap
|
|||||||
PreferenceGroup("OPTIONS")
|
PreferenceGroup("OPTIONS")
|
||||||
WritePreferenceInteger("WheelMouseRelative", \WheelMouseRelative)
|
WritePreferenceInteger("WheelMouseRelative", \WheelMouseRelative)
|
||||||
WritePreferenceInteger("MaxMemCache", \MaxMemCache)
|
WritePreferenceInteger("MaxMemCache", \MaxMemCache)
|
||||||
|
WritePreferenceInteger("MaxThreads", \MaxThreads)
|
||||||
|
WritePreferenceInteger("MaxDownloadSlots", \MaxDownloadSlots)
|
||||||
WritePreferenceInteger("TileLifetime", \TileLifetime)
|
WritePreferenceInteger("TileLifetime", \TileLifetime)
|
||||||
WritePreferenceInteger("Verbose", \Verbose)
|
WritePreferenceInteger("Verbose", \Verbose)
|
||||||
WritePreferenceInteger("Warning", \Warning)
|
WritePreferenceInteger("Warning", \Warning)
|
||||||
@@ -873,6 +900,8 @@ Module PBMap
|
|||||||
PreferenceGroup("OPTIONS")
|
PreferenceGroup("OPTIONS")
|
||||||
\WheelMouseRelative = ReadPreferenceInteger("WheelMouseRelative", #True)
|
\WheelMouseRelative = ReadPreferenceInteger("WheelMouseRelative", #True)
|
||||||
\MaxMemCache = ReadPreferenceInteger("MaxMemCache", 20480) ; 20 MiB, about 80 tiles in memory
|
\MaxMemCache = ReadPreferenceInteger("MaxMemCache", 20480) ; 20 MiB, about 80 tiles in memory
|
||||||
|
\MaxThreads = ReadPreferenceInteger("MaxThreads", 40)
|
||||||
|
\MaxDownloadSlots = ReadPreferenceInteger("MaxDownloadSlots", 2)
|
||||||
\TileLifetime = ReadPreferenceInteger("TileLifetime", 1209600) ; about 2 weeks ;-1 = unlimited
|
\TileLifetime = ReadPreferenceInteger("TileLifetime", 1209600) ; about 2 weeks ;-1 = unlimited
|
||||||
\Verbose = ReadPreferenceInteger("Verbose", #False)
|
\Verbose = ReadPreferenceInteger("Verbose", #False)
|
||||||
\Warning = ReadPreferenceInteger("Warning", #False)
|
\Warning = ReadPreferenceInteger("Warning", #False)
|
||||||
@@ -891,7 +920,7 @@ Module PBMap
|
|||||||
\ColourFocus = ReadPreferenceInteger("ColourFocus", RGBA(255, 255, 0, 255))
|
\ColourFocus = ReadPreferenceInteger("ColourFocus", RGBA(255, 255, 0, 255))
|
||||||
\ColourSelected = ReadPreferenceInteger("ColourSelected", RGBA(225, 225, 0, 255))
|
\ColourSelected = ReadPreferenceInteger("ColourSelected", RGBA(225, 225, 0, 255))
|
||||||
\ColourTrackDefault = ReadPreferenceInteger("ColourTrackDefault", RGBA(0, 255, 0, 150))
|
\ColourTrackDefault = ReadPreferenceInteger("ColourTrackDefault", RGBA(0, 255, 0, 150))
|
||||||
\TimerInterval = 20
|
\TimerInterval = 12
|
||||||
ClosePreferences()
|
ClosePreferences()
|
||||||
EndWith
|
EndWith
|
||||||
SetOptions()
|
SetOptions()
|
||||||
@@ -1021,51 +1050,73 @@ Module PBMap
|
|||||||
ProcedureReturn PBMap\Layers(Name)\Alpha
|
ProcedureReturn PBMap\Layers(Name)\Alpha
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
;-*** These are threaded
|
;-***
|
||||||
|
; If cache size exceeds limit, try to delete the oldest tiles used (first in the time stack)
|
||||||
|
Procedure MemoryCacheManagement()
|
||||||
|
LockMutex(PBMap\MemoryCacheAccessMutex) ; Prevents thread to start or finish
|
||||||
|
Protected CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 4 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
||||||
|
Protected CacheLimit = PBMap\Options\MaxMemCache * 1024
|
||||||
|
MyDebug("Cache size : " + Str(CacheSize/1024) + " / CacheLimit : " + Str(CacheLimit/1024), 5)
|
||||||
|
If CacheSize > CacheLimit
|
||||||
|
MyDebug(" Cache full. Trying cache cleaning", 5)
|
||||||
|
ResetList(PBMap\MemCache\ImagesTimeStack())
|
||||||
|
; Try to free half the cache memory (one pass)
|
||||||
|
While NextElement(PBMap\MemCache\ImagesTimeStack()) And CacheSize > (CacheLimit / 2) ; /2 = half
|
||||||
|
Protected CacheMapKey.s = PBMap\MemCache\ImagesTimeStack()\MapKey
|
||||||
|
; Is the loading over
|
||||||
|
If PBMap\MemCache\Images(CacheMapKey)\Tile <= 0 ;TODO Should not verify this var directly
|
||||||
|
MyDebug(" Delete " + CacheMapKey, 5)
|
||||||
|
If PBMap\MemCache\Images(CacheMapKey)\nImage;IsImage(PBMap\MemCache\Images(CacheMapKey)\nImage)
|
||||||
|
FreeImage(PBMap\MemCache\Images(CacheMapKey)\nImage)
|
||||||
|
MyDebug(" and free image nb " + Str(PBMap\MemCache\Images(CacheMapKey)\nImage), 5)
|
||||||
|
PBMap\MemCache\Images(CacheMapKey)\nImage = 0
|
||||||
|
EndIf
|
||||||
|
DeleteMapElement(PBMap\MemCache\Images(), CacheMapKey)
|
||||||
|
DeleteElement(PBMap\MemCache\ImagesTimeStack(), 1)
|
||||||
|
; ElseIf PBMap\MemCache\Images(CacheMapKey)\Tile = 0
|
||||||
|
; MyDebug(" Delete " + CacheMapKey, 5)
|
||||||
|
; DeleteMapElement(PBMap\MemCache\Images(), CacheMapKey)
|
||||||
|
; DeleteElement(PBMap\MemCache\ImagesTimeStack(), 1)
|
||||||
|
; ElseIf PBMap\MemCache\Images(CacheMapKey)\Tile > 0
|
||||||
|
; ; If the thread is running, try to abort the download
|
||||||
|
; If PBMap\MemCache\Images(CacheMapKey)\Tile\Download
|
||||||
|
; AbortHTTP(PBMap\MemCache\Images(CacheMapKey)\Tile\Download) ; Could lead to error
|
||||||
|
; EndIf
|
||||||
|
EndIf
|
||||||
|
CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 4 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
||||||
|
Wend
|
||||||
|
MyDebug(" New cache size : " + Str(CacheSize/1024) + " / CacheLimit : " + Str(CacheLimit/1024), 5)
|
||||||
|
If CacheSize > CacheLimit
|
||||||
|
MyDebug(" Cache cleaning unsuccessfull, can't add new tiles.", 5)
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
Procedure.i GetTileFromHDD(CacheFile.s)
|
Procedure.i GetTileFromHDD(CacheFile.s)
|
||||||
Protected nImage.i, LifeTime.i, MaxLifeTime.i = PBMap\Options\TileLifetime
|
Protected nImage.i, LifeTime.i, MaxLifeTime.i
|
||||||
If FileSize(CacheFile) <> -1
|
; Everything is OK, loads the file
|
||||||
;Manage tile file lifetime
|
|
||||||
If MaxLifeTime <> -1
|
|
||||||
LifeTime = Date() - GetFileDate(CacheFile, #PB_Date_Modified) ;There's a bug with #PB_Date_Created
|
|
||||||
If LifeTime > MaxLifeTime
|
|
||||||
MyDebug("Deleting too old (" + StrU(LifeTime) + " secs) " + CacheFile, 3)
|
|
||||||
DeleteFile(CacheFile)
|
|
||||||
ProcedureReturn -1
|
|
||||||
EndIf
|
|
||||||
EndIf
|
|
||||||
;Everything is OK, load the file
|
|
||||||
nImage = LoadImage(#PB_Any, CacheFile)
|
nImage = LoadImage(#PB_Any, CacheFile)
|
||||||
If IsImage(nImage)
|
If nImage
|
||||||
MyDebug(" Success loading " + CacheFile + " as nImage " + Str(nImage), 3)
|
MyDebug(" Success loading " + CacheFile + " as nImage " + Str(nImage), 3)
|
||||||
ProcedureReturn nImage
|
ProcedureReturn nImage
|
||||||
Else
|
Else
|
||||||
MyDebug(" Failed loading " + CacheFile + " as nImage " + Str(nImage) + " -> not an image !", 3)
|
MyDebug(" Failed loading " + CacheFile + " as nImage " + Str(nImage) + " -> not an image !", 3)
|
||||||
|
If DeleteFile(CacheFile)
|
||||||
MyDebug(" Deleting faulty image file " + CacheFile, 3)
|
MyDebug(" Deleting faulty image file " + CacheFile, 3)
|
||||||
DeleteFile(CacheFile)
|
|
||||||
EndIf
|
|
||||||
Else
|
Else
|
||||||
MyDebug("Failed loading " + CacheFile + " -> Size <= 0", 3)
|
MyDebug(" Can't delete faulty image file " + CacheFile, 3)
|
||||||
EndIf
|
EndIf
|
||||||
ProcedureReturn -1
|
EndIf
|
||||||
|
ProcedureReturn #False
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
Procedure.i GetTileFromWeb(TileURL.s, CacheFile.s)
|
; **** OLD IMPORTANT NOTICE (please not remove)
|
||||||
Protected *Buffer
|
; This original catchimage/saveimage method is a double operation (uncompress/recompress PNG)
|
||||||
Protected nImage.i = -1
|
|
||||||
Protected FileSize.i, timg
|
|
||||||
FileSize = ReceiveHTTPFile(TileURL, CacheFile)
|
|
||||||
If FileSize > 0
|
|
||||||
MyDebug("Loaded from web " + TileURL + " as CacheFile " + CacheFile, 3)
|
|
||||||
nImage = GetTileFromHDD(CacheFile)
|
|
||||||
Else
|
|
||||||
MyDebug("Problem loading from web " + TileURL + " as CacheFile " + CacheFile, 3)
|
|
||||||
EndIf
|
|
||||||
; **** 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)
|
|
||||||
; 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)
|
||||||
; More than that, the original Purebasic Receive library is still not Proxy enabled.
|
; Protected *Buffer
|
||||||
|
; Protected nImage.i = -1
|
||||||
|
; Protected timg
|
||||||
; *Buffer = ReceiveHTTPMemory(TileURL) ; TODO to thread by using #PB_HTTP_Asynchronous
|
; *Buffer = ReceiveHTTPMemory(TileURL) ; TODO to thread by using #PB_HTTP_Asynchronous
|
||||||
; If *Buffer
|
; If *Buffer
|
||||||
; nImage = CatchImage(#PB_Any, *Buffer, MemorySize(*Buffer))
|
; nImage = CatchImage(#PB_Any, *Buffer, MemorySize(*Buffer))
|
||||||
@@ -1084,106 +1135,175 @@ Module PBMap
|
|||||||
; MyDebug(" Problem loading from web " + TileURL, 3)
|
; MyDebug(" Problem loading from web " + TileURL, 3)
|
||||||
; EndIf
|
; EndIf
|
||||||
; ****
|
; ****
|
||||||
ProcedureReturn nImage
|
|
||||||
EndProcedure
|
;-*** These are threaded
|
||||||
|
|
||||||
|
Threaded Progress = 0, Quit = #False
|
||||||
|
|
||||||
Procedure GetImageThread(*Tile.Tile)
|
Procedure GetImageThread(*Tile.Tile)
|
||||||
Protected nImage.i = -1
|
LockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
|
MyDebug("Thread nb " + Str(*Tile\GetImageThread) + " " + *Tile\key + " starting for image " + *Tile\CacheFile, 5)
|
||||||
|
; If MemoryCache is currently being cleaned, abort
|
||||||
|
; If PBMap\MemoryCacheAccessNB = -1
|
||||||
|
; MyDebug(" Thread nb " + Str(*Tile\GetImageThread) + " " + *Tile\key + " for image " + *Tile\CacheFile + " canceled because of cleaning.", 5)
|
||||||
|
; *Tile\Size = 0 ; \Size = 0 signals that the download has failed
|
||||||
|
; PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
||||||
|
; UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
|
; ProcedureReturn
|
||||||
|
; EndIf
|
||||||
|
; We're accessing MemoryCache
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
|
*Tile\Size = 0
|
||||||
|
*Tile\Download = ReceiveHTTPFile(*Tile\URL, *Tile\CacheFile, #PB_HTTP_Asynchronous)
|
||||||
|
If *Tile\Download
|
||||||
Repeat
|
Repeat
|
||||||
nImage = GetTileFromWeb(*Tile\URL, *Tile\CacheFile)
|
Progress = HTTPProgress(*Tile\Download)
|
||||||
If nImage <> -1
|
Select Progress
|
||||||
MyDebug("Image key : " + *Tile\key + " web image loaded", 3)
|
Case #PB_Http_Success
|
||||||
*Tile\RetryNb = 0
|
*Tile\Size = FinishHTTP(*Tile\Download) ; \Size signals that the download is OK
|
||||||
Else
|
MyDebug(" Thread nb " + Str(*Tile\GetImageThread) + " " + *Tile\key + " for image " + *Tile\CacheFile + " finished. Size : " + Str(*Tile\Size), 5)
|
||||||
MyDebug("Image key : " + *Tile\key + " web image not correctly loaded, will retry in 2 secs", 3)
|
Quit = #True
|
||||||
Delay(2000)
|
Case #PB_Http_Failed
|
||||||
*Tile\RetryNb - 1
|
FinishHTTP(*Tile\Download)
|
||||||
|
*Tile\Size = 0 ; \Size = 0 signals that the download has failed
|
||||||
|
MyDebug(" Thread nb " + Str(*Tile\GetImageThread) + " " + *Tile\key + " for image " + *Tile\CacheFile + " failed.", 5)
|
||||||
|
Quit = #True
|
||||||
|
Case #PB_Http_Aborted
|
||||||
|
FinishHTTP(*Tile\Download)
|
||||||
|
*Tile\Size = 0 ; \Size = 0 signals that the download has failed
|
||||||
|
MyDebug(" Thread nb " + Str(*Tile\GetImageThread) + " " + *Tile\key + " for image " + *Tile\CacheFile + " aborted.", 5)
|
||||||
|
Quit = #True
|
||||||
|
Default
|
||||||
|
MyDebug(" Thread nb " + Str(*Tile\GetImageThread) + " " + *Tile\key + " for image " + *Tile\CacheFile + " downloading " + Str(Progress) + " bytes", 5)
|
||||||
|
If ElapsedMilliseconds() - *Tile\Time > 10000
|
||||||
|
MyDebug(" Thread nb " + Str(*Tile\GetImageThread) + " " + *Tile\key + " for image " + *Tile\CacheFile + " canceled after 10 seconds.", 5)
|
||||||
|
AbortHTTP(*Tile\Download)
|
||||||
EndIf
|
EndIf
|
||||||
Until *Tile\RetryNb <= 0
|
EndSelect
|
||||||
*Tile\nImage = nImage
|
Delay(200) ; Frees CPU
|
||||||
*Tile\RetryNb = -2 ;End of the thread
|
Until Quit
|
||||||
|
EndIf
|
||||||
|
; End of the memory cache access
|
||||||
|
LockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile) ; To free memory outside the thread
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
;-***
|
;-***
|
||||||
|
|
||||||
Procedure.i GetTile(key.s, URL.s, CacheFile.s)
|
Procedure.i GetTile(key.s, URL.s, CacheFile.s)
|
||||||
; Try to find the tile in memory cache. If not found, add it, try to load it from the
|
; MemoryCache access management
|
||||||
; HDD, or launch a loading thread, and try again on the next drawing loop.
|
LockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
Protected img.i = -1
|
; Try to find the tile in memory cache
|
||||||
Protected *timg.ImgMemCach = FindMapElement(PBMap\MemCache\Images(), key)
|
Protected *timg.ImgMemCach = FindMapElement(PBMap\MemCache\Images(), key)
|
||||||
If *timg
|
If *timg
|
||||||
MyDebug("Key : " + key + " found in memory cache", 3)
|
MyDebug("Key : " + key + " found in memory cache", 4)
|
||||||
img = *timg\nImage
|
; Is the associated image already been loaded in memory ?
|
||||||
If img <> -1
|
If *timg\nImage
|
||||||
MyDebug("Image : " + img + " found in memory cache", 3)
|
; Yes, returns the image's nb
|
||||||
|
MyDebug(" as image " + *timg\nImage, 4)
|
||||||
; *** Cache management
|
; *** Cache management
|
||||||
; Move the newly used element to the last position of the time stack
|
; Retrieves the image in the time stack, push it to the end (to say it's the lastly used)
|
||||||
SelectElement(PBMap\MemCache\ImagesTimeStack(), *timg\TimeStackPosition)
|
ChangeCurrentElement(PBMap\MemCache\ImagesTimeStack(), *timg\TimeStackPtr)
|
||||||
MoveElement(PBMap\MemCache\ImagesTimeStack(), #PB_List_Last)
|
MoveElement(PBMap\MemCache\ImagesTimeStack(), #PB_List_Last)
|
||||||
|
; *timg\TimeStackPtr = LastElement(PBMap\MemCache\ImagesTimeStack())
|
||||||
; ***
|
; ***
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
ProcedureReturn *timg
|
ProcedureReturn *timg
|
||||||
|
Else
|
||||||
|
; No, try to load it from HD (see below)
|
||||||
|
MyDebug(" but not the image.", 4)
|
||||||
EndIf
|
EndIf
|
||||||
Else
|
Else
|
||||||
;PushMapPosition(PBMap\MemCache\Images())
|
; The tile has not been found in the cache, so creates a new cache element
|
||||||
;*** Cache management
|
*timg = AddMapElement(PBMap\MemCache\Images(), key)
|
||||||
; if cache size exceeds limit, try to delete the oldest tile used (first in the list)
|
If *timg = 0
|
||||||
Protected CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 4 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
MyDebug(" Can't add a new cache element.", 4)
|
||||||
Protected CacheLimit = PBMap\Options\MaxMemCache * 1024
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
MyDebug("Cache size : " + Str(CacheSize/1024) + " / CacheLimit : " + Str(CacheLimit/1024), 4)
|
ProcedureReturn #False
|
||||||
ResetList(PBMap\MemCache\ImagesTimeStack())
|
|
||||||
While NextElement(PBMap\MemCache\ImagesTimeStack()) And CacheSize > CacheLimit
|
|
||||||
Protected CacheMapKey.s = PBMap\MemCache\ImagesTimeStack()\MapKey
|
|
||||||
Protected Image = PBMap\MemCache\Images(CacheMapKey)\nImage
|
|
||||||
If IsImage(Image) ; Check if the image is valid (is a loading thread running ?)
|
|
||||||
FreeImage(Image)
|
|
||||||
MyDebug("Delete " + CacheMapKey + " As image nb " + Str(Image), 4)
|
|
||||||
DeleteMapElement(PBMap\MemCache\Images(), CacheMapKey)
|
|
||||||
DeleteElement(PBMap\MemCache\ImagesTimeStack())
|
|
||||||
CacheSize = MapSize(PBMap\MemCache\Images()) * Pow(PBMap\TileSize, 2) * 4 ; Size of a tile = TileSize * TileSize * 4 bytes (RGBA)
|
|
||||||
EndIf
|
EndIf
|
||||||
Wend
|
; add a new time stack element at the End
|
||||||
LastElement(PBMap\MemCache\ImagesTimeStack())
|
LastElement(PBMap\MemCache\ImagesTimeStack())
|
||||||
;PopMapPosition(PBMap\MemCache\Images())
|
; Stores the time stack ptr
|
||||||
AddMapElement(PBMap\MemCache\Images(), key)
|
*timg\TimeStackPtr = AddElement(PBMap\MemCache\ImagesTimeStack())
|
||||||
AddElement(PBMap\MemCache\ImagesTimeStack())
|
If *timg\TimeStackPtr = 0
|
||||||
;MoveElement(PBMap\MemCache\ImagesTimeStack(), #PB_List_Last)
|
MyDebug(" Can't add a new time stack element.", 4)
|
||||||
|
DeleteMapElement(PBMap\MemCache\Images())
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
|
ProcedureReturn #False
|
||||||
|
EndIf
|
||||||
|
; 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", 4)
|
||||||
MyDebug("Key : " + key + " added in memory cache", 3)
|
|
||||||
*timg = PBMap\MemCache\Images()
|
|
||||||
*timg\nImage = -1
|
|
||||||
EndIf
|
EndIf
|
||||||
If *timg\Tile = 0 ; Check if a loading thread is not running
|
; If there's no active download thread for this tile
|
||||||
MyDebug("Trying to load from HDD " + CacheFile, 3)
|
If *timg\Tile <= 0
|
||||||
img = GetTileFromHDD(CacheFile.s)
|
; Manage tile file lifetime, delete if too old
|
||||||
If img <> -1
|
If PBMap\Options\TileLifetime <> -1
|
||||||
MyDebug("Key : " + key + " found on HDD", 3)
|
If FileSize(CacheFile) > 0 ; Does the file exists ?
|
||||||
*timg\nImage = img
|
If Date() - GetFileDate(CacheFile, #PB_Date_Modified) > PBMap\Options\TileLifetime ; If Lifetime > MaxLifeTime ; There's a bug with #PB_Date_Created
|
||||||
*timg\Alpha = 256
|
If DeleteFile(CacheFile)
|
||||||
|
MyDebug(" Deleting too old image file " + CacheFile, 3)
|
||||||
|
Else
|
||||||
|
MyDebug(" Can't delete too old image file " + CacheFile, 3)
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
|
ProcedureReturn #False
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
; Try To load it from HD
|
||||||
|
*timg\nImage = 0
|
||||||
|
*timg\Size = FileSize(CacheFile)
|
||||||
|
If *timg\Size > 0
|
||||||
|
*timg\nImage = GetTileFromHDD(CacheFile.s)
|
||||||
|
Else
|
||||||
|
MyDebug(" Failed loading from HDD " + CacheFile + " -> Filesize = " + FileSize(CacheFile), 3)
|
||||||
|
EndIf
|
||||||
|
If *timg\nImage
|
||||||
|
; Image found and loaded from HDD
|
||||||
|
*timg\Alpha = 0
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
ProcedureReturn *timg
|
ProcedureReturn *timg
|
||||||
EndIf
|
Else
|
||||||
MyDebug("Key : " + key + " not found on HDD", 3)
|
; If GetTileFromHDD failed, will load it (again?) from the web
|
||||||
;Launch a new thread
|
If PBMap\ThreadsNB < PBMap\Options\MaxThreads
|
||||||
|
If PBMap\DownloadSlots < PBMap\Options\MaxDownloadSlots
|
||||||
|
; Launch a new web loading thread
|
||||||
|
PBMap\DownloadSlots + 1
|
||||||
Protected *NewTile.Tile = AllocateMemory(SizeOf(Tile))
|
Protected *NewTile.Tile = AllocateMemory(SizeOf(Tile))
|
||||||
If *NewTile
|
If *NewTile
|
||||||
With *NewTile
|
With *NewTile
|
||||||
*timg\Tile = *NewTile
|
|
||||||
*timg\Alpha = 0
|
|
||||||
;*timg\nImage = -1
|
|
||||||
; New tile parameters
|
; New tile parameters
|
||||||
\key = key
|
\key = key
|
||||||
\URL = URL
|
\URL = URL
|
||||||
\CacheFile = CacheFile
|
\CacheFile = CacheFile
|
||||||
\RetryNb = 5
|
\nImage = 0
|
||||||
\nImage = -1
|
\Time = ElapsedMilliseconds()
|
||||||
MyDebug(" Creating get image thread nb " + Str(\GetImageThread) + " to get " + CacheFile, 3)
|
|
||||||
\GetImageThread = CreateThread(@GetImageThread(), *NewTile)
|
\GetImageThread = CreateThread(@GetImageThread(), *NewTile)
|
||||||
|
If \GetImageThread
|
||||||
|
*timg\Tile = *NewTile ; There's now a loading thread
|
||||||
|
*timg\Alpha = 0
|
||||||
|
MyDebug(" Creating get image thread nb " + Str(\GetImageThread) + " to get " + CacheFile + " (key = " + key, 3)
|
||||||
|
PBMap\ThreadsNB + 1
|
||||||
|
Else
|
||||||
|
MyDebug(" Can't create get image thread to get " + CacheFile, 3)
|
||||||
|
FreeMemory(*NewTile)
|
||||||
|
EndIf
|
||||||
EndWith
|
EndWith
|
||||||
Else
|
Else
|
||||||
MyDebug(" Error, can't create a new tile loading thread", 3)
|
MyDebug(" Error, can't allocate memory for a new tile loading thread", 3)
|
||||||
|
EndIf
|
||||||
|
Else
|
||||||
|
MyDebug(" Thread needed " + key + " for image " + CacheFile + " canceled because no free download slot.", 5)
|
||||||
|
EndIf
|
||||||
|
Else
|
||||||
|
MyDebug(" Error, maximum threads nb reached", 3)
|
||||||
EndIf
|
EndIf
|
||||||
EndIf
|
EndIf
|
||||||
ProcedureReturn *timg
|
EndIf
|
||||||
|
UnlockMutex(PBMap\MemoryCacheAccessMutex)
|
||||||
|
ProcedureReturn #False
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
Procedure DrawTiles(*Drawing.DrawingParameters, LayerName.s)
|
Procedure DrawTiles(*Drawing.DrawingParameters, LayerName.s)
|
||||||
@@ -1263,7 +1383,7 @@ Module PBMap
|
|||||||
EndSelect
|
EndSelect
|
||||||
EndWith
|
EndWith
|
||||||
*timg = GetTile(key, URL, CacheFile)
|
*timg = GetTile(key, URL, CacheFile)
|
||||||
If *timg\nImage <> -1
|
If *timg And *timg\nImage
|
||||||
MovePathCursor(px, py)
|
MovePathCursor(px, py)
|
||||||
If *timg\Alpha <= 224
|
If *timg\Alpha <= 224
|
||||||
DrawVectorImage(ImageID(*timg\nImage), *timg\Alpha * PBMap\Layers()\Alpha)
|
DrawVectorImage(ImageID(*timg\nImage), *timg\Alpha * PBMap\Layers()\Alpha)
|
||||||
@@ -1737,23 +1857,23 @@ Module PBMap
|
|||||||
VectorFont(FontID(PBMap\Font), 16)
|
VectorFont(FontID(PBMap\Font), 16)
|
||||||
VectorSourceColor(RGBA(0, 0, 0, 80))
|
VectorSourceColor(RGBA(0, 0, 0, 80))
|
||||||
MovePathCursor(50, 50)
|
MovePathCursor(50, 50)
|
||||||
DrawVectorText(Str(MapSize(PBMap\MemCache\Images())))
|
DrawVectorText("Images in cache : " + Str(MapSize(PBMap\MemCache\Images())))
|
||||||
MovePathCursor(50, 70)
|
MovePathCursor(50, 70)
|
||||||
Protected ThreadCounter = 0
|
Protected ThreadCounter = 0
|
||||||
ForEach PBMap\MemCache\Images()
|
ForEach PBMap\MemCache\Images()
|
||||||
If PBMap\MemCache\Images()\Tile <> 0
|
If PBMap\MemCache\Images()\Tile > 0
|
||||||
If IsThread(PBMap\MemCache\Images()\Tile\GetImageThread)
|
If IsThread(PBMap\MemCache\Images()\Tile\GetImageThread)
|
||||||
ThreadCounter + 1
|
ThreadCounter + 1
|
||||||
EndIf
|
EndIf
|
||||||
EndIf
|
EndIf
|
||||||
Next
|
Next
|
||||||
DrawVectorText(Str(ThreadCounter))
|
DrawVectorText("Threads nb : " + Str(ThreadCounter))
|
||||||
MovePathCursor(50, 90)
|
MovePathCursor(50, 90)
|
||||||
DrawVectorText(Str(PBMap\Zoom))
|
DrawVectorText("Zoom : " + Str(PBMap\Zoom))
|
||||||
MovePathCursor(50, 110)
|
MovePathCursor(50, 110)
|
||||||
DrawVectorText(StrD(*Drawing\Bounds\NorthWest\Latitude) + "," + StrD(*Drawing\Bounds\NorthWest\Longitude))
|
DrawVectorText("Lat-Lon 1 : " + StrD(*Drawing\Bounds\NorthWest\Latitude) + "," + StrD(*Drawing\Bounds\NorthWest\Longitude))
|
||||||
MovePathCursor(50, 130)
|
MovePathCursor(50, 130)
|
||||||
DrawVectorText(StrD(*Drawing\Bounds\SouthEast\Latitude) + "," + StrD(*Drawing\Bounds\SouthEast\Longitude))
|
DrawVectorText("Lat-Lon 2 : " + StrD(*Drawing\Bounds\SouthEast\Latitude) + "," + StrD(*Drawing\Bounds\SouthEast\Longitude))
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
Procedure DrawOSMCopyright(*Drawing.DrawingParameters)
|
Procedure DrawOSMCopyright(*Drawing.DrawingParameters)
|
||||||
@@ -2113,11 +2233,11 @@ Module PBMap
|
|||||||
EndIf
|
EndIf
|
||||||
EndIf
|
EndIf
|
||||||
If DeleteDirectory(PBMap\Options\HDDCachePath, "", #PB_FileSystem_Recursive)
|
If DeleteDirectory(PBMap\Options\HDDCachePath, "", #PB_FileSystem_Recursive)
|
||||||
MyDebug("Cache in : " + PBMap\Options\HDDCachePath + " cleared")
|
MyDebug("Cache in : " + PBMap\Options\HDDCachePath + " cleared", 3)
|
||||||
CreateDirectoryEx(PBMap\Options\HDDCachePath)
|
CreateDirectoryEx(PBMap\Options\HDDCachePath)
|
||||||
ProcedureReturn #True
|
ProcedureReturn #True
|
||||||
Else
|
Else
|
||||||
MyDebug("Can't clear cache in " + PBMap\Options\HDDCachePath)
|
MyDebug("Can't clear cache in " + PBMap\Options\HDDCachePath, 3)
|
||||||
ProcedureReturn #False
|
ProcedureReturn #False
|
||||||
EndIf
|
EndIf
|
||||||
EndProcedure
|
EndProcedure
|
||||||
@@ -2221,7 +2341,7 @@ Module PBMap
|
|||||||
Case #PB_EventType_LeftButtonDown
|
Case #PB_EventType_LeftButtonDown
|
||||||
; LatLon2Pixel(@PBMap\GeographicCoordinates, @PBMap\PixelCoordinates, PBMap\Zoom)
|
; LatLon2Pixel(@PBMap\GeographicCoordinates, @PBMap\PixelCoordinates, PBMap\Zoom)
|
||||||
PBMap\Dragging = #True
|
PBMap\Dragging = #True
|
||||||
;Mem cursor Coord
|
; Memorize cursor Coord
|
||||||
PBMap\MoveStartingPoint\x = CanvasMouseX
|
PBMap\MoveStartingPoint\x = CanvasMouseX
|
||||||
PBMap\MoveStartingPoint\y = CanvasMouseY
|
PBMap\MoveStartingPoint\y = CanvasMouseY
|
||||||
; Clip MouseX to the map range (in X, the map is infinite)
|
; Clip MouseX to the map range (in X, the map is infinite)
|
||||||
@@ -2339,20 +2459,27 @@ Module PBMap
|
|||||||
PBMap\Dragging = #False
|
PBMap\Dragging = #False
|
||||||
PBMap\Redraw = #True
|
PBMap\Redraw = #True
|
||||||
Case #PB_MAP_REDRAW
|
Case #PB_MAP_REDRAW
|
||||||
Debug "Redraw"
|
|
||||||
PBMap\Redraw = #True
|
PBMap\Redraw = #True
|
||||||
Case #PB_MAP_RETRY
|
Case #PB_MAP_RETRY
|
||||||
Debug "Reload"
|
|
||||||
PBMap\Redraw = #True
|
PBMap\Redraw = #True
|
||||||
|
;- Tile web loading thread cleanup
|
||||||
|
; After a Web tile loading thread, clean the tile structure memory, see GetImageThread()
|
||||||
Case #PB_MAP_TILE_CLEANUP
|
Case #PB_MAP_TILE_CLEANUP
|
||||||
*Tile = EventData()
|
*Tile = EventData()
|
||||||
key = *Tile\key
|
key = *Tile\key
|
||||||
;After a Web tile loading thread, clean the tile structure memory and set the image nb in the cache
|
*Tile\Download = 0
|
||||||
;avoid to have threads accessing vars (and avoid mutex), see GetImageThread()
|
If FindMapElement(PBMap\MemCache\Images(), key) <> 0
|
||||||
Protected timg = PBMap\MemCache\Images(key)\Tile\nImage ;Get this new tile image nb
|
; If the map element has not been deleted during the thread lifetime (should not occur)
|
||||||
PBMap\MemCache\Images(key)\nImage = timg ;store it in the cache using the key
|
PBMap\MemCache\Images(key)\Tile = *Tile\Size
|
||||||
FreeMemory(PBMap\MemCache\Images(key)\Tile) ;free the data needed for the thread
|
If *Tile\Size
|
||||||
PBMap\MemCache\Images(key)\Tile = 0 ;clear the data ptr
|
PBMap\MemCache\Images(key)\Tile = -1 ; Web loading thread has finished successfully
|
||||||
|
Else
|
||||||
|
PBMap\MemCache\Images(key)\Tile = 0
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
FreeMemory(*Tile) ; Frees the data needed for the thread (*tile=PBMap\MemCache\Images(key)\Tile)
|
||||||
|
PBMap\ThreadsNB - 1
|
||||||
|
PBMap\DownloadSlots - 1
|
||||||
PBMap\Redraw = #True
|
PBMap\Redraw = #True
|
||||||
EndSelect
|
EndSelect
|
||||||
EndProcedure
|
EndProcedure
|
||||||
@@ -2360,6 +2487,7 @@ Module PBMap
|
|||||||
; Redraws at regular intervals
|
; Redraws at regular intervals
|
||||||
Procedure TimerEvents()
|
Procedure TimerEvents()
|
||||||
If EventTimer() = PBMap\Timer And (PBMap\Redraw Or PBMap\Dirty)
|
If EventTimer() = PBMap\Timer And (PBMap\Redraw Or PBMap\Dirty)
|
||||||
|
MemoryCacheManagement()
|
||||||
Drawing()
|
Drawing()
|
||||||
EndIf
|
EndIf
|
||||||
EndProcedure
|
EndProcedure
|
||||||
@@ -2391,9 +2519,8 @@ Module PBMap
|
|||||||
Protected TimeCounter = ElapsedMilliseconds()
|
Protected TimeCounter = ElapsedMilliseconds()
|
||||||
Repeat
|
Repeat
|
||||||
ForEach PBMap\MemCache\Images()
|
ForEach PBMap\MemCache\Images()
|
||||||
If PBMap\MemCache\Images()\Tile <> 0
|
If PBMap\MemCache\Images()\Tile > 0
|
||||||
If IsThread(PBMap\MemCache\Images()\Tile\GetImageThread)
|
If IsThread(PBMap\MemCache\Images()\Tile\GetImageThread)
|
||||||
PBMap\MemCache\Images()\Tile\RetryNb = 0
|
|
||||||
If ElapsedMilliseconds() - TimeCounter > 2000
|
If ElapsedMilliseconds() - TimeCounter > 2000
|
||||||
; Should not occur
|
; Should not occur
|
||||||
KillThread(PBMap\MemCache\Images()\Tile\GetImageThread)
|
KillThread(PBMap\MemCache\Images()\Tile\GetImageThread)
|
||||||
@@ -2411,17 +2538,24 @@ Module PBMap
|
|||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
Procedure InitPBMap(Window)
|
Procedure InitPBMap(Window)
|
||||||
|
With PBMap
|
||||||
Protected Result.i
|
Protected Result.i
|
||||||
PBMap\ZoomMin = 1
|
\ZoomMin = 1
|
||||||
PBMap\ZoomMax = 18
|
\ZoomMax = 18
|
||||||
PBMap\Dragging = #False
|
\Dragging = #False
|
||||||
PBMap\TileSize = 256
|
\TileSize = 256
|
||||||
PBMap\Dirty = #False
|
\Dirty = #False
|
||||||
PBMap\EditMarker = #False
|
\EditMarker = #False
|
||||||
PBMap\Font = LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold)
|
\Font = LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold)
|
||||||
PBMap\Window = Window
|
\Window = Window
|
||||||
PBMap\Timer = 1
|
\Timer = 1
|
||||||
PBMap\Mode = #MODE_DEFAULT
|
\Mode = #MODE_DEFAULT
|
||||||
|
\MemoryCacheAccessMutex = CreateMutex()
|
||||||
|
If \MemoryCacheAccessMutex = #False
|
||||||
|
MyDebug("Cannot create a mutex", 0)
|
||||||
|
End
|
||||||
|
EndIf
|
||||||
|
EndWith
|
||||||
LoadOptions()
|
LoadOptions()
|
||||||
TechnicalImagesCreation()
|
TechnicalImagesCreation()
|
||||||
SetLocation(0, 0)
|
SetLocation(0, 0)
|
||||||
@@ -2592,9 +2726,10 @@ CompilerIf #PB_Compiler_IsMainFile
|
|||||||
|
|
||||||
; Our main gadget
|
; Our main gadget
|
||||||
PBMap::InitPBMap(#Window_0)
|
PBMap::InitPBMap(#Window_0)
|
||||||
PBMap::SetOption("ShowDegrees", "0") : Degrees = 0
|
PBMap::SetOption("ShowDegrees", "1") : Degrees = 0
|
||||||
PBMap::SetOption("ShowDebugInfos", "0")
|
PBMap::SetOption("ShowDebugInfos", "1")
|
||||||
PBMap::SetOption("Verbose", "0")
|
PBMap::SetDebugLevel(5)
|
||||||
|
PBMap::SetOption("Verbose", "1")
|
||||||
PBMap::SetOption("ShowScale", "1")
|
PBMap::SetOption("ShowScale", "1")
|
||||||
PBMap::SetOption("Warning", "1")
|
PBMap::SetOption("Warning", "1")
|
||||||
PBMap::SetOption("ShowMarkersLegend", "1")
|
PBMap::SetOption("ShowMarkersLegend", "1")
|
||||||
@@ -2737,8 +2872,10 @@ CompilerIf #PB_Compiler_IsMainFile
|
|||||||
CompilerEndIf
|
CompilerEndIf
|
||||||
|
|
||||||
; IDE Options = PureBasic 5.60 (Windows - x64)
|
; IDE Options = PureBasic 5.60 (Windows - x64)
|
||||||
; CursorPosition = 2691
|
; CursorPosition = 2552
|
||||||
; FirstLine = 2684
|
; FirstLine = 2548
|
||||||
; Folding = -------------------
|
; Folding = -------------------
|
||||||
; EnableThread
|
; EnableThread
|
||||||
; EnableXP
|
; EnableXP
|
||||||
|
; CompileSourceDirectory
|
||||||
|
; DisablePurifier = 1,1,1,1
|
Reference in New Issue
Block a user