Fixed a repeat error in Scripts (resolves #890). Added separation between calling script.pause() deliberately and it being called automatically by the reset/reload, in order to preserve manual pauses across server reloads (resolves #891).

This commit is contained in:
Griatch 2015-12-17 00:12:07 +01:00
parent f56500df9a
commit 161383f9ae
3 changed files with 36 additions and 8 deletions

View file

@ -96,7 +96,9 @@ class ExtendedLoopingCall(LoopingCall):
"""
self.callcount += 1
self.start_delay = None
if self.start_delay:
self.start_delay = None
self.starttime = self.clock.seconds()
super(ExtendedLoopingCall, self).__call__()
def force_repeat(self):
@ -130,6 +132,7 @@ class ExtendedLoopingCall(LoopingCall):
if self.running:
total_runtime = self.clock.seconds() - self.starttime
interval = self.start_delay or self.interval
print "next_call_time:", interval, total_runtime, self.interval, interval - (total_runtime % self.interval)
return interval - (total_runtime % self.interval)
return None
@ -169,6 +172,10 @@ class DefaultScript(ScriptBase):
"""
from evennia.utils.utils import calledby
print calledby(2)
print "_start_task:", self.db_interval, self.db._paused_time
self.ndb._task = ExtendedLoopingCall(self._step_task)
if self.db._paused_time:
@ -308,8 +315,12 @@ class DefaultScript(ScriptBase):
return 0
# try to restart a paused script
if self.unpause():
return 1
try:
if self.unpause(manual_unpause=False):
return 1
except RuntimeError:
# manually paused.
return 0
# start the script from scratch
self.is_active = True
@ -349,12 +360,13 @@ class DefaultScript(ScriptBase):
return 0
return 1
def pause(self):
def pause(self, manual_pause=True):
"""
This stops a running script and stores its active state.
It WILL NOT call the `at_stop()` hook.
"""
self.db._manual_pause = manual_pause
if not self.db._paused_time:
# only allow pause if not already paused
task = self.ndb._task
@ -364,10 +376,26 @@ class DefaultScript(ScriptBase):
self._stop_task()
self.is_active = False
def unpause(self):
def unpause(self, manual_unpause=True):
"""
Restart a paused script. This WILL call the `at_start()` hook.
Args:
manual_unpause (bool, optional): This is False if unpause is
called by the server reload/reset mechanism.
Returns:
result (bool): True if unpause was triggered, False otherwise.
Raises:
RuntimeError: If trying to automatically resart this script
(usually after a reset/reload), but it was manually paused,
and so should not the auto-unpaused.
"""
if not manual_unpause and self.db._manual_pause:
# if this script was paused manually (by a direct call of pause),
# it cannot be automatically unpaused (e.g. by a @reload)
raise RuntimeError
if self.db._paused_time:
# only unpause if previously paused
self.is_active = True

View file

@ -349,7 +349,7 @@ class Evennia(object):
ServerConfig.objects.conf("server_restart_mode", "reload")
yield [o.at_server_reload() for o in ObjectDB.get_all_cached_instances()]
yield [p.at_server_reload() for p in PlayerDB.get_all_cached_instances()]
yield [(s.pause(), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances()]
yield [(s.pause(manual_pause=False), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances() if s.is_active]
yield self.sessions.all_sessions_portal_sync()
self.at_server_reload_stop()
# only save OOB state on reload, not on shutdown/reset
@ -368,7 +368,7 @@ class Evennia(object):
yield [(p.unpuppet_all(), p.at_server_shutdown())
for p in PlayerDB.get_all_cached_instances()]
yield ObjectDB.objects.clear_all_sessids()
yield [(s.pause(), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
yield [(s.pause(manual_pause=False), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
ServerConfig.objects.conf("server_restart_mode", "reset")
self.at_server_cold_stop()

View file

@ -207,7 +207,7 @@ class ServerSession(Session):
obj.player = self.player
self.puid = obj.id
self.puppet = obj
obj.scripts.validate()
#obj.scripts.validate()
obj.locks.cache_lock_bypass(obj)
def at_login(self, player):