示例#1
0
	def run(self, task, arg):
		self.cleanup(task)
		self.game.now = time.time()
		end_task = (False, None)
		try:
			#log('sending %s' % repr(arg))
			cmd = task.generator.send(arg)
		except StopIteration as e:
			task.value = e.value
			task.done = True
			end_task = (True, e.value)
		#log('cmd = %s' % repr(cmd))
		if end_task[0] or cmd is None:
			for t in task.waiters:
				websocketd.add_idle(lambda: self.run(t, end_task[1]))
			self.tasks.remove(task)
			if len(self.tasks) == 0:
				self.end_game(end_task[1])
			return
		# Convert cmd to dict if it isn't.
		if not isinstance(cmd, (tuple, list, set, frozenset, dict)):
			cmd = (cmd,)
		if isinstance(cmd, (tuple, list, set, frozenset)):
			def mkcmd(src):
				for c in src:
					if isinstance(c, (Task, str)):
						yield (c, None)
					else:
						yield (None, c)
			cmd = {x: y for x, y in mkcmd(cmd)}
		#log('new cmd: %s' % repr(cmd))
		# Check if we're waiting for a task that is already finished.
		for c in cmd:
			if isinstance(c, Task) and c.done:
				websocketd.add_idle(lambda: self.run(task, c.value))
				return
		# Schedule new timeout.
		if None in cmd:
			self.timeouts[task] = websocketd.add_timeout(cmd.pop(None), lambda: self.timeouts.pop(task) and self.run(task, None))
		# Add waiters to tasks.
		for c in cmd:
			if not isinstance(c, Task):
				continue
			c.waiters.append(task)
		# Add new commands.
		for c in cmd:
			if isinstance(c, Task):
				continue
			if c in self.cmds:
				assert task not in self.cmds[c]
			else:
				self.cmds[c] = {}
			self.cmds[c][task] = cmd[c]
示例#2
0
    def call(self, name, args, kargs, cb):  # {{{
        #log('calling {}'.format(repr((name, args, kargs))))
        data = json.dumps([self.next_mid, name, args, kargs]) + '\n'
        #log('calling %s on %d' % (repr(data), self.process.stdin.fileno()))
        try:
            self.process.stdin.write(data.encode('utf-8'))
            self.process.stdin.flush()
        except:
            log('killing machine handle because of error')

            #traceback.print_exc()
            def kill():
                cb(False, None)
                disable(self.uuid, 'error from machine')

            # Schedule this as a callback, so the generator isn't called recursively.
            websocketd.add_idle(kill)
            return
        self.waiters[0][self.next_mid] = cb
        self.next_mid += 1
示例#3
0
	def call(self, name, args, kargs, cb): # {{{
		#log('calling {}'.format(repr((name, args, kargs))))
		data = json.dumps([self.next_mid, name, args, kargs]) + '\n'
		#log('calling %s on %d' % (repr(data), self.process.stdin.fileno()))
		try:
			self.process.stdin.write(data.encode('utf-8'))
			self.process.stdin.flush()
		except:
			log('killing machine handle because of error')
			#traceback.print_exc()
			def kill():
				cb(False, None)
				disable(self.uuid, 'error from machine')
			# Schedule this as a callback, so the generator isn't called recursively.
			websocketd.add_idle(kill)
			return
		#def debug_cb(success, ret):
		#	log('call {} returned: {}: {}'.format(name, success, ret))
		#	cb(success, ret)
		self.waiters[0][self.next_mid] = cb
		self.next_mid += 1
示例#4
0
				def call(instance, func, args, task):
					if func is not None:
						websocketd.add_idle(lambda: func(args) and False)
					if task is not None:
						instance.cleanup(task);
						websocketd.add_idle(lambda: instance.run(task, args))
示例#5
0
	def launch(self, f, name = 'nameless task'):
		'''Record a generator as a task and schedule it for idle running.'''
		t = Task(f, name)
		self.tasks.append(t)
		websocketd.add_idle(lambda: self.run(t, None))
		return t