From fc28e028be7eee6717b8fb7b355358cd837966d7 Mon Sep 17 00:00:00 2001 From: NaruX Date: Thu, 25 Jul 2019 16:44:59 +0200 Subject: [PATCH] =?UTF-8?q?Bei=20.reg=5Fevent=20Parameter=20prefire=20eing?= =?UTF-8?q?ef=C3=BCgt=20um=20Event=20bei=20Eintritt=20in=20mainloop=20mit?= =?UTF-8?q?=20aktuellem=20Wert=20auszul=C3=B6sen.=20Im=20Helper=20werden?= =?UTF-8?q?=20Event-Queues=20nur=20beim=20deaktiveren=20geleert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/revpimodio2.io.html | 12 +++++++++--- eric-revpimodio2.api | 4 ++-- revpimodio2/helper.py | 8 +++++--- revpimodio2/io.py | 24 ++++++++++++++++-------- revpimodio2/modio.py | 22 ++++++++++++++++++++-- 5 files changed, 52 insertions(+), 18 deletions(-) diff --git a/doc/revpimodio2.io.html b/doc/revpimodio2.io.html index 0637b6f..a83171d 100644 --- a/doc/revpimodio2.io.html +++ b/doc/revpimodio2.io.html @@ -241,7 +241,7 @@ Bytelaenge des IO - 0 bei BITs

IOBase.__reg_xevent

-__reg_xevent(func, delay, edge, as_thread, overwrite) +__reg_xevent(func, delay, edge, as_thread, overwrite, prefire)

Verwaltet reg_event und reg_timerevent.

@@ -260,6 +260,9 @@ Bei True, Funktion als EventCallback-Thread ausfuehren
overwrite
Wenn True, wird Event bei ueberschrieben +
prefire
+
+Ausloesen mit aktuellem Wert, wenn mainloop startet

@@ -330,7 +333,7 @@ IO-Wert als oder

IOBase.reg_event

-reg_event(func, delay=0, edge=BOTH, as_thread=False) +reg_event(func, delay=0, edge=BOTH, as_thread=False, prefire=False)

Registriert fuer IO ein Event bei der Eventueberwachung.

@@ -353,6 +356,9 @@ Ausfuehren bei RISING, FALLING or BOTH Wertaenderung

as_thread
Bei True, Funktion als EventCallback-Thread ausfuehren +
prefire
+
+Ausloesen mit aktuellem Wert, wenn mainloop startet

@@ -502,7 +508,7 @@ Static Methods

IOEvent (Constructor)

-IOEvent(func, edge, as_thread, delay, overwrite) +IOEvent(func, edge, as_thread, delay, overwrite, prefire)

Init IOEvent class.

