I have a stimulus component that is supposed to calculate the time spent on a page. When loading it saves to a variable the start time and on the event turbo:before-cache it calculates Date.now()-start.
My approach kinda works but it always adds a couple more seconds to the real ones..
I just started with stimulus and I wonder if there's a better way of doing this
let startTime;
export default class extends Controller {
initialize(){
this.boundHandleMyEvent = this.handleMyEvent.bind(this);
}
connect() {
startTime = Date.now()
console.log("connect")
document.addEventListener('turbo:before-cache', this.boundHandleMyEvent);
}
disconnect() {
console.log("disconect")
document.removeEventListener('turbo:before-cache', this.boundHandleMyEvent);
}
handleMyEvent() {
fetch(`http://localhost:3002/time/?totalTime=${Date.now()-startTime}&startTime=${startTime}&endTime=${Date.now()}`)
}
```
Thanks
Related
I am curious if anybody has been able to figure out a way to keep how long a scene has been active for. This is critical for when I need to fire certain events, like say "spawn ship 5 minutes into game play".
The issue with the update cycle, is that the current time being passed is not active game time only, so if you get a call or switch apps, upon return you will get that X minute jump in time.
Currently, I use an SKAction.customAction to keep track of my time, and it works, but I cannot guarantee the order in which actions fire, so my events could end up being 1 frame off.
Here is what I am doing now, please let me know what you have done to keep time consistent.
//Note: NodeComponent is a protocol extension to quickly access the GKSKNodeComponent's node
import GameplayKit
class ElapsedTimeComponent:GKComponent,NodeComponent
{
var elapsedTime : TimeInterval = 0.0
override func didAddToEntity() {
node.scene?.addComponentToComponentSystem(self)
self.node.run(SKAction.customAction(withDuration:330000000000000000000000000000000000000){node,seconds in
elapsedTime = seconds
(node as! SKLabelNode).text = "\(seconds)"
})
}
override func update(deltaTime seconds: TimeInterval) {
}
}
So it turns out, SKView has a delegate protocol you can attach anywhere. I have set up my latest test to look like this:
public class GameScene: SKScene,SKViewDelegate {
var previousTime : TimeInterval = 0
var gameTime : TimeInterval = 0
public func view(_ view: SKView, shouldRenderAtTime time: TimeInterval) -> Bool
{
if !self.isPaused{
gameTime += time - previousTime
}
print("GameTime: \(gameTime)")
componentSystems.forEach({$0.update(deltaTime: gameTime)})
self.previousTime = time
return !self.isPaused
}
public override func didMove(to view: SKView) {
view.delegate = self
}
}
https://developer.apple.com/documentation/spritekit/skviewdelegate
If I am understanding this correctly, then the only thing I need to look out for outside of this is ensuring that when returning from game, that the view.isPaused does not unpause my scene at the same exact time (ughhh why do you do this to me Apple) to allow for 1 render loop to occur.
Of course, the downside with this method, is any pause screen I create will have to be outside of this scene since rendering is disabled.
I am calling one API every 10 sec using Observable.timer(0,10000) and unsubscribing on ngOnDestroy() method.But this call is not getting stopped and its keep getting adds in the queue and calling even after leaving that component.
I have tried to destroy the component on ngOnDestroy() function. But it's still its getting call.
it should have called only on this component and should call once every 10 seconds but if we go to other component call is getting added in the queue and once come back to instance component it is calling multiple time every 10 secs.
Code:
this._instanceSub = Observable.timer(0,reference.INSTANCE_CALL_INTERVAL) .subscribe(() => { this.getComonentInstance(this.componentId); }); ngOnDestroy() {
if (this._instanceSub) {
this._instanceSub.unsubscribe();
}
The above code must work i have used the below code for the same
this.subject = new Subject();
ngOnInit() {
timer(0, reference.INSTANCE_CALL_INTERVAL).pipe(
takeUntil(this.subject),
).subscribe(t => this.getComonentInstance(this.componentId));
}
and in ngOndestroy
ngOnDestroy() {
this.subject.next();
}
I want to measure how long (in seconds) it takes users to do certain things in my app. Some examples are logging in, pressing a button on a certain page, etc.
I am using an NSTimer for that. I am starting it in the viewDidLoad of a specific page, and stopping it at the point that I want to measure.
I also want to measure cumulative time for certain things. I would like to start the timer on the log-in screen, and then continue the timer until the user gets to the next view controller and clicks on a certain button.
I'm not sure how to do this. Should create a global variable in my app delegate? Or is there some other better way?
No need for an NSTimer, you just need to record the start times and compare them to the stop times. Try using a little helper class such as:
class MyTimer {
static let shared = MyTimer()
var startTimes = [String : Date]()
func start(withKey key: String) {
startTimes[key] = Date()
}
func measure(key: String) -> TimeInterval? {
if let start = startTimes[key] {
return Date().timeIntervalSince(start)
}
return nil
}
}
To use this, just call start(withKey:) right before you start a long-running task.
MyTimer.shared.start(withKey: "login")
Do something that takes a while and then call measure(key:) when you're done. Because MyTimer is a singleton, it can be called from anywhere in your code.
if let interval = MyTimer.shared.measure("login") {
print("Logging in time: \(interval)")
}
If you're using multiple threads, you may to to add some thread safety to this, but it should work as is in simple scenarios.
I'm trying to create a swipe function to work in iOS devices. I've calculated the start touch position and the end touch position. Now, I want to calculate the start time and end time to get a time difference between the two touch events.
I've tried Time.time and Time.deltatime but as You already know It didn't work. So Please Help. Or if have any better suggestions for swipe, then please suggest me.
Thank You.
I believe what brandon is implying is you need to record Time.time in a variable such as startTime where you detect start touch then where you are recording the end touch do something like:
diffTime = Time.time - startTime
EDIT: Based on your comment I'm assuming it didn't work. Without your code its hard to say where you're getting lost but I'll try a psuedo code example in C# (don't know whether you're using Boo, C#, or Javascript):
public class Example : MonoBehaviour {
public float startTime;
public float diffTime;
void Update() {
if (/* DETECT TOUCH START */ ) {
startTime = Time.time; // Record startTime in secs since game start.
}
if (/* DETECT TOUCH END */ ) {
diffTime = Time.time - startTime; // Record diffTime in secs since startTime.
Debug.Log("startTime / diffTime = " + startTime + " / " + diffTime);
startTime = 0; // Reset startTime.
}
}
}
Platform: iOS6/OSx Lion.
I'm trying to puzzle out the way Phonegap/Cordova work with navigator.geolocation.watchPosition.
The docs says that the option "maximumAge" is the one that ask the system for retrieve the position.
So with these options:
{ maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }
I espect the position request will be fired every 3 seconds?
And no matter what maximumAge I put the success is fired every 1 second...
Anyone can explain please?
Thanks Bye
Rob
I am currently working around this issue by using getCurrentPosition with a setInterval. I'm not sure what the consequences may be, but this seems to give me the most control and appears to be the most consistent method across platforms.
// call this once
setupWatch(3000);
// sets up the interval at the specified frequency
function setupWatch(freq) {
// global var here so it can be cleared on logout (or whenever).
activeWatch = setInterval(watchLocation, freq);
}
// this is what gets called on the interval.
function watchLocation() {
var gcp = navigator.geolocation.getCurrentPosition(
updateUserLoc, onLocationError, {
enableHighAccuracy: true
});
// console.log(gcp);
}
// do something with the results
function updateUserLoc(position) {
var location = {
lat : position.coords.latitude,
lng : position.coords.longitude
};
console.log(location.lat);
console.log(location.lng);
}
// stop watching
function logout() {
clearInterval(activeWatch);
}