84 lines
2.5 KiB
Python
84 lines
2.5 KiB
Python
import subprocess
|
|
import os
|
|
import atexit
|
|
import thread
|
|
from panda3d.core import *
|
|
|
|
class PlanD:
|
|
def __init__(self, pool):
|
|
self.pool = pool
|
|
|
|
# I couldn't resist the name. :)
|
|
pathPath = os.path.join(os.path.dirname(__file__), 'pathd.py')
|
|
|
|
if not config.GetBool('want-doomsday', False) and os.name == 'nt':
|
|
# Hack out Windows crash when doomsday is disabled.
|
|
# If you want to run doomsday on windows (server), you'll need to use the following:
|
|
# self.sp = subprocess.Popen([r'/path/to/p3d/linked/python.exe', pathPath], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
return
|
|
else:
|
|
self.sp = subprocess.Popen(pathPath, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
atexit.register(self.sp.kill)
|
|
self.callback = None
|
|
|
|
self.pool.addWorker(self)
|
|
|
|
def plan(self, callback, navFrom, navTo, radius):
|
|
self.callback = callback
|
|
|
|
params = (tuple(navFrom), tuple(navTo), radius)
|
|
self.sp.stdin.write('%r\n' % (params,))
|
|
self.sp.stdin.flush()
|
|
|
|
thread.start_new_thread(self.__read, ())
|
|
|
|
def __read(self):
|
|
line = self.sp.stdout.readline()
|
|
taskMgr.doMethodLater(0.1, self.__handle, 'inject-%d' % id(self),
|
|
extraArgs=[line])
|
|
|
|
def __handle(self, line):
|
|
x = eval(line)
|
|
if self.callback:
|
|
self.callback(x)
|
|
self.callback = None
|
|
|
|
self.pool.addWorker(self)
|
|
|
|
class PlanJob:
|
|
def __init__(self, callback, navFrom, navTo, radius):
|
|
self.callback = callback
|
|
self.navFrom = navFrom
|
|
self.navTo = navTo
|
|
self.radius = radius
|
|
|
|
def assign(self, pland):
|
|
pland.plan(self.callback, self.navFrom, self.navTo, self.radius)
|
|
|
|
class PlannerPool:
|
|
def __init__(self, workerCount):
|
|
self.workers = []
|
|
self.jobs = []
|
|
|
|
for x in xrange(workerCount):
|
|
PlanD(self) # Registration is its responsibility
|
|
|
|
def addWorker(self, worker):
|
|
self.workers.append(worker)
|
|
self.__flushQueues()
|
|
|
|
def addJob(self, job):
|
|
self.jobs.append(job)
|
|
self.__flushQueues()
|
|
|
|
def __flushQueues(self):
|
|
while self.workers and self.jobs:
|
|
worker = self.workers.pop(0)
|
|
job = self.jobs.pop(0)
|
|
job.assign(worker)
|
|
|
|
def plan(self, callback, navFrom, navTo, radius):
|
|
job = PlanJob(callback, navFrom, navTo, radius)
|
|
self.addJob(job)
|
|
|
|
pool = PlannerPool(config.GetInt('doomsday-threads', 0))
|