Open bartlomiejwolk opened 6 years ago
Buffer has a call that lets you choose the buffer size as well. Does this work for you?
Observable.EveryUpdate().Where(_ => Input.GetMouseButtonDown(0))
.Buffer(TimeSpan.FromMilliseconds(250), 2)
.Where(buffer => buffer.Count >= 2)
.Subscribe(_ => Debug.Log("DoubleClicked!"));
I think it can lead to missing double-clicks. Buffer gatheres clicks into fixed time windows, each window being e.g. 250 ms apart. In my understanding, it's possible to make first click in window A and then the second in window B. Even if both clicks were within 250 ms timeframe this double-click won't be registered. After the first click, Buffer will close window A and emit an IList with just one click in in. The same will happen with window B.
EDIT: Maybe I could use Window(2, 1)
to create a stream of 2 elements for each source element. If elemens in those streams would come at the same time as the source elements then I could use Buffer(TimeSpan.FromMilliseconds(250))
on each of them and then check if number of elements in each IList is more than 2.
What is the UniRx operator that works like a Window()?
@bartlomiejwolk Did you find a solution for this?
I tried to copy the Window behaviour myself. Take your primary click stream and on subscribe add another stream. This second stream does a timeout (ignore errors) but fires a doubleclick if the primary click stream hits again.
Don't know if this is ideal but it does what I need.
var primaryClickStream = Observable.EveryUpdate()
.Where(_ => Input.GetMouseButtonDown(0));
primaryClickStream
.Subscribe(_ =>
{
Observable.Timeout(primaryClickStream, TimeSpan.FromSeconds(_doubleClickTimeoutInSec))
.Subscribe(x => { _doubleClicked = true; },
xe => { } //nothing
);
});
Don't know if this is ideal
Each click you're creating new object ...and this object fails to do what it supposed to do most of the times ...and you're ignoring error reports. That's quite opposite of ideal.
Just timestamp your stuff
var doubleClickObservable =
clickSource
// !!!
.Timestamp()
// !!!
.Pairwise((prev, current) => (current.Timestamp - prev.Timestamp).TotalMilliseconds <= 300)
.Where(fastEnough => fastEnough);
Don't know if this is ideal Just timestamp your stuff Oh yeah this is much cleaner. Thanks for this!
Just for a working example I'll add my finished observable here (with subscribe):
var doubleClickObservable =
clickSource
.Timestamp()
.Pairwise((prev, current) => (current.Timestamp - prev.Timestamp).TotalMilliseconds <= 300)
.Where(fastEnough => fastEnough)
.Subscribe(x => _doubleClicked = true);
If I undersand correctly, in the double-click example from the README.md, there'll always be a minimum 250 ms delay to recognize that double click was performed.
The example:
Is there a way to detect double-click the moment that the second click was entered?