I'm playing around with Java and I've got myself a class for an NPC in a game. One method is called when they collide with another object:
public void collided_in_to(Entity ent) {
if(ent.equals(game.player)) {
this.speak = "Ouch!";
}
}
What I want to do, which I figured was going to be simple, is set this.speak to "" after a given amount of seconds. Coming from a web background, I was looking for an equivalent of Javascripts setTimeout().
I've tried using various timer snippets, such as using Swing timers, but in that case it seemed like every timer would call the same public void actionPerformed(ActionEvent e) method, and so with multiple timers for different events I had no way to differentiate between them. Others used inline anonymous classes, but then I have no way to pass non-final parameters to it.
Is there something I'm missing for this use case, where I want very small simple things to happen after a set time? (Instance method called, variable set, etc.)
Thanks!
How about writing you own simple Timer? I would think of something like this :
public class Timer {
long start = 0;
long delay;
public Timer(long delay) {
this.delay = delay;
}
public void start() {
this.start = System.currentTimeMillis();
}
public boolean isExpired() {
return (System.currentTimeMillis() - this.start) > this.delay;
}
}
Then instantiate the Timer class as a class member and call start() when you want to start the timer.
In your method you call
public void collided_in_to(Entity ent) {
if(ent.equals(game.player)) {
if(this.timer.isExpired()) this.speak = "";
else this.speak = "Ouch!";
}
}
If you're using a game loop you could simply make a seconds passed verification.
Have you considered threads? Thread.sleep() can be used fairly effectively to time it.
Related
I have now tried to set up a delay in libGDX in three different ways.
First I tried to use a Timer, but if I restart the activity, the timer won't start again. This is a known issue when using GestureDetector: https://github.com/libgdx/libgdx/issues/2274
Then I tried setting up a timer using Gdx.graphics.getDeltaTime in my render method, but this doesn't work for me as I have set it to non-continous rendering. Described in answer #2 set a delay in libgdx game
Finally I tried using a while loop and System.getCurrentTimeMilliseconds, however this prevented the application from recognizing a tap while the while loop was looping.
I have also heard of DelayAction, but how does one implement that into the code? https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/actions/DelayAction.html
Is there another way of setting a delay? How do one implement DelayAction? Or how does one fix the Timer bug in libGDX?
Inspired by Barodapride's comment, I found a solution where I make a new thread, and put the while loop here. This code will wait for 1000 ms, and then run foo() on the main thread.
new Thread(new Runnable() {
#Override
public void run() {
long time = System.currentTimeMillis();
while (System.currentTimeMillis() < time + 1000){}
Gdx.app.postRunnable(new Runnable() {
#Override
public void run() {
foo();
}
});
}
}).start();
Well i just create an interface like this:
public interface TimeEvents {
public void handleTime(float secondsToEvent,Events event, Object obj);
public void resetTimer();
public void handleEvent(Events event,Object obj);
}
and create a class implementing it for the game entity i want, the Events for my case is an enum with the event to process (Like wait for x seconds, walk for x seconds, fire for x seconds..), the object is the instance of target object i want to handle by event..
public class FooTimeEvents implements TimeEvents{
[...]
private float timeSeconds = 0;
#Override
public void handleTime(float secondsToEvent,Events event, Object obj){
timeSeconds +=Gdx.graphics.getRawDeltaTime();
if(timeSeconds > secondsToEvent){
timeSeconds-=secondsToEvent;
handleEvent(event,obj);
}
}
#Override
public void handleEvent(Events event,Object obj){
switch (event) {
case EVENT_FOO_1:
executeEventFoo1((Foo1Obj)obj);
break;
case EVENT_FOO_2:
executeEventFoo2((Foo2Obj)obj);
break;
default:
break;
}
}
[...]
you call the handleTime on render method of the entity, and the event will only execute each timeSeconds it was set to..
You can use a RunnableAction with a DelayAction. Here are the steps you would take:
Instantiate a RunnableAction and provide it with a Runnable:
RunnableAction runnableAction = Actions.run(new Runnable(){
public void run(){
// Put whatever you want to do here
}
}
Instantiate a DelayAction and provide it with your RunnableAction:
DelayAction delayAction = Actions.delay(secondsOfDelay, runnableAction);
Now in your render or update method you need to tell your delayAction to 'act':
delayAction.act(delta);
Once the delay has passed the code in your runnable should run. I'm sorry if this syntax isn't exactly correct but this should be the easiest way to go. Let me know if something doesn't work for you and I can help.
There are two good (as considered by most) java practices that i try to combine and fail.
Never leak this in a constructor.
Use enum instead of singleton pattern.
So, I want a singleton that as soon as created, listens for some event. Here's an example. First, the event listener interface:
public interface EventListener {
void doSomething();
}
Then, the event producer:
public class EventProducer implements Runnable{
private EventListener listener;
public EventProducer(EventListener listener) {
if (listener == null) {
throw new NullPointerException("Listener should not be null.");
}
this.listener = listener;
}
#Override
public void run() {
listener.doSomething(); //This may run before the listener is initialized.
do {
long startTime = System.currentTimeMillis();
long currentTime;
do {
currentTime = System.currentTimeMillis();
} while ((currentTime - startTime) < 1000);
listener.doSomething();
} while (!Thread.currentThread().isInterrupted());
listener = null; //Release the reference so the listener may be GCed
}
}
Then, the enum (as the 2nd listed java practice suggests):
public enum ListenerEnum implements EventListener{
INSTANCE;
private int counter;
private final ExecutorService exec;
private ListenerEnum() {
EventProducer ep = new EventProducer(this); //Automatically unregisters when the producer is done.
counter = 0;
exec = Executors.newSingleThreadExecutor();
exec.submit(ep);
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
}
And finally, something to get things started:
public class TestRunner {
public static void main(String[] args) {
ListenerEnum.INSTANCE.doSomething();
}
}
The problem lies in the first line of the ListenerEnum constructor, as we are leaking this, thus not conforming to the 1st listed java practice. This is why our event producer can call a listener's method before the listener is constructed.
How do I deal with this? Normally I would use a Builder pattern, but how is that possible with an enum?
EDIT:
For those that it matters, the event producer in my program actually extends a BroadcastReceiver, so my enum cannot be the event producer, they have to be separate. The producer is created in the constructor of the enum (as the example) and is registered programmatically later on. So I don't actually have a problem leaking this. Nevertheless, I'd like to know if I could avoid it.
EDIT 2:
Ok, since there are suggestions to solve my problem, i'd like to clarify some things. First of all, most suggestions are workarounds. They suggest doing the same thing in a completely different way. I appreciate the suggestions, and probably will accept one as answer and implement it. But the real question should be "How do i implement a Builder pattern with an enum?" The answer i already know and people suggest is "You don't, do it some other way.". Is there anyone who can post something like "You do! You do it this way."?
I was asked to give code close to my actual use case. Modify the following:
public enum ListenerEnum implements EventListener{
INSTANCE;
private EventProducer ep;
private int counter;
private ExecutorService exec;
private ListenerEnum() {
ep = new EventProducer(this); //Automatically unregisters when the producer is done.
counter = 0;
}
public void startGettingEvents() {
exec = Executors.newSingleThreadExecutor();
exec.submit(ep);
}
public void stopGettingEvents() {
exec.shutdownNow();
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
stopGettingEvents();
}
}
}
As well as this:
public class TestRunner {
public static void main(String[] args) {
ListenerEnum.INSTANCE.startGettingEvents();
}
}
Now all i have to do to solve my problem is move the EventsProducer creation to the startGettingEvents() method. That's it. But that is also a workaround. What i'd like to know is: In general, how do you avoid leaking this in the constructor of a listener enum since you can't use the Builder pattern? Or can you actually someway use the Builder pattern with an enum? Is it done only by workarounds in a case by case basis? Or is there a general way to deal with this that i don't know of?
Just create a static initialization block:
public enum ListenerEnum implements EventListener{
INSTANCE;
private int counter;
private static final ExecutorService exec; //this looks strange. I'd move this service out of enum.
private static final EventProducer ep;
static{
exec = Executors.newSingleThreadExecutor();
ep = new EventProducer(INSTANCE); //Automatically unregisters when the producer is done.
exec.submit(ep);
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
}
As long as enum values are final and static they are initialized before the static initialization block. If you decompile the enum you'll see a single initialization block:
static{
INSTANCE = new ListenerEnum();
exec.submit(INSTANCE.ep);
}
First, consider why this shouldn’t escape:
You loose the final field safe publication guaranty in case of an improper publication of the instance
Even with a safe publication there are inconsistencies regarding all action not performed within the constructor at the time of the leakage
You will let escape an incomplete instance in case of subclasses as the subclass’ constructor hasn’t been called so far
That doesn’t apply to you in this narrow case. Submitting to an Executor is not an improper publication and enum’s can’t escape in any other way besides the one you have implemented yourself in the constructor. And its the last thing in the constructor whereas enums can’t have subclasses.
Now that you have edited your question, it makes much lesser sense. The constructor
private ListenerEnum() {
ep = new EventProducer(this);
counter = 0;
}
is not a “leaking this” as long as ep is not a static variable and the constructor of EventProducer does not let leak its this as well. This is important as programmers must be able to create circular object graphs without fearing sudden inconsistencies.
But it is still nothing you should take too easy. As said, it relies on the behavior of the EventProducer regarding leakage and regarding that EventProducer must not call back into ListenerEnum which could break things without being a “leaking this”, technically. After all, you can create code that breaks without breaking thread safety.
So it’s code for which you can’t see the correctness when looking at it as you need knowledge about another class.
There are use cases where passing this to another object is considered safe because of well-known behavior, e.g. weakThis=new WeakReference(this); is a real-life example. However, passing this to something called EventProducer is likely to let alarm bells ringing for every reader which you should avoid even if you know for sure that it’s false-alarm.
However, the big design smell lies in the use of the Singleton pattern in itself. After all, every instance you create is unique in the first place. What is special about the Singleton pattern is that it provides global public access to that instance. Is that really what you want? Did you consider that by using the Singleton pattern, everyone inside the entire application could register that listener again?
The fact that your class is a singleton (whether enum-based or otherwise) is unrelated to your problem. Your problem is simply how to register a listener within the constructor of an object. And the answer is: it's not possible, safely.
I would recommend you do two things:
Ensure your listener doesn't miss out on events by having a queue that it polls for work. This way, if it temporarily isn't listening, the work just queues up. In fact, this means it doesn't really need to be a listener in the traditional sense. It just needs to poll on a queue.
Register the class as a listener using a separate method, as discussed in the comments.
I would give some thought to avoiding a singleton. It doesn't offer many advantages (asides from the minor benefit of being able to call SomeClass.INSTANCE from anywhere). The downsides are most strongly felt during testing, where you find it much harder to mock the class when you wish to test without actually sending things over the network.
Here's a concrete example of why leaking this is dangerous in your case. Your constructor passes this before setting counter to zero:
private ListenerEnum() {
ep = new EventProducer(this);
counter = 0;
}
Now, as soon as this escapes, your event producer might invoke doSomething() 5 times before the constructor completes:
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
The sixth call to this method ought to fail right? Except that your constructor now finishes and sets counter = 0;. Thus allowing the producer to call doSomething() 5 more times.
Note: it doesn't matter if you reorder those lines as the constructor may not be executed in the order it appears in your code.
I've been searching for a solution for a long time, but I wasn't able to find one, so I'll ask my question here.
I have a thread which is started when the program starts and supposed to be idle until it is enabled by the application. Simple code example:
private class UpdaterThread extends Thread {
private static final int UPDATE_RATE = 50;
private Timer updateTimer = new Timer();
private boolean enabled;
public void run() {
while (!closeRequested) {
// If this is uncommented, the thread works as it's supposed to.
// System.out.print("");
if (enabled) {
Snapshot next = getNextSnapshot(1f / UPDATE_RATE);
System.out.println("Got next Snapshot");
updateTimer.sync(UPDATE_RATE);
System.out.println("Push");
currentSnapshot = next;
}
}
}
public void enable() {
enabled = true;
}
public void disable() {
enabled = false;
}
}
When you read a variable, which the JIT believes you didn't modify, it inlines the value. If you then modify the value later, it is too late, the value has been embedded in the code.
A simple way to avoid this is to use volatile but you would still have the problem than the thread is busy waiting for the value to change and there doesn't appear to be a good reason to do this. Another option is to add code which confuses the JIT do it doesn't do this optimisation. An empty synchronized block is enough but a friendlier way is to use Thread.sleep() which at least doesn't use up all your CPU.
I suggest using a volatile fields and sleeping with a period of 10-100 ms. However a simpler option is to not start the thread until it is needed.
since run() is called when the thread is started, you could just wait until later in the program to start it, also threads do not extend "Thread" but implements "Runnable" so the class definition would look like:
public class UpdaterThread implements Runnable
hope it helps :D
For the problem I am solving, I have to run a series of calls at periodic intervals. To achieve this, I have implemented TimerTask. However, I also want to notify the timertask sometimes and need to call the same methods when certain conditions are met even if the timer did not expire. My code looks similar to this.
//File TimerTaskA.java
public class TimerTaskA extends TimerTask
{
#Override
public void run()
{
processEvent1();
processEvent2();
processEvent3();
}
}
//File ProcessEventManager.java
public class ProcessEventManager
{
public TimerTaskA timerTask;
public ProcessEventManager()
{
initTimerTask();
}
public void initTimerTask()
{
Timer timer = new Timer("TimerTaskA", true);
timerTask == new TimerTaskA();
timer.schedule(timerTask , 0, 10000);
}
public void conditionalTask()
{
long time = System.currentTimeMillis();
// some condition statement. here it happens to be time in millisecs ends with 2 or 3.
if (time%10 == 2 || time%10 == 3)
timerTask.run();
}
}
In the ProcessEventManager.conditionalTask() method is it correct to call TimerTask's run() method directly to get through this situation? Is there a better way design wise to solve something like this?
The processEvent methods might be time consuming methods, and I do not want the thread running ProcessEventManager to be blocked while executing those methods. For the TimerTask to take care of running those methods in both the cases when timer expires as well as the condition in ProcessEventManager.conditionalTask is satisfied, what is the best way to do it?
Basically, yes, it is possible to do as you wrote, but a clearer way will be to call some processing method from inside the TimerTask, and when you want to perform this operation, call it directly, not through the TimerTask object.
public class TimerTaskA extends TimerTask
{
public void doCoolThings()
{
processEvent1();
processEvent2();
processEvent3();
}
#Override
public void run()
{
doCoolThings();
}
}
in the other class, when needed:
timerTask.doCoolThings();
The reason as I see it, is mainly because the purpose of run is to serve as the thread (or caller) entry point, not to do a specific task.
In the Observer Design Pattern, the subject notifies all observers by calling the update() operation of each observer. One way of doing this is
void notify() {
for (observer: observers) {
observer.update(this);
}
}
But the problem here is each observer is updated in a sequence and update operation for an observer might not be called till all the observers before it is updated. If there is an observer that has an infinite loop for update then all the observer after it will never be notified.
Question:
Is there a way to get around this problem?
If so what would be a good example?
The problem is the infinite loop, not the one-after-the-other notifications.
If you wanted things to update concurrently, you'd need to fire things off on different threads - in which case, each listener would need to synchronize with the others in order to access the object that fired the event.
Complaining about one infinite loop stopping other updates from happening is like complaining that taking a lock and then going into an infinite loop stops others from accessing the locked object - the problem is the infinite loop, not the lock manager.
Classic design patterns do not involve parallelism and threading. You'd have to spawn N threads for the N observers. Be careful though since their interaction to this will have to be done in a thread safe manner.
You could make use of the java.utils.concurrent.Executors.newFixedThreadPool(int nThreads) method, then call the invokeAll method (could make use of the one with the timout too to avoid the infinite loop).
You would change your loop to add a class that is Callable that takes the "observer" and the "this" and then call the update method in the "call" method.
Take a look at this package for more info.
This is a quick and dirty implementation of what I was talking about:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main
{
private Main()
{
}
public static void main(final String[] argv)
{
final Watched watched;
final List<Watcher> watchers;
watched = new Watched();
watchers = makeWatchers(watched, 10);
watched.notifyWatchers(9);
}
private static List<Watcher> makeWatchers(final Watched watched,
final int count)
{
final List<Watcher> watchers;
watchers = new ArrayList<Watcher>(count);
for(int i = 0; i < count; i++)
{
final Watcher watcher;
watcher = new Watcher(i + 1);
watched.addWatcher(watcher);
watchers.add(watcher);
}
return (watchers);
}
}
class Watched
{
private final List<Watcher> watchers;
{
watchers = new ArrayList<Watcher>();
}
public void addWatcher(final Watcher watcher)
{
watchers.add(watcher);
}
public void notifyWatchers(final int seconds)
{
final List<Watcher> currentWatchers;
final List<WatcherCallable> callables;
final ExecutorService service;
currentWatchers = new CopyOnWriteArrayList<Watcher>(watchers);
callables = new ArrayList<WatcherCallable>(currentWatchers.size());
for(final Watcher watcher : currentWatchers)
{
final WatcherCallable callable;
callable = new WatcherCallable(watcher);
callables.add(callable);
}
service = Executors.newFixedThreadPool(callables.size());
try
{
final boolean value;
service.invokeAll(callables, seconds, TimeUnit.SECONDS);
value = service.awaitTermination(seconds, TimeUnit.SECONDS);
System.out.println("done: " + value);
}
catch (InterruptedException ex)
{
}
service.shutdown();
System.out.println("leaving");
}
private class WatcherCallable
implements Callable<Void>
{
private final Watcher watcher;
WatcherCallable(final Watcher w)
{
watcher = w;
}
public Void call()
{
watcher.update(Watched.this);
return (null);
}
}
}
class Watcher
{
private final int value;
Watcher(final int val)
{
value = val;
}
public void update(final Watched watched)
{
try
{
Thread.sleep(value * 1000);
}
catch (InterruptedException ex)
{
System.out.println(value + "interupted");
}
System.out.println(value + " done");
}
}
I'd be more concerned about the observer throwing an exception than about it looping indefinitely. Your current implementation would not notify the remaining observers in such an event.
1. Is there a way to get around this problem?
Yes, make sure the observer work fine and return in a timely fashion.
2. Can someone please explain it with an example.
Sure:
class ObserverImpl implements Observer {
public void update( Object state ) {
// remove the infinite loop.
//while( true ) {
// doSomething();
//}
// and use some kind of control:
int iterationControl = 100;
int currentIteration = 0;
while( curentIteration++ < iterationControl ) {
doSomething();
}
}
private void doSomething(){}
}
This one prevent from a given loop to go infinite ( if it makes sense, it should run at most 100 times )
Other mechanism is to start the new task in a second thread, but if it goes into an infinite loop it will eventually consume all the system memory:
class ObserverImpl implements Observer {
public void update( Object state ) {
new Thread( new Runnable(){
public void run() {
while( true ) {
doSomething();
}
}
}).start();
}
private void doSomething(){}
}
That will make the that observer instance to return immediately, but it will be only an illusion, what you have to actually do is to avoid the infinite loop.
Finally, if your observers work fine but you just want to notify them all sooner, you can take a look at this related question: Invoke a code after all mouse event listeners are executed..
All observers get notified, that's all the guarantee you get.
If you want to implement some fancy ordering, you can do that:
Connect just a single Observer;
have this primary Observer notify his friends in an order you define in code or by some other means.
That takes you away from the classic Observer pattern in that your listeners are hardwired, but if it's what you need... do it!
If you have an observer with an "infinite loop", it's no longer really the observer pattern.
You could fire a different thread to each observer, but the observers MUST be prohibited from changing the state on the observed object.
The simplest (and stupidest) method would simply be to take your example and make it threaded.
void notify() {
for (observer: observers) {
new Thread(){
public static void run() {
observer.update(this);
}
}.start();
}
}
(this was coded by hand, is untested and probably has a bug or five--and it's a bad idea anyway)
The problem with this is that it will make your machine chunky since it has to allocate a bunch of new threads at once.
So to fix the problem with all the treads starting at once, use a ThreadPoolExecutor because it will A) recycle threads, and B) can limit the max number of threads running.
This is not deterministic in your case of "Loop forever" since each forever loop will permanently eat one of the threads from your pool.
Your best bet is to not allow them to loop forever, or if they must, have them create their own thread.
If you have to support classes that can't change, but you can identify which will run quickly and which will run "Forever" (in computer terms I think that equates to more than a second or two) then you COULD use a loop like this:
void notify() {
for (observer: observers) {
if(willUpdateQuickly(observer))
observer.update(this);
else
new Thread(){
public static void run() {
observer.update(this);
}
}.start();
}
}
Hey, if it actually "Loops forever", will it consume a thread for every notification? It really sounds like you may have to spend some more time on your design.