How to create a simple state machine in java - java

I am currently learning java and would like to know how to control state in a OO way. I implemented a Pong app. If I wanted multiple states like gameplay and menu, and each one of these states had to execute start, stop and run how would I achieve this and how would I switch between these states.
I know I could simply throw in a big switch statement but what's the best way to implement this?
I want to be able to switch to the menu state in the gameplay state and vice versa.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Pong extends Applet implements Runnable, KeyListener{
public void start ()
{
setSize(screen);
setFocusable(true);
Thread th = new Thread (this);
th.start ();
}
public void stop()
{
}
//Etc..
}

You can simulate a basic FSM (Finite State Machine) using enums:
public enum State {
ONE {
#Override
public Set<State> possibleFollowUps() {
return EnumSet.of(TWO, THREE);
}
},
TWO {
#Override
public Set<State> possibleFollowUps() {
return EnumSet.of(THREE);
}
},
THREE // final state
;
public Set<State> possibleFollowUps() {
return EnumSet.noneOf(State.class);
}
}
While the code to generate this will be very verbose if things get more complicated, the nice part is that you get compile-time safety, thread-safety and high performance.

You don't have to do it yourself, here is a very simple but powerful state machine implementation based on Java8 that you can utilize directly:
https://github.com/swiftech/SWState

Related

Several threads for run render in Android 3D game. Thread-safe?

For a long time I tried to make smooth animation for the application. And I got this solution: several threads launch draw frame of SceneRenderer:
public class OGLView extends GLSurfaceView {
public void init(Context context, int versionGLES) {
...
renderer = new SceneRenderer(context, versionGLES);
setRenderer(renderer);
...
}
}
public class SurfaceRunnable implements Runnable {
...
#Override
public void run() {
while(true) {
surfaceView.requestRender(); // draw frame
if (Thread.currentThread().isInterrupted()) break;
}
}
}
public class SurfaceExecutor implements Executor {
private List<Thread> threads = new ArrayList<>();
#Override
public void execute(#NonNull Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setPriority(10);
thread.start();
threads.add(thread);
}
...
}
public class GameActivity extends AppCompatActivity {
private SurfaceExecutor executor = new SurfaceExecutor();
#Override
protected void onResume() {
...
SurfaceRunnable sr = new SurfaceRunnable(oglView);
/* run four threads for SceneRender */
executor.execute(sr);
executor.execute(sr);
executor.execute(sr);
executor.execute(sr);
...
}
}
As a result, the animation has become smoother. Long testing of the application did not lead to errors. Testing on different device configurations did not detect changes in the animation rate. Question: How much is this approach thread safe? All drawing and operations with matrices are done in SceneRenderer. Thank you all. Please, excuse my English.
Without a complete application it's impossible to say whether this is safe or not, as that entirely depends on what those 4 threads are doing and what resources are shared across them.
In all honesty though, this looks like a nasty hack. All 4 threads seem to be doing the same thing, any any fix of "just run 4 copies of the same thing and hope" seems to be running better by luck rather than any particular intentional design benefit.

Setting Button command javafx

I've been using JFrame to learn graphics and test my code because I know it much better. Now I want to update to Javafx. I have this JListener class that handles all the buttons for my JFrame. Is it possible to still use this class with Javafx? If so how?
For example, with JFrame I could use Button.setActionCommand("command"); and when the button was pressed it would run this with the actionListener, can I do this same thing with javafx?
package src.com.Kingdom;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Scanner;
import java.net.*;
public class JListener implements ActionListener
{
private boolean registered = false;
registerClient register;
loginClient login;
static GUIs gui = new GUIs();
#Override
public void actionPerformed(ActionEvent e) {
switch(e.getActionCommand()) {
case("login"):
login = new loginClient(gui.getUsername(), gui.getPassword());
System.out.println("Login");
break;
case("exit"):
System.out.println("exit");
break;
case("register"):
System.out.println("register");
gui.getFrame().dispose();
gui.createRegisterGui();
break;
case("registerperson"):
if(gui.checkRegister()) {
if(hasInternet()) {
if(!(registered)) {
registered = true;
try {
register =
new registerClient(gui.getUsername(), gui.getPassword(), gui.getEmail(), gui.getAge());
} catch(Exception ex) {
GUIs.showError(ex.getMessage());
}
if(!(register.isRegistered())) {
gui.createLoginGui();
}
new Timer().schedule(new TimerTask() {
public void run() {
registered = false;
}
},1000*1);
}
} else {
GUIs.showError("No Internet! Please connect to internet to connect!");
}
} else {
GUIs.showError("Problem with registration format");
}
break;
}
}
}
It is technically possible to integrate JavaFX and Swing. Oracle provide a tutorial on this. I don't recommend integrating the two unless you really need to (which you probably don't in this case). Note that the level of integration possible is just embedding Swing Components into JavaFX nodes (or vice versa). You cannot directly use a Swing listener to take action on a JavaFX button press.
Instead, I recommend that you write your code native to a single library, either JavaFX or Swing.
For your example code. The JavaFX equivalent for handling button actions is:
button.setOnAction(EventHandler<ActionEvent>)
How would I set the String for the action command? Is this possible? Or do I have to do it a different way?
You wouldn't, it's not necessary.
I don't code Swing, so I'm not familiar with the Swing ActionEvent. From looking at your code, your listener seems to be providing a single point for handling multiple action events which originate from different sources, then acting on them.
For JavaFX, just define separate event handlers for each source rather than using switches, then you don't need to pass a string to the action command because it is clear what action is to be taken based upon the context.
For instance:
loginButton.setOnAction(event -> { /** handle login **/});
exitButton.setOnAction(event -> { /** handle exit **/});
If you have multiple ways to trigger the actions, for instance an exit could be triggered by both a menu item and a button, then you can define a variable for the action handler and reuse that for each instance, for instance:
EventHandler<ActionEvent> exitHandler = event -> { /** handle exit **/ };
exitButton.setOnAction(exitHandler);
exitMenuItem.setOnAction(exitHandler);

