+
    KiC  c                   s   R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t	 ^ RI
Ht ^ RIHt ^ RIHt ^ RIHt ]P$                  P'                  ]P(                  R	4      tR
 tRR ltR t]R 4       tR tR t ! R R4      t]! 4       tR# )z(Keep track of game executables' presenceN)settings)	get_games)Game)NotificationSource)cache_single)	AsyncCall)loggerzgame-paths.jsonc                  s    / p \        R ^/R7      pV FR  pVP                  R4      R9   d   K  \        VR,          4      pVP                  4       pV'       g   KG  W@VR,          &   KT  	  V # )Z	installed)ZfiltersZrunnerid)ZsteamZweb)r   Zgetr   get_path_from_config)
game_pathsZ	all_gamesZdb_gamegamepaths        ;/usr/lib/python3.14/site-packages/lutris/util/path_cache.pyget_game_pathsr      sk    J;"23I;;x $44GDM"((*$(74=!      c                s   \         P                  P                  \        4      '       d   V '       g   R# \        P                  ! 4       p\        \        RRR7      ;_uu_ 4       p\        4       p\        P                  ! W2^R7       RRR4       \        P                  ! 4       p\        P                  4        \        P                  ! RWA,
          4       R#   + '       g   i     LX; i)zGenerate a new cache pathNwutf-8ZencodingZindentz&Game path cache built in %0.2f seconds)osr   existsGAME_PATH_CACHE_PATHtimeopenr   jsondumpget_path_cachecache_clearr   debug)ZrecreateZ
start_time
cache_filer	   Zend_times   &    r   build_path_cacher       s    	ww~~*++HJ	"C'	:	:j#%
		*3 
; yy{H 
LL98;PQ 
;	:s   ##CC&	c                s   \         P                  ! RV 4       V P                  4       pV'       g   \         P                  ! RV 4       R# \	        4       pWV P
                  &   \        \        RRR7      ;_uu_ 4       p\        P                  ! W#^R7       RRR4       \        P                  4        R#   + '       g   i     L&; i)z-Add or update the path of a game in the cachezAdding %s to path cachezNo path for %sNr   r   r   r   )r   r   r   warningread_path_cacher   r   r   r   r   r   r   )r
   r   current_cacher   s   &   r   add_to_path_cacher"   -   s    
LL*D1$$&D'.#%M!$''	"C'	:	:j		-A6 
;  
;	:s   ;B22C	c                 s    \        4       # )zUReturn the contents of the path cache file; this
dict is cached, so do not modify it.)r     r   r   r   r   ;   s     r   c                 s    \        \        RR7      ;_uu_ 4       p  \        P                  ! V 4      uuRRR4       #   \        P                   d    / u uuRRR4       # i ; i  + '       g   i     R# ; i)z@Read the contents of the path cache file, and does not cache it.r   r   N)r   r   r   ZloadZJSONDecodeError)r   s    r   r    r    B   s[    	"W	5	5	99Z( 
6	5 ## 	I	 
6	5	 
6	5	5s&   A#<A A#A  A##A4	c                 s   \         P                  ! R V 4       \        4       pV P                  V9  d$   \         P                  ! RW P                  4       R# WP                   \        \        RRR7      ;_uu_ 4       p\        P                  ! W^R7       RRR4       \        P                  4        R#   + '       g   i     L&; i)zRemoving %s from path cachez!Game %s (id=%s) not in cache pathNr   r   r   r   )r   r   r    r   r   r   r   r   r   r   r   )r
   r!   r   s   &  r   remove_from_path_cacher$   K   s    
LL.5#%Mwwm#:D''Jgg	"C'	:	:j		-A6 
;  
;	:s   <B33C	c                   sX   a  ] tR t^Wt o RtR t]R 4       tV 3R lR ltR t	R t
RtV tR	# )
MissingGamesa  This class is a singleton that holds a set of game-ids for games whose directories
are missing. It is updated on a background thread, but there's a NotificationSource ('updated')
that fires when that thread has made changes and exited, so that the UI cab update then.c                sP    \        4       V n        \        4       V n        R V n        R # )N)r   updatedZsetmissing_game_ids_update_runningself   &r   __init__ZMissingGames.__init__\   s    )+ ##r   c                s    V P                   RJ# )z1True if the missing games have ever been updated.N)r(   r)   r+   r   is_initializedZMissingGames.is_initializeda   s     ##4//r   c                s   < V ^8  d   QhRR/# )i   ZreturnNr#   )Zformat__classdict__s   "r   Z__annotate__ZMissingGames.__annotate__f   s     Q QD Qr   c                s|    V P                   '       g*   RV n         \        V P                  V P                  4       R# R# )zThis starts the check for all games; the actual list of game-ids will be obtained
on the worker thread, and this method will start it.TN)r(   r   _update_missing_games_update_missing_games_cbr)   r+   r   update_all_missingZMissingGames.update_all_missingf   s3     ####'D d00$2O2OP $r   c                s   \         P                  ! R4       Rp\        4       P                  4        F  w  r#V'       g   K  W P                  9   p\
        P                  P                  V4      '       * pWE8w  g   KI  V'       d   V P                  P                  V4       MV P                  P                  V4       RpK  	  V# )zThis is the method that runs on the worker thread; it checks each game given
and returns True if any changes to missing_game_ids was made.zChecking for missing gamesFT)
r   r   r   Zitemsr'   r   r   r   ZaddZdiscard)r*   changedZgame_idr   Z
old_statusZ
new_statuss   &     r   r/   Z"MissingGames._update_missing_gamesn   s     	12+-335MGt$(=(==
!#!55
+!--11':--55g>"G 6 r   c                s    R V n         V'       d   \        P                  ! RV4       R# V'       d   V P                  P	                  4        R# R# )Fz"Unable to detect missing games: %sN)r(   r   Z	exceptionr&   Zfire)r*   r2   Zerrors   &&&r   r0   Z%MissingGames._update_missing_games_cb   s6    $A5ILL r   )r(   r'   r&   N)Z__name__Z
__module__Z__qualname__Z__firstlineno____doc__r,   Zpropertyr-   r1   r/   r0   Z__static_attributes__Z__classdictcell__)r.   s   @r   r%   r%   W   s?     `$
 0 0Q Q(   r   r%   )F)r3   r   r   r   Zlutrisr    Zlutris.database.gamesr   Zlutris.gamer   Zlutris.gui.widgetsr   Zlutris.utilr   Zlutris.util.jobsr   Zlutris.util.logr   r   ZjoinZ	CACHE_DIRr   r   r   r"   r   r    r$   r%   ZMISSING_GAMESr#   r   r   <module>r4      s    .  	   +  1 $ & "ww||H$6$68IJ 
R!  	!1  1 h r   