Merge tag 'unstable/2.7.0_rc3' into pkg/debian_rc

This commit is contained in:
2023-11-20 12:42:40 +01:00
3 changed files with 55 additions and 5 deletions

View File

@@ -3,4 +3,4 @@
__author__ = "Sven Sager <akira@revpimodio.org>"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__license__ = "LGPLv2"
__version__ = "2.7.0rc2"
__version__ = "2.7.0rc3"

View File

@@ -88,15 +88,41 @@ class IOList(object):
io_del._parentdevice._update_my_io_list()
def __enter__(self):
"""
Read inputs on entering context manager and write outputs on leaving.
All entries are read when entering the context manager. Within the
context manager, further .readprocimg() or .writeprocimg() calls can
be made and the process image can be read or written. When exiting,
all outputs are always written into the process image.
When 'autorefresh=True' is used, all read or write actions in the
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:
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.readprocimg()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Write outputs to process image before leaving the context manager."""
if self.__modio._imgwriter.is_alive():
# Reset new data flat to sync with imgwriter
self.__modio._imgwriter.newdata.clear()
# Write outputs on devices without autorefresh
self.__modio.writeprocimg()
if self.__modio._imgwriter.is_alive():
# Wait until imgwriter has written outputs
self.__modio._imgwriter.newdata.wait(2.5)
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
def __getattr__(self, key):

View File

@@ -70,6 +70,7 @@ class RevPiModIO(object):
"_autorefresh",
"_buffedwrite",
"_configrsc",
"_context_manager",
"_debug",
"_devselect",
"_exit",
@@ -146,6 +147,7 @@ class RevPiModIO(object):
self._autorefresh = autorefresh
self._configrsc = configrsc
self._context_manager = False
self._monitoring = monitoring
self._procimg = "/dev/piControl0" if procimg is None else procimg
self._set_device_based_cycle_time = True
@@ -205,6 +207,22 @@ class RevPiModIO(object):
if self._myfh is not None:
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:
"""
Eventhandler fuer Programmende.
@@ -805,6 +823,9 @@ class RevPiModIO(object):
:param blocking: Wenn False, blockiert das Programm hier NICHT
: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
if self._looprunning:
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
"""
# 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
if self._looprunning:
raise RuntimeError("can not start multiple loops mainloop/cycleloop")