Class: RbSDL2::RWOps

Inherits:
Object
  • Object
show all
Defined in:
lib/rb_sdl2/rw_ops/rw_ops.rb,
lib/rb_sdl2/rw_ops/rw_ops_pointer.rb

Direct Known Subclasses

RWFile, RWMemory, RWObject

Defined Under Namespace

Classes: RWOpsPointer

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ptr) ⇒ RWOps

Returns a new instance of RWOps.



21
22
23
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 21

def initialize(ptr)
  @ptr = ptr
end

Class Method Details

.openObject



8
9
10
11
12
13
14
15
16
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 8

def open(...)
  rw = new(...)
  return rw unless block_given?
  begin
    yield(rw)
  ensure
    rw.close
  end
end

Instance Method Details

#closeObject

close 呼び出しの結果によらずポインターは開放されます。 継承先のクラスは close をオーバーライドしてポインターを適切に扱う必要があります。



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 27

def close
  # SDL_RWclose は必ずポインターを開放する。二重開放を防ぐ。
  unless closed?
    # クローズ処理は @ptr 先にあるメンバーの close 関数内あるため、SDL_RWclose() を呼ぶ。
    err = ::SDL.RWclose(@ptr)
    raise RbSDL2Error if err < 0
  end
rescue => e
  # Ruby IO と同じように例外を出さない。デバッグモードでは例外を出す。
  raise e if $DEBUG
ensure
  # ポインターは開放済みのためファイナライザーを停止させる。
  @ptr.autorelease = false
  @ptr = nil
end

#closed?Boolean

Returns:

  • (Boolean)


43
44
45
46
47
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 43

def closed?
  # @ptr があるのに autorelease? が false の場合はポインターが Ruby の外に渡されているだろう。
  # この場合をクローズされたと判断する。
  !@ptr&.autorelease?
end

#pos=(n) ⇒ Object



49
50
51
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 49

def pos=(n)
  seek(n, IO::SEEK_SET)
end

#read(length = nil) ⇒ Object

Raises:

  • (IOError)


53
54
55
56
57
58
59
60
61
62
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 53

def read(length = nil)
  raise IOError if closed?
  len = length.nil? ? size - tell : length
  raise ArgumentError if len < 0
  return "" if len == 0
  ptr = ::FFI::MemoryPointer.new(len)
  num = ::SDL.RWread(@ptr, ptr, 1, len)
  raise RbSDL2Error if num == 0
  ptr.read_bytes(num)
end

#seek(offset, whence = IO::SEEK_SET) ⇒ Object

Raises:

  • (IOError)


64
65
66
67
68
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 64

def seek(offset, whence = IO::SEEK_SET)
  raise IOError if closed?
  raise RbSDL2Error if ::SDL.RWseek(@ptr, offset, whence) == -1
  0
end

#sizeObject

Raises:

  • (IOError)


70
71
72
73
74
75
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 70

def size
  raise IOError if closed?
  num = ::SDL.RWsize(@ptr)
  raise RbSDL2Error if num < 0
  num
end

#tellObject Also known as: pos

Raises:

  • (IOError)


77
78
79
80
81
82
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 77

def tell
  raise IOError if closed?
  num = ::SDL.RWtell(@ptr)
  raise RbSDL2Error if num == -1
  num
end

#to_ptrObject

close メソッドを呼び出した後、インスタンスからポインターを取り出すことはできません。

Raises:

  • (TypeError)


86
87
88
89
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 86

def to_ptr
  raise TypeError if closed?
  @ptr
end

#write(*str) ⇒ Object

Raises:

  • (FrozenError)


91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/rb_sdl2/rw_ops/rw_ops.rb', line 91

def write(*str)
  raise FrozenError if frozen?
  raise IOError if closed?
  str.inject(0) do |sum, obj|
    bytes = obj.to_s
    len = bytes.size
    ptr = ::FFI::MemoryPointer.new(len).write_bytes(bytes)
    num = ::SDL.RWwrite(@ptr, ptr, 1, len)
    raise RbSDL2Error if num < len
    sum + len
  end
end