Basic timed event implementation.
This commit is contained in:
parent
27a20b349c
commit
35b6e146cb
3 changed files with 67 additions and 12 deletions
22
src/core.py
22
src/core.py
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 it’s 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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue