Postpone a functions execution until after some time has elapsed.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""Various utility functions used by this plugin"""
from threading import Timer
import datetime # only needed for example usage...
from datetime import timedelta # only needed for example usage...
import time # only needed for example usage...
def debounce(wait):
"""Postpone a functions execution until after some time has elapsed
:type wait: int
:param wait: The amount of Seconds to wait before the next call can execute.
"""
def decorator(fun):
def debounced(*args, **kwargs):
def call_it():
fun(*args, **kwargs)
try:
debounced.t.cancel()
except AttributeError:
pass
debounced.t = Timer(wait, call_it)
debounced.t.start()
return debounced
return decorator
#
# Example Usage
#
class Person:
TITLES = ('Dr', 'Mr', 'Mrs', 'Ms')
def __init__(self, name, surname, birthdate):
self.name = name
self.surname = surname
self.birthdate = birthdate
self.age = None
self.age_last_calculated = None
def fullname(self):
return '{0} {1}'.format(self.name, self.surname)
@debounce(1)
def calculate_age(self):
today = datetime.date.today()
age = today.year - self.birthdate.year
self.age = age
self.age_last_calculated = today
#
# Only the last printed output (1.9) should have values other than 'None'
my_age_as_days = 365 * 35 # approximate
my_age = datetime.datetime.now() - timedelta(days=my_age_as_days)
person = Person('Jon', 'LaBelle', my_age)
# call the debounced function (should output 'None'):
person.calculate_age()
print('calculated_age: {0}'.format(person.age)) # >> None
print('age_last_calculated: {0}'.format(person.age_last_calculated)) # >> None
# sleep a bit... then call the debounced function again (should output 'None'):
time.sleep(0.1)
person.calculate_age()
print('calculated_age: {0}'.format(person.age)) # >> None
print('age_last_calculated: {0}'.format(person.age_last_calculated)) # >> None
# sleep a bit more... then call the debounced function again (should output 'None'):
time.sleep(0.4)
person.calculate_age()
print('calculated_age: {0}'.format(person.age)) # >> None
print('age_last_calculated: {0}'.format(person.age_last_calculated)) # >> None
# sleep until the wait time thresh-hold has been satisified (1-second)...
# then call the debounced function again (should output values for Age and Last Calculated):
time.sleep(1.9)
person.calculate_age()
print('calculated_age: {0}'.format(person.age)) # >> 23
print('age_last_calculated: {0}'.format(person.age_last_calculated)) # 2018-05-23