Hi djungleorm,
Firstly a huge thank you for creating and maintiaining this mod. It is really a fantastic thing - and I imagine will quickly become my favourite KSP mod! I've just "finished" the stock tech tree with a ISRU mining SSTE and wanted a new challenge so I think I'll try to play through career again (on Interstellar perhaps) but this time using only (well mostly) python .. Can't be that hard right?
Anyway after catching up with this thread, and in particular this comment above (bold) I wondered whether you actually need to consider a new events mechanism at all - can't this already be done fairly straightforwardly on the client side?
For python at least, the asyncio module allows you to create and run tasks as cooperatively scheduled co-routines, so you can create asychronous flight plans based on some simple event handling with coroutines monitoring the streams that you've already implemented in the KRPC client library.
I threw together a quick example below that will monitor altitude and speed and handle triggered events in either order.
#!/usr/bin/python3
import asyncio
import krpc
class KspSession(object):
def __init__ (self):
self.conn = krpc.connect(name="stream_test")
self.msg("KRPC client Connected!")
# Set up a queue for tasks to communicate
self.event_queue = asyncio.Queue()
self.vessel = self.conn.space_center.active_vessel
# Get the event loop and add some tasks
self.loop = asyncio.get_event_loop()
self.loop.create_task(
self.listen_flight_attr(self.vessel.surface_reference_frame,
"mean_altitude",
3000, 8000))
self.loop.create_task(
self.listen_flight_attr(self.vessel.orbit.body.reference_frame,
"speed",
170, 240))
# Finally add a task to handle all the flight events
self.loop.create_task(self.handle_flight_events())
def msg(self, s, duration=5.0):
self.conn.ui.message(s, duration=duration)
@asyncio.coroutine
def handle_flight_events (self):
while True:
# Wait until an item is put on the queue before dequeuing
data = yield from self.event_queue.get()
self.msg('Flight event: {} at {}'.format(data[0], data[1]))
# Process event here..
# Test part, adjust course, deploy chutes, suicide burn etc..
@asyncio.coroutine
def listen_flight_attr(self, ref, attr, minimum, maximum):
self.msg("Listening for '{}' events between {} and {}".format(attr, minimum, maximum))
with self.conn.stream(self.vessel.flight, ref) as flight:
while True:
yield # Let the CPU do other work
val = getattr(flight(), attr)
if val > minimum and val < maximum:
# Put the flight data on the queue
data = ( attr, val )
asyncio.async(self.event_queue.put(data))
return
def run(self):
# Run all tasks in an event loop, and don't stop
self.loop.run_forever()
sess = KspSession()
sess.run()
Hope this is helpful!
Best regards,
Tom.