<commit_before>require_relative 'scene_view/scene_view'
require_relative 'scene_actor'
require_relative 'event_relay'
require_relative 'animation/animation'

module Metro

  #
  # A scene is a basic unit of a game. Within a scene you define a number of methods
  # that handle the initial setup, event configuration, logic updating, and drawing.
  #
  # @see #show
  # @see #update
  # @see #draw
  # @see #events
  #
  # A fair number of private methods within Scene are prefaced with an underscore.
  # These methods often call non-underscored methods within those methods. This allows
  # for scene to configure or perform some functionality, while providing an interface
  # so that every subclass does not have to constantly call `super`.
  #
  class Scene

    #
    # As Scene does a lot of work for you with regarding to setting up content, it is
    # best not to override #initialize and instead define an #after_initialize method
    # within the subclasses of Scene.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def after_initialize ; end

    #
    # The events method is where a scene has access to configure the events that it
    # would like to listen for during the scene.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    # @param [EventRelay] e is the EventRelay that you can register for button up,
    #   button down, or button held events.
    #
    # @see EventRelay
    #
    def events(e) ; end

    #
    # This method is called right after the scene has been adopted by the window
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def show ; end

    #
    # This is called every update interval while the window is being shown.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def update ; end

    #
    # This is called after every {#update} and when the OS wants the window to
    # repaint itself.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def draw ; end

    #
    # Before a scene is transisitioned away from to a new scene, this method is called
    # to allow for the scene to complete any taskss, stop any actions, or pass any
    # information from the existing scene to the scene that is about to replace it.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    # @param [Scene] new_scene this is the instance of the scene that is about to replace
    #   the current scene.
    #
    def prepare_transition_to(new_scene) ; end

    #
    # Before a scene is transisitioned to it is called with the previous scene. This
    # allows for the new scene to rerieve any data from the previous scene to assist
    # with the layout of the current scene.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    # @param [Scene] old_scene this is the instance of the scene that is being moved
    #   away from.
    #
    def prepare_transition_from(old_scene) ; end


    #
    # Define a scene actor with the given name and options.
    #
    def self.draw(actor_name,options = {})
      scene_actor = SceneActor.new actor_name, options

      define_method actor_name do
        instance_variable_get("@#{actor_name}")
      end

      define_method "#{actor_name}=" do |value|
        instance_variable_set("@#{actor_name}",value)
      end

      scene_actors.push scene_actor
    end

    #
    # Define several standard scene actors.
    #
    def self.draws(*actor_names)
      actor_names = actor_names.flatten.compact

      actor_names.each do |actor_name|
        draw actor_name
      end

      scene_actors
    end

    #
    # @return a list of all the SceneActors that have been defined for this Scene.
    #
    def self.scene_actors
      @scene_actors ||= []
    end

    #
    # Setups up the Actors for the Scene based on the SceneActors that have been
    # defined.
    #
    # @note this method should not be overriden, otherwise the actors will perish!
    # @see #after_initialize
    #
    def initialize
      self.class.scene_actors.each do |scene_actor|
        actor_data = { 'name' => scene_actor.name }.merge (view[scene_actor.name] || {})
        actor_instance = scene_actor.create(actor_data)
        actor_instance.scene = self
        send "#{scene_actor.name}=", actor_instance
      end

      after_initialize
    end

    #
    # The window is the main instance of the game. Using window can access a lot of
    # underlying Metro::Window, a subclass of Gosu::Window, that the Scene class is
    # obfuscating.
    #
    # @see Metro::Window
    # @see Gosu::Window
    #
    attr_reader :window

    #
    # Setting the window places the scene within in the specified window. Which
    # will cause a number of variables and settings to be set up. The {#show}
    # method is called after the window has been set.
    #
    def window=(window)
      @window = window

      @event_relays = []

      @scene_events = EventRelay.new(self,window)
      events(@scene_events)

      @event_relays << @scene_events

      @updaters = []

      @drawers = []

      self.class.scene_actors.each do |scene_actor|
        actor = send(scene_actor.name)
        actor.window = window
        @drawers << actor
      end

      show
    end

    #
    # Allows you to set or retrieve the scene name for the Scene.
    #
    # @example Retrieving the default scene name
    #
    #     class ExampleScene
    #       def show
    #         puts "Showing Scene: #{self.class.scene_name}"
    #       end
    #     end
    #
    #     ExampleScene.scene_name
    #
    # @example Setting a custom name for the Scene
    #
    #     class RollingCreditsScene
    #       scene_name "credits"
    #     end
    #
    # @param [String] scene_name when specified it will set the scene name for the class
    #   to the value specified.
    #
    # @return the String name of the scene which it can be used as a reference for transitioning
    #   or for generating the appropriate view information.
    #
    def self.scene_name(scene_name=nil)
      @scene_name ||= begin
        root_name = to_s[/^(.+)Scene$/,1]
        root_name.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
        root_name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
        root_name.downcase!
        root_name
      end

      scene_name ? @scene_name = scene_name.to_s : @scene_name
    end

    #
    # @return the string representation of a scene, this is used for debugging.
    #
    def to_s<commit_msg>FIX: Scenes without Scene suffix will work again<commit_after>require_relative 'scene_view/scene_view'
require_relative 'scene_actor'
require_relative 'event_relay'
require_relative 'animation/animation'

