feat: Add context manager for modio instance

Signed-off-by: Sven Sager <akira@narux.de>
This commit is contained in:
2023-10-27 14:58:11 +02:00
parent 12a34e7d11
commit 5a6ed54e5c
2 changed files with 32 additions and 4 deletions

View File

@@ -99,8 +99,10 @@ class IOList(object):
When 'autorefresh=True' is used, all read or write actions in the When 'autorefresh=True' is used, all read or write actions in the
background are performed automatically. background are performed automatically.
""" """
if not self.__modio._context_manager:
# If ModIO itself is in a context manager, it sets the _looprunning=True flag itself
if self.__modio._looprunning: if self.__modio._looprunning:
raise RuntimeError("can not start multiple mainloop/cycleloop/with sessions") raise RuntimeError("can not enter context manager inside mainloop or cycleloop")
self.__modio._looprunning = True self.__modio._looprunning = True
self.__modio.readprocimg() self.__modio.readprocimg()
@@ -114,6 +116,8 @@ class IOList(object):
outputs are automatically written in the background. outputs are automatically written in the background.
""" """
self.__modio.writeprocimg() self.__modio.writeprocimg()
if self.__modio._context_manager:
# Do not reset if ModIO is in a context manager itself, it will handle that flag
self.__modio._looprunning = False self.__modio._looprunning = False
def __getattr__(self, key): def __getattr__(self, key):

View File

@@ -70,6 +70,7 @@ class RevPiModIO(object):
"_autorefresh", "_autorefresh",
"_buffedwrite", "_buffedwrite",
"_configrsc", "_configrsc",
"_context_manager",
"_debug", "_debug",
"_devselect", "_devselect",
"_exit", "_exit",
@@ -146,6 +147,7 @@ class RevPiModIO(object):
self._autorefresh = autorefresh self._autorefresh = autorefresh
self._configrsc = configrsc self._configrsc = configrsc
self._context_manager = False
self._monitoring = monitoring self._monitoring = monitoring
self._procimg = "/dev/piControl0" if procimg is None else procimg self._procimg = "/dev/piControl0" if procimg is None else procimg
self._set_device_based_cycle_time = True self._set_device_based_cycle_time = True
@@ -205,6 +207,22 @@ class RevPiModIO(object):
if self._myfh is not None: if self._myfh is not None:
self._myfh.close() self._myfh.close()
def __enter__(self):
if self._context_manager:
raise RuntimeError("can not use multiple context managers of same instance")
if self._looprunning:
raise RuntimeError("can not enter context manager with running mainloop or cycleloop")
self._context_manager = True
self._looprunning = True
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.writeprocimg()
self.exit(full=True)
self._looprunning = False
self._context_manager = False
def __evt_exit(self, signum, sigframe) -> None: def __evt_exit(self, signum, sigframe) -> None:
""" """
Eventhandler fuer Programmende. Eventhandler fuer Programmende.
@@ -805,6 +823,9 @@ class RevPiModIO(object):
:param blocking: Wenn False, blockiert das Programm hier NICHT :param blocking: Wenn False, blockiert das Programm hier NICHT
:return: None or the return value of the cycle function :return: None or the return value of the cycle function
""" """
# Check for context manager
if self._context_manager:
raise RuntimeError("Can not start cycleloop inside a context manager (with statement)")
# Prüfen ob ein Loop bereits läuft # Prüfen ob ein Loop bereits läuft
if self._looprunning: if self._looprunning:
raise RuntimeError("can not start multiple loops mainloop/cycleloop") raise RuntimeError("can not start multiple loops mainloop/cycleloop")
@@ -1060,6 +1081,9 @@ class RevPiModIO(object):
:param blocking: Wenn False, blockiert das Programm hier NICHT :param blocking: Wenn False, blockiert das Programm hier NICHT
""" """
# Check for context manager
if self._context_manager:
raise RuntimeError("Can not start mainloop inside a context manager (with statement)")
# Prüfen ob ein Loop bereits läuft # Prüfen ob ein Loop bereits läuft
if self._looprunning: if self._looprunning:
raise RuntimeError("can not start multiple loops mainloop/cycleloop") raise RuntimeError("can not start multiple loops mainloop/cycleloop")