Skip to content

Commit c37fc2f

Browse files
committed
Improve SelectionTracker processing speed.
Just a combination of improvements using stdlibrary tools.
1 parent 915ee15 commit c37fc2f

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

sc2reader/plugins/utils.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import json
44
from functools import wraps
55
from datetime import datetime
6-
from sc2reader import log_utils
6+
from sc2reader.log_utils import loggable
77

88
from functools import wraps
9+
from bisect import bisect_left
10+
911
def plugin(func):
1012
@wraps(func)
1113
def wrapper(**options):
@@ -26,28 +28,45 @@ def default(self, obj):
2628

2729
class GameState(dict):
2830
def __init__(self, initial_state):
31+
self._frames = list()
32+
self._frameset = set()
2933
self[0] = initial_state
3034

3135
def __getitem__(self, frame):
3236
if frame in self:
3337
return super(GameState, self).__getitem__(frame)
3438

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
3750
state = self[prev_frame].copy()
3851
self[frame] = state
3952
return state
4053

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+
4161

62+
@loggable
4263
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()
4766

4867
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)
5170

5271
def deselect(self, mode, data):
5372
if mode == 0x01:
@@ -71,7 +90,7 @@ def __str__(self):
7190
return ', '.join(str(obj) for obj in self.objects)
7291

7392
def copy(self):
74-
return UnitSelection(*self.objects)
93+
return UnitSelection(self.objects[:])
7594

7695

7796
class PlayerSelection(dict):
@@ -82,5 +101,5 @@ def __init__(self):
82101
def copy(self):
83102
new = PlayerSelection()
84103
for bank, selection in self.iteritems():
85-
new[bank] = UnitSelection(*selection.objects)
104+
new[bank] = UnitSelection(selection.objects[:])
86105
return new

0 commit comments

Comments
 (0)