Is this a valid way to minimize binding invalidations?

I have some complex Observable structures, which may or may not be bad ideas, but which are not the focus of this question.
The problem with those structures is that they generate a lot of invalidations of Observable objects being displayed by the UI. As near as I can tell, when the JavaFX UI is displaying something, it registers a ChangeListener on it, so any attempts to use lazy evaluation go out the window. That is, invalidating the observable seems to tell the UI that it has potentially changed, which causes the UI to immediately request it's value, forcing it to evaluate immediately.
So, I had the idea of deferring the invalidations via Platform.runLater().
I created a class called DeferredBinding that delegates everything to a wrapped Binding, except the invalidate() method, which it defers to the JavaFX UI thread to be processed later. It seems to work... I can invalidate a hundred times and it only seems to actually process the invalidation once.
But, I've not seen this pattern before and I am afraid it might fall into the category of "nice try but bad idea".
So, question: is this a bad idea? I am particularly concerned of errors introduced into other Observable objects that depend on the DeferredBinding. Will they be fine once the Platform.runLater() happens?
package com.myapp.SAM.model.datastructures;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.Binding;
import javafx.beans.value.ChangeListener;
import javafx.collections.ObservableList;
/**
* Specialized binding that defers its invalidations to the JavaFX UI thread in a throttled manner. The idea being that, if invalidate() is called many times,
* it only basically happens once (when the UI thread gets to it).
*/
public class DeferredBinding<T> implements Binding<T> {
private static final Logger logger = Logger.getLogger(DeferredBinding.class.getName());
private final Binding<T> binding;
private final AtomicBoolean pendingInvalidation = new AtomicBoolean(false);
public DeferredBinding(Binding<T> binding) {
this.binding = binding;
}
#Override
public void addListener(ChangeListener<? super T> listener) {
binding.addListener(listener);
}
#Override
public void removeListener(ChangeListener<? super T> listener) {
binding.removeListener(listener);
}
#Override
public T getValue() {
return binding.getValue();
}
#Override
public void addListener(InvalidationListener listener) {
binding.addListener(listener);
}
#Override
public void removeListener(InvalidationListener listener) {
binding.removeListener(listener);
}
#Override
public boolean isValid() {
return binding.isValid();
}
/**
* Override logic for invalidate() method to defer invalidation to runLater. Throttle the invalidations so as not to floor the JavaFX UI thread with
* multiple calls
*/
#Override
public void invalidate() {
if (pendingInvalidation.getAndSet(true) == false) {
Platform.runLater(() -> {
// Signal that the UI is processing the pending invalidation, so any additional invalidations must schedule another update.
pendingInvalidation.set(false);
binding.invalidate();
});
}
}
#Override
public ObservableList<?> getDependencies() {
return binding.getDependencies();
}
#Override
public void dispose() {
binding.dispose();
}
}
I would not try to solve performance problems ahead of time. Measure your application to determine if you have a problem and then go ahead..
Let's assume you have a problem, there are many ways to solve your abstract problem. Three solutions come to my mind:
1
Coalesce updates (Platform.runLater()) to prevent saturation of the FX event queue as you have done in your example.
And since you are just invalidating the binding you do not have to fear loosing a value on the way. So it seems (without knowing the full application) that this way should work.
2
Using the Nodes built-in behavior of marking regions dirty for (re-)layouting. At some point you will call javafx.scene.Parent.requestLayout() (this is the "invalidation") which will at some point in the future call javafx.scene.Parent.layoutChildren() to apply the dirty attributes to the region.
3
Using solution 2 in a different way: By using a virtualized layout container. The TableView, TreeTableView and ListView all use the virtualized approach to update only the visible cells.
See com.sun.javafx.scene.control.skin.VirtualFlow and com.sun.javafx.scene.control.skin.VirtualContainerBase for some JDK examples, another example would be the Flowless API.
As you did not tell any specifics I can not guide you any further. But it should be clear, that your approach may very well work and there are other ways.