module Metro

  #
  # A scene is a basic unit of a game. Within a scene you define a number of methods
  # that handle the initial setup, event configuration, logic updating, and drawing.
  #
  # @see #show
  # @see #update
  # @see #draw
  # @see #events
  #
  # A fair number of private methods within Scene are prefaced with an underscore.
  # These methods often call non-underscored methods within those methods. This allows
  # for scene to configure or perform some functionality, while providing an interface
  # so that every subclass does not have to constantly call `super`.
  #
  class Scene

    #
    # As Scene does a lot of work for you with regarding to setting up content, it is
    # best not to override #initialize and instead define an #after_initialize method
    # within the subclasses of Scene.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def after_initialize ; end

    #
    # The events method is where a scene has access to configure the events that it
    # would like to listen for during the scene.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    # @param [EventRelay] e is the EventRelay that you can register for button up,
    #   button down, or button held events.
    #
    # @see EventRelay
    #
    def events(e) ; end

    #
    # This method is called right after the scene has been adopted by the window
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def show ; end

    #
    # This is called every update interval while the window is being shown.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def update ; end

    #
    # This is called after every {#update} and when the OS wants the window to
    # repaint itself.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    def draw ; end

    #
    # Before a scene is transisitioned away from to a new scene, this method is called
    # to allow for the scene to complete any taskss, stop any actions, or pass any
    # information from the existing scene to the scene that is about to replace it.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    # @param [Scene] new_scene this is the instance of the scene that is about to replace
    #   the current scene.
    #
    def prepare_transition_to(new_scene) ; end

    #
    # Before a scene is transisitioned to it is called with the previous scene. This
    # allows for the new scene to rerieve any data from the previous scene to assist
    # with the layout of the current scene.
    #
    # @note This method should be implemented in the Scene subclass.
    #
    # @param [Scene] old_scene this is the instance of the scene that is being moved
    #   away from.
    #
    def prepare_transition_from(old_scene) ; end


    #
    # Define a scene actor with the given name and options.
    #
    def self.draw(actor_name,options = {})
      scene_actor = SceneActor.new actor_name, options

      define_method actor_name do
        instance_variable_get("@#{actor_name}")
      end

      define_method "#{actor_name}=" do |value|
        instance_variable_set("@#{actor_name}",value)
      end

      scene_actors.push scene_actor
    end

    #
    # Define several standard scene actors.
    #
    def self.draws(*actor_names)
      actor_names = actor_names.flatten.compact

      actor_names.each do |actor_name|
        draw actor_name
      end

      scene_actors
    end

    #
    # @return a list of all the SceneActors that have been defined for this Scene.
    #
    def self.scene_actors
      @scene_actors ||= []
    end

    #
    # Setups up the Actors for the Scene based on the SceneActors that have been
    # defined.
    #
    # @note this method should not be overriden, otherwise the actors will perish!
    # @see #after_initialize
    #
    def initialize
      self.class.scene_actors.each do |scene_actor|
        actor_data = { 'name' => scene_actor.name }.merge (view[scene_actor.name] || {})
        actor_instance = scene_actor.create(actor_data)
        actor_instance.scene = self
        send "#{scene_actor.name}=", actor_instance
      end

      after_initialize
    end

    #
    # The window is the main instance of the game. Using window can access a lot of
    # underlying Metro::Window, a subclass of Gosu::Window, that the Scene class is
    # obfuscating.
    #
    # @see Metro::Window
    # @see Gosu::Window
    #
    attr_reader :window

    #
    # Setting the window places the scene within in the specified window. Which
    # will cause a number of variables and settings to be set up. The {#show}
    # method is called after the window has been set.
    #
    def window=(window)
      @window = window

      @event_relays = []

      @scene_events = EventRelay.new(self,window)
      events(@scene_events)

      @event_relays << @scene_events

      @updaters = []

      @drawers = []

      self.class.scene_actors.each do |scene_actor|
        actor = send(scene_actor.name)
        actor.window = window
        @drawers << actor
      end

      show
    end

    #
    # Allows you to set or retrieve the scene name for the Scene.
    #
    # @example Retrieving the default scene name
    #
    #     class ExampleScene
    #       def show
    #         puts "Showing Scene: #{self.class.scene_name}"
    #       end
    #     end
    #
    #     ExampleScene.scene_name
    #
    # @example Setting a custom name for the Scene
    #
    #     class RollingCreditsScene
    #       scene_name "credits"
    #     end
    #
    # @param [String] scene_name when specified it will set the scene name for the class
    #   to the value specified.
    #
    # @return the String name of the scene which it can be used as a reference for transitioning
    #   or for generating the appropriate view information.
    #
    def self.scene_name(scene_name=nil)
      @scene_name ||= begin
        root_name = to_s.gsub(/Scene$/,'')
        root_name.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
        root_name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
        root_name.downcase!
        root_name
      end

      scene_name ? @scene_name = scene_name.to_s : @scene_name
    end

    #
    # @return the string representation of a scene, this is used for debugging.
    #
    def to_s
{'fraction_non_alphanumeric': 0.07266252462494317, 'fraction_numerical': 0.0006819215032580694, 'mean_word_length': 2.435450286309214, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '721912', 'n_tokens_mistral': 3892, 'n_tokens_neox': 3748, 'n_words': 1488}