Class: SFML::Network::SocketSelector

Inherits:
Object
  • Object
show all
Defined in:
lib/sfml/network/socket_selector.rb

Overview

Multiplex many sockets onto a single blocking #wait. Useful for one-thread network servers — register every socket / listener you care about, call #wait, then ask each one whether it’s ‘ready?`. Ready means there’s data to read or, for a listener, an incoming connection waiting.

selector = SFML::Network::SocketSelector.new
selector.add(listener)
clients.each { |c| selector.add(c) }

if selector.wait(timeout: 1.0)
  if selector.ready?(listener)
    # accept() will not block
  end
  clients.each do |c|
    next unless selector.ready?(c)
    # receive() will return data
  end
end

Ruby’s ‘IO.select` covers a similar use case for plain Ruby IO objects; this binding exists for game code that’s already using ‘SFML::Network::TcpSocket,Listener` / `UdpSocket`.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSocketSelector

Returns a new instance of SocketSelector.

Raises:



27
28
29
30
31
32
# File 'lib/sfml/network/socket_selector.rb', line 27

def initialize
  ptr = C::Network.sfSocketSelector_create
  raise Error, "sfSocketSelector_create returned NULL" if ptr.null?

  @handle = FFI::AutoPointer.new(ptr, C::Network.method(:sfSocketSelector_destroy))
end

Instance Attribute Details

#handleObject (readonly)

:nodoc:



90
91
92
# File 'lib/sfml/network/socket_selector.rb', line 90

def handle
  @handle
end

Instance Method Details

#add(socket) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/sfml/network/socket_selector.rb', line 34

def add(socket)
  case socket
  when TcpListener then C::Network.sfSocketSelector_addTcpListener(@handle, socket.handle)
  when TcpSocket   then C::Network.sfSocketSelector_addTcpSocket(@handle,  socket.handle)
  when UdpSocket   then C::Network.sfSocketSelector_addUdpSocket(@handle,  socket.handle)
  else
    raise ArgumentError,
          "SocketSelector#add expects TcpListener, TcpSocket, or UdpSocket (got #{socket.class})"
  end
  self
end

#clearObject



58
59
60
61
# File 'lib/sfml/network/socket_selector.rb', line 58

def clear
  C::Network.sfSocketSelector_clear(@handle)
  self
end

#ready?(socket) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
82
83
84
85
86
87
88
# File 'lib/sfml/network/socket_selector.rb', line 79

def ready?(socket)
  case socket
  when TcpListener then C::Network.sfSocketSelector_isTcpListenerReady(@handle, socket.handle)
  when TcpSocket   then C::Network.sfSocketSelector_isTcpSocketReady(@handle,  socket.handle)
  when UdpSocket   then C::Network.sfSocketSelector_isUdpSocketReady(@handle,  socket.handle)
  else
    raise ArgumentError,
          "SocketSelector#ready? expects TcpListener, TcpSocket, or UdpSocket (got #{socket.class})"
  end
end

#remove(socket) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/sfml/network/socket_selector.rb', line 46

def remove(socket)
  case socket
  when TcpListener then C::Network.sfSocketSelector_removeTcpListener(@handle, socket.handle)
  when TcpSocket   then C::Network.sfSocketSelector_removeTcpSocket(@handle,  socket.handle)
  when UdpSocket   then C::Network.sfSocketSelector_removeUdpSocket(@handle,  socket.handle)
  else
    raise ArgumentError,
          "SocketSelector#remove expects TcpListener, TcpSocket, or UdpSocket (got #{socket.class})"
  end
  self
end

#wait(timeout: nil) ⇒ Object

Block until at least one registered socket has activity, or ‘timeout` elapses. `timeout` may be a SFML::Time, a Numeric (seconds), or nil / SFML::Time.zero (no timeout — block forever). Returns true if a socket is ready, false on timeout.



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sfml/network/socket_selector.rb', line 67

def wait(timeout: nil)
  t =
    case timeout
    when nil     then SFML::Time.zero
    when Time    then timeout
    when Numeric then SFML::Time.seconds(timeout.to_f)
    else
      raise ArgumentError, "timeout must be SFML::Time, Numeric, or nil"
    end
  C::Network.sfSocketSelector_wait(@handle, t.to_native)
end