def execute_predicting(self, context): # A variant of the this code that runs while predicting, executing # all paths of the if. # True if no block has been the main choice yet. first = True # Has any instance of this node been predicted? We only predict # once per node, for performance reasons. predicted = self.serial in context.predicted if not predicted: context.predicted.add(self.serial) for cond, block in self.prepared_entries: try: cond_value = (cond is None) or eval(cond, context.globals, context.scope) except: cond_value = False # The taken branch. if first and cond_value: first = False for i in block.children: try: i.execute(context) except: pass # Not-taken branches, only if not already predicted. elif not predicted: ctx = SLContext(context) ctx.children = [] for i in block.children: try: i.execute(ctx) except: pass for i in ctx.children: predict_displayable(i)
def execute_predicting(self, context): # A variant of the this code that runs while predicting, executing # all paths of the if. # True if no block has been the main choice yet. first = True # Has any instance of this node been predicted? We only predict # once per node, for performance reasons. predicted = self.serial in context.predicted if not predicted: context.predicted.add(self.serial) for cond, block in self.prepared_entries: try: cond_value = (cond is None) or eval(cond, context.globals, context.scope) except: cond_value = False # The taken branch. if first and cond_value: first = False for i in block.children: try: i.execute(context) except: pass # Not-taken branches, only if not already predicted. elif not predicted: ctx = SLContext(context) ctx.children = [ ] for i in block.children: try: i.execute(context) except: pass for i in ctx.children: predict_displayable(i)
def execute(self, context): debug = context.debug screen = renpy.ui.screen cache = context.cache.get(self.serial, None) if cache is None: context.cache[self.serial] = cache = SLCache() copy_on_change = cache.copy_on_change if debug: self.debug_line() if cache.constant: profile_log.write(" reused constant displayable") if cache.constant: for i in cache.constant_uses_scope: if copy_on_change: if i._scope(context.scope, False): cache.constant = None break else: i._scope(context.scope, True) else: context.children.append(cache.constant) screen.widgets.update(cache.constant_widgets) return # Create the context. ctx = SLContext(context) # True if we encountered an exception that we're recovering from # due to being in prediction mode. fail = False # The main displayable we're predicting. main = None # True if we're using an imagemap. imagemap = False try: # Evaluate the positional arguments. positional_values = self.positional_values positional_exprs = self.positional_exprs if positional_values and positional_exprs: values = eval(positional_exprs, context.globals, context.scope) positional = [ b if (a is use_expression) else a for a, b in zip(positional_values, values) ] elif positional_values: positional = positional_values elif positional_exprs: positional = eval(positional_exprs, context.globals, context.scope) else: positional = [ ] keywords = ctx.keywords = self.default_keywords.copy() if self.constant: if ctx.uses_scope is None: ctx.uses_scope = [ ] if ctx.widgets is None: ctx.widgets = { } SLBlock.keywords(self, ctx) # Get the widget id and transform, if any. widget_id = keywords.pop("id", None) transform = keywords.pop("at", None) # If we don't know the style, figure it out. if ("style" not in keywords) and self.style: keywords["style"] = ctx.style_prefix + self.style if widget_id and (widget_id in screen.widget_properties): keywords.update(screen.widget_properties[widget_id]) old_d = cache.displayable if old_d: old_main = old_d._main or old_d else: old_main = None reused = False if debug: self.report_arguments(cache, positional, keywords, transform) if old_d and (positional == cache.positional) and (keywords == cache.keywords): reused = True d = old_d # The main displayable, if d is a composite displayable. (This is # the one that gets the scope, and gets children added to it.) main = old_main if widget_id: screen.widgets[widget_id] = main if self.scope and main.uses_scope: if copy_on_change: if main._scope(ctx.scope, False): reused = False else: main._scope(ctx.scope, True) if reused and cache.imagemap: imagemap = True cache.imagemap.reuse() renpy.ui.imagemap_stack.append(cache.imagemap) if not reused: cache.positional = positional cache.keywords = keywords.copy() # This child creation code is copied below, for the copy_on_change # case. if self.scope: keywords["scope"] = ctx.scope if self.replaces: keywords['replaces'] = old_main # Pass the context if self.pass_context: keywords['context'] = ctx d = self.displayable(*positional, **keywords) main = d._main or d main._location = self.location if widget_id: screen.widgets[widget_id] = main # End child creation code. imagemap = self.imagemap cache.copy_on_change = False # We no longer need to copy on change. cache.children = None # Re-add the children. if debug: if reused: profile_log.write(" reused displayable") elif self.constant: profile_log.write(" created constant displayable") else: profile_log.write(" created displayable") except: if not context.predicting: raise fail = True ctx.children = [ ] stack = renpy.ui.stack stack.append(ctx) try: # Evaluate children. (Inlined SLBlock.execute) for i in self.children: try: i.execute(ctx) except: if not context.predicting: raise fail = True finally: stack.pop() if imagemap: cache.imagemap = renpy.ui.imagemap_stack.pop() cache.imagemap.cache.finish() # If a failure occurred during prediction, predict main (if known), # and ctx.children, and return. if fail: predict_displayable(main) for i in ctx.children: predict_displayable(i) return if ctx.children != cache.children: if reused and copy_on_change: # This is a copy of the child creation code from above. if self.scope: keywords["scope"] = ctx.scope if self.replaces: keywords['replaces'] = old_main if self.pass_context: keywords['context'] = ctx d = self.displayable(*positional, **keywords) main = d._main or d main._location = self.location if widget_id: screen.widgets[widget_id] = main # End child creation code. cache.copy_on_change = False reused = False if reused: main._clear() if self.child_or_fixed and len(ctx.children) != 1: f = Fixed() for i in ctx.children: f.add(i) main.add(f) else: for i in ctx.children: main.add(i) # Migrate grabs. if old_main and (renpy.display.focus.grab is old_main): renpy.display.focus.new_grab = main cache.displayable = d cache.children = ctx.children if transform is not None: if reused and (transform == cache.raw_transform): d = cache.transform else: cache.raw_transform = transform if isinstance(transform, Transform): d = transform(child=d) elif isinstance(transform, list_or_tuple): for t in transform: if isinstance(t, Transform): d = t(child=d) else: d = t(d) else: d = transform(d) if isinstance(d, Transform): if cache.transform is not None: d.take_state(cache.transform) d.take_execution_state(cache.transform) cache.transform = d else: cache.transform = None cache.raw_transform = None context.children.append(d) if self.constant: cache.constant = d if widget_id is not None: ctx.widgets[widget_id] = main if self.scope and main.uses_scope: ctx.uses_scope.append(main) if context.widgets is None: cache.constant_widgets = ctx.widgets if context.uses_scope is None: cache.constant_uses_scope = ctx.uses_scope