diff --git a/eric-revpimodio2.api b/eric-revpimodio2.api index 889636a..25c1302 100644 --- a/eric-revpimodio2.api +++ b/eric-revpimodio2.api @@ -106,7 +106,7 @@ revpimodio2.io.IOBase.get_defaultvalue?4() revpimodio2.io.IOBase.get_value?4() revpimodio2.io.IOBase.length?7 revpimodio2.io.IOBase.name?7 -revpimodio2.io.IOBase.reg_event?4(func, delay=0, edge=BOTH, as_thread=False) +revpimodio2.io.IOBase.reg_event?4(func, delay=0, edge=BOTH, as_thread=False, prefire=False) revpimodio2.io.IOBase.reg_timerevent?4(func, delay, edge=BOTH, as_thread=False) revpimodio2.io.IOBase.set_value?4(value) revpimodio2.io.IOBase.type?7 @@ -114,7 +114,7 @@ revpimodio2.io.IOBase.unreg_event?4(func=None, edge=None) revpimodio2.io.IOBase.value?7 revpimodio2.io.IOBase.wait?4(edge=BOTH, exitevent=None, okvalue=None, timeout=0) revpimodio2.io.IOBase?1(parentdevice, valuelist, iotype, byteorder, signed) -revpimodio2.io.IOEvent?1(func, edge, as_thread, delay, overwrite) +revpimodio2.io.IOEvent?1(func, edge, as_thread, delay, overwrite, prefire) revpimodio2.io.IOList._private_register_new_io_object?5(new_io) revpimodio2.io.IOList?1() revpimodio2.io.IntIO._get_signed?5() diff --git a/revpimodio2/helper.py b/revpimodio2/helper.py index 37af3cb..fb5e2ce 100644 --- a/revpimodio2/helper.py +++ b/revpimodio2/helper.py @@ -413,9 +413,11 @@ class ProcimgWriter(Thread): if self.__eventwork != value: with self.lck_refresh: self.__eventwork = value - self.__eventqth = queue.Queue() - self._eventq = queue.Queue() - self.__dict_delay = {} + if not value: + # Nur leeren beim deaktivieren + self.__eventqth = queue.Queue() + self._eventq = queue.Queue() + self.__dict_delay = {} # Threadmanagement if value and not self.__eventth.is_alive(): diff --git a/revpimodio2/io.py b/revpimodio2/io.py index ce3ba20..eb5b21b 100644 --- a/revpimodio2/io.py +++ b/revpimodio2/io.py @@ -21,15 +21,16 @@ class IOEvent(object): """Basisklasse fuer IO-Events.""" - __slots__ = "as_thread", "delay", "edge", "func", "overwrite" + __slots__ = "as_thread", "delay", "edge", "func", "overwrite", "prefire" - def __init__(self, func, edge, as_thread, delay, overwrite): + def __init__(self, func, edge, as_thread, delay, overwrite, prefire): """Init IOEvent class.""" self.as_thread = as_thread self.delay = delay self.edge = edge self.func = func self.overwrite = overwrite + self.prefire = prefire class IOList(object): @@ -368,7 +369,7 @@ class IOBase(object): @return Namen des IOs""" return self._name - def __reg_xevent(self, func, delay, edge, as_thread, overwrite): + def __reg_xevent(self, func, delay, edge, as_thread, overwrite, prefire): """Verwaltet reg_event und reg_timerevent. @param func Funktion die bei Aenderung aufgerufen werden soll @@ -376,6 +377,7 @@ class IOBase(object): @param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung @param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren @param overwrite Wenn True, wird Event bei ueberschrieben + @param prefire Ausloesen mit aktuellem Wert, wenn mainloop startet """ # Prüfen ob Funktion callable ist @@ -391,11 +393,15 @@ class IOBase(object): raise ValueError( "parameter 'edge' can be used with bit io objects only" ) + if prefire and self._parentdevice._modio._looprunning: + raise RuntimeError( + "prefire can not be used if mainloop is running" + ) if self not in self._parentdevice._dict_events: with self._parentdevice._filelock: self._parentdevice._dict_events[self] = \ - [IOEvent(func, edge, as_thread, delay, overwrite)] + [IOEvent(func, edge, as_thread, delay, overwrite, prefire)] else: # Prüfen ob Funktion schon registriert ist for regfunc in self._parentdevice._dict_events[self]: @@ -429,7 +435,7 @@ class IOBase(object): # Eventfunktion einfügen with self._parentdevice._filelock: self._parentdevice._dict_events[self].append( - IOEvent(func, edge, as_thread, delay, overwrite) + IOEvent(func, edge, as_thread, delay, overwrite, prefire) ) def _get_address(self): @@ -464,7 +470,8 @@ class IOBase(object): else: return bytes(self._parentdevice._ba_devdata[self._slc_address]) - def reg_event(self, func, delay=0, edge=BOTH, as_thread=False): + def reg_event( + self, func, delay=0, edge=BOTH, as_thread=False, prefire=False): """Registriert fuer IO ein Event bei der Eventueberwachung. Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert @@ -478,9 +485,10 @@ class IOBase(object): @param delay Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt @param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung @param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren + @param prefire Ausloesen mit aktuellem Wert, wenn mainloop startet """ - self.__reg_xevent(func, delay, edge, as_thread, True) + self.__reg_xevent(func, delay, edge, as_thread, True, prefire) def reg_timerevent(self, func, delay, edge=BOTH, as_thread=False): """Registriert fuer IO einen Timer, welcher nach delay func ausfuehrt. @@ -501,7 +509,7 @@ class IOBase(object): @param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren """ - self.__reg_xevent(func, delay, edge, as_thread, False) + self.__reg_xevent(func, delay, edge, as_thread, False, False) def set_value(self, value): """Setzt den Wert des IOs. diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py index d08544c..3133c2e 100644 --- a/revpimodio2/modio.py +++ b/revpimodio2/modio.py @@ -10,7 +10,7 @@ from json import load as jload from multiprocessing import cpu_count from os import access, F_OK, R_OK from queue import Empty -from revpimodio2 import acheck, DeviceNotFoundError +from revpimodio2 import acheck, DeviceNotFoundError, BOTH, RISING, FALLING from signal import signal, SIG_DFL, SIGINT, SIGTERM from threading import Thread, Event, Lock from timeit import default_timer @@ -771,11 +771,29 @@ class RevPiModIO(object): self._exit.clear() self._looprunning = True - # Beim Eintritt in mainloop Bytecopy erstellen + # Beim Eintritt in mainloop Bytecopy erstellen und prefire anhängen for dev in self._lst_refresh: with dev._filelock: dev._ba_datacp = dev._ba_devdata[:] + # Prefire Events vorbereiten + for io in dev._dict_events: + for regfunc in dev._dict_events[io]: + if not regfunc.prefire: + continue + + if regfunc.edge == BOTH \ + or regfunc.edge == RISING and io.value \ + or regfunc.edge == FALLING and not io.value: + if regfunc.as_thread: + self._imgwriter.__eventqth.put( + (regfunc, io._name, io.value), False + ) + else: + self._imgwriter._eventq.put( + (regfunc, io._name, io.value), False + ) + # ImgWriter mit Eventüberwachung aktivieren self._imgwriter._collect_events(True) e = None