Using delay on a Observable within concatMap doesn't emit any items - functional-programming

Snippet1 (without delay function):
Observable.range(1, 10)
.concatMap {
Observable.just(it)
}
.subscribe{ print(it)}
Output : 12345678910
Snippet2 (with delay function):
Observable.range(1, 10)
.concatMap {
Observable.just(it).delay(1, TimeUnit.SECONDS)
}
.subscribe{ print(it)}
Output : DOESN'T PRINT ANYTHING
Why using a delay will result in emitting nothing? I am unable to comprehend what actually is happening here?

Related

Access last value from a SignalProducer when terminated

I have a signal producer, when it's terminated I would like to know if a value was sent, I only need the last one, seems so simple ...
let myProducer: SignalProducer<MyObject, MyError> = getMyProducer()
myProducer.on(terminated: {
// I need the last value here
// Or I need to know if value was never called
}).start()
I've tried to store the value in a local var :
let myProducer: SignalProducer<MyObject, MyError> = getMyProducer()
var myValue: MyObject?
myProducer.on(value: { value in
myValue = value
}, terminated: {
guard let value = myValue else {
// value was never called
return
}
// value was called
}).start()
But sometimes terminated is called while value has been called but myValue is still nil...
First, are you really sure that you want the terminated event?
Under normal conditions, an event stream ends with a completed event. Exceptions are failed when a failure has occurred and interrupted, when the observation was ended before the stream could complete normally (E.g. cancellation).
Second: Can your SignalProducer fail, and in the failure case, do you still want the last value sent before the failure?
If not, its as easy as using the take(last:) operator:
enum MyError: Error {
case testError
}
let (signal, input) = Signal<Int, MyError>.pipe()
let observer = Signal<Int, MyError>.Observer(
value: { print("value: \($0)") },
failed: { print("error: \($0)") },
completed: { print("completed") },
interrupted: { print("interrupted") }
)
signal
.take(last: 1)
.observe(observer)
input.send(value: 1) // Nothing printed
input.send(value: 2) // Nothing printed
input.send(value: 3) // Nothing printed
input.sendCompleted() // value 3 printed
I'm using a Signal here so I can manually send events to it just for demonstration, the same works for SignalProducer as well.
Note: If we send interrupted or a failed event, the last value 3 will not be sent because those to terminating events short circuit the normal flow.
If your SignalProducer can fail, and you still want to get the last value before the failure, you can use flatMapError to ignore the Error before the last operator:
signal
.flatMapError { _ in
return .empty
}
.take(last: 1)
.observe(observer)
my answer :
producer
.flatMapError { _ in SignalProducer<Value, NoError>.empty }
.collect()
startWithResult( { result in
case let .success(results):
done(with: results.last)
case let .failure(error):
() // should not happen as errors are flatmapped
})

recursion in typescript gets undefined

I'm using a canvas object inside my component to generate a chart. In order for it animate i'm calling the method recursively. I keep getting an error saying that the method is not defined. Not sure how I need to structure it.
any assistance appreciated.
// Animate function
protected animate(draw_to) {
// Clear off the canvas
this.ctx.clearRect(0, 0, this.width, this.height);
// Start over
this.ctx.beginPath();
// arc(x, y, radius, startAngle, endAngle, anticlockwise)
// Re-draw from the very beginning each time so there isn't tiny line spaces between each section (the browser paint rendering will probably be smoother too)
this.ctx.arc(this.x, this.y, this.radius, this.start, draw_to, false);
// Draw
this.ctx.stroke();
// Increment percent
this.curr++;
// Animate until end
if (this.curr < this.finish + 1) {
// Recursive repeat this function until the end is reached
requestAnimationFrame(function () {
error happens here >>> this.animate(this.circum * this.curr / 100 + this.start);
});
}
}
You need to use an arrow function to keep the same context in the function you give to requestAnimationFrame.
requestAnimationFrame(() => {
error happens here >>> this.animate(this.circum * this.curr / 100 + this.start);
});
Another option is:
requestAnimationFrame(this.animate.bind(this, this.circum * this.curr / 100 + this.start));
You are passing a reference to this.animate which is already bound to the correct this along with the parameters.

Swift get value from UnsafeMutablePointer<Void> using UnsafePointer<String>

