Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 676 lines (516 sloc) 16.087 kb
1ef50bd @mattetti prepped for release
authored
1 # BubbleWrap for RubyMotion
2
b0df1d4 @mattetti updated the README
authored
3 A collection of (tested) helpers and wrappers used to wrap CocoaTouch code and provide more Ruby like APIs.
4
5 [BubbleWrap website](http://bubblewrap.io)
68252d8 @mattetti added the mailing list to the README
authored
6 [BubbleWrap mailing list](https://groups.google.com/forum/#!forum/bubblewrap)
1ef50bd @mattetti prepped for release
authored
7
7952f8b @siuying update README with gem installation
siuying authored
8 ## Installation
afdd51c @siuying add "Getting Started" to README
siuying authored
9
1d986e5 @siuying ruby highlight code
siuying authored
10 ```ruby
7952f8b @siuying update README with gem installation
siuying authored
11 gem install bubble-wrap
1d986e5 @siuying ruby highlight code
siuying authored
12 ```
afdd51c @siuying add "Getting Started" to README
siuying authored
13
68428d9 @siuying minor fix README format
siuying authored
14 ## Setup
afdd51c @siuying add "Getting Started" to README
siuying authored
15
1d169dd @jamesotron Update readme.
jamesotron authored
16 1. Edit the `Rakefile` of your RubyMotion project and add the following require line:
930d8c7 @supermarin fixed the require codeblock
supermarin authored
17
1d986e5 @siuying ruby highlight code
siuying authored
18 ```ruby
7952f8b @siuying update README with gem installation
siuying authored
19 require 'bubble-wrap'
20 ```
afd071b @jamesotron Update documentation.
jamesotron authored
21
6c6a671 @mattetti updated the README
authored
22 BubbleWrap is split into multiple modules so that you can easily choose which parts
1d169dd @jamesotron Update readme.
jamesotron authored
23 are included at compile-time.
afd071b @jamesotron Update documentation.
jamesotron authored
24
1d169dd @jamesotron Update readme.
jamesotron authored
25 The above example requires the `core` and `http` modules. If you wish to only
6c6a671 @mattetti updated the README
authored
26 include the core modules use the following line of code instead:
6656d8d @siuying revise README sources
siuying authored
27
4fa50bd @siuying minor README update
siuying authored
28 ```ruby
6c6a671 @mattetti updated the README
authored
29 require 'bubble-wrap/core'
4fa50bd @siuying minor README update
siuying authored
30 ```
d2f1002 @mattetti Update README.md
authored
31
6c6a671 @mattetti updated the README
authored
32 If you wish to only include the `HTTP` wrapper:
afdd51c @siuying add "Getting Started" to README
siuying authored
33
afd071b @jamesotron Update documentation.
jamesotron authored
34 ```ruby
35 require 'bubble-wrap/http'
36 ```
37
319e8ef @mattetti finished the rss parser internal cleanup and added a loader
authored
38 If you wish to only include the `RSS Parser` wrapper:
39
40 ```ruby
41 require 'bubble-wrap/rss_parser'
42 ```
1ef50bd @mattetti prepped for release
authored
43
1d169dd @jamesotron Update readme.
jamesotron authored
44 If you wish to only include the `Reactor` wrapper:
45
46 ```ruby
47 require 'bubble-wrap/reactor'
48 ```
49
2de8b44 @clayallsopp create a 'bubble-wrap/ui' requirement for all the UI-related wrappers
clayallsopp authored
50 If you wish to only include the UI-related wrappers:
51
52 ```ruby
53 require 'bubble-wrap/ui'
54 ```
55
79e5bcb @clayallsopp update README
clayallsopp authored
56 If you wish to only include the `Camera` wrapper:
57
58 ```ruby
59 require 'bubble-wrap/camera'
60 ```
61
8c01048 @clayallsopp update README
clayallsopp authored
62 If you wish to only include the `Location` wrapper:
63
64 ```ruby
65 require 'bubble-wrap/location'
66 ```
67
2faf6c3 @clayallsopp Add `BubbleWrap::Media` and 'bubble-wrap/media'
clayallsopp authored
68 If you wish to only include the `Media` wrapper:
69
70 ```ruby
71 require 'bubble-wrap/media'
72 ```
73
1d169dd @jamesotron Update readme.
jamesotron authored
74 If you want to include everything (ie kitchen sink mode) you can save time and do:
75
76 ```ruby
77 require 'bubble-wrap/all'
78 ```
79
80
6c6a671 @mattetti updated the README
authored
81 Note: **DON'T** use `app.files =` in your Rakefile to set up your files once you've required BubbleWrap.
82 Make sure to append onto the array or use `+=`.
1ef50bd @mattetti prepped for release
authored
83
6c6a671 @mattetti updated the README
authored
84 2. Now, you can use BubbleWrap extension in your app:
3303fed @mattetti slightly updated the HTTP API and updated the doc
authored
85
86 ```ruby
6c6a671 @mattetti updated the README
authored
87 class AppDelegate
88 def application(application, didFinishLaunchingWithOptions:launchOptions)
2466381 @toamitkumar Updated typo on readme - replaced documents_path to App.documents_path
toamitkumar authored
89 puts "#{App.name} (#{App.documents_path})"
6c6a671 @mattetti updated the README
authored
90 true
3303fed @mattetti slightly updated the HTTP API and updated the doc
authored
91 end
92 end
93 ```
94
6c6a671 @mattetti updated the README
authored
95 Note: You can also vendor this repository but the recommended way is to
96 use the versioned gem.
1ef50bd @mattetti prepped for release
authored
97
14978e8 @mattetti cleaned up and updated the README
authored
98
6c6a671 @mattetti updated the README
authored
99 ## Core
14978e8 @mattetti cleaned up and updated the README
authored
100
faad30b @mattetti bumped the version # and updated the doc
authored
101 ### Misc
102
103 UUID generator:
104 ```ruby
105 BubbleWrap.create_uuid
106 => "68ED21DB-82E5-4A56-ABEB-73650C0DB701"
107 ```
108
109 Localization (using `NSBundle.mainBundle.localizedStringForKey`):
110 ```ruby
111 BubbleWrap.localized_string(:foo, 'fallback')
112 => "fallback"
113 ```
114
115 Color conversion:
116 ```ruby
117 BubbleWrap.rgba_color(23, 45, 12, 0.4)
118 => #<UIDeviceRGBColor:0x6db6ed0>
119 BubbleWrap.rgb_color(23, 45, 12)
120 => #<UIDeviceRGBColor:0x8ca88b0>
121 'blue'.to_color
122 => #<UICachedDeviceRGBColor:0xda535c0>
123 'dark_gray'.to_color
124 => #<UICachedDeviceWhiteColor:0x8bb5be0>
125 '#FF8A19'.to_color
126 => #<UIDeviceRGBColor:0x8d54110>
127 ```
128
129 Debug flag:
130 ```ruby
131 BubbleWrap.debug?
132 => false
133 BubbleWrap.debug = true
134 => true
135 BubbleWrap.debug?
136 => true
137 ```
138
6c6a671 @mattetti updated the README
authored
139 ### App
14978e8 @mattetti cleaned up and updated the README
authored
140
04f0a84 @jamesotron Update readme.
jamesotron authored
141 A module with useful methods related to the running application
142
143 ```ruby
144 > App.documents_path
145 # "/Users/mattetti/Library/Application Support/iPhone Simulator/5.0/Applications/EEC6454E-1816-451E-BB9A-EE18222E1A8F/Documents"
146 > App.resources_path
147 # "/Users/mattetti/Library/Application Support/iPhone Simulator/5.0/Applications/EEC6454E-1816-451E-BB9A-EE18222E1A8F/testSuite_spec.app"
148 > App.name
149 # "testSuite"
150 > App.identifier
151 # "io.bubblewrap.testSuite"
f03227e @mattetti added App.run_later{ }
authored
152 > App.alert("BubbleWrap is awesome!")
153 # creates and shows an alert message.
154 > App.run_after(0.5) { p "It's #{Time.now}" }
155 # Runs the block after 0.5 seconds.
95896d3 @mattetti added App.open_url
authored
156 > App.open_url("http://matt.aimonetti.net")
157 # Opens the url using the device's browser. (accepts a string url or an instance of `NSURL`.
b0df1d4 @mattetti updated the README
authored
158 > App::Persistence['channels'] # application specific persistence storage
159 # ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
160 > App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
161 # ['TF1', 'France 2', 'France 3']
04f0a84 @jamesotron Update readme.
jamesotron authored
162 ```
14978e8 @mattetti cleaned up and updated the README
authored
163
6c6a671 @mattetti updated the README
authored
164 Other available methods:
b0df1d4 @mattetti updated the README
authored
165
6c6a671 @mattetti updated the README
authored
166 * `App.notification_center`
167 * `App.user_cache`
168 * `App.states`
169 * `App.frame`
170 * `App.delegate`
fcc562d @colinta Changed App.app to App.shared
colinta authored
171 * `App.shared`
6c6a671 @mattetti updated the README
authored
172 * `App.current_locale`
b0df1d4 @mattetti updated the README
authored
173
14978e8 @mattetti cleaned up and updated the README
authored
174
6c6a671 @mattetti updated the README
authored
175 ### Device
14978e8 @mattetti cleaned up and updated the README
authored
176
6c6a671 @mattetti updated the README
authored
177 A collection of useful methods about the current device:
14978e8 @mattetti cleaned up and updated the README
authored
178
6c6a671 @mattetti updated the README
authored
179 Examples:
ba82301 @jamesotron What a difference a CR makes: fix markdown problems on yard.
jamesotron authored
180
6c6a671 @mattetti updated the README
authored
181 ```ruby
182 > Device.iphone?
183 # true
184 > Device.ipad?
185 # false
186 > Device.front_camera?
187 # true
188 > Device.rear_camera?
189 # true
190 > Device.orientation
191 # :portrait
192 > Device.simulator?
193 # true
194 > Device.retina?
195 # false
196 > Device.screen.width
197 # 320
198 > Device.screen.height
199 # 480
96e9fab @jamesotron Update README based on my last commit.
jamesotron authored
200 > Device.screen.width_for_orientation(:landscape_left)
6c6a671 @mattetti updated the README
authored
201 # 480
96e9fab @jamesotron Update README based on my last commit.
jamesotron authored
202 > Device.screen.height_for_orientation(:landscape_left)
6c6a671 @mattetti updated the README
authored
203 # 320
204 ```
52e4e68 @siuying fix spec
siuying authored
205
7a777f7 @clayallsopp fix README format
clayallsopp authored
206 ### Camera
eb0139b @clayallsopp making Camera an object inside Device
clayallsopp authored
207
208 Added interface for better camera access:
209
210 ```ruby
211 # Uses the front camera
79e5bcb @clayallsopp update README
clayallsopp authored
212 BW::Device.camera.front.picture(media_types: [:movie, :image]) do |result|
eb0139b @clayallsopp making Camera an object inside Device
clayallsopp authored
213 image_view = UIImageView.alloc.initWithImage(result[:original_image])
214 end
215
216 # Uses the rear camera
79e5bcb @clayallsopp update README
clayallsopp authored
217 BW::Device.camera.rear.picture(media_types: [:movie, :image]) do |result|
eb0139b @clayallsopp making Camera an object inside Device
clayallsopp authored
218 image_view = UIImageView.alloc.initWithImage(result[:original_image])
219 end
220
221 # Uses the photo library
79e5bcb @clayallsopp update README
clayallsopp authored
222 BW::Device.camera.any.picture(media_types: [:movie, :image]) do |result|
eb0139b @clayallsopp making Camera an object inside Device
clayallsopp authored
223 image_view = UIImageView.alloc.initWithImage(result[:original_image])
224 end
225 ```
226
6c6a671 @mattetti updated the README
authored
227 ### JSON
228
229 `BubbleWrap::JSON` wraps `NSJSONSerialization` available in iOS5 and offers the same API as Ruby's JSON std lib.
be2fa6c @clayallsopp update README for UIButton helper
clayallsopp authored
230
231 ```ruby
6c6a671 @mattetti updated the README
authored
232 BW::JSON.generate({'foo => 1, 'bar' => [1,2,3], 'baz => 'awesome'})
233 => "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
234 BW::JSON.parse "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
235 => {"foo"=>1, "bar"=>[1, 2, 3], "baz"=>"awesome"}
be2fa6c @clayallsopp update README for UIButton helper
clayallsopp authored
236 ```
52e4e68 @siuying fix spec
siuying authored
237
6c6a671 @mattetti updated the README
authored
238 ### NSIndexPath
239
240 Helper methods added to give `NSIndexPath` a bit more of a Ruby
241 interface.
242
243
244 ### NSNotificationCenter
52e4e68 @siuying fix spec
siuying authored
245
246 Helper methods to give NSNotificationCenter a Ruby-like interface:
247
248 ```ruby
249 def viewWillAppear(animated)
4a19e38 @smgt Add App to notification center.
smgt authored
250 @foreground_observer = App.notification_center.observe UIApplicationWillEnterForegroundNotification do |notification|
52e4e68 @siuying fix spec
siuying authored
251 loadAndRefresh
252 end
c654f59 @colinta spec, and updated README
colinta authored
253
4a19e38 @smgt Add App to notification center.
smgt authored
254 @reload_observer = App.notification_center.observe ReloadNotification do |notification|
52e4e68 @siuying fix spec
siuying authored
255 loadAndRefresh
256 end
257 end
258
259 def viewWillDisappear(animated)
4a19e38 @smgt Add App to notification center.
smgt authored
260 App.notification_center.unobserve @foreground_observer
261 App.notification_center.unobserve @reload_observer
52e4e68 @siuying fix spec
siuying authored
262 end
263
264 def reload
4a19e38 @smgt Add App to notification center.
smgt authored
265 App.notification_center.post ReloadNotification
52e4e68 @siuying fix spec
siuying authored
266 end
27cc639 @jamesotron Move Kernel methods to BubbleWrap module. Fix spec/ns_notification_cente...
jamesotron authored
267 ```
b0df1d4 @mattetti updated the README
authored
268
6c6a671 @mattetti updated the README
authored
269
270 ### NSUserDefaults
271
272 Helper methods added to the class repsonsible for user preferences used
273 by the `App::Persistence` module shown below.
274
275 ### Persistence
276
277 Offers a way to persist application specific information using a very
278 simple interface:
279
280 ``` ruby
281 > App::Persistence['channels'] # application specific persistence storage
282 # ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
283 > App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
284 # ['TF1', 'France 2', 'France 3']
285 ```
286
07816bf @mattetti added the KVO wrapper to the README
authored
287 ### Observers
288 **Since: > version 0.4**
289
290 You can observe for object's changes and trigger blocks:
291
292 ``` ruby
293 class ExampleViewController < UIViewController
294 include BW::KVO
295
296 def viewDidLoad
aba1b54 @janweinkauff correct KVO code example
janweinkauff authored
297 @label = UILabel.alloc.initWithFrame [[20,20],[280,44]]
298 @label.text = ""
299 view.addSubview @label
c654f59 @colinta spec, and updated README
colinta authored
300
f982e64 @janweinkauff added support for symbols as selectors to the KVO module
janweinkauff authored
301 observe(@label, :text) do |old_value, new_value|
07816bf @mattetti added the KVO wrapper to the README
authored
302 puts "Hello from viewDidLoad!"
303 end
304 end
305
306 def viewDidAppear(animated)
f982e64 @janweinkauff added support for symbols as selectors to the KVO module
janweinkauff authored
307 observe(@label, :text) do |old_value, new_value|
07816bf @mattetti added the KVO wrapper to the README
authored
308 puts "Hello from viewDidAppear!"
309 end
310 end
311
312 end
313 ```
314
315
6c6a671 @mattetti updated the README
authored
316 ### String
317
318 The Ruby `String` class was extended to add `#camelize` and
319 `#underscore` methods.
320
321 ```ruby
322 > "matt_aimonetti".camelize
323 => "MattAimonetti"
324 > "MattAimonetti".underscore
325 => "matt_aimonetti"
326 ```
327
328 ### Time
329
330 The `Time` Ruby class was added a class level method to convert a
331 iso8601 formatted string into a Time instance.
332
333 ```ruby
334 > Time.iso8601("2012-05-31T19:41:33Z")
335 => 2012-05-31 21:41:33 +0200
336 ```
337
5062154 @clayallsopp require 'bubble-wrap/location'
clayallsopp authored
338 ## Location
02091c8 @clayallsopp BW::Location wrapper for CoreLocation
clayallsopp authored
339
340 Added interface for Ruby-like GPS access:
341
342 ```ruby
343 BW::Location.get do |result|
344 p "From Lat #{result[:from].latitude}, Long #{result[:from].longitude}"
345 p "To Lat #{result[:to].latitude}, Long #{result[:to].longitude}"
346 end
347 ```
348
349 Also available is `BW::Location.get_significant`, for monitoring significant location changes.
350
2faf6c3 @clayallsopp Add `BubbleWrap::Media` and 'bubble-wrap/media'
clayallsopp authored
351 ## Media
352
353 Added wrapper for playing remote and local media. Available are `modal` and custom presentation styles:
354
355 ```ruby
356 # Plays in your custom frame
d0c53e8 @clayallsopp cleaner README example
clayallsopp authored
357 local_file = NSURL.fileURLWithPath(File.join(NSBundle.mainBundle.resourcePath, 'test.mp3'))
358 BW::Media.play(local_file) do |media_player|
2faf6c3 @clayallsopp Add `BubbleWrap::Media` and 'bubble-wrap/media'
clayallsopp authored
359 media_player.view.frame = [[10, 100], [100, 100]]
360 self.view.addSubview media_player.view
361 end
362
363 # Plays in an independent modal controller
364 BW::Media.play_modal("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3")
365 ```
366
2de8b44 @clayallsopp create a 'bubble-wrap/ui' requirement for all the UI-related wrappers
clayallsopp authored
367 ## UI
368
369 ### Gestures
370
371 Extra methods on `UIView` for working with gesture recognizers. A gesture recognizer can be added using a normal Ruby block, like so:
372
373 ```ruby
374 view.whenTapped do
375 UIView.animateWithDuration(1,
376 animations:lambda {
377 # animate
378 # @view.transform = ...
379 })
380 end
381 ```
382
383 There are similar methods for pinched, rotated, swiped, panned, and pressed (for long presses). All of the methods return the actual recognizer object, so it is possible to set the delegate if more fine-grained control is needed.
384
6c6a671 @mattetti updated the README
authored
385 ### UIViewController
386
387 A custom method was added to `UIViewController` to return the content
388 frame of a view controller.
389
2de8b44 @clayallsopp create a 'bubble-wrap/ui' requirement for all the UI-related wrappers
clayallsopp authored
390 ### UIControl / UIButton
8ecb4db @clayallsopp Update README
clayallsopp authored
391
2de8b44 @clayallsopp create a 'bubble-wrap/ui' requirement for all the UI-related wrappers
clayallsopp authored
392 Helper methods to give `UIButton` a Ruby-like interface. Ex:
8ecb4db @clayallsopp Update README
clayallsopp authored
393
394 ```ruby
2de8b44 @clayallsopp create a 'bubble-wrap/ui' requirement for all the UI-related wrappers
clayallsopp authored
395 button.when(UIControlEventTouchUpInside) do
396 self.view.backgroundColor = UIColor.redColor
8ecb4db @clayallsopp Update README
clayallsopp authored
397 end
398 ```
6c6a671 @mattetti updated the README
authored
399
400 ## HTTP
401
402 `BubbleWrap::HTTP` wraps `NSURLRequest`, `NSURLConnection` and friends to provide Ruby developers with a more familiar and easier to use API.
403 The API uses async calls and blocks to stay as simple as possible.
404
405 To enable it add the following require line to your `Rakefile`:
406 ```ruby
407 require 'bubble-wrap/http'
408 ```
409
410 Usage example:
411
412 ```ruby
413 BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
414 p response.body.to_str
415 end
416 ```
417
418 ```ruby
419 BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
420 p response.body.to_str # prints the response's body
421 end
422 ```
423
424 ```ruby
425 data = {first_name: 'Matt', last_name: 'Aimonetti'}
426 BubbleWrap::HTTP.post("http://foo.bar.com/", {payload: data}) do |response|
427 if response.ok?
428 json = BubbleWrap::JSON.parse(response.body.to_str)
429 p json['id']
430 elsif response.status_code.to_s =~ /40\d/
95b32ff @chalkers Adding in in to documentation since alert isn't on the kernal anymore
chalkers authored
431 App.alert("Login failed")
6c6a671 @mattetti updated the README
authored
432 else
7e6cd04 @chalkers Adding in in to documentation since alert isn't on the kernal anymore
chalkers authored
433 App.alert(response.error_message)
6c6a671 @mattetti updated the README
authored
434 end
435 end
436 ```
437
faad30b @mattetti bumped the version # and updated the doc
authored
438 A `:download_progress` option can also be passed. The expected object
439 would be a Proc that takes two arguments: a float representing the
440 amount of data currently received and another float representing the
441 total amount of data expected.
442
443
319e8ef @mattetti finished the rss parser internal cleanup and added a loader
authored
444 ## RSS Parser
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
445 **Since: > version 1.0.0**
6c6a671 @mattetti updated the README
authored
446
1232b88 @mattetti added tests and delayed the loading of XML in some cases (RSS Parser)
authored
447 The RSS Parser provides an easy interface to consume RSS feeds in an
448 asynchronous (non blocking) way.
449
450
451 ```ruby
452 feed_parser = BW::RSSParser.new("http://feeds2.feedburner.com/sdrbpodcast")
453 feed_parser.parse do |item|
454 # called asynchronously as items get parsed
455 p item.title
456 end
457 ```
458
459 The yielded RSS item is of type `RSSParser::RSSItem` and has the
460 following attributes:
461
462 * title
463 * description
464 * link
465 * guid
466 * pubDate
467 * enclosure
468
469 The item can be converted into a hash by calling `to_hash` on it.
470
471 ### Delegate
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
472 **Since: > version 1.0.0**
1232b88 @mattetti added tests and delayed the loading of XML in some cases (RSS Parser)
authored
473
474 You can also designate a delegate to the parser and implement change
475 state callbacks:
476
477 ```ruby
478 feed_parser = BW::RSSParser.new("http://feeds.feedburner.com/sdrbpodcast")
479 feed_parser.delegate = self
480 feed.parse do |item|
481 p item.title
482 end
483
484 # Delegate method
485 def when_parser_initializes
486 p "The parser is ready!"
487 end
488
489 def when_parser_parses
490 p "The parser started parsing the document"
491 end
492
493 def when_parser_is_done
494 p "The feed is entirely parsed, congratulations!"
495 end
496 ```
497
498 These delegate methods are optional, however, you might find the
499 `when_parser_is_done` callback useful if you collected all the items and
500 want to process all at once for instance.
501
502 ### Parsing a remote content or actual data
503
504 You have the choice to initialize a parser instance with a string
505 representing an URL, an instance of `NSURL` or my specifying that the
506 passed param is some data to parse directly.
507
508 ```ruby
509 # string representing an url:
510 feed_parser = BW::RSSParser.new("http://feeds2.feedburner.com/sdrbpodcast")
511 # a NSURL instance:
512 url = NSURL.alloc.initWithString("http://matt.aimonetti.net/atom.xml")
513 feed_parser = BW::RSSParser.new(url)
514 # Some data
515 feed = File.read('atom.xml')
516 feed_parser = BW::RSSParser.new(feed, true)
517 ```
518
519
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
520 ## Reactor
521 **Since: > version 1.0.0**
1232b88 @mattetti added tests and delayed the loading of XML in some cases (RSS Parser)
authored
522
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
523 `BubbleWrap::Reactor` is a simplified, mostly complete implementation of
c654f59 @colinta spec, and updated README
colinta authored
524 the [Event Machine](http://rubyeventmachine.com/) API. In fact
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
525 `BubbleWrap::Reactor` is aliased to `EM` in the runtime environment.
1232b88 @mattetti added tests and delayed the loading of XML in some cases (RSS Parser)
authored
526
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
527 ### Deferables
528
529 BubbleWrap provides both a `Deferrable` mixin and a `DefaultDeferrable`
530 class, which simply mixes in deferrable behaviour if you don't want to
531 implement your own.
532
533 A deferrable is an object with four states: unknown, successful, failure
534 and timeout. When you initially create a deferrable it is in an unknown
535 state, however you can assign callbacks to be run when the object
536 changes to either successful or failure state.
537
538 #### Success
539
540 ```ruby
541 > d = EM::DefaultDeferrable.new
542 => #<BubbleWrap::Reactor::DefaultDeferrable:0x6d859a0>
543 > d.callback { |what| puts "Great #{what}!" }
544 => [#<Proc:0x6d8a1e0>]
545 > d.succeed "justice"
546 Great justice!
547 => nil
548 ```
549
550 #### Failure
551
552 ```ruby
553 > d = EM::DefaultDeferrable.new
554 => #<BubbleWrap::Reactor::DefaultDeferrable:0x8bf3ee0>
555 > d.errback { |what| puts "Great #{what}!" }
556 => [#<Proc:0x8bf3ef0>]
557 > d.fail "sadness"
558 Great sadness!
559 => nil
560 ```
561
562 #### Timeout
563
564 ```ruby
565 > d = EM::DefaultDeferrable.new
566 => #<BubbleWrap::Reactor::DefaultDeferrable:0x8bf5910>
567 > d.errback { puts "Great scott!" }
568 => [#<Proc:0x8bf6350>]
569 > d.timeout 2
570 => #<BubbleWrap::Reactor::Timer:0x6d920a0 @timer=#<__NSCFTimer:0x6d91990>>
571 # wait...
572 > Great scott!
573 ```
574
575 ### Timers
576
577 *All timers can be cancelled using `EM.cancel_timer`.*
578
579 #### One-shot timers
580
581 ```ruby
582 > EM.add_timer 1.0 do
583 > puts "Great scott!"
584 > end
585 => 146335904
586 > Great scott!
587 ```
588
589 #### Periodic timers
590
591 ```ruby
592 > count = 0
593 => 0
594 > timer = EM.add_periodic_timer 1.0 do
595 > count = count + 1
596 > puts "Great scott!"
597 > (count < 10) || EM.cancel_timer(timer)
598 > end
599 => 146046832
600 > Great scott!
601 Great scott!
602 Great scott!
603 Great scott!
604 Great scott!
605 Great scott!
606 Great scott!
607 Great scott!
608 Great scott!
609 Great scott!
610 ```
611
612 ### Scheduling operations
613
c654f59 @colinta spec, and updated README
colinta authored
614 You can use `EM.schedule` to schedule blocks to be executed
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
615 asynchronously. BubbleWrap deviates from the EventMachine
616 API here in that it also provides `EM.schedule_on_main` which
c654f59 @colinta spec, and updated README
colinta authored
617 makes sure that the task is run asynchronously, but on the
618 application's main thread - this is necessary if you are
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
619 updating the user interface.
620
621 ```ruby
622 > EM.schedule { puts Thread.current.object_id }
623 146027920
624 => nil
625 > EM.schedule_on_main { puts Thread.current.object_id }
626 112222480
627 => nil
628 ```
629
630 ### Deferrable operations
631
632 You can also use `EM.defer` in much the same way as `EM.schedule`
c654f59 @colinta spec, and updated README
colinta authored
633 with one important difference, you can pass in a second `proc`
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
634 which will be called when the first has completed, and be passed
5586f9a @jamesotron Add a defer_on_main method to Reactor.
jamesotron authored
635 it's result as an argument. Just like `EM.schedule`, `EM.defer`
636 also has an `EM.defer_on_main` version.
d2b92a9 @jamesotron Add reactor documentation.
jamesotron authored
637
638 ```ruby
639 > operation = proc { 99 }
640 => #<Proc:0x6d763c0>
641 > callback = proc { |speed| puts speed >= 99 ? "Time travel!" : "Conventional travel!" }
642 => #<Proc:0x8bd3910>
643 > EM.defer(operation, callback)
644 => nil
645 Time travel!
646 ```
647
648 ### Events
649
650 Although not part of the EventMachine API, BubbleWrap provides
651 an `Eventable` mixin for use instrumenting objects with simple
652 event triggering behaviour. `BubbleWrap::Reactor` uses this
653 behind the scenes in several places, and as it's a very handy
654 idiom it is available as a public API.
655
656 ```ruby
657 > o = Class.new { include EM::Eventable }.new
658 => #<#<Class:0x6dc1310>:0x6dc2ec0>
659 > o.on(:november_5_1955) { puts "Ow!" }
660 => [#<Proc:0x6dc6300>]
661 > o.on(:november_5_1955) { puts "Flux capacitor!" }
662 => [#<Proc:0x6dc6300>, #<Proc:0x6dc1ba0>]
663 > o.trigger(:november_5_1955)
664 Ow!
665 Flux capacitor!
666 => [nil, nil]
667 ```
6c6a671 @mattetti updated the README
authored
668
2d9e597 @jamesotron Fix extra crud that mistakenly got in when I merged in bw-dispatch.
jamesotron authored
669 # Suggestions?
670
b0df1d4 @mattetti updated the README
authored
671 Do you have a suggestion for a specific wrapper? Feel free to open an
672 issue/ticket and tell us about what you are after. If you have a
673 wrapper/helper you are using and are thinking that others might enjoy,
674 please send a pull request (with tests if possible).
1232b88 @mattetti added tests and delayed the loading of XML in some cases (RSS Parser)
authored
675
Something went wrong with that request. Please try again.