Class: Bridgetown::Signals

Inherits:
Signalize::Struct
  • Object
show all
Includes:
Enumerable
Defined in:
bridgetown-core/lib/bridgetown-core/signals.rb

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(key, *value, &block) ⇒ Object

rubocop:disable Style/MissingRespondToMissing



55
56
57
58
59
60
61
62
# File 'bridgetown-core/lib/bridgetown-core/signals.rb', line 55

def method_missing(key, *value, &block) # rubocop:disable Style/MissingRespondToMissing
  return nil if value.empty? && block.nil?

  key = key.to_s
  return self[key.chop] = value[0] if key.end_with?("=")

  super(key.to_sym)
end

Class Method Details

.signal_accessorObject



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'bridgetown-core/lib/bridgetown-core/signals.rb', line 11

def self.signal_accessor(...)
  super

  return unless members.include?(:members)

  # So…we need to support site data that could have a `members` key. This is how we do it:
  # by conditionally providing the value the gem class expects when it's gem code, otherwise we
  # provide the `members` signal value.
  define_method :members do
    if caller_locations(1..1).first.path.end_with?("/lib/signalize/struct.rb")
      self.class.members
    else
      members_signal.value
    end
  end
end

Instance Method Details

#[](key) ⇒ Object



36
37
38
39
40
# File 'bridgetown-core/lib/bridgetown-core/signals.rb', line 36

def [](key)
  return unless key?(key)

  send(key)
end

#[]=(key, value) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
# File 'bridgetown-core/lib/bridgetown-core/signals.rb', line 42

def []=(key, value)
  unless key?(key)
    if instance_of?(Bridgetown::Signals)
      raise Bridgetown::Errors::FatalException,
            "You must use a unique subclass of `Bridgetown::Signals' before adding new members"
    end

    self.class.signal_accessor(key)
  end

  send(:"#{key}=", value)
end

#batch_mutationsObject

You can access signals and mutate objects (aka push to an array, change a hash value), and by making those changes with a block, this method will track which signals were accessed and resave them with duplicated objects thereby triggering new dependent effects or subscriptions.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'bridgetown-core/lib/bridgetown-core/signals.rb', line 67

def batch_mutations
  ef = Signalize.effect { yield self }
  node = ef.receiver._sources
  deps = []
  while node
    deps << node._source
    node = node._next_source
  end

  ef.() # dispose

  Signalize.batch do
    self.class.members.each do |member_name|
      matching_dep = deps.find { _1 == send(:"#{member_name}_signal") }
      next unless matching_dep

      Signalize.batch do
        new_value = matching_dep.value.dup
        matching_dep.value = nil
        matching_dep.value = new_value
      end
    end
  end

  nil
end

#eachObject



28
29
30
# File 'bridgetown-core/lib/bridgetown-core/signals.rb', line 28

def each(...)
  to_h.each(...)
end

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
# File 'bridgetown-core/lib/bridgetown-core/signals.rb', line 32

def key?(key)
  self.class.members.include?(key.to_sym)
end