3
3
import json
4
4
from functools import wraps
5
5
from datetime import datetime
6
- from sc2reader import log_utils
6
+ from sc2reader . log_utils import loggable
7
7
8
8
from functools import wraps
9
+ from bisect import bisect_left
10
+
9
11
def plugin (func ):
10
12
@wraps (func )
11
13
def wrapper (** options ):
@@ -26,28 +28,45 @@ def default(self, obj):
26
28
27
29
class GameState (dict ):
28
30
def __init__ (self , initial_state ):
31
+ self ._frames = list ()
32
+ self ._frameset = set ()
29
33
self [0 ] = initial_state
30
34
31
35
def __getitem__ (self , frame ):
32
36
if frame in self :
33
37
return super (GameState , self ).__getitem__ (frame )
34
38
35
- # If this particular key doesn't exist, create it
36
- prev_frame = sorted (filter (lambda key : key < frame , self .keys ()))[- 1 ]
39
+ # Get the previous frame from our sorted frame list
40
+ # bisect_left returns the left most key where an item is
41
+ # less than or equal to the value in that key. If it is
42
+ # less than we need to subtract 1
43
+ key = bisect_left (self ._frames , frame )
44
+ if key == len (self ._frames ) or self ._frames [key ] > frame :
45
+ prev_frame = self ._frames [key - 1 ]
46
+ else :
47
+ prev_frame = self ._frames [key ]
48
+
49
+ # Copy the previous state and use it as our basis here
37
50
state = self [prev_frame ].copy ()
38
51
self [frame ] = state
39
52
return state
40
53
54
+ def __setitem__ (self , frame , value ):
55
+ if frame not in self ._frameset :
56
+ self ._frames .insert (bisect_left (self ._frames , frame ), frame )
57
+ self ._frameset .add (frame )
58
+
59
+ super (GameState , self ).__setitem__ (frame , value )
60
+
41
61
62
+ @loggable
42
63
class UnitSelection (object ):
43
- def __init__ (self , * new_objects ):
44
- self .logger = log_utils .get_logger (UnitSelection )
45
- self .objects = list ()
46
- self .select (new_objects )
64
+ def __init__ (self , objects = None ):
65
+ self .objects = objects or list ()
47
66
48
67
def select (self , new_objects ):
49
- object_set = set (self .objects + list (new_objects ))
50
- self .objects = sorted (object_set , key = lambda obj : obj .id )
68
+ new_set = set (self .objects + list (new_objects ))
69
+ self .objects = sorted (new_set , key = lambda obj : obj .id )
51
70
52
71
def deselect (self , mode , data ):
53
72
if mode == 0x01 :
@@ -71,7 +90,7 @@ def __str__(self):
71
90
return ', ' .join (str (obj ) for obj in self .objects )
72
91
73
92
def copy (self ):
74
- return UnitSelection (* self .objects )
93
+ return UnitSelection (self .objects [:] )
75
94
76
95
77
96
class PlayerSelection (dict ):
@@ -82,5 +101,5 @@ def __init__(self):
82
101
def copy (self ):
83
102
new = PlayerSelection ()
84
103
for bank , selection in self .iteritems ():
85
- new [bank ] = UnitSelection (* selection .objects )
104
+ new [bank ] = UnitSelection (selection .objects [:] )
86
105
return new
0 commit comments