opal-async 1.1.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a38a4215b9b7cdde96a1e4d00c08c5940bd829c052281b93ba7286c31bab856a
4
- data.tar.gz: d329ce4369abd51128b468dc61fe26266fd96590688f55a6e2d934b631da831c
3
+ metadata.gz: bcf44d0cb1a3c702b3c60521a2e173b7a3824fd8a37e80cd0fb18d5c4e0ffc2c
4
+ data.tar.gz: 28e4364132c94e690752669a3211796ec2b3423314a0db4892348d92fb0beb46
5
5
  SHA512:
6
- metadata.gz: 7d2373f2972e5402a14523f2975d544a2ba0faa4a2e68e527e4d27c3b327d279b687cccdda0b80ec34389149c0fa6d418e8faa04d9fc4b68f8f0ae96b679e1d4
7
- data.tar.gz: 13b4c95d7c39c6f5d7a0497156e40f72fc01ae96f5e32707a09b230bc3c2e81d803aae4bfd94315f956b005b892855aacdf59670824b5de99e3aa15c530f36ff
6
+ metadata.gz: 695a85e00e549b7616d7bf120e8651d574c8d42cf58e4483fd7e0a7a36581942836457ad2bdb08a03232217f7bb92434a6fa75cbac217f5498e545186ae66430
7
+ data.tar.gz: e4a46e19095d1017f93574d52f40a47ff5dfd85b290ce0acb5a885e2500eec44813acdb2f3ea683ef6813711e0f8ccbb4c5beaae0969e3a908e0cb7bd51cf1ab
data/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Change Log
2
+
3
+ ## 1.4.0
4
+
5
+ - Drop `Array#cycle` and `Array#each` overrides and re-implement as `Array#async_cycle` and `Array#async_each`
6
+ - Asynchronous `Kernel#async_loop` alternative to `Kernel#loop`
7
+
8
+ ## 1.3.0
9
+
10
+ - Asynchronous `Array#each` method that is web browser event loop friendly
11
+ - `Thread#kill` and `Thread#stop` for partial-compatibility with Ruby `Thread`
12
+
13
+ ## 1.2.0
14
+
15
+ - Asynchronous `Array#cycle` method that is web browser event loop friendly
16
+
17
+ ## 1.1.1
18
+
19
+ - Added `Thread` class extension to enable using `Async::Task` as `Thread` in Opal
20
+
21
+ ## 1.1.0
22
+
23
+ - Initial version
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # Opal: Async
2
+ [![Gem Version](https://badge.fury.io/rb/opal-async.svg)](https://badge.fury.io/rb/opal-async)
2
3
 
3
4
  ## Installation
4
5
 
5
6
  Add this line to your application's Gemfile:
6
7
 
7
- gem 'opal-async', github: "ravenstine/opal-async
8
+ gem 'opal-async', '~> 1.3.0'
8
9
 
9
10
  And then execute:
10
11
 
@@ -14,12 +15,11 @@ Or install it yourself as:
14
15
 
15
16
  $ gem install opal-async
16
17
 
17
- Then require 'opal-async' in both your Opal code and your Opal compilation environment.
18
-
18
+ Then require 'opal-async' in both your [Opal](https://opalrb.com/) code and your Opal compilation environment.
19
19
 
20
20
  ## Usage
21
21
 
22
- #### Enumerator
22
+ ### Enumerator
23
23
 
24
24
  The enumerator provides iteration methods for any enumerable object. These methods are 'non-blocking', so other operations in the event loop can continue to be executed in between iterations. Beware, this is not faster than a normal blocking iteration; it is trading off performance for not blocking other operations you may want to have continue such as UI updates & camera frame capture. Very large arrays will take a long time to finish while the overhead may not be noticeable for smaller arrays. It is best to do some tests and assess whether the trade-off is balanced enough for your needs.
25
25
 
@@ -43,21 +43,21 @@ enumerator.map{|x| x + 2}.each_slice(3).each{|x| puts x}
43
43
  #=> [9,10,11]
44
44
  ```
45
45
 
46
- ##### Available enumerator methods:
46
+ #### Available enumerator methods:
47
47
  - each
48
48
  - map
49
49
  - each_slice
50
50
  - select
51
51
  - reject
52
52
 
53
- #### Task
53
+ ### Task
54
54
  A task contains code that will be added to the call stack of the event loop. The Enumerator uses tasks to run small chunks of code without blocking the event loop. A task can do the same things that a Timeout or an Interval can do but with some added features and optimizations.
55
55
 
56
56
  With no options provided, a task will be run immediately once the event loop comes back to it(if the environment supports this). If the environment does not support immediates, it will attempt to polyfill an immediate before falling back on a 0ms timeout.
57
57
 
58
- Example:
58
+ Example:
59
59
 
60
- ```
60
+ ```ruby
61
61
  Async::Task.new do
62
62
  puts "hello world"
63
63
  end
@@ -67,7 +67,7 @@ end
67
67
 
68
68
  By default, a task will only run once. To make a task repeat, set the option times to however many times you want the task to repeat. You can also have access to countup and countdown variables.
69
69
 
70
- ```
70
+ ```ruby
71
71
  Async::Task.new do times: 5 do |countup, countdown|
72
72
  puts countdown
73
73
  end
@@ -77,11 +77,11 @@ end
77
77
  #=> 3
78
78
  #=> 2
79
79
  #=> 1
80
- ```
80
+ ```
81
81
 
82
82
  To make a task repeat infinitely, set times to ```:infinite```, or repeat to ```true```. A countup will be provided but no countdown. You can also use ```:i``` for short.
83
83
 
84
- ```
84
+ ```ruby
85
85
  Async::Task.new times: :infinite do
86
86
  puts "forever"
87
87
  end
@@ -95,7 +95,7 @@ end
95
95
 
96
96
  The step option will determine how much you want your task to "step".
97
97
 
98
- ```
98
+ ```ruby
99
99
  Async::Task.new times: 10, step: 2 do |countup, countdown|
100
100
  puts countup
101
101
  end
@@ -109,15 +109,15 @@ end
109
109
 
110
110
  To set a delay time on your task, specify the delay option with the number of milliseconds you want the duration of the delay to be. This can also be done when you have set your task to repeat.
111
111
 
112
- ```
112
+ ```ruby
113
113
  Async::Task.new delay: 1000 do
114
114
  puts "this took 1 second"
115
- end
115
+ end
116
116
  ```
117
117
 
118
118
  The delay and steps of a task can be modified within the execution of the task. The following example will start out slow and increase in speed:
119
119
 
120
- ```
120
+ ```ruby
121
121
  task = Async::Task.new times: 5, delay: 5000 do |countup, countdown|
122
122
  puts countdown
123
123
  task.delay = task.delay - 1000
@@ -128,7 +128,7 @@ Tasks also have callbacks that can be performed on certain events.
128
128
 
129
129
  Here is an example of how to execute code after a repeating task has finished:
130
130
 
131
- ```
131
+ ```ruby
132
132
  task = Async::Task.new times: 3, delay: 1000 do |countup, countdown|
133
133
  puts countdown
134
134
  end
@@ -144,24 +144,101 @@ task.on_finish {puts "BOOM"}
144
144
  Other callbacks include ```on_start``` and ```on_stop```.
145
145
 
146
146
 
147
- #### Other Timers
147
+ ### Other Timers
148
148
 
149
- You can also timeouts and intervals specifically:
149
+ You can also set timeouts and intervals, specifically:
150
150
 
151
151
 
152
- ```
153
- Timeout.new 3000 do
152
+ ```ruby
153
+ Async::Timeout.new 3000 do
154
154
  puts "I just waited 3 seconds."
155
155
  end
156
156
  ```
157
157
 
158
- ```
159
- Interval.new 3000 do
158
+ ```ruby
159
+ Async::Interval.new 3000 do
160
160
  puts "I'm going to do this every 3 seconds."
161
161
  end
162
162
  ```
163
163
 
164
+ ### Ruby Extensions
165
+
166
+ [opal-async](https://rubygems.org/gems/opal-async) ships with some Opal Ruby extensions that enhance Ruby classes with asynchronous capabilities.
167
+
168
+ You may activate all the Ruby extensions via this require statement:
169
+
170
+ ```ruby
171
+ require 'async/ext'
172
+ ```
173
+
174
+ #### Thread
175
+
176
+ You may use the `Async::Task` class as a `Thread` class in Opal to perform asynchronous work with an extra `require` statement.
177
+
178
+ ```ruby
179
+ require 'async/ext/thread' # not needed if you called `require 'async/ext'`
180
+
181
+ Thread.new do
182
+ puts "hello world"
183
+ end
184
+ ```
185
+
186
+ #### Array
187
+
188
+ The follow `Array` methods have been added to work asynchronously via `Async::Task`:
189
+ - `Array#async_cycle`
190
+ - `Array#async_each`
191
+
192
+ This makes them not block the web browser event loop, thus allowing other tasks to update the DOM unhindered while running.
193
+
194
+ Example:
195
+
196
+ ```ruby
197
+ require 'async/ext/array' # not needed if you called `require 'async/ext'`
198
+
199
+ Async::Task.new do
200
+ [1,2,3,4].async_cycle do |n|
201
+ puts n
202
+ Async::Task.new do
203
+ # make a DOM update that is not blocked
204
+ end
205
+ sleep(1)
206
+ end
207
+ end
208
+ ```
209
+
210
+ #### Kernel
211
+
212
+ The follow `Kernel` method has been added to work asynchronously via `Async::Task`:
213
+ - `Array#async_loop`
214
+
215
+ This makes it not block the web browser event loop, thus allowing other tasks to update the DOM unhindered while running.
216
+
217
+ Example:
218
+
219
+ ```ruby
220
+ require 'async/ext/kernel' # not needed if you called `require 'async/ext'`
221
+
222
+ Async::Task.new do
223
+ async_loop do
224
+ Async::Task.new do
225
+ # make a DOM update that is not blocked
226
+ end
227
+ sleep(1)
228
+ end
229
+ end
230
+ ```
231
+
232
+ ## In The Wild
233
+
234
+ opal-async is currently used in:
235
+ - [Glimmer DSL for Opal](https://github.com/AndyObtiva/glimmer-dsl-opal)
236
+
237
+ ## Change Log
238
+
239
+ [CHANGELOG.md](CHANGELOG.md)
240
+
164
241
  ## Contributors
165
242
 
166
243
  - [Benjamin Titcomb](https://github.com/Ravenstine) (Creator and Main Contributor)
167
- - [Andy Maleh](https://github.com/AndyObtiva) (Gemifier)
244
+ - [Andy Maleh](https://github.com/AndyObtiva) (Gemifier and Maintainer)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.4.0
data/opal/async/ext.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'async/ext/thread'
2
+ require 'async/ext/array'
3
+ require 'async/ext/kernel'
@@ -0,0 +1,30 @@
1
+ require 'async/task'
2
+
3
+ class Array
4
+ def async_cycle(n=nil, &block)
5
+ array = self * n unless n.nil?
6
+ index = 0
7
+ looper = lambda do
8
+ if n.nil?
9
+ block.call(self[index])
10
+ index += 1
11
+ index = index % self.size
12
+ Async::Task.new(&looper)
13
+ else
14
+ block.call(array.shift)
15
+ Async::Task.new(&looper) unless array.empty?
16
+ end
17
+ end
18
+ Async::Task.new(&looper)
19
+ end
20
+
21
+ def async_each(&block)
22
+ array = self
23
+ index = 0
24
+ looper = lambda do
25
+ block.call(array.shift)
26
+ Async::Task.new(&looper) unless array.empty?
27
+ end
28
+ Async::Task.new(&looper)
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ require 'async/task'
2
+
3
+ module Kernel
4
+ def async_loop(&block)
5
+ looper = lambda do
6
+ block.call
7
+ Async::Task.new(&looper)
8
+ end
9
+ Async::Task.new(&looper)
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ require 'thread' # bring the thread compatibility class from Opal first
2
+
3
+ class Thread
4
+ def initialize(*args, &proc)
5
+ @async_task = Async::Task.new do
6
+ proc.call(*args)
7
+ end
8
+ end
9
+
10
+ def stop
11
+ @async_task.stop
12
+ end
13
+
14
+ def kill
15
+ @async_task.stop
16
+ end
17
+ end
data/opal/async/task.rb CHANGED
@@ -1,5 +1,23 @@
1
1
  module Async
2
2
  class Task
3
+ class << self
4
+ # returns general status of whether a task is running.
5
+ # Useful to code running in the task block to determine if it is running
6
+ # as part of a task or not and take special actions accordingly.
7
+ def started?
8
+ @@started = false unless defined? :@@started
9
+ @@started
10
+ end
11
+
12
+ def start
13
+ @@started = true
14
+ end
15
+
16
+ def stop
17
+ @@started = false
18
+ end
19
+ end
20
+
3
21
  attr_accessor :delay, :times
4
22
  def initialize options={}, &block
5
23
  @options = options
@@ -15,6 +33,7 @@ module Async
15
33
  @delay = @options[:delay] || 0
16
34
  @times = @options[:times]
17
35
  @proc = Proc.new do
36
+ self.class.start
18
37
  if @times
19
38
  if @times.is_a?(Fixnum)
20
39
  @block.call(@countup, @countdown)
@@ -34,6 +53,7 @@ module Async
34
53
  @block.call
35
54
  @stopped = true
36
55
  end
56
+ self.class.stop
37
57
  end
38
58
  end
39
59
 
@@ -110,9 +130,9 @@ module Async
110
130
  };
111
131
  var mc = new MessageChannel();
112
132
 
113
- mc.port1.onmessage = function(){
133
+ mc.port1.onmessage = function(){
114
134
  if (!#{stopped?}){
115
- task.apply(task)
135
+ task.apply(task)
116
136
  }
117
137
  };
118
138
  mc.port2.postMessage(null);
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-async
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravenstine
8
8
  - Andy Maleh
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-06-20 00:00:00.000000000 Z
12
+ date: 2021-08-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: opal
@@ -101,6 +101,20 @@ dependencies:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
+ - !ruby/object:Gem::Dependency
105
+ name: rake-tui
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
104
118
  description: Provides non-blocking tasks and enumerators for Opal.
105
119
  email:
106
120
  - benjamin@pixelstreetinc.com
@@ -108,9 +122,11 @@ email:
108
122
  executables: []
109
123
  extensions: []
110
124
  extra_rdoc_files:
125
+ - CHANGELOG.md
111
126
  - LICENSE.txt
112
127
  - README.md
113
128
  files:
129
+ - CHANGELOG.md
114
130
  - LICENSE.txt
115
131
  - README.md
116
132
  - VERSION
@@ -119,6 +135,10 @@ files:
119
135
  - opal/async.rb
120
136
  - opal/async/countdown.rb
121
137
  - opal/async/enumerator.rb
138
+ - opal/async/ext.rb
139
+ - opal/async/ext/array.rb
140
+ - opal/async/ext/kernel.rb
141
+ - opal/async/ext/thread.rb
122
142
  - opal/async/interval.rb
123
143
  - opal/async/task.rb
124
144
  - opal/async/timeout.rb
@@ -127,7 +147,7 @@ homepage: http://github.com/AndyObtiva/opal-async
127
147
  licenses:
128
148
  - MIT
129
149
  metadata: {}
130
- post_install_message:
150
+ post_install_message:
131
151
  rdoc_options:
132
152
  - "--main"
133
153
  - README
@@ -147,8 +167,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
167
  - !ruby/object:Gem::Version
148
168
  version: '0'
149
169
  requirements: []
150
- rubygems_version: 3.1.2
151
- signing_key:
170
+ rubygems_version: 3.1.4
171
+ signing_key:
152
172
  specification_version: 4
153
173
  summary: Provides non-blocking tasks and enumerators for Opal.
154
174
  test_files: []