Sha256: 1c0ad8e3403564a6ef017ad2bd845b5620ebaeb621d26959a52381ede75d64e9

Contents?: true

Size: 1.67 KB

Versions: 2

Compression:

Stored size: 1.67 KB

Contents

# frozen_string_literal: true

module Gamefic
  module Scriptable
    # Functions that provide proxies for referencing a narrative's entities
    # from class-level scripts.
    #
    module Proxy
      # The object that fetches a proxied entity.
      #
      class Agent
        attr_reader :symbol

        # @param symbol [Symbol, Integer]
        def initialize symbol
          @symbol = symbol
        end

        def fetch container
          result = safe_fetch(container)
          raise ArgumentError, "Unable to fetch entity from proxy agent symbol `#{symbol}`" unless result

          result
        end

        private

        def safe_fetch container
          if symbol.to_s =~ /^\d+$/
            Stage.run(container, symbol) { |sym| entities[sym] }
          elsif symbol.to_s.start_with?('@')
            Stage.run(container, symbol) { |sym| instance_variable_get(sym) }
          else
            Stage.run(container, symbol) { |sym| send(sym) }
          end
        rescue NoMethodError
          nil
        end
      end

      # Proxy a method or instance variable.
      #
      # @example
      #   proxy(:method_name)
      #   proxy(:@instance_variable_name)
      #
      # @param symbol [Symbol]
      def proxy symbol
        Agent.new(symbol)
      end

      # @param object [Object]
      # @return [Object]
      def unproxy object
        case object
        when Agent
          object.fetch self
        when Array
          object.map { |obj| unproxy obj }
        when Hash
          object.transform_values { |val| unproxy val }
        else
          object
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
gamefic-3.2.1 lib/gamefic/scriptable/proxy.rb
gamefic-3.2.0 lib/gamefic/scriptable/proxy.rb