I am trying to pass contextInfo of typeUnsafeMutablePointer<Void> to UISaveVideoAtPathToSavedPhotosAlbum and use it in the callback function. For some reason I am unable to access contextInfo as a string using UnsafePointer<String>(x).memory when I am in the callback function.
I am pretty sure it is something simple I am missing but have spent way to many hours trying to figure this out.
Below is some code that I have tried.
The following code works.
var testStr:String = "hello"
takesAMutableVoidPointer(&testStr)
func takesAMutableVoidPointer(x: UnsafeMutablePointer<Void>){
var pStr:String = UnsafePointer<String>(x).memory
println("x = \(x)")
println("pStr = \(pStr)")
}
However the following code does not work.
var testStr:String = "hello"
if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(filePath){ //the filePath is compatible
println("Compatible")
//UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, nil, nil)
UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, "video:didFinishSavingWithError:contextInfo:", &testStr)
}
else{
println("Not Compatible")
}
func video(video: NSString, didFinishSavingWithError error:NSError, contextInfo:UnsafeMutablePointer<Void>){
var pStr:String = UnsafePointer<String>(contextInfo).memory
println("contextInfo = \(contextInfo)")
println("pStr = \(pStr)")
}
Once I get to the following line:
var pStr:String = UnsafePointer<String>(contextInfo).memory
I keep getting the following error:
Thread 1: EXC_BAD_ACCESS(code=1, address=0x0)
Any help with this would be greatly appreciated.
Thanks.
Update
Rintaro commented that testStr needs to be top level but the following code works.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var testStr:String = "hello"
takesAMutableVoidPointer(&testStr)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func takesAMutableVoidPointer(x: UnsafeMutablePointer<Void>){
var answer = UnsafePointer<String>(x).memory
println("x = \(x)")
println("answer = \(answer)")
}
}
I am trying not to use global variables unless I have to. I may have to but since I am able to execute the above code, it seems as though I do not need to use a global variable.
As discussed in OP comments, testStr has already been freed.
Is there any way to force the retaining of a variable that has been created in a function? Then release it later?
It's not impossible, but I don't know this is the best way to do that.
Anyway, try this with Playground or OS X "Command Line Tool" template:
import Foundation
func foo() {
var str:NSString = "Hello World"
let ptr = UnsafePointer<Void>(Unmanaged<NSString>.passRetained(str).toOpaque())
bar(ptr)
}
func bar(v:UnsafePointer<Void>) {
let at = dispatch_time(
DISPATCH_TIME_NOW,
Int64(2.0 * Double(NSEC_PER_SEC))
)
dispatch_after(at, dispatch_get_main_queue()) {
baz(v)
}
}
func baz(v:UnsafePointer<Void>) {
println("notified")
let str = Unmanaged<NSString>.fromOpaque(COpaquePointer(v)).takeRetainedValue()
println("info: \(str)")
}
foo()
println("started")
dispatch_main()
Unmanaged<NSString>.passRetained(str) increments the retain count.
Unmanaged<NSString>.fromOpaque(...).takeRetainedValue() decrements it, and extract the object.
I think, using pure Swift String is impossible. because String is struct and is allocated in stack memory. Maybe the buffer of it is allocated in heap, but we cannot access it directly.

Geb: Warn when a page takes longer than expected - Test Context in Page Object

We want to add some type of functionality that when a page takes longer than x seconds to load a warning is presented. We don't want that to throw a WaitTimeoutException, because the test can still execute cleanly, just longer than desired. We would still use the default timeout to throw our WaitTimeoutException after 20 seconds. This implies that x is less than 20. It's essentially a performance check on the page itself.
I've tried using the onLoad function:
void onLoad(Page previousPage) {
double warnSeconds = 0.001
LocalDateTime warnTime = LocalDateTime.now().plusMillis((int)(warnSeconds * 1000))
boolean warned = false
boolean pageReady = false
while(!warned && !pageReady) {
if(LocalDateTime.now() > warnTime) {
log.warn("${this.class.simpleName} took longer than ${warnSeconds} seconds to load")
warned = true
}
pageReady = js.exec('return document.readyState') == 'complete'
}
}
However:
"Sets this browser's page to be the given page, which has already been
initialised with this browser instance."
Any help would be great. Thanks.
______________________________________EDIT_______________________________________
Instead of using my own timer, used javascript window.performance. Now I'm looking to be able to access a variable in my test from my pages.
______________________________________EDIT_______________________________________
void onLoad(Page previousPage) {
def performance
//TODO system property page time
def pageTime = 8000
if (browser.driver instanceof InternetExplorerDriver) {
performance = js.exec('return JSON.stringify(window.performance.toJSON());')
} else {
performance = js.exec('return window.performance || window.webkitPerformance || window.mozPerformance ' +
'|| window.msPerformance;')
}
int time = performance['timing']['loadEventEnd'] - performance['timing']['fetchStart']
if (time > pageTime) {
String errorMessage = "${this.class.simpleName} took longer than ${pageTime} milliseconds " +
"to load. Took ${time} milliseconds."
log.error(errorMessage)
//TODO Soft Assert
}
}
New chunk of code to actually get the correct performance data instead of using my own timer. Now where I have //TODO Soft Assert, I have an object in my test that I want to access from my Page Object, but have no context. How can I get context?

Simple Timer in Meteor JS

I am creating a simple countdown timer for a game. I am using CoffeeScript and Meteor. I have a Handlebars "Timer" template with a {{time}} expression.
Here is the code:
clock = 10
timeLeft = () ->
if clock > 0
clock--
else
"That's All Folks"
Meteor.clearInterval(interval)
interval = Meteor.setInterval(timeLeft, 1000)
if Meteor.isClient
Template.timer.time = interval
The above code just gives me a static display of 8 or 6 instead of the countdown timer.
If I add a few console.log statements I can see it work as designed in the terminal.
clock = 10
timeLeft = () ->
if clock > 0
clock--
console.log clock
else
console.log "That's All Folks"
Meteor.clearInterval(interval)
interval = Meteor.setInterval(timeLeft, 1000)
if Meteor.isClient
Template.timer.time = interval
If you want to update a value in handlebars you need to use Session so that its reactive, otherwise the Templating system won't be aware of when to update it in the ui. Also you passed the template a handler thats the handle instead of the timer value.
Using the below, I've used Session to pass this data through to handlebars.
clock = 10
timeLeft = ->
if clock > 0
clock--
Session.set "time", clock
console.log clock
else
console.log "That's All Folks"
Meteor.clearInterval interval
interval = Meteor.setInterval(timeLeft, 1000)
if Meteor.isClient
Template.timer.time = ->
Session.get "time"
Also in javascript in case anyone else wants this:
var clock = 10;
var timeLeft = function() {
if (clock > 0) {
clock--;
Session.set("time", clock);
return console.log(clock);
} else {
console.log("That's All Folks");
return Meteor.clearInterval(interval);
}
};
var interval = Meteor.setInterval(timeLeft, 1000);
if (Meteor.isClient) {
Template.registerHelper("time", function() {
return Session.get("time");
});
}
In essence you tell Session the time value, and when its updated it tells the templating system to redraw with the updated time value.

Resources