Source code for crappy.inout.inout
# coding: utf-8
from time import time
from .._global import DefinitionError
[docs]class MetaIO(type):
""" Metaclass that will define all IO objects.
All IO classes should be of this type.
To do so, simply add ``__metaclass__ = MetaIO`` in the class definition.
(Obviously, you must import this Metaclass first.)
MetaIO is a MetaClass: we will NEVER do ``c = MetaIO(...)``.
The :meth:`__init__` is used to init the classes of type MetaIO (with
``__metaclass__ = MetaIO`` as a class attribute) and NOT an instance of
MetaClass.
"""
classes = {} # This dict will keep track of all the existing cam classes
# Attention: It keeps track of the CLASSES, not the instances !
# If a class is defined without these
IOclasses = {} # Classes that are inputs and outputs
Oclasses = {} # Classes that only outputs
Iclasses = {} # Classes that only inputs
needed_methods = ["open", "close"]
# methods, it will raise an error
def __new__(mcs, name: str, bases: tuple, dict_: dict) -> type:
# print "[MetaIO.__new__] Creating class",name,"from metaclass",mcs
return type.__new__(mcs, name, bases, dict_)
def __init__(cls, name: str, bases: tuple, dict_: dict) -> None:
# print "[MetaIO.__init__] Initializing",cls
type.__init__(cls, name, bases, dict_) # This is the important line
# It creates the class, the same way we could do this:
# MyClass = type(name,bases,dict_)
# bases is a tuple containing the parents of the class
# dict is the dict with the methods
# MyClass = type("MyClass",(object,),{'method': do_stuff})
# is equivalent to
# class MyClass(object):
# def method():
# do_stuff()
# Check if this class hasn't already been created
if name in MetaIO.classes:
raise DefinitionError("Cannot redefine " + name + " class")
# Check if mandatory methods are defined
missing_methods = []
for m in MetaIO.needed_methods:
if m not in dict_:
missing_methods.append(m)
if name != "InOut":
if missing_methods:
raise DefinitionError("Class " + name + " is missing methods: " + str(
missing_methods))
i = ("get_data" in dict_ or "get_stream" in dict_)
o = ("set_cmd" in dict_)
if i and o:
MetaIO.IOclasses[name] = cls
elif i:
MetaIO.Iclasses[name] = cls
elif o:
MetaIO.Oclasses[name] = cls
else:
raise DefinitionError(
name + " needs at least get_data, get_stream or set_cmd method")
MetaIO.classes[name] = cls
class InOut(metaclass=MetaIO):
@classmethod
def is_input(cls) -> bool:
return hasattr(cls, 'get_data')
@classmethod
def is_output(cls) -> bool:
return hasattr(cls, 'set_cmd')
def eval_offset(self) -> list:
assert self.is_input(), "eval_offset only works for inputs!"
if not hasattr(self, 'eval_offset_delay'):
self.eval_offset_delay = 2 # Default value
t0 = time()
table = []
while True:
if time() > t0 + self.eval_offset_delay:
break
table.append(self.get_data()[1:])
ret = []
for i in zip(*table):
ret.append(-sum(i) / len(i))
return ret