a
    V$cA?                     @   s  d dl mZmZmZmZmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZ d dlmZ d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZe j e j!B Z"dd Z#e#e_#da$erdd	 Z%nej&Z%d
d Z'G dd de(Z)G dd de*Z+dd Z,dd Z-G dd de.Z/G dd de0Z1G dd de(Z2dd Z3G dd dej4Z5G dd dej4Z6dS )     )divisionabsolute_importwith_statementprint_functionunicode_literals)PY2
basestringbchrbordchropenpystrrangeroundstrtobytesunicode)OptionalNc                 C   sT   | t u r|tu rt}g }|tu r,t| }n$|| |}|jtjkrP||| |S N)RevertableSetobjectset__new____init__)clsbasestateobj r   renpy/revertable.py_reconstructor5   s    r    Tc                 C   s   t | ddS )N)__name____doc__r   )	functoolswrapsmethodr   r   r   _method_wrapperO   s    r'   c                    s   t   fdd}|S )Nc                    sJ   t jjj}t| |vr4t| |  f|t| < da | g|R i |S NT)	renpygamelogmutatedidweakrefref_cleanmutate_flag)selfargskwargsr,   r%   r   r   do_mutationV   s
    
zmutator.<locals>.do_mutationr'   )r&   r5   r   r%   r   mutatorT   s    r7   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	CompressedLista  
    Compresses the changes in a queue-like list. What this does is to try
    to find a central sub-list for which has objects in both lists. It
    stores the location of that in the new list, and then elements before
    and after in the sub-list.

    This only really works if the objects in the list are unique, but the
    results are efficient even if this doesn't work.
    c                 C   sZ  t |d d }|| }t |d d }td|d D ]<}|||  |u rV|| } q|||  |u r6|| } qq6|| _d| _d| _g | _d S |}|d }	|}
|d }t |}t |}|r|
r||d  ||
d  u r|d8 }|
d8 }
q|	|k r"||k r"||	 || u r"|	d7 }	|d7 }qt|td|
| _|| _|	| _t|t||| _d S )N      r   )	lenr   prestartendpostlist__getitem__slice)r2   oldnew
new_center	new_pivotold_halfi
old_center	new_startnew_end	old_startold_endlen_newlen_oldr   r   r   r   q   s>     
&
zCompressedList.__init__c                 C   s   | j || j| j  | j S r   )r<   r=   r>   r?   )r2   rD   r   r   r   
decompress   s    zCompressedList.decompressc                 C   s   d | j| j| j| jS )Nz<CompressedList {} [{}:{}] {}>)formatr<   r=   r>   r?   r2   r   r   r   __repr__   s    zCompressedList.__repr__N)r!   
__module____qualname__r"   r   rP   rS   r   r   r   r   r8   f   s   
3r8   c                   @   s   e Zd Zdd ZeejZer(eejZeej	Z	er@eej
Z
eejZeejZeejZeejZeejZeejZeejZeejZeejZdd ZeejZereejZ[dd Zdd ZeZd	d
 Zdd Zdd Zdd Zdd ZdS )RevertableListc                 G   s4   t jj}|d urd |jt| < tj| g|R   d S r   )r)   r*   r+   r,   r-   r@   r   r2   r3   r+   r   r   r   r      s    zRevertableList.__init__c                    s   t   fdd}|S )Nc                     s    | i |}t |S r   )rV   )r3   r4   lr%   r   r   	newmethod   s    z)RevertableList.wrapper.<locals>.newmethodr6   r&   rY   r   r%   r   wrapper   s    zRevertableList.wrapperc                 C   s&   t | |}t|trt|S |S d S r   )r@   rA   
isinstancerB   rV   )r2   indexrvr   r   r   rA      s    
zRevertableList.__getitem__c                 C   s.   t |tstdt|jtt| |S )Nz0can't multiply sequence by non-int of type '{}'.)	r\   int	TypeErrorrQ   typer!   rV   r@   __mul__)r2   otherr   r   r   rb      s    
zRevertableList.__mul__c                 C   s   | d d  S r   r   rR   r   r   r   copy   s    zRevertableList.copyc                 C   s   g | d d < d S r   r   rR   r   r   r   clear   s    zRevertableList.clearc                 C   s   | dd S )zN
        Gets a clean copy of this object before any mutation occurs.
        Nr   rR   r   r   r   r0      s    zRevertableList._cleanc                 C   sJ   | r|s|S t jjdu r|S t| t jjk s<t|t jjk r@|S t|| S )z
        Takes a clean copy of this object, compresses it, and returns compressed
        information that can be passed to rollback.
        N)r)   configlist_compression_lengthr;   r8   r2   cleanr   r   r   	_compress   s     zRevertableList._compressc                 C   s.   t |tr|| | dd< n|| dd< dS )z
        Rolls this object back, using the information created by _compress.

        Since compressed can come from a save file, this method also has to
        recognize and deal with old data.
        N)r\   r8   rP   r2   
