Added more stable events.
- added PIDs to all events, so they can be deleted safely. - scheduler.del_event(pid) cleanly deletes events from the scheduler - added @delevent for deleting events based on PID (@ps shows this now) - Events has a self.repeat property allowing them to only be repeated a certain time (default is infinitely many times). After the set number of repeats, the event deletes itself from the scheduler. Events are currently not persistently stored; this is left for future commits. . Griatch
This commit is contained in:
parent
642932a403
commit
5e866c6b73
5 changed files with 148 additions and 26 deletions
|
|
@ -775,3 +775,21 @@ def cmd_help(command):
|
||||||
|
|
||||||
source_object.emit_to(string)
|
source_object.emit_to(string)
|
||||||
GLOBAL_CMD_TABLE.add_command("help", cmd_help)
|
GLOBAL_CMD_TABLE.add_command("help", cmd_help)
|
||||||
|
|
||||||
|
## def cmd_testevent(command):
|
||||||
|
## from src import events
|
||||||
|
## from src import scheduler
|
||||||
|
## source_object = command.source_object
|
||||||
|
|
||||||
|
## if not command.command_argument:
|
||||||
|
## #event = events.IntervalEvent()
|
||||||
|
## event = events.IntervalEvent()
|
||||||
|
## event.repeats = 3
|
||||||
|
## event.interval = 5
|
||||||
|
## pid = scheduler.add_event(event)
|
||||||
|
## source_object.emit_to("event with pid %s added." % pid)
|
||||||
|
## else:
|
||||||
|
## pid = command.command_argument
|
||||||
|
## scheduler.del_event(pid)
|
||||||
|
## source_object.emit_to("event with pid %s removed (if it existed)." % pid)
|
||||||
|
## GLOBAL_CMD_TABLE.add_command("testevent", cmd_testevent)
|
||||||
|
|
|
||||||
|
|
@ -135,13 +135,18 @@ def cmd_ps(command):
|
||||||
"""
|
"""
|
||||||
source_object = command.source_object
|
source_object = command.source_object
|
||||||
|
|
||||||
source_object.emit_to("-- Interval Events --")
|
source_object.emit_to("Processes Scheduled:\n-- PID [time/interval] [repeats] description --")
|
||||||
for event in scheduler.schedule:
|
for event in scheduler.SCHEDULE:
|
||||||
source_object.emit_to(" [%d/%d] %s" % (
|
repeats = "[inf] "
|
||||||
event.get_nextfire(),
|
if event.repeats != None:
|
||||||
event.interval,
|
repeats = "[%i] " % event.repeats
|
||||||
event.description))
|
source_object.emit_to(" %i [%d/%d] %s%s" % (
|
||||||
source_object.emit_to("Totals: %d interval events" % (len(scheduler.schedule),))
|
event.pid,
|
||||||
|
event.get_nextfire(),
|
||||||
|
event.interval,
|
||||||
|
repeats,
|
||||||
|
event.description))
|
||||||
|
source_object.emit_to("Totals: %d interval events" % (len(scheduler.SCHEDULE),))
|
||||||
GLOBAL_CMD_TABLE.add_command("@ps", cmd_ps,
|
GLOBAL_CMD_TABLE.add_command("@ps", cmd_ps,
|
||||||
priv_tuple=("genperms.process_control",), help_category="Admin")
|
priv_tuple=("genperms.process_control",), help_category="Admin")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ from src.helpsys import helpsystem
|
||||||
from src.config.models import CommandAlias
|
from src.config.models import CommandAlias
|
||||||
from src.config import edit_aliases
|
from src.config import edit_aliases
|
||||||
from src import cache
|
from src import cache
|
||||||
|
from src import scheduler
|
||||||
|
|
||||||
|
|
||||||
def cmd_reload(command):
|
def cmd_reload(command):
|
||||||
"""
|
"""
|
||||||
@reload - reload game subsystems
|
@reload - reload game subsystems
|
||||||
|
|
@ -761,3 +764,37 @@ def cmd_setcmdalias(command):
|
||||||
GLOBAL_CMD_TABLE.add_command("@setcmdalias", cmd_setcmdalias,
|
GLOBAL_CMD_TABLE.add_command("@setcmdalias", cmd_setcmdalias,
|
||||||
priv_tuple=("genperms.process_control",),
|
priv_tuple=("genperms.process_control",),
|
||||||
help_category="Admin")
|
help_category="Admin")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_delevent(command):
|
||||||
|
"""
|
||||||
|
@delevent - remove events manually
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
@delevent <pid>
|
||||||
|
|
||||||
|
Removes an event with the given pid (process ID) from the event scheduler.
|
||||||
|
To see all active events and their pids, use the @ps command.
|
||||||
|
"""
|
||||||
|
source_object = command.source_object
|
||||||
|
|
||||||
|
if not command.command_argument:
|
||||||
|
source_object.emit_to("Usage: @delevent <pid>")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
pid = int(command.command_argument)
|
||||||
|
except ValueError:
|
||||||
|
source_object.emit_to("You must supply a valid pid number.")
|
||||||
|
return
|
||||||
|
event = scheduler.get_event(pid)
|
||||||
|
if event:
|
||||||
|
desc = event.description
|
||||||
|
scheduler.del_event(pid)
|
||||||
|
source_object.emit_to("Event %i - '%s' removed." % (pid, desc))
|
||||||
|
else:
|
||||||
|
source_object.emit_to("No event found with a pid of %i. Use @ps to list process IDs." % pid)
|
||||||
|
|
||||||
|
GLOBAL_CMD_TABLE.add_command("@delevent", cmd_delevent,
|
||||||
|
priv_tuple=("genperms.process_control",),
|
||||||
|
help_category="Admin")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,28 @@ class IntervalEvent(object):
|
||||||
"""
|
"""
|
||||||
Represents an event that is triggered periodically. Sub-class this and
|
Represents an event that is triggered periodically. Sub-class this and
|
||||||
fill in the stub function.
|
fill in the stub function.
|
||||||
|
|
||||||
|
self.repeats decides if this event will fire indefinitely or only a
|
||||||
|
certain number of times.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, description="IntervalEvent"):
|
||||||
"""
|
"""
|
||||||
Executed when the class is instantiated.
|
Executed when the class is instantiated.
|
||||||
"""
|
"""
|
||||||
|
# This is a globally unique ID of this event. If None, a new one will
|
||||||
|
# be allocated when the event is added to the scheduler.
|
||||||
|
self.pid = None
|
||||||
# This is set to prevent a Nonetype exception on @ps before the
|
# This is set to prevent a Nonetype exception on @ps before the
|
||||||
# event is fired for the first time.
|
# event is fired for the first time.
|
||||||
self.time_last_executed = time.time()
|
self.time_last_executed = time.time()
|
||||||
# This is what shows up on @ps in-game.
|
# This used to describe the event in @ps listings.
|
||||||
self.name = None
|
self.description = description
|
||||||
# An interval (in seconds) for execution.
|
# An interval (in seconds) for execution.
|
||||||
self.interval = None
|
self.interval = None
|
||||||
|
# How many times to repeat this event.
|
||||||
|
# None : indefinitely,
|
||||||
|
# positive integer : number of times
|
||||||
|
self.repeats = None
|
||||||
# A reference to the task.LoopingCall object.
|
# A reference to the task.LoopingCall object.
|
||||||
self.looped_task = None
|
self.looped_task = None
|
||||||
|
|
||||||
|
|
@ -39,6 +49,18 @@ class IntervalEvent(object):
|
||||||
"""
|
"""
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def __eq__(self, event2):
|
||||||
|
"""
|
||||||
|
Handles comparison operations.
|
||||||
|
"""
|
||||||
|
return self.pid == event2.pid
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
"""
|
||||||
|
Used for dictionary key comparisons.
|
||||||
|
"""
|
||||||
|
return self.pid
|
||||||
|
|
||||||
def start_event_loop(self):
|
def start_event_loop(self):
|
||||||
"""
|
"""
|
||||||
Called to start up the event loop when the event is added to the
|
Called to start up the event loop when the event is added to the
|
||||||
|
|
@ -78,9 +100,16 @@ class IntervalEvent(object):
|
||||||
def fire_event(self):
|
def fire_event(self):
|
||||||
"""
|
"""
|
||||||
Set the last ran stamp and fire off the event.
|
Set the last ran stamp and fire off the event.
|
||||||
|
Stop repeating if number of repeats have been achieved.
|
||||||
"""
|
"""
|
||||||
self.set_lastfired()
|
self.set_lastfired()
|
||||||
self.event_function()
|
self.event_function()
|
||||||
|
if self.repeats != None:
|
||||||
|
self.repeats -= 1
|
||||||
|
if self.repeats <= 0 and self.pid != None:
|
||||||
|
scheduler.del_event(self.pid)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IEvt_Check_Sessions(IntervalEvent):
|
class IEvt_Check_Sessions(IntervalEvent):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,23 @@ ADDING AN EVENT:
|
||||||
* Profit.
|
* Profit.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# List of IntervalEvent sub-classed objects.
|
# dict of IntervalEvent sub-classed objects, keyed by their
|
||||||
schedule = []
|
# process id:s.
|
||||||
|
SCHEDULE = []
|
||||||
|
|
||||||
|
def next_free_pid():
|
||||||
|
"""
|
||||||
|
Find the next free pid
|
||||||
|
"""
|
||||||
|
pids = [event.pid for event in SCHEDULE]
|
||||||
|
if not pids:
|
||||||
|
return 0
|
||||||
|
maxpid = max(pids)
|
||||||
|
freepids = [pid for pid in xrange(maxpid+1) if pid not in pids]
|
||||||
|
if freepids:
|
||||||
|
return min(freepids)
|
||||||
|
return maxpid + 1
|
||||||
|
|
||||||
def add_event(event):
|
def add_event(event):
|
||||||
"""
|
"""
|
||||||
Adds an event instance to the scheduled event list. Call this any time you
|
Adds an event instance to the scheduled event list. Call this any time you
|
||||||
|
|
@ -19,21 +33,40 @@ def add_event(event):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
* event: (IntervalEvent) The event to add to the scheduler.
|
* event: (IntervalEvent) The event to add to the scheduler.
|
||||||
"""
|
Returns:
|
||||||
|
* pid : (int) The process ID assigned to this event, for future reference.
|
||||||
|
|
||||||
#don't add multiple instances of the same event, instead replace
|
"""
|
||||||
if event in schedule:
|
# Make sure not to add multiple instances of the same event.
|
||||||
schedule[schedule.index(event)] = event
|
matches = [i for i, stored_event in enumerate(SCHEDULE) if event == stored_event]
|
||||||
return
|
if matches:
|
||||||
|
# Before replacing an event, stop its old incarnation.
|
||||||
|
del_event(matches[0])
|
||||||
|
SCHEDULE[matches[0]] = event
|
||||||
else:
|
else:
|
||||||
schedule.append(event)
|
# Add a new event with a fresh pid.
|
||||||
|
event.pid = next_free_pid()
|
||||||
|
SCHEDULE.append(event)
|
||||||
event.start_event_loop()
|
event.start_event_loop()
|
||||||
|
return event.pid
|
||||||
|
|
||||||
def del_event(event):
|
def get_event(pid):
|
||||||
"""
|
"""
|
||||||
Remove an event from scheduler.
|
Return an event with the given pid, if it exists,
|
||||||
|
otherwise return None.
|
||||||
"""
|
"""
|
||||||
if event in schedule:
|
pid = int(pid)
|
||||||
i = schedule.index(event)
|
imatches = [i for i, stored_event in enumerate(SCHEDULE) if stored_event.pid == pid]
|
||||||
schedule[i].stop_event_loop()
|
if imatches:
|
||||||
del schedule[i]
|
return SCHEDULE[imatches[0]]
|
||||||
|
|
||||||
|
def del_event(pid):
|
||||||
|
"""
|
||||||
|
Remove an event from scheduler. There should never be more than one
|
||||||
|
event with a certain pid, this cleans up in case there are any multiples.
|
||||||
|
"""
|
||||||
|
pid = int(pid)
|
||||||
|
imatches = [i for i, stored_event in enumerate(SCHEDULE) if stored_event.pid == pid]
|
||||||
|
for imatch in imatches:
|
||||||
|
SCHEDULE[imatch].stop_event_loop()
|
||||||
|
del SCHEDULE[imatch]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue