New Cache (Helped with Gimini)

This commit is contained in:
2025-09-14 17:36:20 +02:00
parent c7add6c0de
commit 04492e513d

View File

@@ -104,178 +104,217 @@ DeclareModule Cache
Structure Param Structure Param
CallBackLoadMedia.CallBackLoadMedia CallBackLoadMedia.CallBackLoadMedia
;LoadList
LoadListSemaphore.i
LoadListMutex.i LoadListMutex.i
List LoadList.i() List LoadList.i()
;CacheList NewTaskSemaphore.i
CacheListMutex.i CacheListMutex.i
Map CacheList.Core::FileData() Map CacheList.Core::FileData()
BackGroundThread.i Array WorkerThreads.i(1)
;Signal New Image Loaded
SignalMutex.i SignalMutex.i
Signal.b ;Signal When new image is loaded Signal.b
;Message
QuitMutex.i QuitMutex.i
Quit.b Quit.b
EndStructure EndStructure
Global Param.Param Global Param.Param
Param\LoadListSemaphore=CreateSemaphore(1)
Param\LoadListMutex=CreateMutex()
Param\CacheListMutex=CreateMutex()
param\SignalMutex=CreateMutex()
Param\QuitMutex=CreateMutex()
Declare InitCache()
Declare SetCallBackLoadMedia(CallBackLoadMedia.i) Declare SetCallBackLoadMedia(CallBackLoadMedia.i)
Declare AddFileToLoadList(FilePath.s) Declare AddFileToLoadList(FilePath.s)
Declare CacheClean() Declare CacheClean()
Declare AutoLoadStart()
Declare.i GetFileDataFromCache(FilePath.s,Image.i=0) Declare.i GetFileDataFromCache(FilePath.s,Image.i=0)
Declare.b GetSignalAndReset() Declare.b GetSignalAndReset()
Declare Quit() Declare QuitCache()
EndDeclareModule EndDeclareModule
Module Cache Module Cache
EnableExplicit
;- CORRIGÉ : La constante est maintenant privée au module, sans 'Global'.
#WORKER_THREADS = 4
Procedure InitCache()
Param\LoadListMutex = CreateMutex()
Param\CacheListMutex = CreateMutex()
Param\SignalMutex = CreateMutex()
Param\QuitMutex = CreateMutex()
Param\NewTaskSemaphore = CreateSemaphore(0)
Dim Param\WorkerThreads(#WORKER_THREADS - 1)
EndProcedure
Procedure SetCallBackLoadMedia(CallBackLoadMedia.i) Procedure SetCallBackLoadMedia(CallBackLoadMedia.i)
Param\CallBackLoadMedia=CallBackLoadMedia Param\CallBackLoadMedia = CallBackLoadMedia
EndProcedure
Procedure CacheWorkerThread(ThreadID.i)
Protected Quit.b = #False
Protected *Ptr.Core::FileData
Repeat
WaitSemaphore(Param\NewTaskSemaphore)
LockMutex(Param\QuitMutex)
Quit = Param\Quit
UnlockMutex(Param\QuitMutex)
If Quit = #False
LockMutex(Param\LoadListMutex)
If ListSize(Param\LoadList()) > 0
FirstElement(Param\LoadList())
*Ptr = Param\LoadList()
DeleteElement(Param\LoadList())
Else
*Ptr = 0
EndIf
UnlockMutex(Param\LoadListMutex)
If *Ptr
If *Ptr\Image = 0 And FileSize(*Ptr\FilePath) > 0
Debug "Worker " + ThreadID + " charge: " + GetFilePart(*Ptr\FilePath)
If Param\CallBackLoadMedia <> 0
Param\CallBackLoadMedia(*Ptr)
Else
*Ptr\Image = LoadImage(#PB_Any, *Ptr\FilePath)
EndIf
If IsImage(*Ptr\Image)
Protected result.ImgTools::DefDisplayImage
ImgTools::ImageToContainer(@result, *Ptr\Image, 256, 256, ImgTools::#Image_Style_Fit)
ResizeImage(*Ptr\Image, result\Width, result\Height, #PB_Image_Smooth)
*Ptr\State = 1
LockMutex(Param\SignalMutex)
Param\Signal = #True
UnlockMutex(Param\SignalMutex)
Else
Debug "ERREUR de chargement: " + *Ptr\FilePath
*Ptr\Image = CreateImage(#PB_Any, 256, 256, 24, RGB(255, 0, 0))
*Ptr\State = 1
EndIf
EndIf
EndIf
EndIf
Until Quit = #True
Debug "Cache Worker " + ThreadID + " terminé."
EndProcedure EndProcedure
Procedure StartWorkers()
If IsThread(Param\WorkerThreads(0)) = #False
Debug "Démarrage du pool de " + #WORKER_THREADS + " threads."
Protected i
For i = 0 To #WORKER_THREADS - 1
Param\WorkerThreads(i) = CreateThread(@CacheWorkerThread(), i)
Next
EndIf
EndProcedure
Procedure AddFileToLoadList(FilePath.s) Procedure AddFileToLoadList(FilePath.s)
Protected *Ptr Protected *Ptr
LockMutex(param\CacheListMutex) LockMutex(Param\CacheListMutex)
*Ptr=AddMapElement(param\CacheList(),FilePath) If FindMapElement(Param\CacheList(), FilePath) = #False
*Ptr = AddMapElement(Param\CacheList(), FilePath)
param\CacheList()\FilePath=FilePath Param\CacheList()\FilePath = FilePath
param\CacheList()\State=0 Param\CacheList()\State = 0
UnlockMutex(param\CacheListMutex) UnlockMutex(Param\CacheListMutex)
LockMutex(Param\LoadListMutex)
LastElement(param\LoadList())
AddElement(param\LoadList())
Debug "AddFileToLoadList:"+Str(ListIndex(param\LoadList()))
param\LoadList()=*Ptr
UnlockMutex(Param\LoadListMutex)
EndProcedure
Procedure LoadCacheDataThread(*Ptr.core::FileData)
If *Ptr\Image=0 And FileSize(*Ptr\FilePath)>0
Debug "Cache Load:"+*Ptr\FilePath
;Param\CallBackLoadMedia=0 ;To Force to use Internal Loader
If Param\CallBackLoadMedia<>0 ; <- Use extern procedure to Load Image
LockMutex(Param\CacheListMutex)
Param\CallBackLoadMedia(*Ptr)
UnlockMutex(Param\CacheListMutex)
Else
LockMutex(Param\CacheListMutex) ; <- Or intern with PB Plugin
*Ptr\Image=LoadImage(#PB_Any,*Ptr\FilePath)
If IsImage(*Ptr\Image)
Else
*Ptr\Image=0
EndIf
UnlockMutex(Param\CacheListMutex)
EndIf
;Resize Image to Thumnails MaxSize LockMutex(Param\LoadListMutex)
If IsImage(*Ptr\Image) AddElement(Param\LoadList())
Protected result.ImgTools::DefDisplayImage Param\LoadList() = *Ptr
ImgTools::ImageToContainer(@result,*Ptr\Image,256,256,ImgTools::#Image_Style_Fit) UnlockMutex(Param\LoadListMutex)
ResizeImage(*Ptr\Image,result\Width,result\Height,#PB_Image_Smooth)
*Ptr\State=1; Ready to Display Image SignalSemaphore(Param\NewTaskSemaphore)
;We Have a new Image i Signal it
LockMutex (Param\SignalMutex)
Param\Signal=#True
UnlockMutex (Param\SignalMutex)
;If can't load image
Else
;MessageRequester("Thumbnails Error","ERROR THREAD LOAD IMAGE"+Chr(13)+FilePath+Chr(13)+" in "+#PB_Compiler_Procedure+"()",#PB_MessageRequester_Ok | #PB_MessageRequester_Error)
Debug "ERROR THREAD LOAD IMAGE"+Chr(13)+*Ptr\FilePath
*Ptr\Image=CreateImage(#PB_Any,320,200)
StartDrawing(ImageOutput(*Ptr\Image))
Box(0,0,320,200,RGB(0,255,0))
StopDrawing()
*Ptr\State=1
EndIf
Else Else
Debug "Cache Load Error:"+*Ptr\FilePath UnlockMutex(Param\CacheListMutex)
EndIf EndIf
SignalSemaphore(Param\LoadListSemaphore)
EndProcedure EndProcedure
Procedure BackgroundThread(n.i) Procedure.i GetFileDataFromCache(FilePath.s, Image.i = 0)
Protected Quit.b Protected *Ptr.core::FileData
Repeat
Repeat LockMutex(Param\CacheListMutex)
*Ptr = FindMapElement(Param\CacheList(), FilePath)
UnlockMutex(Param\CacheListMutex)
If *Ptr = 0
StartWorkers()
LockMutex(Param\CacheListMutex)
*Ptr = AddMapElement(Param\CacheList(), FilePath)
*Ptr\FilePath = FilePath
If Image = 0
*Ptr\State = 0
*Ptr\Image = 0
LockMutex(Param\LoadListMutex) LockMutex(Param\LoadListMutex)
;Select Data from Id AddElement(Param\LoadList())
If LastElement(Param\LoadList())<>0 Param\LoadList() = *Ptr
Debug "BackgroundThread:"+Str(ListIndex(param\LoadList()))
Protected *Ptr.core::FileData
*Ptr=Param\LoadList()
WaitSemaphore(Param\LoadListSemaphore)
Debug "LoadList index:"+Str(ListIndex(Param\LoadList()))+"/"+ListSize(Param\LoadList())
If CreateThread(@LoadCacheDataThread(),*Ptr)<>0
DeleteElement(Param\LoadList())
Else
Debug "######################Can't Start Thread"
End
EndIf
EndIf
UnlockMutex(Param\LoadListMutex) UnlockMutex(Param\LoadListMutex)
;Else SignalSemaphore(Param\NewTaskSemaphore)
; Debug "Wait Semaphore" Else
; Delay(200) *Ptr\State = 1
; EndIf *Ptr\Image = Image
EndIf
; Debug "LOADLIST SIZE:"+Str(ListSize(Param\LoadList())) UnlockMutex(Param\CacheListMutex)
LockMutex(Param\QuitMutex) EndIf
Quit=Param\Quit
UnlockMutex(Param\QuitMutex) ProcedureReturn *Ptr
Until ListSize(Param\LoadList())=0 Or Quit=#True
Delay(1)
Until Quit=#True
Debug "Bye Bye ! Cache::BackgroundThread()"
EndProcedure EndProcedure
Procedure Quit() Procedure QuitCache()
Debug "QUIT CACHE" Debug "Arrêt du cache..."
If IsThread(Param\BackGroundThread) If IsThread(Param\WorkerThreads(0))
LockMutex(Param\QuitMutex) LockMutex(Param\QuitMutex)
Param\Quit=#True Param\Quit = #True
UnlockMutex(Param\QuitMutex) UnlockMutex(Param\QuitMutex)
Debug "Cache::Quit Wait Param\BackGroundThread"
WaitThread(Param\BackGroundThread) Protected i
Debug "Cache::Quit Finish" For i = 0 To #WORKER_THREADS - 1
EndIf SignalSemaphore(Param\NewTaskSemaphore)
Next
For i = 0 To #WORKER_THREADS - 1
If IsThread(Param\WorkerThreads(i))
WaitThread(Param\WorkerThreads(i))
EndIf
Next
Debug "Tous les workers sont arrêtés."
EndIf
FreeMutex(Param\LoadListMutex)
FreeMutex(Param\CacheListMutex)
FreeMutex(Param\SignalMutex)
FreeMutex(Param\QuitMutex)
FreeSemaphore(Param\NewTaskSemaphore)
EndProcedure EndProcedure
Procedure AutoLoadStart() Procedure.b GetSignalAndReset()
If IsThread(Param\BackGroundThread)=#False Protected Signal.b
Param\BackGroundThread=CreateThread(@BackgroundThread(),0) LockMutex(Param\SignalMutex)
EndIf Signal = Param\Signal
Param\Signal = #False
UnlockMutex(Param\SignalMutex)
ProcedureReturn Signal
EndProcedure EndProcedure
Procedure Free(*Ptr.core::FileData) Procedure Free(*Ptr.core::FileData)
If IsImage(*Ptr\Image):FreeImage(*Ptr\Image):EndIf If IsImage(*Ptr\Image): FreeImage(*Ptr\Image): EndIf
FreeMap(*Ptr\MetaData()) FreeMap(*Ptr\MetaData())
EndProcedure EndProcedure
;TODO remake it
Procedure CacheClean() Procedure CacheClean()
Protected *Ptr.core::FileData Protected *Ptr.core::FileData
LockMutex(Param\CacheListMutex) LockMutex(Param\CacheListMutex)
ForEach Param\CacheList() ForEach Param\CacheList()
If MapSize(Param\CacheList())<500 If MapSize(Param\CacheList()) < 500
Break; Break
Else Else
*Ptr=Param\CacheList() *Ptr = Param\CacheList()
If *Ptr\State=1 And *Ptr\Selected=#False If *Ptr\State = 1 And *Ptr\Selected = #False
Debug "Free Cache :"+GetFilePart(*Ptr\FilePath)+" State:"+Str(*Ptr\State) Debug "Nettoyage cache : " + GetFilePart(*Ptr\FilePath)
Free(*Ptr) Free(*Ptr)
DeleteMapElement(Param\CacheList()) DeleteMapElement(Param\CacheList())
EndIf EndIf
@@ -283,48 +322,9 @@ Module Cache
Next Next
UnlockMutex(Param\CacheListMutex) UnlockMutex(Param\CacheListMutex)
EndProcedure EndProcedure
Procedure.i GetFileDataFromCache(FilePath.s,Image.i=0)
LockMutex(Param\CacheListMutex)
Protected *Ptr.core::FileData
*Ptr=FindMapElement(Param\CacheList(),FilePath)
UnlockMutex(Param\CacheListMutex)
If *Ptr=0
;AddToLoadList
LockMutex(Param\CacheListMutex)
*Ptr=AddMapElement(Param\CacheList(),FilePath)
*Ptr\FilePath=FilePath
If Image=0
*Ptr\State=0
*Ptr\Image=0
Else ;If We have Image (Ex when use Blob in DB)
*Ptr\State=1
*Ptr\Image=Image
EndIf
UnlockMutex(Param\CacheListMutex)
LockMutex(Param\LoadListMutex)
Debug "ListSize:"+Str(ListSize(param\LoadList()))
FirstElement(param\LoadList())
AddElement(param\LoadList())
Param\LoadList()=*Ptr
UnlockMutex(Param\LoadListMutex)
AutoLoadStart()
EndIf
ProcedureReturn *Ptr
EndProcedure
Procedure.b GetSignalAndReset()
Protected Signal.b
LockMutex (Param\SignalMutex)
Signal=Param\Signal
Param\Signal=#False
UnlockMutex (Param\SignalMutex)
ProcedureReturn Signal
EndProcedure
EndModule EndModule
;-Thumbs ;-Thumbs
DeclareModule Thumbs DeclareModule Thumbs
Declare SetCallBackLoadFromIndex(GadgetId.i,CallBackLoadFromIndex.i) Declare SetCallBackLoadFromIndex(GadgetId.i,CallBackLoadFromIndex.i)
@@ -495,7 +495,7 @@ Module Thumbs
Delay(10) Delay(10)
Debug "No Set CallBackLoadFromIndex" Debug "No Set CallBackLoadFromIndex"
EndIf EndIf
Cache::AutoLoadStart()
Else Else
Delay(50) Delay(50)
EndIf EndIf
@@ -959,6 +959,7 @@ CompilerIf #PB_Compiler_IsMainFile
If OpenWindow(#Win_main, 0, 0, 1024, 600, "Thumbnails", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget) If OpenWindow(#Win_main, 0, 0, 1024, 600, "Thumbnails", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
ButtonGadget(#Gdt_Folder,0,0,100,25,"Choose Folder") ButtonGadget(#Gdt_Folder,0,0,100,25,"Choose Folder")
Cache::InitCache()
Thumbs::ThumbsGadget(#Gdt_ThumbA,0,50,WindowWidth(#Win_main),WindowHeight(#Win_main)-50,128,@CallBackLoadFromIndexB()) Thumbs::ThumbsGadget(#Gdt_ThumbA,0,50,WindowWidth(#Win_main),WindowHeight(#Win_main)-50,128,@CallBackLoadFromIndexB())
Repeat Repeat
Event = WaitWindowEvent() Event = WaitWindowEvent()
@@ -997,11 +998,12 @@ CompilerIf #PB_Compiler_IsMainFile
Until Event = #PB_Event_CloseWindow Until Event = #PB_Event_CloseWindow
Thumbs::FreeThumbsGadget(#Gdt_ThumbA) Thumbs::FreeThumbsGadget(#Gdt_ThumbA)
Cache::QuitCache()
EndIf EndIf
CompilerEndIf CompilerEndIf
; IDE Options = PureBasic 6.21 (Windows - x64) ; IDE Options = PureBasic 6.21 (Windows - x64)
; CursorPosition = 205 ; CursorPosition = 1000
; FirstLine = 205 ; FirstLine = 954
; Folding = ------ ; Folding = ------
; EnableThread ; EnableThread
; EnableXP ; EnableXP