compressedr   r   r   	_rollback  s    
zRevertableList._rollbackN)r!   rT   rU   r   r7   r@   __delitem__r   Z__delslice____setitem__Z__setslice____iadd____imul__appendextendinsertpopremovereversesortr[   __add__Z__getslice__rA   rb   __rmul__rd   re   r0   rj   rm   r   r   r   r   rV      s:   












	

rV   c                  G   s   t t|  S r   )rV   r   )r3   r   r   r   revertable_range  s    r{   c                  O   s   t t| i |S r   )rV   sorted)r3   r4   r   r   r   revertable_sorted  s    r}   c                   @   s   e Zd Zdd ZeejZeejZeejZeej	Z	eej
Z
eejZeejZertdd Zdd Zdd ZnejZejZejZd	d
 Zdd Zdd Zdd Zdd ZdS )RevertableDictc                 O   s:   t jj}|d urd |jt| < tj| g|R i | d S r   )r)   r*   r+   r,   r-   dictr   )r2   r3   r4   r+   r   r   r   r     s    zRevertableDict.__init__c                 C   s,   t | }tdjjt@ tkr(t|}|S Nr9   )r   keyssys	_getframef_codeco_flagsFUTURE_FLAGSrV   r2   r^   r   r   r   r   0  s    
zRevertableDict.keysc                 C   s,   t | }tdjjt@ tkr(t|}|S r   )r   valuesr   r   r   r   r   rV   r   r   r   r   r   8  s    
zRevertableDict.valuesc                 C   s,   t | }tdjjt@ tkr(t|}|S r   )r   itemsr   r   r   r   r   rV   r   r   r   r   r   @  s    
zRevertableDict.itemsc                 C   s   || v S r   r   )r2   keyr   r   r   has_keyM  s    zRevertableDict.has_keyc                 C   s   t  }||  |S r   )r~   updater   r   r   r   rd   P  s    
zRevertableDict.copyc                 C   s   t |  S r   )r@   r   rR   r   r   r   r0   U  s    zRevertableDict._cleanc                 C   s   |S r   r   rh   r   r   r   rj   X  s    zRevertableDict._compressc                 C   s"   |    |D ]\}}|| |< qd S r   )re   )r2   rl   kvr   r   r   rm   [  s    zRevertableDict._rollbackN)r!   rT   rU   r   r7   r   rn   ro   re   ru   popitem
setdefaultr   r   r   r   r   
itervaluesiterkeys	iteritemsr   rd   r0   rj   rm   r   r   r   r   r~     s(   







	r~   c                   @   s8  e Zd Zdd Zdd ZejZejZdd Ze	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZe	e
jZdd Zee
jZee
jZee
jZee
jZee
jZee
jZee
j Z ee
j!Z!ee
j"Z"[d	d
 Z#dd Z$dd Z%dS )r   c                 C   s,   t |tr| |d   n
| | d S )Nr   )r\   tupler   r   )r2   r   r   r   r   __setstate__d  s    
zRevertableSet.__setstate__c                 C   s   dd | D f}|S )Nc                 S   s   i | ]
}|d qS )Tr   ).0rH   r   r   r   
<dictcomp>k      z.RevertableSet.__getstate__.<locals>.<dictcomp>r   r   r   r   r   __getstate__j  s    zRevertableSet.__getstate__c                 G   s4   t jj}|d urd |jt| < tj| g|R   d S r   )r)   r*   r+   r,   r-   r   r   rW   r   r   r   r   r  s    zRevertableSet.__init__c                    s   t   fdd}|S )Nc                     s(    | i |}t |tr t|S |S d S r   )r\   r   r   )r3   r4   r^   r%   r   r   rY     s    
z(RevertableSet.wrapper.<locals>.newmethodr6   rZ   r   r%   r   r[     s    zRevertableSet.wrapperc                 C   s   t | S r   )r@   rR   r   r   r   r0     s    zRevertableSet._cleanc                 C   s   |S r   r   rh   r   r   r   rj     s    zRevertableSet._compressc                 C   s   t |  t | | d S r   )r   re   r   rk   r   r   r   rm     s    
zRevertableSet._rollbackN)&r!   rT   rU   r   r   r   
__reduce____reduce_ex__r   r7   r   __iand____ior____isub____ixor__addre   difference_updatediscardintersection_updateru   rv   symmetric_difference_updater   union_updater[   __and____sub____xor____or__rd   
differenceintersectionsymmetric_differenceunionr0   rj   rm   r   r   r   r   r   b  sB   






















r   c                       sX   e Zd Z fddZdd Zdd ZeejZeej	Z	dd Z
d	d
 Zdd Z  ZS )RevertableObjectc                    s2   t t| | }tjj}|d ur.d |jt|< |S r   )superr   r   r)   r*   r+   r,   r-   )r   r3   r4   r2   r+   	__class__r   r   r     s
    zRevertableObject.__new__c                 O   s   |s|rt jjrtdd S )Nzobject() takes no parameters.)r)   rf   	developerr`   r2   r3   r4   r   r   r   r     s    zRevertableObject.__init__c                 C   s   t jjrd| jv rtdd S )N	__slots__zpClasses with __slots__ do not support rollback.To create a class with slots, inherit from python_object instead.)r)   rf   r   __dict__r`   )r   r   r   r   __init_subclass__  s    z"RevertableObject.__init_subclass__c                 C   s
   | j  S r   )r   rd   rR   r   r   r   r0     s    zRevertableObject._cleanc                 C   s   |S r   r   rh   r   r   r   rj     s    zRevertableObject._compressc                 C   s   | j   | j | d S r   )r   re   r   rk   r   r   r   rm     s    
