Skip to content

Commit

Permalink
added parse_yaml_async option to IRSDK Class, with this option turned…
Browse files Browse the repository at this point in the history
… on YAML can be parsed in non blocking mode
  • Loading branch information
kutu committed May 15, 2018
1 parent 19d8744 commit 33de892
Showing 1 changed file with 36 additions and 24 deletions.
60 changes: 36 additions & 24 deletions irsdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import struct
import ctypes
import yaml
from threading import Thread
from urllib import request, error
from yaml.reader import Reader as YamlReader

Expand All @@ -14,7 +15,7 @@
except ImportError:
from yaml import Loader as YamlLoader

VERSION = '1.1.11'
VERSION = '1.2.0'

SIM_STATUS_URL = 'http://127.0.0.1:32034/get_sim_status?object=simStatus'

Expand Down Expand Up @@ -289,7 +290,8 @@ class VarHeader(IRSDKStruct):
unit = IRSDKStruct.property_value_str(112, '32s')

class IRSDK:
def __init__(self):
def __init__(self, parse_yaml_async=False):
self.parse_yaml_async = parse_yaml_async
self.is_initialized = False
self.last_session_info_update = 0

Expand Down Expand Up @@ -469,20 +471,31 @@ def get_session_info_update_by_key(self, key):
def _get_session_info(self, key):
if self.last_session_info_update < self._header.session_info_update:
self.last_session_info_update = self._header.session_info_update
for sesData in self.__session_info_dict.values():
# keep previous parsed data, in case, binary data not changed
if sesData['data']:
sesData['data_last'] = sesData['data']
sesData['data'] = None
for session_data in self.__session_info_dict.values():
# keep previous parsed data, in case binary data not changed
if session_data['data']:
session_data['data_last'] = session_data['data']
session_data['data'] = None

if key not in self.__session_info_dict:
self.__session_info_dict[key] = dict(data=None)

sesData = self.__session_info_dict[key]
session_data = self.__session_info_dict[key]

# already have and parsed
if sesData['data']:
return sesData['data']
if session_data['data']:
return session_data['data']

if self.parse_yaml_async:
if 'async_session_info_update' not in session_data or session_data['async_session_info_update'] < self.last_session_info_update:
session_data['async_session_info_update'] = self.last_session_info_update
Thread(target=self._parse_yaml, args=(key, session_data)).start()
else:
self._parse_yaml(key, session_data)
return session_data['data']

def _parse_yaml(self, key, session_data):
session_info_update = self.last_session_info_update

start = self._header.session_info_offset
end = self._header.session_info_len
Expand All @@ -497,17 +510,16 @@ def _get_session_info(self, key):

# section not found
if not data_binary:
if 'data_last' in sesData:
return sesData['data_last']
if 'data_last' in session_data:
return session_data['data_last']
else:
del self.__session_info_dict[key]
return None

# is binary data the same as last time?
if 'data_binary' in sesData and data_binary == sesData['data_binary'] and 'data_last' in sesData:
sesData['data'] = sesData['data_last']
return sesData['data']
sesData['data_binary'] = data_binary
if 'data_binary' in session_data and data_binary == session_data['data_binary'] and 'data_last' in session_data:
session_data['data'] = session_data['data_last']
return session_data['data']
session_data['data_binary'] = data_binary

# parsing
yaml_src = re.sub(YamlReader.NON_PRINTABLE, '', data_binary.translate(YAML_TRANSLATER).rstrip(b'\x00').decode(YAML_CODE_PAGE))
Expand All @@ -516,13 +528,13 @@ def team_name_replace(m):
return 'TeamName: "%s"' % re.sub(r'(["\\])', '\\\\\\1', m.group(1))
yaml_src = re.sub(r'TeamName: (.*)', team_name_replace, yaml_src)
result = yaml.load(yaml_src, Loader=YamlLoader)
if result:
sesData['data'] = result[key]
if sesData['data']:
sesData['update'] = self.last_session_info_update
elif 'data_last' in sesData:
sesData['data'] = sesData['data_last']
return sesData['data']
# check if result is available, and yaml data is not updated while we were parsing it in async mode
if result and (not self.parse_yaml_async or self.last_session_info_update == session_info_update):
session_data['data'] = result[key]
if session_data['data']:
session_data['update'] = session_info_update
elif 'data_last' in session_data:
session_data['data'] = session_data['data_last']

@property
def _broadcast_msg_id(self):
Expand Down

0 comments on commit 33de892

Please sign in to comment.