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 windows
import connection
import timed_events
from data_forms import DataFormsTab
from config import config
from config import config, options
from logger import logger
from user import User
from room import Room
@ -619,9 +620,6 @@ class Core(object):
tab.resize()
self.refresh_window()
def check_timed_events(self):
pass
def read_keyboard(self):
"""
Get the next keyboard key pressed and returns it.
@ -631,6 +629,7 @@ class Core(object):
"""
res = read_char(self.stdscr)
while res is None:
log.debug('checking events')
self.check_timed_events()
res = read_char(self.stdscr)
return res
@ -705,7 +704,8 @@ class Core(object):
curses.curs_set(1)
curses.noecho()
curses.nonl()
curses.raw()
if not options.debug:
curses.raw()
theme.init_colors()
stdscr.keypad(True)
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.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):
"""
Execute the /command or just send the line on the current room

View file

@ -35,7 +35,7 @@ def get_next_byte(s):
try:
c = s.getkey()
except:
return (None, "KEY_RESIZE")
return (None, None)
if len(c) >= 4:
return (None, c)
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
# clipboard or not
global last_char_time
last_char_time = time.time()
# global last_char_time
# last_char_time = time.time()
s.timeout(1000)
(first, char) = get_next_byte(s)
if first is None:
return None
if not isinstance(first, int): # Keyboard special, like KEY_HOME etc
return char
if first == 127 or first == 8:
@ -57,8 +60,8 @@ def read_char(s):
if first < 127: # ASCII char on one byte
if first <= 26: # transform Ctrl+* keys
char = chr(first + 64)
if char == 'M' and time.time() - last_char_time < 0.0005:
char = 'J'
# if char == 'M' and time.time() - last_char_time < 0.0005:
# char = 'J'
return "^"+char
if first == 27:
second = read_char(s)

View file

@ -14,15 +14,55 @@
# You should have received a copy of the GNU General Public License
# 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):
"""
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
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.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)