Solving a concurrent modification exception in a swingworker application

I'm writing an application in which some simulation is run in a SwingWorker. In this simulation some sets keep data which are modified in the doInBackground() method of the SwingWorker. This data needs to be shown by the GUI, but obviously this fails because as soon as the GUI starts accessing the sets a concurrent modification exception is thrown because the SwingWorker is modifying the same sets.
How would I go about sharing this data without the SwingWorker having to wait for the GUI to finish drawing the data? Do I have to copy the data and then publish() those? Won't this increase the amount of data by a lot (there is a lot of data)? Are there other ways around this problem?
Here's some simplified code:
public class World {
public Set<Foo> fooSet = new HashSet<Foo>();
}
public class Simulator extends SwingWorker<Void, Void> {
private World world;
private WorldPanel worldPanel;
public Simulator(World world, WorldPanel worldPanel) {
this.world = world;
this.worldPanel = worldPanel;
}
#Override
protected Void doInBackground() throws Exception {
while (true) {
doSomethingWithFooSet() //structurally modifies the set
publish();
}
}
#Override
protected void process(List<Void> voidList) {
worldPanel.repaint();
}
}
public class WorldPanel extends JPanel {
private final World world;
public WorldPanel(World world) {
this.world = world;
}
#Override
public void paintComponent(Graphics g) {
drawWorld() //reads from fooSet in world
}
}
Don't get me wrong, I understand why this doesn't work, I'm just wondering what I should change in this design to be able to do what I want to do: access the same data that my simulation is modifying. Does process() run on the EDT? If so, would it be possible to let process() update the sets in a copy of the world object which the WorldPanel uses to draw the data?
You cannot simultaneously update and display the world object, so you have two ways out: do update and displaying sequentially, or clone data so that updated and displayed data are different. To implement the first variant, just do not use SwingWorker. In the second variant, if simple cloning the whole world is unacceptable, let the background thread compute not just the new state of the world, but also commands to modify the world's image. Publish that commands and then process them to update the picture.
I would add a flag in the gui, wether it shall show/access the data or not
initially set it to false and when your worker finishes reload the accessing part with switched flag

How to access variables in a runnable object in Java

I am going to simulate a traffic light system.
I created the Road Class which extends JFrame and implements Runnable.
Inside the run() method I added the logic to increase the Y Position of each car and It is now simulating the movements of cars.
But now I need to check the status of the Traffic Light, before move a car.
This is my TrafficLight class,
import java.util.Random;
public class TrafficLight implements Runnable {
volatile boolean stop;
public TrafficLight(boolean stop) {
this.stop = stop;
}
#Override
public void run() {
Random randomGenerator = new Random();
while (true) {
if (stop) {
stop = false; //change current status
} else {
stop = true; //change current status
}
try {
Thread.sleep(2000 + randomGenerator.nextInt(2000));
} catch (Exception ex) {
System.out.println("error");
}
}
}
}
Is there any way to check this volatile variable stop, from my Road Class.
If not please suggest me another solution to do this.
Thanks.
Implement an accessor for stop.
public class TrafficLight implements Runnable {
volatile boolean stop;
// Irrelevant code
public boolean isStop() {
return stop;
}
}
Receive the TrafficLight on the Road class constructor and use it to get access to the stop variable
public class Road implements Runnable {
private TrafficLight trafficLight;
public Road (TrafficLight trafficLight) {
this.trafficLight = trafficLight;
}
#Override
public void run() {
// Irrelevant code
if(trafficLight.isStop()) {
// do something
}
}
}
Road (or whoever needs the value) should have access to an instance of TrafficLight and ask it if its green. You can provide a boolean method.
BUT access to this property (stop) should be guarded. volatile keyword doesn't help very much (see below).
I should do something like:
private synchronized void toogleStopped() { // guarded
this.stop = !this.stop;
}
public synchronized boolean isStopped() { // guarded
return this.stop;
}
Events
If some other object needs to react to changes in lights (react to "light has changed" event), use Observer design pattern as #TejasArjun suggested.
Why volatile doesn't help
volatile makes Java avoid assuming variable is not changed "from outside". So if a thread sets its value (or read it before), a second read will use (probably) a cached value (already saved in a CPU register or something). volatile makes Java always read the value from memory.
Said that, the lost update problem remains even with volatile keyword. One thread can 1) read 2) write. Another thread can do the same. And they can do it in this order:
Thread 1 reads false
Thread 2 reads false
Thread 1 sets true (assuming it read false)
Thread 2 sets true (assuming it read false)
And that's not nice :)
So you must tell Java to make read&write atomically. That's why we can use synchronized keyword to make sure a thread does the whole sync'ed block at once, not interlaced with another thread.
Put another way, Does this mean that cars need to listen to traffic light changes?. Observer design pattern may also help here.

Categories