Class: Zui::StateStore
- Inherits:
-
Object
show all
- Defined in:
- lib/zui/state_store.rb
Instance Method Summary
collapse
Constructor Details
#initialize(on_change) ⇒ StateStore
Returns a new instance of StateStore.
5
6
7
8
9
10
11
|
# File 'lib/zui/state_store.rb', line 5
def initialize(on_change)
@values = {}
@on_change = on_change
@lock = Mutex.new
@transaction_depth = 0
@pending = {}
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *arguments) ⇒ Object
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/zui/state_store.rb', line 41
def method_missing(name, *arguments)
raw = name.to_s
if raw.end_with?("=")
raise ArgumentError, "expected one value" unless arguments.length == 1
return write(raw.delete_suffix("=").to_sym, arguments.first)
end
if arguments.empty?
found, value = @lock.synchronize { [@values.key?(name), @values[name]] }
return value if found
end
super
end
|
Instance Method Details
#[](name) ⇒ Object
21
22
23
|
# File 'lib/zui/state_store.rb', line 21
def [](name)
@lock.synchronize { @values.fetch(name.to_sym) }
end
|
#[]=(name, value) ⇒ Object
25
26
27
|
# File 'lib/zui/state_store.rb', line 25
def []=(name, value)
write(name.to_sym, value)
end
|
#define(name, initial) ⇒ Object
13
14
15
16
17
18
19
|
# File 'lib/zui/state_store.rb', line 13
def define(name, initial)
key = name.to_sym
@lock.synchronize do
raise ArgumentError, "state already defined: #{key}" if @values.key?(key)
@values[key] = initial
end
end
|
#respond_to_missing?(name, include_private = false) ⇒ Boolean
56
57
58
59
|
# File 'lib/zui/state_store.rb', line 56
def respond_to_missing?(name, include_private = false)
key = name.to_s.delete_suffix("=").to_sym
@lock.synchronize { @values.key?(key) } || super
end
|
#transaction ⇒ Object
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# File 'lib/zui/state_store.rb', line 61
def transaction
raise ArgumentError, "transaction requires a block" unless block_given?
@lock.synchronize { @transaction_depth += 1 }
yield self
ensure
changes = @lock.synchronize do
@transaction_depth -= 1
next [] unless @transaction_depth.zero?
flushed = @pending.values
@pending.clear
flushed
end
changes.each { |change| @on_change.call(*change) }
end
|
#update(name) ⇒ Object
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/zui/state_store.rb', line 29
def update(name)
raise ArgumentError, "update requires a block" unless block_given?
key = name.to_sym
change, value = @lock.synchronize do
raise NoMethodError, "unknown state: #{key}" unless @values.key?(key)
next_value = yield(@values[key])
[store_locked(key, next_value), next_value]
end
@on_change.call(*change) if change
value
end
|