zRevertableObject._rollback)r!   rT   rU   r   r   r   r7   r   __setattr____delattr__r0   rj   rm   __classcell__r   r   r   r   r     s   	

r   c                    s   t   fdd}|S )Nc                    s"   dt j _ | g|R i |S r(   )r)   r*   contextforce_checkpointr   r%   r   r   do_checkpoint  s    z$checkpointing.<locals>.do_checkpointr6   )r&   r   r   r%   r   checkpointing  s    r   c                       s   e Zd ZdZ fddZdd Zdd Z fdd	Zee	e
jjZerXee	e
jjZee	e
jjZee	e
jjZee	e
jj
Z
dddZ  ZS )RollbackRandomzJ
    This is used for Random objects returned by renpy.random.Random.
    c                    s0   t jj}|d urd |jt| < tt|   d S r   )r)   r*   r+   r,   r-   r   r   r   )r2   r+   r   r   r   r     s    zRollbackRandom.__init__c                 C   s   |   S r   )getstaterR   r   r   r   r0     s    zRollbackRandom._cleanc                 C   s   |S r   r   rh   r   r   r   rj     s    zRollbackRandom._compressc                    s   t t| | d S r   )r   r   setstaterk   r   r   r   rm     s    zRollbackRandom._rollbackNc                 C   s$   |du r|   }t }|| |S zF
        Returns a new RNG object separate from the main one.
        Nrandomr   seedr2   r   rD   r   r   r   Random  s
    
zRollbackRandom.Random)N)r!   rT   rU   r"   r   r0   rj   rm   r   r7   r   r   r   r   Z	jumpaheadgetrandbitsr   r   r   r   r   r   r     s   r   c                       sF   e Zd ZdZ fddZ fddZdd Zdd	 ZdddZ  Z	S )	DetRandomz
    This is renpy.random.
    c                    s   t t|   g | _d S r   )r   r   r   stackrR   r   r   r   r     s    zDetRandom.__init__c                    sP   | j r| j  }ntt|  }tjj}|jd ur@|jj	| dtj
 _|S r(   )r   ru   r   r   r   r)   r*   r+   currentrr   r   r   )r2   r^   r+   r   r   r   r     s    
zDetRandom.randomc                 C   s$   |dd }|   | j| dS )zu
        Pushes the random numbers in l onto the stack so they will be generated
        in the order given.
        N)rw   r   rs   )r2   rX   llr   r   r   pushback$  s    zDetRandom.pushbackc                 C   s   | j dd= dS )zI
        Resets the RNG, removing all of the pushbacked numbers.
        N)r   rR   r   r   r   reset/  s    zDetRandom.resetNc                 C   s$   |du r|   }t }|| |S r   r   r   r   r   r   r   6  s
    
zDetRandom.Random)N)
r!   rT   rU   r"   r   r   r   r   r   r   r   r   r   r   r     s   r   )7
__future__r   r   r   r   r   renpy.compatr   r   r	   r
   r   r   r   r   r   r   r   r   typingr   marshalr   r.   rer   timeiotypescopyregr#   r)   CO_FUTURE_DIVISIONCO_FUTURE_WITH_STATEMENTr   r    r1   r'   r$   r7   r   r8   r@   rV   r{   r}   r   r~   r   r   r   r   r   r   r   r   r   r   r   <module>   s@   8
IeFJ(+