def __init__(self, pool, space): self.state = Simulator.initializing self.should_run = False self.pool = pool self.space = space self.scene = Scene().populate(simplejson.loads(space.scene_document)) self.event_queue = Queue.Queue(-1) self.script_engine = None self.physics_engine = None self.state = Simulator.ready
def incoming_loop(self): while self.should_run: message = self.ws_client.receive() if message == None: break event = events.parse_event_json(message) if isinstance(event, events.AuthenticationResponse): if event.authenticated: self.username = event.username elif isinstance(event, events.JoinSpaceResponse): if event.joined: self.space_id = event.space_id self.scene = Scene().populate(simplejson.loads(event.scene_doc)) elif isinstance(event, events.NodeAdded): json = simplejson.loads(event.json_data) if 'children' in json: node = Group().populate(json) else: node = Object().populate(json) parent = self.scene.get_node(event.parent_id) parent.children.append(node) elif isinstance(event, events.UserExited): user_node = self.scene.get_user(event.username) if user_node: self.scene.remove_node(user_node) elif isinstance(event, events.PlaceableMoved): node = self.scene.get_node(event.uid) if node: print 'should set the new node position' #thing.position = Position().hydrate(event.position) #thing.orientation = Orientation().hydrate(event.orientation) elif isinstance(event, events.PoolInfo) or isinstance(event, events.TemplateUpdated) or isinstance(event, events.Heartbeat): pass # don't care else: print 'Unhandled incoming space event: %s' % event if self.event_handler: self.event_handler(event)
class SimClient: def __init__(self, session_key, ws_host, ws_port, ws_origin, event_handler=None): self.session_key = session_key self.ws_client = WebSocketClient(ws_host, ws_port, ws_origin) self.event_handler = event_handler self.username = None self.space_id = None self.scene = None self.should_run = True self.incoming_event_thread = threading.Thread(target=self.incoming_loop) self.incoming_event_thread.start() def incoming_loop(self): while self.should_run: message = self.ws_client.receive() if message == None: break event = events.parse_event_json(message) if isinstance(event, events.AuthenticationResponse): if event.authenticated: self.username = event.username elif isinstance(event, events.JoinSpaceResponse): if event.joined: self.space_id = event.space_id self.scene = Scene().populate(simplejson.loads(event.scene_doc)) elif isinstance(event, events.NodeAdded): json = simplejson.loads(event.json_data) if 'children' in json: node = Group().populate(json) else: node = Object().populate(json) parent = self.scene.get_node(event.parent_id) parent.children.append(node) elif isinstance(event, events.UserExited): user_node = self.scene.get_user(event.username) if user_node: self.scene.remove_node(user_node) elif isinstance(event, events.PlaceableMoved): node = self.scene.get_node(event.uid) if node: print 'should set the new node position' #thing.position = Position().hydrate(event.position) #thing.orientation = Orientation().hydrate(event.orientation) elif isinstance(event, events.PoolInfo) or isinstance(event, events.TemplateUpdated) or isinstance(event, events.Heartbeat): pass # don't care else: print 'Unhandled incoming space event: %s' % event if self.event_handler: self.event_handler(event) def authenticate(self): self.ws_client.send(events.AuthenticationRequest(self.session_key).to_json()) def join_space(self, space_id): self.ws_client.send(events.JoinSpaceRequest(space_id).to_json()) def add_user(self): self.ws_client.send(events.AddUserRequest(self.space_id, self.username).to_json()) def notify_template_updated(self, template_id, url, key=None): self.ws_client.send(events.TemplateUpdated(self.space_id, template_id, url, key).to_json()) def request_pool_info(self): self.ws_client.send(events.PoolInfoRequest().to_json()) def send_event(self, event): self.ws_client.send(event.to_json()) def close(self): self.should_run = False self.ws_client.close()
class Simulator: """The class responsible for managing various aspects of Space simulation such as the event queue, run loop, and scene.""" initializing, ready, running, terminating, stopped = range(5) possible_states = [ initializing, ready, running, terminating, stopped ] def __init__(self, pool, space): self.state = Simulator.initializing self.should_run = False self.pool = pool self.space = space self.scene = Scene().populate(simplejson.loads(space.scene_document)) self.event_queue = Queue.Queue(-1) self.script_engine = None self.physics_engine = None self.state = Simulator.ready def __unicode__(self): return "Simulator for %s" % self.space def stop(self): if self.state != Simulator.running: print 'Tried to stop a simulator which is not running: ' % self.state return self.state = Simulator.terminating self.should_run = False self.state = Simulator.stopped def run(self): """The simulation loop""" if not self.state == Simulator.ready: print "Tried to run a simulator in an unready state: %s" % self return self.state = Simulator.running self.should_run = True while self.should_run: try: event = self.event_queue.get(block=True, timeout=5) except Queue.Empty: self.pool.sim_server.send_space_event(self.space.id, Heartbeat()) continue if not self.should_run: return if event.event_name() == 'AddUserRequest': user_node = self.scene.get_user(event.username) if user_node is None: user_node = Group() user_node.username = event.username user_node.set_loc(event.position) user_node.set_quat(event.orientation) self.scene.children.append(user_node) self.pool.sim_server.send_space_event(self.space.id, NodeAdded(self.space.id, self.scene.uid, to_json(user_node))) else: print "Already have a user with id", event.username elif event.event_name() == 'UserExited': #print 'User exited', event.username user_node = self.scene.get_user(event.username) if user_node: self.scene.remove_node(user_node.uid) self.pool.sim_server.send_space_event(self.space.id, NodeRemoved(self.space.id, user_node.uid)) elif event.event_name() == 'UserMessage': if event.connection.user != None and event.username == event.connection.user.username: self.pool.sim_server.send_space_event(self.space.id, UserMessage(self.space.id, event.username, event.message)) elif event.event_name() == 'UserMoveRequest': if event.connection.user != None and event.username == event.connection.user.username: user_node = self.scene.get_user(event.username) if user_node == None: print "No such user node: %s" % event.username else: user_node.set_loc(event.position) user_node.set_quat(event.orientation) response = PlaceableMoved(self.space.id, user_node.uid, user_node.loc, user_node.quat) self.pool.sim_server.send_space_event(self.space.id, response) elif event.event_name() == 'TemplateUpdated': if event.connection.user != None and event.connection.user.is_staff: self.pool.sim_server.send_space_event(self.space.id, TemplateUpdated(self.space.id, event.template_id, event.url, event.key)) else: print "Unknown event: %s" % event.event_name() print "Exiting %s %s" % (self, datetime.datetime.now())