Class: Shoes::DisplayService

Inherits:
Object
  • Object
show all
Extended by:
Log
Defined in:
lacci/lib/shoes/display_service.rb

Constant Summary

Constants included from Log

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

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Log

configure_logger, log_init, logger

Constructor Details

#initializeDisplayService

Returns a new instance of DisplayService.



165
166
167
# File 'lacci/lib/shoes/display_service.rb', line 165

def initialize
  @display_drawable_for = {}
end

Class Method Details

.dispatch_event(event_name, event_target, *args, **kwargs) ⇒ void

This method returns an undefined value.

Send a Shoes event to all subscribers. An event_target may be nil, to indicate there is no target.

Parameters:

  • event_name (String)

    the name of the event

  • event_target (String)

    the specific target, if any

  • args (Array)

    arguments to pass to the subscribing block

  • args (Array)

    keyword arguments to pass to the subscribing block



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lacci/lib/shoes/display_service.rb', line 43

def dispatch_event(event_name, event_target, *args, **kwargs)
  @@display_event_handlers ||= {}

  unless @log
    log_init("DisplayService")
  end

  raise "Cannot dispatch on event_name :any!" if event_name == :any

  @log.debug("Dispatch event: #{event_name.inspect} T: #{event_target.inspect} A: #{args.inspect} KW: #{kwargs.inspect}")

  # When true, this makes sure all events and properties are 100% strings, no symbols.
  if ENV["SCARPE_DEBUG"]
    args = JSON.parse JSON.dump(args)
    new_kw = {}
    kwargs.each do |k, v|
      new_kw[k] = JSON.parse JSON.dump(v)
    end
    kwargs = new_kw
  end

  same_name_handlers = @@display_event_handlers[event_name] || {}
  any_name_handlers = @@display_event_handlers[:any] || {}

  # Do we have any keys, in same_name_handlers or any_name_handlers, matching the target or :any?
  # Note that "nil" is a target like any other for these purposes -- subscribing to a nil target
  # won't get you non-nil-target events and vice-versa.
  handlers = [
    same_name_handlers[:any],           # Same name, any target
    same_name_handlers[event_target],   # Same name, same target
    any_name_handlers[:any],            # Any name, any target
    any_name_handlers[event_target],    # Any name, same target
  ].compact.inject([], &:+)
  kwargs[:event_name] = event_name
  kwargs[:event_target] = event_target if event_target
  handlers.each { |h| h[:handler].call(*args, **kwargs) }
  nil
end

.display_serviceObject

Get the current display service instance. This requires a display service class having been set first. @see set_display_service_class



156
157
158
159
160
161
162
# File 'lacci/lib/shoes/display_service.rb', line 156

def display_service
  return @service if @service

  raise "No display service was set!" unless @display_service_klass

  @service = @display_service_klass.new
end

.full_reset!void

This method returns an undefined value.

Reset the display service, for instance between unit tests. This destroys all existing subscriptions.



134
135
136
137
# File 'lacci/lib/shoes/display_service.rb', line 134

def full_reset!
  @@display_event_handlers = {}
  @json_debug_serialize = nil
end

.set_display_service_class(klass) ⇒ Object

Set the Display Service class which will handle display service functions for this process. This can only be set once. The display service can be a subclass of Shoes::DisplayService, but isn't required to be.

Shoes will create an instance of this class with no arguments passed to initialize, and use it as the display service for the lifetime of the process.

Parameters:

  • klass (Class)

    the class for the display service



148
149
150
151
152
# File 'lacci/lib/shoes/display_service.rb', line 148

def set_display_service_class(klass)
  raise "Can only set a single display service class!" if @display_service_klass

  @display_service_klass = klass
end

.subscribe_to_event(event_name, event_target, &handler) ⇒ Integer

Subscribe to the given event name and target. It's permitted to subscribe to event_name :any for all event names, and event_target :any for all targets. An event_target of nil means "no target", and only matches events dispatched with a nil target. The subscription will return an unsubscribe ID, which can be used later to unsubscribe from the notification.

Parameters:

  • event_name (String, Symbol)

    the event name to subscribe to, or :any for all event names

  • event_target (String, Symbol, NilClass)

    the event target to subscribe to, or :any for all targets - nil is a valid target

Returns:

  • (Integer)

    an unsubscription ID which can be used later to cancel the subscription



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lacci/lib/shoes/display_service.rb', line 93

def subscribe_to_event(event_name, event_target, &handler)
  @@display_event_handlers ||= {}
  @@display_event_unsub_id ||= 0
  unless handler
    raise "Must pass a block as a handler to DisplayService.subscribe_to_event!"
  end

  unless @log
    log_init("DisplayService")
  end

  @log.debug("Subscribe to event: #{event_name.inspect} T: #{event_target.inspect}")

  id = @@display_event_unsub_id
  @@display_event_unsub_id += 1

  @@display_event_handlers[event_name] ||= {}
  @@display_event_handlers[event_name][event_target] ||= []
  @@display_event_handlers[event_name][event_target] << { handler:, unsub_id: id }

  id
end

.unsub_from_events(unsub_id) ⇒ void

This method returns an undefined value.

Unsubscribe from any event subscriptions matching the unsub ID.

Parameters:

  • unsub_id (Integer)

    the unsub ID returned when subscribing



120
121
122
123
124
125
126
127
128
# File 'lacci/lib/shoes/display_service.rb', line 120

def unsub_from_events(unsub_id)
  raise "Must provide an unsubscribe ID!" if unsub_id.nil?

  @@display_event_handlers.each do |_e_name, target_hash|
    target_hash.each do |_target, h_list|
      h_list.delete_if { |item| item[:unsub_id] == unsub_id }
    end
  end
end

Instance Method Details

#create_display_drawable_for(drawable_class_name, drawable_id, properties, parent_id:, is_widget:) ⇒ Object

These methods are an interface to DisplayService objects.



171
172
173
# File 'lacci/lib/shoes/display_service.rb', line 171

def create_display_drawable_for(drawable_class_name, drawable_id, properties, parent_id:, is_widget:)
  raise "Override in DisplayService implementation!"
end

#destroyObject



199
200
201
# File 'lacci/lib/shoes/display_service.rb', line 199

def destroy
  raise "Override in DisplayService implementation!"
end

#query_display_drawable_for(id, nil_ok: false) ⇒ Object



189
190
191
192
193
194
195
196
197
# File 'lacci/lib/shoes/display_service.rb', line 189

def query_display_drawable_for(id, nil_ok: false)
  @display_drawable_for ||= {}
  display_drawable = @display_drawable_for[id]
  unless display_drawable || nil_ok
    raise "Could not find display drawable for linkable ID #{id.inspect}!"
  end

  display_drawable
end

#set_drawable_pairing(id, display_drawable) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lacci/lib/shoes/display_service.rb', line 175

def set_drawable_pairing(id, display_drawable)
  if id.nil?
    raise Shoes::Errors::BadLinkableIdError, "Linkable ID may not be nil!"
  end

  @display_drawable_for ||= {}
  if @display_drawable_for[id]
    raise Shoes::Errors::DuplicateCreateDrawableError, "There is already a drawable for #{id.inspect}! Not setting a new one."
  end

  @display_drawable_for[id] = display_drawable
  nil
end