Class: Scarpe::Webview::RelayDisplayService

Inherits:
Shoes::DisplayService show all
Includes:
Scarpe::WVRelayUtil, Shoes::Log
Defined in:
lib/scarpe/wv/webview_relay_display.rb

Overview

This display service creates a child process and sends events back and forth, but creates no drawables of its own. The child process will spawn a worker with its own Webview::DisplayService where the real Webview exists. By splitting the Webview process from the Shoes drawables, it can be easier to return control to Webview's event handler promptly. Also, the Ruby process could run background threads if it wanted, and otherwise behave like a process not containing Webview.

Constant Summary

Constants included from Shoes::Log

Shoes::Log::DEFAULT_COMPONENT, Shoes::Log::DEFAULT_DEBUG_LOG_CONFIG, Shoes::Log::DEFAULT_LOG_CONFIG

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Scarpe::WVRelayUtil

#event_loop_for, #ready_to_read?, #receive_datagram, #respond_to_datagram, #send_datagram

Methods included from Shoes::Log

configure_logger, #log_init, logger

Methods inherited from Shoes::DisplayService

dispatch_event, display_service, full_reset!, #query_display_drawable_for, set_display_service_class, #set_drawable_pairing, subscribe_to_event, unsub_from_events

Constructor Details

#initializeRelayDisplayService

Create a Webview Relay Display Service



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/scarpe/wv/webview_relay_display.rb', line 24

def initialize
  super()
  log_init("Webview::RelayDisplayService")

  @event_subs = []
  @shutdown = false
  @i_am = :parent

  server = TCPServer.new("127.0.0.1", 0)
  port = server.addr[1]

  @pid = spawn(RbConfig.ruby, File.join(__dir__, "wv_display_worker.rb"), port.to_s)
  @from = @to = server.accept

  # Subscribe to all event notifications and relay them to the worker
  @event_subs << bind_shoes_event(event_name: :any, target: :any) do |*args, **kwargs|
    unless kwargs[:relayed]
      kwargs[:relayed] = true
      send_datagram({ type: :event, args:, kwargs: })
    end

    # Forward the run event to the child process before doing this
    if event_name == "run"
      run_event_loop
    end
  rescue Scarpe::AppShutdownError
    @shutdown = true
    @log.info("Attempting to shut down...")
    self.destroy
  end
end

Instance Attribute Details

#shutdownObject

Returns the value of attribute shutdown.



21
22
23
# File 'lib/scarpe/wv/webview_relay_display.rb', line 21

def shutdown
  @shutdown
end

Instance Method Details

#create_display_drawable_for(drawable_class_name, drawable_id, properties) ⇒ Object

This method sends a message to the worker process to create a drawable. No actual drawable is created or registered with the display service.



70
71
72
73
# File 'lib/scarpe/wv/webview_relay_display.rb', line 70

def create_display_drawable_for(drawable_class_name, drawable_id, properties)
  send_datagram({ type: :create, class_name: drawable_class_name, id: drawable_id, properties: })
  # Don't need to return anything. It wouldn't be used anyway.
end

#destroyObject

Tell the worker process to quit, and set a flag telling the event loop to shut down.



76
77
78
79
80
81
82
# File 'lib/scarpe/wv/webview_relay_display.rb', line 76

def destroy
  unless @shutdown
    send_datagram({ type: :destroy })
  end
  @shutdown = true
  (@events_subs || []).each { |unsub_id| DisplayService.unsub_from_events(unsub_id) }
end

#run_event_loopObject

Run, sending and responding to datagrams continuously.



57
58
59
60
61
62
63
64
65
66
# File 'lib/scarpe/wv/webview_relay_display.rb', line 57

def run_event_loop
  until @shutdown
    respond_to_datagram while ready_to_read?
    sleep 0.1
  end
rescue Scarpe::AppShutdownError
  @shutdown = true
  @log.info("Attempting to shut down...")
  self.destroy
end