def periodic(): global periodic_exc global run_periodic if not renpy.config.audio_periodic_thread: periodic_pass() return with periodic_condition: for c in all_channels: c.get_context() if periodic_exc is not None: exc = periodic_exc periodic_exc = None six.reraise(exc[0], exc[1], exc[2]) run_periodic = True periodic_condition.notify()
def run(self, node=None): """ Executes as many nodes as possible in the current context. If the node argument is given, starts executing from that node. Otherwise, looks up the node given in self.current, and executes from there. """ self.exception_handler = None self.abnormal = True if node is None: node = renpy.game.script.lookup(self.current) developer = renpy.config.developer tracing = sys.gettrace() is not None # Is this the first time through the loop? first = True while node: if node.name == self.come_from_name: self.come_from_name = None node = self.call(self.come_from_label, return_site=node.name) self.make_dynamic(["_return", "_begin_rollback"]) renpy.store._begin_rollback = False this_node = node type_node_name = type(node).__name__ renpy.plog(1, "--- start {} ({}:{})", type_node_name, node.filename, node.linenumber) self.current = node.name self.last_abnormal = self.abnormal self.abnormal = False self.defer_rollback = None if renpy.config.line_log: ll_entry = LineLogEntry(node.filename, node.linenumber, node, self.last_abnormal) if ll_entry not in self.line_log: self.line_log.append(ll_entry) if not renpy.store._begin_rollback: update_rollback = False force_rollback = False elif first or self.force_checkpoint or (node.rollback == "force"): update_rollback = True force_rollback = True elif not renpy.config.all_nodes_rollback and (node.rollback == "never"): update_rollback = False force_rollback = False else: update_rollback = True force_rollback = False # Force a new rollback to start to match things in the forward log. if renpy.game.log.forward and renpy.game.log.forward[0][ 0] == node.name: update_rollback = True force_rollback = True first = False if update_rollback: if self.rollback and renpy.game.log: renpy.game.log.begin(force=force_rollback) if self.rollback and self.force_checkpoint: renpy.game.log.checkpoint(hard=False) self.force_checkpoint = False self.seen = False renpy.test.testexecution.take_name(self.current) try: try: check_infinite_loop() if tracing: self.report_coverage(node) renpy.game.exception_info = "While running game code:" self.next_node = None renpy.plog(2, " before execute {} ({}:{})", type_node_name, node.filename, node.linenumber) node.execute() renpy.plog(2, " after execute {} ({}:{})", type_node_name, node.filename, node.linenumber) if developer and self.next_node: self.check_stacks() except renpy.game.CONTROL_EXCEPTIONS as e: # An exception ends the current translation. self.translate_interaction = None raise except Exception as e: self.translate_interaction = None exc_info = sys.exc_info() short, full, traceback_fn = renpy.error.report_exception( e, editor=False) try: if self.exception_handler is not None: self.exception_handler(short, full, traceback_fn) elif renpy.display.error.report_exception( short, full, traceback_fn): raise except renpy.game.CONTROL_EXCEPTIONS as ce: raise ce except Exception as ce: six.reraise(exc_info[0], exc_info[1], exc_info[2]) node = self.next_node except renpy.game.JumpException as e: node = renpy.game.script.lookup(e.args[0]) self.abnormal = True except renpy.game.CallException as e: if e.from_current: return_site = node.name else: if self.next_node is None: raise Exception( "renpy.call can't be used when the next node is undefined." ) return_site = self.next_node.name node = self.call(e.label, return_site=return_site) self.abnormal = True renpy.store._args = e.args renpy.store._kwargs = e.kwargs if self.seen: renpy.game.persistent._seen_ever[ self.current] = True # @UndefinedVariable renpy.game.seen_session[self.current] = True renpy.plog(2, " end {} ({}:{})", type_node_name, this_node.filename, this_node.linenumber) if self.rollback and renpy.game.log: renpy.game.log.complete()
def save(slotname, extra_info='', mutate_flag=False): """ :doc: loadsave :args: (filename, extra_info='') Saves the game state to a save slot. `filename` A string giving the name of a save slot. Despite the variable name, this corresponds only loosely to filenames. `extra_info` An additional string that should be saved to the save file. Usually, this is the value of :var:`save_name`. :func:`renpy.take_screenshot` should be called before this function. """ if mutate_flag: renpy.python.mutate_flag = False roots = renpy.game.log.freeze(None) if renpy.config.save_dump: save_dump(roots, renpy.game.log) logf = StringIO() try: dump((roots, renpy.game.log), logf) except: t, e, tb = sys.exc_info() if mutate_flag: six.reraise(t, e, tb) try: bad = find_bad_reduction(roots, renpy.game.log) except: six.reraise(t, e, tb) if bad is None: six.reraise(t, e, tb) e.args = (e.args[0] + ' (perhaps {})'.format(bad), ) + e.args[1:] six.reraise(t, e, tb) if mutate_flag and renpy.python.mutate_flag: raise SaveAbort() screenshot = renpy.game.interface.get_screenshot() json = { "_save_name": extra_info, "_renpy_version": list(renpy.version_tuple), "_version": renpy.config.version } for i in renpy.config.save_json_callbacks: i(json) json = json_dumps(json) sr = SaveRecord(screenshot, extra_info, json, logf.getvalue()) location.save(slotname, sr) location.scan() clear_slot(slotname)
def save(slotname, extra_info='', mutate_flag=False): """ :doc: loadsave :args: (filename, extra_info='') Saves the game state to a save slot. `filename` A string giving the name of a save slot. Despite the variable name, this corresponds only loosely to filenames. `extra_info` An additional string that should be saved to the save file. Usually, this is the value of :var:`save_name`. :func:`renpy.take_screenshot` should be called before this function. """ if mutate_flag: renpy.python.mutate_flag = False roots = renpy.game.log.freeze(None) if renpy.config.save_dump: save_dump(roots, renpy.game.log) logf = StringIO() try: dump((roots, renpy.game.log), logf) except: t, e, tb = sys.exc_info() if mutate_flag: six.reraise(t, e, tb) try: bad = find_bad_reduction(roots, renpy.game.log) except: six.reraise(t, e, tb) if bad is None: six.reraise(t, e, tb) e.args = ( e.args[0] + ' (perhaps {})'.format(bad), ) + e.args[1:] six.reraise(t, e, tb) if mutate_flag and renpy.python.mutate_flag: raise SaveAbort() screenshot = renpy.game.interface.get_screenshot() json = { "_save_name" : extra_info, "_renpy_version" : list(renpy.version_tuple), "_version" : renpy.config.version } for i in renpy.config.save_json_callbacks: i(json) json = json_dumps(json) sr = SaveRecord(screenshot, extra_info, json, logf.getvalue()) location.save(slotname, sr) location.scan() clear_slot(slotname)
def run(self, node=None): """ Executes as many nodes as possible in the current context. If the node argument is given, starts executing from that node. Otherwise, looks up the node given in self.current, and executes from there. """ self.exception_handler = None self.abnormal = True if node is None: node = renpy.game.script.lookup(self.current) developer = renpy.config.developer tracing = sys.gettrace() is not None # Is this the first time through the loop? first = True while node: if node.name == self.come_from_name: self.come_from_name = None node = self.call(self.come_from_label, return_site=node.name) self.make_dynamic([ "_return" ]) this_node = node type_node_name = type(node).__name__ renpy.plog(1, "--- start {} ({}:{})", type_node_name, node.filename, node.linenumber) self.current = node.name self.last_abnormal = self.abnormal self.abnormal = False self.defer_rollback = None if renpy.config.line_log: ll_entry = LineLogEntry(node.filename, node.linenumber, node, self.last_abnormal) if ll_entry not in self.line_log: self.line_log.append(ll_entry) if first or self.force_checkpoint or (node.rollback == "force"): update_rollback = True force_rollback = True elif not renpy.config.all_nodes_rollback and (node.rollback == "never"): update_rollback = False force_rollback = False else: update_rollback = True force_rollback = False # Force a new rollback to start to match things in the forward log. if renpy.game.log.forward and renpy.game.log.forward[0][0] == node.name: update_rollback = True force_rollback = True first = False if update_rollback: if self.rollback and renpy.game.log: renpy.game.log.begin(force=force_rollback) if self.rollback and self.force_checkpoint: renpy.game.log.checkpoint(hard=False) self.force_checkpoint = False self.seen = False renpy.test.testexecution.take_name(self.current) try: try: check_infinite_loop() if tracing: self.report_coverage(node) renpy.game.exception_info = "While running game code:" self.next_node = None renpy.plog(2, " before execute {} ({}:{})", type_node_name, node.filename, node.linenumber) node.execute() renpy.plog(2, " after execute {} ({}:{})", type_node_name, node.filename, node.linenumber) if developer and self.next_node: self.check_stacks() except renpy.game.CONTROL_EXCEPTIONS as e: # An exception ends the current translation. self.translate_interaction = None raise except Exception as e: self.translate_interaction = None exc_info = sys.exc_info() short, full, traceback_fn = renpy.error.report_exception(e, editor=False) try: if self.exception_handler is not None: self.exception_handler(short, full, traceback_fn) elif renpy.display.error.report_exception(short, full, traceback_fn): raise except renpy.game.CONTROL_EXCEPTIONS as ce: raise ce except Exception as ce: six.reraise(exc_info[0], exc_info[1], exc_info[2]) node = self.next_node except renpy.game.JumpException as e: node = renpy.game.script.lookup(e.args[0]) self.abnormal = True except renpy.game.CallException as e: if e.from_current: return_site = node.name else: if self.next_node is None: raise Exception("renpy.call can't be used when the next node is undefined.") return_site = self.next_node.name node = self.call(e.label, return_site=return_site) self.abnormal = True renpy.store._args = e.args renpy.store._kwargs = e.kwargs if self.seen: renpy.game.persistent._seen_ever[self.current] = True # @UndefinedVariable renpy.game.seen_session[self.current] = True renpy.plog(2, " end {} ({}:{})", type_node_name, this_node.filename, this_node.linenumber) if self.rollback and renpy.game.log: renpy.game.log.complete()