Basic timed event implementation.

This commit is contained in:
Florent Le Coz 2011-04-09 22:18:36 +02:00
parent 27a20b349c
commit 35b6e146cb
3 changed files with 67 additions and 12 deletions

View file

@ -43,9 +43,10 @@ import tabs
import xhtml import xhtml
import windows import windows
import connection import connection
import timed_events
from data_forms import DataFormsTab from data_forms import DataFormsTab
from config import config from config import config, options
from logger import logger from logger import logger
from user import User from user import User
from room import Room from room import Room
@ -619,9 +620,6 @@ class Core(object):
tab.resize() tab.resize()
self.refresh_window() self.refresh_window()
def check_timed_events(self):
pass
def read_keyboard(self): def read_keyboard(self):
""" """
Get the next keyboard key pressed and returns it. Get the next keyboard key pressed and returns it.
@ -631,6 +629,7 @@ class Core(object):
""" """
res = read_char(self.stdscr) res = read_char(self.stdscr)
while res is None: while res is None:
log.debug('checking events')
self.check_timed_events() self.check_timed_events()
res = read_char(self.stdscr) res = read_char(self.stdscr)
return res return res
@ -705,7 +704,8 @@ class Core(object):
curses.curs_set(1) curses.curs_set(1)
curses.noecho() curses.noecho()
curses.nonl() curses.nonl()
curses.raw() if not options.debug:
curses.raw()
theme.init_colors() theme.init_colors()
stdscr.keypad(True) stdscr.keypad(True)
curses.ungetch(" ") # H4X: without this, the screen is curses.ungetch(" ") # H4X: without this, the screen is
@ -1379,6 +1379,18 @@ class Core(object):
self.focus_tab_named(roster_row.get_jid().full) self.focus_tab_named(roster_row.get_jid().full)
self.refresh_window() self.refresh_window()
def add_timed_event(self, event):
self.timed_events.add(event)
def check_timed_events(self):
now = datetime.now()
for event in self.timed_events:
if event.has_timed_out(now):
res = event()
if not res:
self.timed_events.remove(event)
break
def execute(self,line): def execute(self,line):
""" """
Execute the /command or just send the line on the current room Execute the /command or just send the line on the current room

View file

@ -35,7 +35,7 @@ def get_next_byte(s):
try: try:
c = s.getkey() c = s.getkey()
except: except:
return (None, "KEY_RESIZE") return (None, None)
if len(c) >= 4: if len(c) >= 4:
return (None, c) return (None, c)
return (ord(c), c.encode('latin-1')) # returns a number and a bytes object return (ord(c), c.encode('latin-1')) # returns a number and a bytes object
@ -47,9 +47,12 @@ def read_char(s):
""" """
# We use a timer to know if we are pasting from the # We use a timer to know if we are pasting from the
# clipboard or not # clipboard or not
global last_char_time # global last_char_time
last_char_time = time.time() # last_char_time = time.time()
s.timeout(1000)
(first, char) = get_next_byte(s) (first, char) = get_next_byte(s)
if first is None:
return None
if not isinstance(first, int): # Keyboard special, like KEY_HOME etc if not isinstance(first, int): # Keyboard special, like KEY_HOME etc
return char return char
if first == 127 or first == 8: if first == 127 or first == 8:
@ -57,8 +60,8 @@ def read_char(s):
if first < 127: # ASCII char on one byte if first < 127: # ASCII char on one byte
if first <= 26: # transform Ctrl+* keys if first <= 26: # transform Ctrl+* keys
char = chr(first + 64) char = chr(first + 64)
if char == 'M' and time.time() - last_char_time < 0.0005: # if char == 'M' and time.time() - last_char_time < 0.0005:
char = 'J' # char = 'J'
return "^"+char return "^"+char
if first == 27: if first == 27:
second = read_char(s) second = read_char(s)

View file

@ -14,15 +14,55 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Poezio. If not, see <http://www.gnu.org/licenses/>. # along with Poezio. If not, see <http://www.gnu.org/licenses/>.
"""
To use these, just use core.add_timed_event(event)
where event is an instance of one of these classes
"""
import logging
log = logging.getLogger(__name__)
import datetime
class TimedEvent(object): class TimedEvent(object):
""" """
An event with a callback that is called when the specified time is passed An event with a callback that is called when the specified time is passed
Note that these events can NOT be used for very small delay or a very Note that these events can NOT be used for very small delay or a very
precise date, since the check for events is done once per second, as precise date, since the check for events is done once per second, as
a maximum a maximum.
""" """
def __init__(self, callback, *args, **kwargs): def __init__(self, date, callback, *args):
self._callback = callback self._callback = callback
self.args = args self.args = args
self.repetive = False
self.next_call_date = date
def __call__(self):
"""
the call should return False if this event should be remove from
the events list.
If its true, the date should be updated beforehand to a later date,
or else it will be called every second
"""
self._callback(*self.args)
return self.repetive
def has_timed_out(self, current_date):
"""
returns True if the callback should be called
"""
if self.next_call_date < current_date:
return True
else:
return False
class DelayedEvent(TimedEvent):
"""
The date is calculated from now + a delay in seconds
Use it if you want an event to happen in, e.g. 6 seconds
"""
def __init__(self, delay, callback, *args):
date = datetime.datetime.now() + datetime.timedelta(0, delay)
TimedEvent.__init__(self, date, callback, args)