Module: Plaything::OpenAL

Extended by:
FFI::Library
Defined in:
lib/plaything/openal.rb,
lib/plaything/objects/buffer.rb,
lib/plaything/objects/device.rb,
lib/plaything/objects/source.rb,
lib/plaything/objects/context.rb,
lib/plaything/support/paramable.rb,
lib/plaything/support/type_class.rb,
lib/plaything/support/managed_pointer.rb

Defined Under Namespace

Classes: Buffer, Context, Device, ManagedPointer, Source

Constant Summary collapse

Error =

Errors

Class.new(StandardError)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.attach_function(c_name, params, returns, options = {}) ⇒ Object

Overridden for three purposes.

  1. Allows us to only supply OpenAL name, and converts it to snake_case for attaching the function.

  2. Wraps the call in an error-raise checker.

  3. Creates a bang method that does not do automatic error checking.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/plaything/openal.rb', line 32

def self.attach_function(c_name, params, returns, options = {})
  ruby_name = c_name
    .to_s
    .sub(/\Aalc?/, "")
    .gsub(/(?<!\A)\p{Lu}/u, '_\0')
    .downcase
  bang_name = "#{ruby_name}!"
  error_method = :"#{c_name.to_s[/\Aalc?/, 0]}GetError"

  super(ruby_name, c_name, params, returns, options)
  alias_method(bang_name, ruby_name)

  define_method(ruby_name) do |*args, &block|
    public_send(error_method) # clear error
    public_send(bang_name, *args, &block).tap do
      error = public_send(error_method) # clear error
      unless error == :no_error
        raise Error, "#{ruby_name} failed with #{error}"
      end
    end
  end

  module_function ruby_name
  module_function bang_name
end

.Paramable(type) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/plaything/support/paramable.rb', line 3

def self.Paramable(type)
  Module.new do
    define_method(:al_type) do
      type
    end

    def set(parameter, value)
      type = if value.is_a?(Integer)
        OpenAL.public_send(:"#{al_type}i", self, parameter, value)
      elsif value.is_a?(Float)
        OpenAL.public_send(:"#{al_type}f", self, parameter, value)
      else
        raise TypeError, "invalid type of #{value}, must be int or float"
      end
    end

    def get(parameter, type = :enum)
      name = if type == Integer
        :i
      elsif type == Float
        :f
      elsif type == :enum
        :i
      else
        raise TypeError, "unknown type #{type}"
      end

      reader = { f: :float, i: :int }.fetch(name)

      FFI::MemoryPointer.new(reader) do |ptr|
        OpenAL.public_send(:"get_#{al_type}#{name}", self, parameter, ptr)
        value = ptr.public_send(:"read_#{reader}")
        value = OpenAL.enum_type(:parameter)[value] if type == :enum
        return value
      end
    end
  end
end

.TypeClass(type) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/plaything/support/type_class.rb', line 3

def self.TypeClass(type)
  Class.new do
    extend FFI::DataConverter

    define_singleton_method(:type) do
      type
    end

    class << self
      def inherited(other)
        other.native_type(type)
      end

      def to_native(source, ctx)
        source.value
      end

      def from_native(value, ctx)
        new(value)
      end

      def size
        type.size
      end
    end

    def initialize(value)
      @value = value
    end

    def ==(other)
      other.is_a?(self.class) and other.value == value
    end

    def to_native
      self.class.to_native(self, nil)
    end

    attr_reader :value
  end
end

Instance Method Details

#alBufferiObject

Sources



154
# File 'lib/plaything/openal.rb', line 154

attach_function :alBufferi, [ Buffer, :parameter, :int ], :void

#alGetEnumValueObject

Utility



144
# File 'lib/plaything/openal.rb', line 144

attach_function :alGetEnumValue, [ :string ], :int

#alListenerfObject

Listeners



147
# File 'lib/plaything/openal.rb', line 147

attach_function :alListenerf, [ :parameter, :float ], :void

#alSourceiObject

Sources



150
# File 'lib/plaything/openal.rb', line 150

attach_function :alSourcei, [ Source, :parameter, :int ], :void