1 """ World and player state. """
3 from .scenes.base import WorldEvent
4 from .roaches import build_roach
8 """ World and player state. """
11 self._state = self._build_initial_state()
15 return self._state["level"]
19 return self._state["roaches"]
21 def _build_initial_state(self):
24 build_roach(self, "roupert"),
27 "smart", "strong", "fast",
33 "roachel", None, "roeginald",
37 "robot": {"seating": []},
38 "roomba": {"seating": []},
39 "quadcopter": {"seating": []},
46 def _get_obj(self, name):
47 parts = name.split(".")
50 if isinstance(obj, dict):
52 elif isinstance(obj, list):
55 raise KeyError("%r not found in world" % (name,))
58 def _apply_set(self, action, updates):
59 for name, value in updates.items():
60 obj, key = self._get_obj(name)
63 def _apply_append(self, action, updates):
64 for name, value in updates.items():
65 obj, key = self._get_obj(name)
68 def _apply_reset(self, action):
69 self._state = self._build_initial_state()
71 def _apply_unknown(self, action, *args, **kw):
72 raise ValueError("Unknown world event action: %r" % (action,))
75 return WorldDictProxy(self._state)
77 def apply_event(self, action, *args, **kw):
78 handler = getattr(self, "_apply_%s" % (action,))
79 return handler(action, *args, **kw)
82 def _maybe_subproxy(proxy, name, value):
83 """ Return a sub world proxy if appropriate. """
84 if isinstance(value, dict):
85 prefix = "%s%s." % (proxy._prefix, name)
86 return WorldDictProxy(value, _prefix=prefix, _top=proxy._top)
87 elif isinstance(value, list):
88 prefix = "%s%s." % (proxy._prefix, name)
89 return WorldListProxy(value, _prefix=prefix, _top=proxy._top)
94 """ Base for world proxies. """
96 def __init__(self, state, _prefix='', _top=None):
102 self.__dict__.update({
109 def _record_change(self, fullname, value, action="set"):
110 self._events.append(WorldEvent(action, {
114 def pop_events(self):
115 events, self._events = self._events, []
119 class WorldDictProxy(WorldBaseProxy):
120 """ World dictionary proxy that records changes and produces events. """
122 def __setattr__(self, name, value):
123 self._top._record_change("%s%s" % (self._prefix, name), value)
125 def __getattr__(self, name):
126 # return None for attributes that don't exist
127 value = self._state.get(name)
128 return _maybe_subproxy(self, name, value)
130 def __setitem__(self, name, value):
131 return self.__setattr__(name, value)
133 def __getitem__(self, name):
134 return self.__getattr__(name)
138 (k, _maybe_subproxy(self, k, v)) for k, v in self._state.items())
141 class WorldListProxy(WorldBaseProxy):
142 """ World list proxy that records changes and produces events. """
144 def __setitem__(self, index, value):
145 self._top._record_change("%s%s" % (self._prefix, index), value)
147 def __getitem__(self, index):
148 return _maybe_subproxy(self, index, self._state[index])
151 return len(self._state)
154 return bool(self._state)
156 def append(self, value):
157 self._top._record_change(self._prefix, value, action="append")