<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run(self, react=True, strict=True, roles=1):
 """Select a cast and perform the next scene. :param bool react: If `True`, then Property directives are executed at the point they are encountered. Pass `False` to skip them so they can be enacted later on. :param bool strict: Only fully-cast scripts to be performed. :param int roles: Maximum number of roles permitted each character. This method is a generator. It yields events from the performance. If a :py:class:`~turberfield.dialogue.model.Model.Condition` is encountered, it is evaluated. No events are generated while the most recent condition is False. A new :py:class:`~turberfield.dialogue.model.Model.Shot` resets the current condition. """

        try:
            folder, index, self.script, self.selection, interlude = self.next(
                self.folders, self.ensemble,
                strict=strict, roles=roles
            )
        except TypeError:
            raise GeneratorExit
        with self.script as dialogue:
            model = dialogue.cast(self.selection).run()
            for shot, item in model:

                if self.condition is not False:
                    yield shot
                    yield item

                if not self.shots or self.shots[-1][:2] != shot[:2]:
                    self.shots.append(shot._replace(items=self.script.fP))
                    self.condition = None

                if isinstance(item, Model.Condition):
                    self.condition = self.allows(item)

                if react:
                    self.react(item)

            for key, value in model.metadata:
                if value not in self.metadata[key]:
                    self.metadata[key].append(value)