示例#1
0
	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
示例#2
0
	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)
示例#3
0
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()
示例#4
0
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())