callbacks_attachable 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +41 -60
- data/callbacks_attachable.gemspec +2 -3
- data/lib/callbacks_attachable.rb +1 -2
- data/mrbgem.rake +2 -3
- data/mrblib/callback.rb +27 -0
- data/mrblib/callback_registry.rb +12 -29
- data/mrblib/callbacks_attachable.rb +21 -48
- data/mrblib/version.rb +1 -1
- metadata +5 -7
- data/mrblib/all_instances_callback.rb +0 -16
- data/mrblib/instance_callback.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3cbb8d4bd7ce32583ce955de64c50b6c573df8
|
4
|
+
data.tar.gz: 9f7a8fa43ff82a24fad63277df0a8966fff4bc9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04afd03c6c374d2cbd40052dafd3c92f9884d8a77303643aec0b91dec3a4655887e27d5d881d5eeb78419765313040cf2e658b6f2e842a33a82a92cf7cc228b6
|
7
|
+
data.tar.gz: 48e973e7699b8ead7d098afb8589b261cdf481340a757693a9e629ed4a9906fbe1c42df06349318f6d0f47c906319f5bdbbc9581e9925857a5344e38489cf4e4
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015
|
3
|
+
Copyright (c) 2015 - 2017 Christopher Aue
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
# CallbacksAttachable
|
2
2
|
|
3
|
-
Attach callbacks to
|
4
|
-
|
5
|
-
individual callbacks.
|
3
|
+
Attach callbacks to classes to be triggered for all instances or attach them
|
4
|
+
to an individual instance to be triggered only for this instance.
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
9
8
|
Add this line to your application's Gemfile:
|
10
9
|
|
11
10
|
```ruby
|
12
|
-
gem 'callbacks_attachable'
|
11
|
+
gem 'callbacks_attachable', '~> 2.0'
|
13
12
|
```
|
14
13
|
|
15
14
|
And then execute:
|
16
15
|
|
17
16
|
$ bundle
|
18
17
|
|
19
|
-
Or install it yourself
|
18
|
+
Or install it yourself:
|
20
19
|
|
21
20
|
$ gem install callbacks_attachable
|
22
21
|
|
@@ -32,90 +31,72 @@ end
|
|
32
31
|
|
33
32
|
### Callbacks attached to the class
|
34
33
|
|
35
|
-
Attach callbacks for an event
|
34
|
+
Attach callbacks for an event for all instances of a class with:
|
36
35
|
|
37
36
|
```ruby
|
38
|
-
callback = AClass.on(:event) do |method|
|
39
|
-
puts
|
37
|
+
callback = AClass.on(:event) do |instance, method|
|
38
|
+
puts instance.__send__(method)
|
40
39
|
end
|
41
|
-
```
|
42
40
|
|
43
|
-
|
44
|
-
|
41
|
+
instance0 = AClass.new(value: 0)
|
42
|
+
instance1 = AClass.new(value: 1)
|
45
43
|
|
46
|
-
|
47
|
-
|
44
|
+
AClass.trigger(:event, :value) # => 0
|
45
|
+
# 1
|
48
46
|
```
|
49
47
|
|
50
|
-
The
|
51
|
-
|
52
|
-
|
53
|
-
instances with `.trigger_for`:
|
54
|
-
|
55
|
-
```ruby
|
56
|
-
an_instance = AClass.new
|
57
|
-
AClass.trigger_for(an_instance, :event, :__id__)
|
58
|
-
# => puts the result of an_instance.__id__
|
59
|
-
```
|
48
|
+
The first argument of the callback is the instance the callback is executed
|
49
|
+
for. The second and further arguments given to `.trigger` are passed to the
|
50
|
+
callback as additional arguments.
|
60
51
|
|
61
|
-
|
62
|
-
|
52
|
+
Registering a callback returns a `Callback` object. To cancel the callback use
|
53
|
+
`#cancel` on that object.
|
63
54
|
|
64
55
|
```ruby
|
65
56
|
callback = AClass.on(:event) { do_something }
|
66
|
-
|
57
|
+
callback.cancel
|
67
58
|
```
|
68
59
|
|
69
60
|
If you want to execute a callback just a single time attach it with `.once_on`:
|
70
61
|
|
71
62
|
```ruby
|
72
|
-
AClass.once_on(:
|
73
|
-
AClass.trigger(:
|
74
|
-
|
75
|
-
AClass.trigger(:
|
63
|
+
AClass.once_on(:singular) { puts 'callback called!' }
|
64
|
+
AClass.trigger(:singular) # => puts 'callback called!' and immediately
|
65
|
+
# detaches the callback
|
66
|
+
AClass.trigger(:singular) # => does nothing
|
76
67
|
```
|
77
68
|
|
78
|
-
To
|
79
|
-
will be detached if it has a truthy (!) return value.
|
69
|
+
To filter the instances to call the callback for, use the `:if` option:
|
80
70
|
|
81
71
|
```ruby
|
82
|
-
|
83
|
-
AClass.
|
84
|
-
|
85
|
-
|
72
|
+
instance0 = AClass.new(value: 0)
|
73
|
+
instance1 = AClass.new(value: 1)
|
74
|
+
instance2 = AClass.new(value: 2)
|
75
|
+
AClass.on(:even, if: proc{ |inst| inst.value.even? }) do |instance|
|
76
|
+
puts instance.value
|
86
77
|
end
|
87
78
|
|
88
|
-
AClass.trigger(:
|
89
|
-
|
90
|
-
AClass.trigger(:count_to_two) # => puts 2 and detaches the callback
|
91
|
-
AClass.trigger(:count_to_two) # => does nothing
|
79
|
+
AClass.trigger(:even) # => 0
|
80
|
+
# 2
|
92
81
|
```
|
93
82
|
|
83
|
+
This is especially useful in combination with `.once_on` to execute the
|
84
|
+
callback just for the first instance meeting certain criteria.
|
85
|
+
|
94
86
|
### Callbacks attached to an instance
|
95
87
|
|
96
88
|
All above mentioned methods on the class level also exist for each instance of
|
97
|
-
the class.
|
98
|
-
`#trigger` on it. They are also called, when calling `.trigger` or
|
99
|
-
`.trigger_for(instance, ...)` on its class.
|
89
|
+
the class.
|
100
90
|
|
101
|
-
Callbacks
|
102
|
-
|
91
|
+
Callbacks for an individual instance are executed by calling `#trigger` on it.
|
92
|
+
This also executes callbacks attached to the class.
|
103
93
|
|
104
94
|
```ruby
|
105
|
-
|
106
|
-
an_instance2 = AClass.new
|
107
|
-
|
108
|
-
callback1 = an_instance1.on(:event) { puts 'This is #1!' }
|
109
|
-
callback2 = an_instance2.on(:event) { puts 'This is #2!' }
|
110
|
-
|
111
|
-
an_instance1.trigger(:event) # => puts 'This is #1!'
|
112
|
-
an_instance2.trigger(:event) # => puts 'This is #2!'
|
95
|
+
instance = AClass.new
|
113
96
|
|
114
|
-
AClass.
|
115
|
-
|
116
|
-
an_instance1.off(:event, callback)
|
117
|
-
an_instance2.off(:event, callback)
|
118
|
-
```
|
97
|
+
AClass.on(:event) { puts 'class callback' }
|
98
|
+
instance.on(:event) { puts 'instance callback' }
|
119
99
|
|
120
|
-
|
121
|
-
|
100
|
+
instance.trigger(:event) # => 'class callback'
|
101
|
+
# 'instance callback'
|
102
|
+
```
|
@@ -6,9 +6,8 @@ Gem::Specification.new do |spec|
|
|
6
6
|
spec.version = CallbacksAttachable::VERSION
|
7
7
|
spec.summary = %q{Attach callbacks to classes or individual instances.}
|
8
8
|
spec.description = <<-DESC
|
9
|
-
Attach callbacks to
|
10
|
-
|
11
|
-
individual callbacks.
|
9
|
+
Attach callbacks to classes to be triggered for all instances or attach them
|
10
|
+
to an individual instance to be triggered only for this instance.
|
12
11
|
DESC
|
13
12
|
|
14
13
|
spec.homepage = "https://github.com/christopheraue/m-ruby-callbacks_attachable"
|
data/lib/callbacks_attachable.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require_relative "../mrblib/callbacks_attachable"
|
2
2
|
require_relative "../mrblib/version"
|
3
3
|
require_relative "../mrblib/callback_registry"
|
4
|
-
require_relative "../mrblib/
|
5
|
-
require_relative "../mrblib/all_instances_callback"
|
4
|
+
require_relative "../mrblib/callback"
|
data/mrbgem.rake
CHANGED
@@ -4,9 +4,8 @@ MRuby::Gem::Specification.new('mruby-callbacks_attachable') do |spec|
|
|
4
4
|
spec.version = CallbacksAttachable::VERSION
|
5
5
|
spec.summary = %q{Attach callbacks to classes or individual instances.}
|
6
6
|
spec.description = <<-DESC
|
7
|
-
Attach callbacks to
|
8
|
-
|
9
|
-
individual callbacks.
|
7
|
+
Attach callbacks to classes to be triggered for all instances or attach them
|
8
|
+
to an individual instance to be triggered only for this instance.
|
10
9
|
DESC
|
11
10
|
|
12
11
|
spec.homepage = "https://github.com/christopheraue/m-ruby-callbacks_attachable"
|
data/mrblib/callback.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module CallbacksAttachable
|
2
|
+
class Callback
|
3
|
+
def initialize(registry, event, opts = {}, callback)
|
4
|
+
@registry = registry
|
5
|
+
@event = event
|
6
|
+
@call_condition = opts.fetch(:if, false)
|
7
|
+
@cancel_condition = opts.fetch(:until, false)
|
8
|
+
@callback = callback
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(instance, args)
|
12
|
+
return if @call_condition and not @call_condition.call instance, *args
|
13
|
+
@callback.call(instance, *args)
|
14
|
+
cancel if @cancel_condition and @cancel_condition.call instance, *args
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_cancel(&on_cancel)
|
18
|
+
@on_cancel = on_cancel
|
19
|
+
end
|
20
|
+
|
21
|
+
def cancel
|
22
|
+
@registry.deregister @event, self
|
23
|
+
@on_cancel.call if @on_cancel
|
24
|
+
true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/mrblib/callback_registry.rb
CHANGED
@@ -1,45 +1,28 @@
|
|
1
1
|
module CallbacksAttachable
|
2
2
|
class CallbackRegistry
|
3
|
-
def initialize(
|
4
|
-
@
|
5
|
-
@callback_class = callback_class
|
3
|
+
def initialize(owner)
|
4
|
+
@owner = owner
|
6
5
|
@callbacks = {}
|
7
6
|
end
|
8
7
|
|
9
|
-
def
|
10
|
-
@callbacks[event] ||=
|
11
|
-
|
12
|
-
@callbacks[event]
|
8
|
+
def register(event, opts, callback)
|
9
|
+
@callbacks[event] ||= {}
|
10
|
+
callback = Callback.new(self, event, opts, callback)
|
11
|
+
@callbacks[event][callback] = true
|
12
|
+
callback
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
17
|
-
registered_callback = @object.on(event, *opts) do |*args|
|
18
|
-
callback_registry.off(event, registered_callback)
|
19
|
-
yield(*args)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def until_true_on(event, *opts, &callback)
|
24
|
-
callback_registry = self
|
25
|
-
registered_callback = @object.on(event, *opts) do |*args|
|
26
|
-
yield(*args).tap do |result|
|
27
|
-
callback_registry.off(event, registered_callback) if result
|
28
|
-
end
|
29
|
-
end
|
15
|
+
def registered?(event)
|
16
|
+
@callbacks.key? event
|
30
17
|
end
|
31
18
|
|
32
19
|
def trigger(instance, event, args)
|
33
|
-
|
34
|
-
|
35
|
-
# dup the callback list so that removing callbacks while iterating does
|
36
|
-
# still call all callbacks during map.
|
37
|
-
@callbacks[event].dup.all?{ |callback| callback.call(instance, args) }
|
20
|
+
@callbacks[event] and @callbacks[event].keys.each{ |callback| callback.call(instance, args) }
|
38
21
|
end
|
39
22
|
|
40
|
-
def
|
41
|
-
return unless @callbacks[event]
|
23
|
+
def deregister(event, callback)
|
42
24
|
@callbacks[event].delete(callback)
|
25
|
+
@callbacks.delete(event) if @callbacks[event].empty?
|
43
26
|
end
|
44
27
|
end
|
45
28
|
end
|
@@ -1,67 +1,40 @@
|
|
1
1
|
module CallbacksAttachable
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def on(*args, &block)
|
8
|
-
__callback_registry__.on(*args, &block)
|
2
|
+
module RegistryOwnable
|
3
|
+
def on(event, opts = {}, &callback)
|
4
|
+
__callbacks__.register(event, opts, callback)
|
9
5
|
end
|
10
|
-
alias on_event on
|
11
6
|
|
12
|
-
def once_on(
|
13
|
-
|
7
|
+
def once_on(event, opts = {}, &callback)
|
8
|
+
on(event, opts.merge(until: proc{ true }), &callback)
|
14
9
|
end
|
15
|
-
alias once_on_event once_on
|
16
10
|
|
17
|
-
def
|
18
|
-
|
19
|
-
end
|
20
|
-
alias until_true_on_event until_true_on
|
21
|
-
|
22
|
-
def off(*args)
|
23
|
-
__callback_registry__.off(*args)
|
24
|
-
end
|
25
|
-
alias off_event off
|
26
|
-
|
27
|
-
def trigger(event, *args)
|
28
|
-
ObjectSpace.each_object(self).all?{ |inst| inst.trigger(event, *args) }
|
11
|
+
def on?(event)
|
12
|
+
__callbacks__.registered? event
|
29
13
|
end
|
30
|
-
alias trigger_event trigger
|
31
14
|
|
32
|
-
def
|
33
|
-
@
|
15
|
+
private def __callbacks__
|
16
|
+
@__callbacks__ ||= CallbackRegistry.new(self)
|
34
17
|
end
|
35
18
|
end
|
36
19
|
|
37
|
-
|
38
|
-
__callback_registry__.on(*args, &block)
|
39
|
-
end
|
40
|
-
alias on_event on
|
20
|
+
include RegistryOwnable
|
41
21
|
|
42
|
-
def
|
43
|
-
|
22
|
+
def self.included(klass)
|
23
|
+
klass.extend ClassMethods
|
44
24
|
end
|
45
|
-
alias once_on_event once_on
|
46
25
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
alias until_true_on_event until_true_on
|
26
|
+
module ClassMethods
|
27
|
+
include RegistryOwnable
|
51
28
|
|
52
|
-
|
53
|
-
|
29
|
+
def trigger(event, *args)
|
30
|
+
ObjectSpace.each_object(self).all?{ |inst| inst.trigger(event, *args) }
|
31
|
+
end
|
54
32
|
end
|
55
|
-
alias off_event off
|
56
33
|
|
57
34
|
def trigger(event, *args)
|
58
|
-
self.class.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def __callback_registry__
|
65
|
-
@__callback_registry__ ||= CallbackRegistry.new(self, InstanceCallback)
|
35
|
+
@class_callbacks ||= self.class.__send__ :__callbacks__
|
36
|
+
@class_callbacks.trigger(self, event, args)
|
37
|
+
@__callbacks__ and @__callbacks__.trigger(self, event, args)
|
38
|
+
true
|
66
39
|
end
|
67
40
|
end
|
data/mrblib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: callbacks_attachable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Aue
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -53,9 +53,8 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.4'
|
55
55
|
description: |
|
56
|
-
Attach callbacks to
|
57
|
-
|
58
|
-
individual callbacks.
|
56
|
+
Attach callbacks to classes to be triggered for all instances or attach them
|
57
|
+
to an individual instance to be triggered only for this instance.
|
59
58
|
email:
|
60
59
|
- rubygems@christopheraue.net
|
61
60
|
executables: []
|
@@ -70,10 +69,9 @@ files:
|
|
70
69
|
- callbacks_attachable.gemspec
|
71
70
|
- lib/callbacks_attachable.rb
|
72
71
|
- mrbgem.rake
|
73
|
-
- mrblib/
|
72
|
+
- mrblib/callback.rb
|
74
73
|
- mrblib/callback_registry.rb
|
75
74
|
- mrblib/callbacks_attachable.rb
|
76
|
-
- mrblib/instance_callback.rb
|
77
75
|
- mrblib/version.rb
|
78
76
|
homepage: https://github.com/christopheraue/m-ruby-callbacks_attachable
|
79
77
|
licenses:
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module CallbacksAttachable
|
2
|
-
class AllInstancesCallback
|
3
|
-
def initialize(klass, opts = {}, &callback)
|
4
|
-
@class = klass
|
5
|
-
@skip = opts.fetch(:skip, 0)
|
6
|
-
@callback = callback
|
7
|
-
@call_counts = {}
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(instance, args)
|
11
|
-
@call_counts[instance.__id__] = @call_counts[instance.__id__].to_i + 1
|
12
|
-
return true if @call_counts[instance.__id__] <= @skip
|
13
|
-
false != instance.instance_exec(*args, &@callback)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/mrblib/instance_callback.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module CallbacksAttachable
|
2
|
-
class InstanceCallback
|
3
|
-
def initialize(instance, opts = {}, &callback)
|
4
|
-
@instance = instance
|
5
|
-
@skip = opts.fetch(:skip, 0)
|
6
|
-
@callback = callback
|
7
|
-
@call_count = 0
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(instance, args)
|
11
|
-
@call_count += 1
|
12
|
-
return true if @call_count <= @skip
|
13
|
-
@callback.call(*args) != false
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|