Class: Bridgetown::Signals

Inherits:
Signalize::Struct
  • Object
show all
Includes:
Enumerable
Defined in:
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



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

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

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

  super(key.to_sym)
end

Class Method Details

.signal_accessorObject



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

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



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

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

  send(key)
end

#[]=(key, value) ⇒ Object



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

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.



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

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



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

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

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


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

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