Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use asyncio with sync wrapper, stay compatible #98

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions SimConnect/AsyncLoop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import asyncio
from threading import Thread, Condition
import logging

logger = logging.getLogger(__name__)

class AsyncLoop(Thread):
def __init__(self):
Thread.__init__(self)
self.async_loop = None
self._condition_var = Condition()

def start(self):
with self._condition_var:
Thread.start(self)
self._condition_var.wait()

def run(self):
self.async_loop = asyncio.new_event_loop()
logger.debug("AsyncLoop: %s", self.async_loop)
self.async_loop.call_soon_threadsafe(self._notify_start)
self.async_loop.run_forever()

def _notify_start(self):
with self._condition_var:
self._condition_var.notify_all()

def stop(self):
self.async_loop.call_soon_threadsafe(self.async_loop.stop)
self.join()
self.async_loop.close()

def execute(self, routine):
future_runner = asyncio.run_coroutine_threadsafe(routine, loop=self.async_loop)
return future_runner.result()
21 changes: 17 additions & 4 deletions SimConnect/RequestList.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,24 @@
class Request(object):

def get(self):
return self.value
return self.sm.async_loop.execute(self.async_get())

async def async_get(self):
return await self.async_value

def set(self, _value):
self.value = _value

@property
def value(self):
return self.sm.async_loop.execute(self.async_value)

@property
async def async_value(self):
if self._deff_test():
# self.sm.run()
if (self.LastData + self.time) < millis():
if self.sm.get_data(self):
if await self.sm.async_get_data(self):
self.LastData = millis()
else:
return None
Expand Down Expand Up @@ -133,9 +140,12 @@ def __getattr__(self, _name):
return None

def get(self, _name):
return self.sm.async_loop.execute(self.async_get(_name))

async def async_get(self, _name):
if getattr(self, _name) is None:
return None
return getattr(self, _name).value
return await getattr(self, _name).async_value

def set(self, _name, _value=0):
temp = getattr(self, _name)
Expand Down Expand Up @@ -175,10 +185,13 @@ def find(self, key):
return None

def get(self, key):
return self.sm.async_loop.execute(self.async_get(key))

async def async_get(self, key):
request = self.find(key)
if request is None:
return None
return request.value
return await request.async_value

def set(self, key, _value):
request = self.find(key)
Expand Down
16 changes: 12 additions & 4 deletions SimConnect/SimConnect.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ctypes
from ctypes import *
from ctypes.wintypes import *
import logging
Expand All @@ -7,6 +8,8 @@
from .Attributes import *
import os
import threading
import asyncio
from .AsyncLoop import *

_library_path = os.path.splitext(os.path.abspath(__file__))[0] + '.dll'

Expand Down Expand Up @@ -122,6 +125,8 @@ def __init__(self, auto_connect=True, library_path=_library_path):

self.Requests = {}
self.Facilities = []
self.async_loop = AsyncLoop()
self.async_loop.start()
self.dll = SimConnectDll(library_path)
self.hSimConnect = HANDLE()
self.quit = 0
Expand Down Expand Up @@ -178,6 +183,7 @@ def _run(self):

def exit(self):
self.quit = 1
self.async_loop.stop()
self.timerThread.join()
self.dll.Close(self.hSimConnect)

Expand All @@ -202,7 +208,7 @@ def add_to_notification_group(self, group, evnt, bMaskable=False):
self.hSimConnect, group, evnt, bMaskable
)

def request_data(self, _Request):
async def request_data(self, _Request):
_Request.outData = None
self.dll.RequestDataOnSimObjectType(
self.hSimConnect,
Expand Down Expand Up @@ -243,16 +249,18 @@ def set_data(self, _Request):
return False

def get_data(self, _Request):
self.request_data(_Request)
return self.async_loop.execute(self.async_get_data(_Request))

async def async_get_data(self, _Request):
await self.request_data(_Request)
# self.run()
attemps = 0
while _Request.outData is None and attemps < _Request.attemps:
# self.run()
time.sleep(.01)
await asyncio.sleep(.01)
attemps += 1
if _Request.outData is None:
return False

return True

def send_event(self, evnt, data=DWORD(0)):
Expand Down