I'm making a simple matching game and would like a count down timer. Is there a way to set off an event every dt? I found some code using threads, but seems a lot more complicated for what I need.
Something like this should work:
TimerTask countdown = new TimerTask() {
public void run() {
synchronized(UiApplication.getEventLock()) {
//do the stuff to the UI, ie change the counter
}
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(countdown, 0, dt);
I didn't test this, so I may have a typo in there, but this is the basic idea. Take a look at the TimerTask and Timer documentation for more info.
Related
I use the libpd4unity package to communicate with Pure Data. I receive a bang from Pure Data with LibPD.Bang. On a bang event I play sound by FMOD.
Problem is, that I receive bangs frequently, for example once every 500 ms but event doesn't trigger in specific length of frame. Usually length change 1 frame less or more.
Is there a solution for this problem? For example a framerate independent event? I want to know if event (delegate) in Unity3D is framerate independent or not.
Because there is tempo for playing each sound and just 1 frame ruins rhythm.
I need to sync sounds for playing by each separate bang.
Regarding your question on whether delegates are dependent or independent from Unity's framerate, there's no straight answer. It depends on how your delegates are called. Are they called from a thread? Are they executed in a thread?
Coroutines are not framerate independent, they are executed in Unity's loop.
The following script should shine a light on the difference between handling delegates in coroutines and in threads.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class DelegatesAndFramerate : MonoBehaviour {
delegate void MyDelegate();
MyDelegate myDelegate1; // done with coroutines
MyDelegate myDelegate2; // done with threads
Thread thread;
bool threadDone = false;
private int frameCount = 0;
private int delegate1CallCount = 0;
private int delegate2CallCount = 0;
private int callerLoopsCount_coroutine = 0;
private int callerLoopsCount_thread = 0;
void Start () {
myDelegate1 += Elab1;
myDelegate2 += Elab2;
StartCoroutine(CallerCoroutine());
thread = new Thread(new ThreadStart(CallerThread));
thread.Start();
}
void Update()
{
frameCount++;
}
void Elab1()
{
delegate1CallCount++;
}
void Elab2()
{
delegate2CallCount++;
}
IEnumerator CallerCoroutine()
{
while(true)
{
callerLoopsCount_coroutine++;
myDelegate1();
yield return null;
}
}
void CallerThread()
{
while(!threadDone)
{
callerLoopsCount_thread++;
myDelegate2();
}
}
void OnDestroy()
{
Debug.Log("Frame Count: " + frameCount);
Debug.Log("Delegate Call Count (Coroutine): " + delegate1CallCount);
Debug.Log("Delegate Call Count (Thread): " + delegate2CallCount);
Debug.Log("Caller Loops Count (Coroutine): " + callerLoopsCount_coroutine);
Debug.Log("Caller Loops Count (Thread): " + callerLoopsCount_thread);
threadDone = true;
thread.Join();
}
}
If you attach it to a GameObject and let Unity play for some seconds you'll see that the times the delegate was called from a coroutine is equal to the number of executed frames whilst the times the delegate was called from the thread will be way bigger.
I have experience in interfacing softwares similar to Pure Data and I think what you need is a (rather typical) thread with all your delegates there, create a queue of commands for Unity and digest it in Unity's Update.
Not knowing libPD in the specific this might not be the best practice for the case but it is a widely used approach. Basically the producer-consumer pattern.
Basing on the example GUITextScript.cs, libPD only requires you to subscribe to the right delegates. You don't have control on when these are executed, the library has; so if you keep having this issue it's worth submitting a bug report to the developers I guess.
I want to have something like a TimerTask in JavaFX.
I have a order of Functions, this Functions should be repeated every 1/2 Second maybe every 1/4 Second.
This Functions have some effects for a GUI Component in JavaFX.
Can you give me an TimerTask (JavaFX) example ? I can not use Timer Task, becouse the Compiler said this:
Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-0
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:237)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:398)
at javafx.scene.Parent$1.onProposedChange(Parent.java:245)
at com.sun.javafx.collections.VetoableObservableList.clear(VetoableObservableList.java:146)
at com.sun.javafx.charts.Legend$1.onChanged(Legend.java:55)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:134)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:48)
at com.sun.javafx.collections.ObservableListWrapper.callObservers(ObservableListWrapper.java:97)
at com.sun.javafx.collections.ObservableListWrapper.clear(ObservableListWrapper.java:184)
at javafx.scene.chart.AreaChart.updateLegend(AreaChart.java:420)
at javafx.scene.chart.XYChart$2.onChanged(XYChart.java:96)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:134)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:48)
at com.sun.javafx.collections.ObservableListWrapper.callObservers(ObservableListWrapper.java:97)
at com.sun.javafx.collections.ObservableListWrapper.removeFromList(ObservableListWrapper.java:383)
at com.sun.javafx.collections.ObservableListWrapper.removeAll(ObservableListWrapper.java:271)
at de.sick.suit.framework.control.fx.HistogramChart.deleteData(HistogramChart.java:170)
at de.sick.suit.framework.samples.ImageHistogram.run(ImageHistogram.java:200)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Thank you for your help!
You can use a ScheduledService. The example from the javadoc:
you may want to ping a server on a regular basis to see if there are any updates. Such as ScheduledService might be implemented like this:
ScheduledService<Document> svc = new ScheduledService<>(Duration.seconds(1)) {
protected Task<Document> createTask() {
return new Task<Document>() {
protected Document call() {
// Connect to a Server
// Get the XML document
// Parse it into a document
return document;
}
}
// TIMER
Timeline line = new Timeline(new KeyFrame(Duration.seconds(0.2), new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent arg0)
{
sek++;
puls(imgHisto, startingArea);
System.out.println(" Sek: " + sek);
}
}));
line.setCycleCount(Animation.INDEFINITE);
line.play();
I handeld the Problem with a TimeLine. This works very fine for my example!
You need to provide more Code, but as of now I think you are not updating the UI properly. If you are in another Thread (which you seem to be if you are using a Task), whenever you want to update the UI you need to use
Platform.runLater();
Your Stacktrace indicates this.
You were updating GUI component outside the JavaFX application thread.
Try something like this
Platform.runLater(new Runnable(){
#Override
public void run(){
//update GUI here
}
});
I'm learning to develop windows phone application. I started with a browser based app by following this tutorial - http://blogs.msdn.com/b/jaimer/archive/2011/02/04/back-button-press-when-using-webbrowser-control-in-wp7.aspx. I'm experimenting with http://m.facebook.com I can correctly use back button to go to the previous page and all that stuff but I'm not able to implement exit on double tap of back button.
I have seen many browsers app which exit after double tapping the back button. for example - Flipkart - http://www.windowsphone.com/en-us/store/app/flipkart/84fc03ea-210d-4e3e-88e0-de502a2434c5
There is no double tab event for back button. How can we achieve this?
You can create a global long that represents the last time the user pressed the back button.
Every time the back button is pressed, you can make your program subtract the number of elapsed ticks. If it has passed a short amount of ticks, you can make your program exit. If not, set the last tick variable once more.
You can get the current tick that represents the current time with System.DateTime.Ticks.
Simple code sample:
long LastExitAttemptTick = DateTime.Ticks;
private void BackButtonPressHandler(...)
{
long thisTick = DateTime.Ticks;
if (LastExitAttemptTick - thisTick < [specified amount])
throw new Exception("Exit Exception"); //You can use XNA, but this is a quick and dirty way of exiting
else
LastExitAttemptTick = DateTime.Ticks;
}
You can use a value of 10,000,000 ticks (1 second). MSDN says 10,000 ticks per millisecond, so 10,000 * 1000 = 10,000,000.
EDIT: Or as you said, you can also use DateTime.Now and use the seconds value instead. Either way works.
well this kind of logic could work for you
make a global variable
int Count=0
protected ovverride void OnBackKeyPress(CancelEventArgs e)
{
if(Count==0)
{
e.Canel=true;
Count++;
}
else if(Count==1)
{
Count=0;
//code for exiting
//may be App.Current.Terminate(); in wp8
//or in wp7
//if (NavigationService.CanGoBack)
//{
// while (NavigationService.RemoveBackEntry() != null)
// {
// NavigationService.RemoveBackEntry();
// }
//}
}
}
Hope this helps
To close the application on double click, you can use DispatcherTimer task to check whether a two clicks are within one second, if yes close the application else start timer and again check. The snippet for that as follows:
make a DispatcherTimer object as a class field like,
DispatcherTimer dt = new DispatcherTimer();
In your class's constructor specify the interval you want to check for double tap and also add event handler to perform some action when specified time has elapsed. You can do in a class's constructor,
dt.Interval = TimeSpan.FromSeconds(1.0);
dt.Tick += delegate(object s, EventArgs e)
{
dt.Stop();
};
Here what we're doing is we're specifying timespan of 1 second to check whether double tap occurs within that second. Tick event is for what we want to do when timer completes its 1 second. We're simply going to stop the timer.
Now navigate to back key event handler and here is my code to check double tap:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
if (!dt.IsEnabled)
dt.Start();
else
new Microsoft.Xna.Framework.Game().Exit();
}
When for the first tap, timer is not started, it will go to if condition and will start the timer. If second tap occurs after 1 second, then the Tick event we wrote in constructor will fire and according to logic written there, the timer will stop.
Now assume the double tap occurs consequently within 1 second. For the 1st tap as usual it will start the timer, if immediately user presses back button again, then in its handler, it will check whether timer is running. As timer has not completed its 1 second interval, else condition will fired up and the application will close.
I used XNA library / shortcut to force close the application. To work with new Microsoft.Xna.Framework.Game().Exit(); method you should add a microsoft.xna.framework.game.dll in a reference.
Make TimeSpan interval as required.
Hope this helps. Thanks.
EDIT:
Sometimes XNA is not installed on windows 8. Here is a solution for that, so that you add above mentioned assembly reference in you project.
http://blogs.msdn.com/b/astebner/archive/2012/02/29/10274694.aspx
You have to download update which is around around 23MB.
To save time here's a Dropbox link to above assembly reference:
https://db.tt/RYTwv7cS
Yes there is no Double Tap event for back button. You have to write your own logic to exit application on Double Tap on device back key tap twice. Here is the solution this may be help you.
Create a Global variable and initialize with zero
Int TapCount =0;
Now Override OnBackKeyPress event with your own logic.
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
TapCount++;
if(TapCount==2)
{
if( windows phone 8 )
{
Application.Current.Terminate();
}
else
{
if (NavigationService.CanGoBack)
{
while (NavigationService.RemoveBackEntry() != null)
{
NavigationService.RemoveBackEntry();
}
}
}
}
else
e.Canel=true;
base.OnBackKeyPress(e);
}
It's very simple. I've implemented it like this:
First declare global variable:
int count;
Now initialize its value in OnNavigatedTo(NavigationEventArgs e) method:
count = 0;
Now at last add the below code to your cs file:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
count++;
e.Cancel = true;
if(count == 2)
{ e.Cancel = false; base.OnBackKeyPress(e); }
}
I developed Windows service that is using System.Threading.Timer. Timer is starting every x minutes and it works fine (timer is updatet at the end of method). But, if there is an error in try block service just stops despite the fact that I'm updating timer and telling him when to start again
why is that happening? Here is code :
System.Threading.Timer serviceTimer;
protected override void OnStart(string[] args)
{
TimeSpan diff;
diff = nextRun - now;
TimerCallback timerDelegate =
new TimerCallback(MyTimerCallback);
serviceTimer = new System.Threading.Timer(timerDelegate, null,
diff, new TimeSpan(-1));
}
public void MyTimerCallback(object something)
{
try
{
//possible error that happened
}
catch(Exception)
{
}
finally
{
//diff is a new variable telling timer when to start again
serviceTimer.Change(diff, new TimeSpan(-1));
}
}
what am I missing why service stops if there was an error?
Maybe the timer wasn't able to change. Timer.Change returns a boolean:
true if the timer was successfully updated; otherwise, false.
But you're not checking that result. I'd recommend probably disposing the timer and newing up a new one each time, since it's already fired and you created it as a "one shot" timer, e.g.
finally
{
serviceTimer.Dispose();
serviceTimer = new System.Threading.Timer(timerDelegate, null,
diff, new TimeSpan(-1));
}
In case that someone deals with same problem I figured something like this:
Since I want my service to stay alive no matter what :
I 'm reporting to the service manager that the service has successfully started -
base.OnStart(args);
In configuration you can set legacyUnhandledExceptionPolicy set to true (1)
Is there a easy way to perform a method after a given delay like in iOS out of the box?
On iPhone I would do this:
[self performSelector:#selector(connectSensor) withObject:nil afterDelay:2.5];
It will then schedule the method connectSensor on the main thread (UI thread) to be executed after 2,5 seconds. And because it is automatically scheduled on the main thread, you don't have to worry about cross thread issues. (There is also a performSelectorOnBackground version)
So how would I do this properly in WP7?
Currently I'm accomplishing this with a timer, but I'm not sure if this is a good solution.
private Timer timer;
private void DoSomethingAfterDaly()
{
// ... do something here
timer = new Timer( (o) => Deployment.Current.Dispatcher.BeginInvoke(() => NavigationService.GoBack()), null, 2500, Timeout.Infinite);
}
How could this be encapsulated into an extension method so I can just call this.Perform(MyMethod, null, 2500); ?
You can use a BackgroundWorker like so:
private void Perform(Action myMethod, int delayInMilliseconds)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) => Thread.Sleep(delayInMilliseconds);
worker.RunWorkerCompleted += (s, e) => myMethod.Invoke();
worker.RunWorkerAsync();
}
The call into this method would look like this:
this.Perform(() => MyMethod(), 2500);
The background worker will run the sleep on a thread off of the UI thread so your application is free to do other things while the delay is occurring.
You can use the Reactive Extensions for WP7 to observe on a timer:
Observable
.Timer(TimeSpan.FromMilliseconds(2500))
.SubscribeOnDispatcher()
.Subscribe(_ =>
{
NavigationService.GoBack();
});
Given the brevity of this code, I don't think you'd gain much by creating an extension method for it :) For more information about the Reactive Extensions for WP7, take a look at this MSDN page
.