ó
ÔŒ\c           @  sz  d  d l  m Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l m Z m Z m	 Z	 d e
 f d „  ƒ  YZ e e j _ e ƒ  e j _ d „  Z i  Z d „  Z d „  Z d	 „  Z i  Z d
 „  Z d „  Z d „  Z e d e ƒ e d e ƒ e d e ƒ e d e ƒ d „  Z d a d „  Z e d „ Z e Z d „  Z d e
 f d „  ƒ  YZ  d „  Z! e  e j" _  e! e j" _! d S(   iÿÿÿÿ(   t   print_functionN(   t   dumpt   dumpst   loadst
   Persistentc           B  sA   e  Z d  „  Z d „  Z d „  Z d „  Z e d „ Z d „  Z RS(   c         C  s   |  j  ƒ  d  S(   N(   t   _update(   t   self(    (    s   renpy/persistent.pyt   __init__%   s    c         C  s   |  j  j | ƒ d  S(   N(   t   __dict__t   update(   R   t   data(    (    s   renpy/persistent.pyt   __setstate__(   s    c         C  s   |  j  S(   N(   R   (   R   (    (    s   renpy/persistent.pyt   __getstate__+   s    c         C  s4   | j  d ƒ r0 | j d ƒ r0 t d | ƒ ‚ n  d  S(   Nt   __s%   Persistent object has no attribute %r(   t
   startswitht   endswitht   AttributeErrort   None(   R   t   attr(    (    s   renpy/persistent.pyt   __getattr__/   s    c         C  s   t  |  j ƒ } x. | D]& } | d d k r2 q n  |  j | =q W| r} |  j j ƒ  |  j j ƒ  |  j j ƒ  |  j j ƒ  n  d S(   sƒ   
        Resets the persistent data.

        `progress`
            If true, also resets progress data that Ren'Py keeps.
        i    t   _N(   t   listR   t
   _seen_evert   cleart   _seen_imagest   _chosent   _seen_audio(   R   t   progresst   keyst   i(    (    s   renpy/persistent.pyt   _clear5   s    c         C  sÒ   |  j  d k r$ t j j ƒ  |  _  n  |  j s9 i  |  _ n  |  j sN i  |  _ n  |  j sc i  |  _ n  |  j sx i  |  _ n  |  j	 s t
 ƒ  |  _	 n  |  j d k rÎ i d d 6d d 6d d 6d d 6d d 6|  _ n  d S(   sf   
        Updates the persistent data to be the latest version of
        the persistent data.
        i    t   _preferencesR   R   R   t   _seen_translatesN(   R   R   t   renpyt   preferencest   PreferencesR   R   R   R   R    t   sett   _changed(   R   (    (    s   renpy/persistent.pyR   K   s&    					(	   t   __name__t
   __module__R   R   R   R   t   FalseR   R   (    (    (    s   renpy/persistent.pyR   #   s   				c         C  sG   t  j |  ƒ } |  | k sC t j j r: t d |  ƒ ‚ qC |  } n  | S(   sÏ   
    A "safe" version of deepcopy. If an object doesn't implement __eq__
    correctly, we replace it with its original.

    This tries to ensure we don't constantly find changes in the same
    field.
    s5   To be persisted, %r must support equality comparison.(   t   copyt   deepcopyR!   t   configt	   developert	   Exception(   t   ot   rv(    (    s   renpy/persistent.pyt   safe_deepcopyw   s    		c          C  sÉ   t  }  t j ƒ  } t j j } t | ƒ } t t j ƒ  ƒ t | j ƒ  ƒ B} xv | D]n } | d k rk qS n  t j	 | d ƒ } | j	 | d ƒ } | | k sS | | j | <t | ƒ t | <t }  qS qS W|  S(   s  
    This finds changes in the persistent object. When it finds a change, it
    backs up that changed, and puts the current time for that field into
    persistent._changed.

    This returns True if there was at least one change, and False
    otherwise.
    R%   N(   R(   t   timeR!   t   gamet
   persistentt   varsR$   t   backupR   t   getR   R%   R0   t   True(   R/   t   nowR3   t   pvarst   fieldst   ft   oldt   new(    (    s   renpy/persistent.pyt   find_changes‘   s    
"c         C  sª   t  j j |  ƒ s d Sy> t |  d ƒ } | j ƒ  j d ƒ } | j ƒ  t | ƒ } WnE d d l	 } y' | j
 j j d ƒ | j
 j j ƒ  Wn n Xd SX| j ƒ  | S(   s•   
    Loads persistence data from `filename`. Returns None if the data
    could not be loaded, or a Persistent object if it could be
    loaded.
    t   rbt   zlibiÿÿÿÿNs   Loading persistent.(   t   ost   patht   existsR   t   filet   readt   decodet   closeR   t   renpy.displayt   displayt   logt   writet	   exceptionR   (   t   filenameR;   t   sR3   R!   (    (    s   renpy/persistent.pyt   load¶   s"    

c          C  s¸   t  j j t j j d ƒ }  t |  ƒ } | d k r] t  j j t j j d ƒ }  t |  ƒ } n  | d k ru t ƒ  } n  t	 | ƒ } x0 t	 | ƒ j
 ƒ  D] \ } } t | ƒ t | <q” W| S(   s°   
    Loads the persistent data from disk.

    This performs the initial load of persistent data from the local
    disk, so that we can configure the savelocation system.
    s   persistent.newR3   N(   RA   RB   t   joinR!   R+   t   savedirRO   R   R   R4   t	   iteritemsR0   R5   (   RM   R3   t   vt   k(    (    s   renpy/persistent.pyt   initÖ   s    c         C  s   | t  |  <d S(   s!  
    :doc: persistent

    Registers a function that is used to merge values of a persistent field
    loaded from disk with values of current persistent object.

    `field`
        The name of a field on the persistent object.

    `function`
        A function that is called with three parameters, `old`, `new`, and
        `current`:

        `old`
            The value of the field in the older object.

        `new`
            The value of the field in the newer object.

        `current`
            The value of the field in the current persistent object. This is
            provided for cases where the identity of the object referred to
            by the field can't change.

        The function is expected to return the new value of the field in the
        persistent object.
    N(   t   registry(   t   fieldt   func(    (    s   renpy/persistent.pyt   register_persistentõ   s    c         C  s   | S(   N(    (   R<   R=   t   current(    (    s   renpy/persistent.pyt   default_merge  s    c         C  s   | j  |  ƒ | j  | ƒ | S(   N(   R	   (   R<   R=   RZ   (    (    s   renpy/persistent.pyt   dictset_merge  s    R   R   R   R   c         C  sT  t  j  ƒ  } t j j } t | ƒ } t |  ƒ } t | j ƒ  ƒ t | j ƒ  ƒ B} xû | D]ó } | j | d ƒ } | j | d ƒ } | | k r• qY n  | j	 j | d ƒ }	 |  j	 j | d ƒ }
 t
 | |
 ƒ }
 |	 |
 k rï | } | } |	 } n | } | } |
 } t j | t ƒ } | | | | ƒ } | | | <t | ƒ t | <| | j	 | <qY Wd S(   sd   
    Merges `other` (which must be a persistent object) into the
    current persistent object.
    i    N(   R1   R!   R2   R3   R4   R$   R   R6   R   R%   t   minRV   R[   R0   R5   (   t   otherR8   R3   R9   t   ovarsR:   R;   t   pvalt   ovalt   ptimet   otimeR=   R<   t   tt
   merge_funct   val(    (    s   renpy/persistent.pyt   merge%  s2    "	
c          C  sO   x4 t  j j j ƒ  D] \ }  } |  t k r Pq q Wd St ƒ  t  j j ƒ  d S(   si   
    Checks to see if we need to run update. If we do, runs update and
    restarts the interaction.
    N(   R!   t   loadsavet   locationt   load_persistentt   persistent_mtimeR	   t   exportst   restart_interaction(   t   mtimet   _data(    (    s   renpy/persistent.pyt   check_updateV  s    c         C  s–   t  ƒ  } | p |  } t j j j ƒ  } | j ƒ  t } xB | D]: \ } } | t k r\ q> n  | d k rn q> n  t | ƒ q> W| a | r’ t	 ƒ  n  d S(   s   
    Loads the persistent data from persistent files that are newer than
    persistent_mtime, and merges it into the persistent object.
    N(
   R>   R!   Rh   Ri   Rj   t   sortRk   R   Rg   t   save(   t
   force_savet	   need_savet   pairsRn   R^   (    (    s   renpy/persistent.pyR	   f  s    	
c          C  s\   t  s
 d Sy2 t t j j ƒ j d ƒ }  t j j j |  ƒ Wn t j	 j
 rX ‚  qX n Xd S(   s,   
    Saves the persistent data to disk.
    NR@   (   t   should_save_persistentR   R!   R2   R3   t   encodeRh   Ri   t   save_persistentR+   R,   (   R
   (    (    s   renpy/persistent.pyRr     s    t   _MultiPersistentc           B  s,   e  Z d  „  Z d „  Z d „  Z d „  Z RS(   c         C  s   |  j  j ƒ  } | d =| S(   Nt	   _filename(   R   R)   (   R   t   state(    (    s   renpy/persistent.pyR   ¤  s    c         C  s   |  j  j | ƒ d  S(   N(   R   R	   (   R   R{   (    (    s   renpy/persistent.pyR   ©  s    c         C  s.   | j  d ƒ r* | j d ƒ r* t ƒ  ‚ n  d  S(   NR   (   R   R   R   R   (   R   t   name(    (    s   renpy/persistent.pyR   ¬  s    c         C  sz   |  j  } t | d d ƒ } t |  | ƒ | j ƒ  y t j | d | ƒ Wn( t j | ƒ t j | d | ƒ n Xd  S(   Ns   .newt   wb(   Rz   RD   R   RG   RA   t   renamet   unlink(   R   t   fnR;   (    (    s   renpy/persistent.pyRr   ³  s    	
(   R&   R'   R   R   R   Rr   (    (    (    s   renpy/persistent.pyRy   ¢  s   			c         C  sÁ  t  j j |  ƒ }  t  j j ƒ  j s3 t d ƒ ‚ n  t  j r^ t j	 j
 t j d d ƒ g } n¨ t  j rv t d ƒ ‚ n t  j rÁ t j	 j d ƒ g } d t j k r| j t j d d ƒ qnE t  j rñ t j	 j d ƒ t j	 j d	 ƒ g } n t j	 j d ƒ g } d
 t j k r(t j d
 g } n  y t j | d ƒ Wn n Xd } x2 | D]* } | d |  } t j	 j | ƒ rTPqTqTWy t t | d ƒ j ƒ  ƒ } Wn t ƒ  } n X| | _ | S(   Ns>   MultiPersistent objects must be created during the init phase.t   ANDROID_OLD_PUBLICs   ../RenPy/Persistents(   MultiPersistent is not supported on iOS.s   ~/RenPy/Persistentt   APPDATAs   /RenPy/persistents   ~/.renpy/persistents   ~/Library/RenPy/persistentt   RENPY_MULTIPERSISTENTiÿÿÿÿt    t   /R?   (   R!   Rl   t   fsencodeR2   t   contextt
   init_phaseR-   t   androidRA   RB   RP   t   environt   iost   windowst
   expandusert   appendt	   macintosht   makedirsRC   R   RD   RE   Ry   Rz   (   R|   t   filesR€   R/   (    (    s   renpy/persistent.pyt   MultiPersistentÁ  s@    	"				(#   t
   __future__R    RA   R)   R1   R!   t   renpy.loadsaveR   R   R   t   objectR   R2   R3   R0   R5   R>   RO   RU   RV   RY   R[   R\   Rg   R   Rk   Rp   R(   R	   R7   Rv   Rr   Ry   R’   Rh   (    (    (    s   renpy/persistent.pyt   <module>   s>   P		%	 		 			.	$		4