Moving objects on a screen without delays/lag - java

I am looking to move objects across a canvas or other component(s), but to do so without noticeable latency/delays. Now, to get it out of the way I am using double buffering with multiple layers (most of which only get drawn once). In my case I have a background that gets drawn once when the map generates, a mask layer (things behind the object), and a fringe layer (things in front of the object). The only thing that's actually getting re-drawn is the actual object moving around the screen.
That being said, I have also setup KeyListeners on this, and moved my object movement into a drawing and processing into separate threads (e.g. a thread dedicated to drawing the canvas, and a thread dedicated to processing the movement).
What I notice is that when I press a key to move the object (W,A,S,D) it will move a small amount (a single move action), followed by a slight delay, then move constantly until I stop pressing the keys.
Is there a better way to implement movement from the keyboards to reduce/eliminate delay?
-Edit-
I realized I could probably sum this up in a single statement: How to make controls for a game that feel responsive, without awkward delays/latency.

What operating system are you using? On linux / possibly mac, holding a key down performs several cycles which involve calling both the press and release methods constantly (You know how if you hold a key down in a text box, one character appears, then there's a delay, then several more appear rapidly? In linux, the operating system executes press, then release, really really fast.) In windows, however, the release method is never called until the key is actually released. (basically, it just keeps calling the press method really fast.)
A very ugly and hacky answer, but I hope it helps:
It is helpful to know the timing of these cycles. Typically, it goes something like this:
User presses and holds a button (say, the 'a' key). The 'a' key's press function is immediately called.
There is about a quarter to half second delay (often adjustable in system settings).
'a' key's release function is called
Few millisecond delay (between 2 and 10 ms by my testing)
Press function is called again
Slightly longer delay (Between 20 and 30 ms by my testing).
Repeat starting on third bullet point.
With this cycle in mind, it is theoretically possible (actually, completely possible. I've tested it.) to use timing to detect whether or not the user has actually released the key. Basically, if the key is released for more than 10 milliseconds (I'd go 15, just to be safe), then you know that the user has released the key.
This solution involves creating a boolean for each relevant key. Your KeyListeners, in turn, will do nothing more than set these booleans to true / false (maybe when they are pressed, they are set to true, and when they are released, they are set to false.)
Then, you create one more boolean for every key which will represent whether or not the keys are really being pressed. Create a thread which watches the first booleans (the ones controlled by the KeyListeners). Every time the first booleans are set to true, set the corresponding second boolean to true.
However, whenever the first booleans are set to false, wait 15 milliseconds, and check again. If they are still set to false, then set the corresponding second boolean to false. Why? If it's been 15 milliseconds and they are still false, then you know that the user has actually released the key.
KeyListener:
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode == 65){
aPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e){
if(e.getKeyCode == 65){
aPressed = false;
}
}
Separate Thread (calling it trueKeyListener)
boolean waiting = false;
long tWaitStart;
Runnable trueKeyListener = new Runnable(){
#Override
public void run(){
while(true){//Instead of true, use some variable, like running
if(aPressed){
aTruePressed = true;
}else if(!waiting){//not yet waiting for the 15 ms
waiting = true;
tWaitStart = System.nanoTime();
}else if(System.nanoTime() - tWaitStart >= 15000000){//waiting is over
waiting = false;
if(!aPressed){//a still isn't pressed
aTruePressed = false;
}
}
}
}
};
As far as I know, timing the booleans is the only way to make it work on any operating system. As I said, this shouldn't be (or at least wasn't when I last coded something like this) an issue on a Windows OS.
Edit: Finally, as I forgot to mention, you can create one more thread which watches the truePressed booleans and handles movement accordingly.
Secondly, just some advice, if there are several relevant keys in your application, I recommend using arrays of pressed booleans, truePressed booleans, waiting booleans, and tWaitStart longs for handling multiple keys in one for loop.
Second Edit: I have found this question which seems very similar to yours. I hope it helps.

Try calling right before repaint() inside your repaint loop.
Toolkit.getDefaultToolkit().sync()

Related

Is there a way to check if a block has already been broken before and a player hasn't just replaced it? Spiggot

I'm creating a plugin with Spiggot that every time you break a certain block or kill and entity it expands the border(The border is gonna start of being small). I have realised that after someone breaking a block they can replace in and repeat meaning the border will become infinite does anyone know a way I can prevent this I thought about using persistent variables inside the items but they were blocks that had been broken not items so I couldn't I don't think this question needs any code but for some reason if you need the main part here it is:
#EventHandler
public void onBlockBreak(BlockBreakEvent e)
{
if (e.getBlock().getType() == Material.DIAMOND_ORE)
{
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "worldborder add 6 1");
}
if (e.getBlock().getType() == Material.IRON_ORE)
{
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "worldborder add 0.5 1");
}
if (e.getBlock().getType() == Material.GOLD_ORE)
{
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "worldborder add 1 1");
}
if (e.getBlock().getType() == Material.ANCIENT_DEBRIS)
{
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "worldborder add 0.5 1");
}
}
You can create a global variable containing the coordinates of blocks that have been broken. In order for the most efficient solution, I'd recommend this variable be a HashSet, as there is an O(1) time complexity for checking for the presence of an element.
private final Set<Location> blocksBroken = new HashSet<>();
Then in your onBlockBreak method, at the start you can check if the location of the block is in the Set - if it is, don't expand the border:
if (blocksBroken.contains(e.getBlock().getLocation())) return;
But in the case that the border is expanded, simply add the location of the broken block to the Set:
blocksBroken.add(e.getBlock().getLocation());
It is worth noting that this solution is really only efficient assuming there will not be a ridiculously high number of blocks broken by players, because for every block broken, the location of the block is broken in memory. This means that the amount of memory used by the solution is proportional to the number of blocks broken (O(n) space complexity). Personally, I'd really only concern about this after ~10,000 blocks.
You could set the owner of the item and prevent placing if an owner is set.
I have solved this i can create a listener for when a block gets added to someone’s inventory then add a persistent variable there and check in the onblockbreak listener
Firstly, I'm assuming the blocks that grow the worldborder are ore-types like Diamond ore and Iron ore. An idea to prevent this exploit would be to prevent players from placing that ore-type entirely, hopefully that won't be a problem.
You could use the Class BlockPlaceEvent, and method getBlockPlaced() to achieve this.
Also, I'd recommend using switch statements rather than multiple ifs.

Java Splitting Up Work Between Frames

First I'll explain what I want to do and afterwords I'll provide a proposed solution.
Problem
I'm running a game where I want to do a certain amount of work every frame. For example, I have N objects that are in a queue waiting to be initialized (imagine initialization is a fairly expensive operation and N is large) and after adding them all, I want to create their collision boxes, and after that, I want to merge them together to limit render calls. I can't do these operations on a different thread because all this stuff is heavily coupled with the game world. But I want to split up all these operations into bite-size chunks to run each frame so that there is minimal lag (framerate dips). How would I go about doing this?
Proposed Solution
It would be nice to have a function that can stop after one call and continue where it left off after calling it again:
For example,
boolean loadEverything() {
for (int i = 0; i < objectsToAdd.length; i++) {
world.add(objectsToAdd[i]);
if (i % 10 == 0) {
return stop();
}
}
makeCollision();
return stop();
mergeObjects();
return true;
}
Calling loadEverything() the first objectsToAdd/10 times adds 10 objects to the game world at a time. Then calling it after should run makeCollision() and then stop. Calling it again runs mergeObjects() and then the function returns true. In the caller function I would run loadEverything() until it returns true.
I'm aware of yeild-return, yield-break implementations like those described here exist, but I'm wondering if there's a more general implementation of them, or that maybe a better solution exists that doesn't require any extra dependencies.
Do you look at Coroutine yet? There's native implementation in Kotlin but in Java there're options here and here.
By all means we need to make sure those OpenGL or Box2D operations that required to be in main thread should be in main thread, as I believe coroutine will be created under a new thread. So there might not be gain to split works for those kind of operations.
Another option
You say you need to split works in creating objects in run time. Can you predict or estimate the number of objects you would want before hand? and so if you don't really need to dynamically create object like that, I suggest to look at Object Pool in libgdx (see more here). That link has working example to use Pool in your game.
Such Pool already have initialized objects ready to be grabbed and used on-demand, also can grow if need in run time, so initially if you can provide a good estimation of number of objects you intend to use, it's all good.
Why don't you add one static variable which would keep it's value between function calls? Then you can loop from current value to current value + 10, increase current value (that static variable) by 10 and exit.

Why printing all running threads in Java unblocks an application?

I created a GUI Application in JavaFX which communicates with a serial device (I use a jssc connector). When I want to get data I send a communicate, then wait 1s until the wait function terminates. Communicate is also being sent, among other things, when I click one of the buttons (for starting a device, for identification, etc.). During development process I noticed a bug - communication hangs (but only when receiving messages, I still can send one-way communicates for ie. starting a device) when I click too many buttons too fast or I click buttons which send more than one communicate.
Communication is mainly handled by my own class SerialPortDevice. I create an object of a class' type and then invoke particular methods. Here's the method which waits for a message:
private String waitForMessage() throws SerialPortException {
long operationStartTime = System.currentTimeMillis();
long connectionTimeout = SerialPortCommunicationParameters.CONNECTION_TIMEOUT_IN_MILLIS;
String resultMessage = "";
do {
if (readEventOccurred) {
System.out.println();
resultMessage = receiveMessage();
System.out.println("After receiving a message");
messageReceived = true;
}
} while (((System.currentTimeMillis() - operationStartTime) < connectionTimeout) && (!messageReceived));
if (!readEventOccurred) {
resultMessage = NO_RESPONSE;
}
System.out.println("Time elapsed: " + (System.currentTimeMillis() - operationStartTime + "ms"));
return resultMessage;
}
One can notice that message is being received only when a flag readEventOccured is true. It's handled by my implementation of the SerialPortEventListener:
class SerialPortDeviceReader implements SerialPortEventListener {
private SerialPortDevice device;
SerialPortDeviceReader(SerialPortDevice device) {
this.device = device;
}
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR()) {
System.out.println("Serial Event Occured!");
device.setReadEventOccurred(true);
}
}
}
readEventOccured is a boolean field in the SerialPortDevice class which contains waitForMessage function. Also, waitForMessage is invoked by another function, singleConversation:
String singleConversation(String testMessage) {
String resultMessage = NO_RESPONSE;
try {
openConnection();
sendMessage(testMessage);
resultMessage = waitForMessage();
closeConnection();
} catch (SerialPortException e) {
e.printStackTrace();
return resultMessage;
}
System.out.println();
readEventOccurred = false;
messageReceived = false;
return resultMessage;
}
... Which is the only function setting readEventOccured to false. And it is a "top level" function in a SerialPortDevice class which handles sending and receiving a communicates to and from a device.
So communication looks like this:
Button click -> Button handler invocation -> device.singleCommunication(buttons_specific_communicate) -> some methods run and then it comes to the waitForMessage -> method waits 1s for the event -> event occurs (everytime - I get the "Serial Event Occured" communicate) -> readEventOccured is being set to true -> if there is some time left (there is always some time left, everything lasts a miliseconds), message is being received in the waitForMessage method.
There is no problem if I click buttons with a short (in a human sense, 2-3s for example) delay or I don't click these which do send more than one communicate inside their handlers. In different situations weird things happen. I still get the message "Serial Event Occured" (so I suppose readEventOccured is also being set to true) but waitForMessage function does not execute
if(readEventOccured)
statement's code. Also, I have to run an application again to be able to communicate with a device (I mean receiving data, sending works perfectly).
What solved my problem was adding "volatile" modifier to the readEventOccured flag (makes sense by the way, things go fast sometimes). But it didn't please me. I wanted to make a code to run correctly without "volatile". My coworker came up with an idea something goes wrong with threads that are being created when I click buttons and invoke communication - maybe something blocks other thing somewhere? First thing I did was to print all the currently runnig threads and... Man, it solved a problem. App was not hanging anymore. Really, I performed "hanging" scenarios 10-20 times with and without
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
System.out.println(threadSet);
at the beginning of the waitForMessage method and result were unambigous - it somehow removed my problem.
I'm almost certainly sure getting and printing threads is not a solution itself. It's something that is being done by the way but I can't find out what is this. Any useful information? Maybe better understanding Threads in Java would help me? Or it is something else?
Cheers
What you're doing is the textbook example of what happens when there are no visibility guarantees. If we distil your code into its essential bits, we get something like this:
boolean flag = false;
void consume() {
while (true) {
if (flag) {
//we received flag, hooray
}
}
}
void produce() {
flag = true;
}
Now, if produce() and consume() run in different threads, there is absolutely no guarantee that consume() will EVER see flag set to true. volatile creates a memory barrier, meaning that all reads/writes of those variable will be fully ordered.
What you also have in the code though, is lots of System.out.println() lines. These complicate the picture, as they themselves are synchronized, and thus create happens-before relationships between different parts of the code. Unfortunately they don't create the correct sequence, but poke in a few more and you can accidentally get it right. The key word here is "accidentally", you shouldn't rely on this behaviour at all.
So marking readEventOccurred as volatile sort of fixes the problem but going a bit further we can see that your waitForMessage() spin-waits, which is rarely a good idea. I would take a look at the CountDownLatch class for example, designed for similar scenarios. (An even better candidate is its close friend, CyclicBarrier.)
What solved my problem was adding "volatile" modifier to the readEventOccured flag (makes sense by the way, things go fast sometimes). But it didn't please me. I wanted to make a code to run correctly without "volatile".
The fact that adding volatile fixes the problem indicates you've run into the lack of guarantees by the Java Memory Model when multiple threads are involved. Simply put there is no guarantee of when a change on one thread is visible on other threads except for specific situations.
The probably reason why printing 'fixes' the problem is the fact that it:
Changes the timing of the program, might mean the situation in which it fails no longer exists.
Temporarily suspends the threads to read out their current state, maybe the JVM also uses that as an opportunity to synchronize memory.
Multithreaded communication is hard, so I recommend you take a look at the classes available in java.util.concurrent, which have guarantees that you might be able to use to solve your problem more elegantly.

Detect screen press at certain times

So, I am fairly new to java and android programming and I am having an issue coming up with the code for a project I am working on. Basically, there is a list of times, which I assume need to be stored as an array. Once the game has started, it needs to do one of two things:
If the user presses the screen within a few milliseconds of a time in the array, it will register as a hit and increase count.
If the user presses the screen outside of the "hit" time, it will register as a miss and reset count to 0.
Now, I have all the elements in place to make everything work (increasing count on screen press, etc). My issue is with the code to detect if the user pressed the screen on time or not. I have tried doing some searches, but I can't figure it out. Here is a small list of the times that are "good" hits:
0.25
0.84
1.03
1.60
2.3
2.6
2.9
These times can change a little and some can be removed if its not working correctly. The biggest issue I can think of is making sure that it starts the timer when the game starts so the times match up. The current timer starts at 100 and counts down 1 second at a time and when it reaches zero it takes the user to the game over screen. This of course can change if there is a better way to do it or a different way that it has to happen to make the screen press detection code work.
Any idea how to make this work?
Really, all you need to do is log the current system time at the time the game starts. Then, it's just:
long startTime = System.currentTimeMillis();
//...
System.currentTimeMillis() - startTime;
Then, to check if you're within the bounds set at any point in the array (which I will assume is an array of doubles):
public final static int THRESHOLD_MSEC = 100;
public boolean isHit(double time) {
int time = System.currentTimeMillis - startTime;
for(double d : array)
if(Math.abs(d-time) < THRESHOLD_MSEC) return true;
return false;
}
Then, elsewhere in your application, you can handle what happens when isHit returns either true or false. I'm not going to write that part for you. A point of note: a few milliseconds is nothing in comparison to human reflexes, and nobody will be able to make that time.

How to manage the game state in face of the EDT?

I'm developing a real time strategy game clone on the Java platform and I have some conceptional questions about where to put and how to manage the game state. The game uses Swing/Java2D as rendering. In the current development phase, no simulation and no AI is present and only the user is able to change the state of the game (for example, build/demolish a building, add-remove production lines, assemble fleets and equipment). Therefore, the game state manipulation can be performed in the event dispatch thread without any rendering lookup. The game state is also used to display various aggregated information to the user.
However, as I need to introduce simulation (for example, building progress, population changes, fleet movements, manufacturing process, etc.), changing the game state in a Timer and EDT will surely slow down the rendering.
Lets say the simulation/AI operation is performed in every 500ms and I use SwingWorker for the computation of about 250ms in length. How can I ensure, that there is no race condition regarding the game state reads between the simulation and the possible user interaction?
I know that the result of the simulation (which is small amount of data) can be efficiently moved back to the EDT via the SwingUtilities.invokeLater() call.
The game state model seems to be too complex to be infeasible for just using immutable value classes everywhere.
Is there a relatively correct approach to eliminate this read race condition? Perhaps doing a full/partial game state cloning on every timer tick or change the living space of the game state from EDT into some other thread?
Update: (from the comments I gave)
The game operates with 13 AI controlled players, 1 human player and has about 10000 game objects (planets, buildings, equipment, research, etc.). A game object for example has the following attributes:
World (Planets, Players, Fleets, ...)
Planet (location, owner, population, type,
map, buildings, taxation, allocation, ...)
Building (location, enabled, energy, worker, health, ...)
In a scenario, the user builds a new building onto this planet. This is performed in EDT as the map and buildings collection needs to be changed. Parallel to this, a simulation is run on every 500ms to compute the energy allocation to the buildings on all game planets, which needs to traverse the buildings collection for statistics gathering. If the allocation is computed, it is submitted to the EDT and each building's energy field gets assigned.
Only human player interactions have this property, because the results of the AI computation are applied to the structures in EDT anyway.
In general, 75% of the object attributes are static and used only for rendering. The rest of it is changeable either via user interaction or simulation/AI decision. It is also ensured, that no new simulation/AI step is started until the previous one has written back all changes.
My objectives are:
Avoid delaying the user interaction, e.g. user places the building onto the planet and only after 0.5s gets the visual feedback
Avoid blocking the EDT with computation, lock wait, etc.
Avoid concurrency issues with collection traversal and modification, attribute changes
Options:
Fine grained object locking
Immutable collections
Volatile fields
Partial snapshot
All of these have advantages, disadvantages and causes to the model and the game.
Update 2: I'm talking about this game. My clone is here. The screenshots might help to imagine the rendering and data model interactions.
Update 3:
I'll try to give a small code sample for clarify my problem as it seems from the comments it is misunderstood:
List<GameObject> largeListOfGameObjects = ...
List<Building> preFilteredListOfBuildings = ...
// In EDT
public void onAddBuildingClicked() {
Building b = new Building(100 /* kW */);
largeListOfGameObjects.add(b);
preFilteredListOfBuildings.add(b);
}
// In EDT
public void paint(Graphics g) {
int y = 0;
for (Building b : preFilteredListOfBuildings) {
g.drawString(Integer.toString(b.powerAssigned), 0, y);
y += 20;
}
}
// In EDT
public void assignPowerTo(Building b, int amount) {
b.powerAssigned = amount;
}
// In simulation thread
public void distributePower() {
int sum = 0;
for (Building b : preFilteredListOfBuildings) {
sum += b.powerRequired;
}
final int alloc = sum / (preFilteredListOfBuildings.size() + 1);
for (final Building b : preFilteredListOfBuildings) {
SwingUtilities.invokeLater(=> assignPowerTo(b, alloc));
}
}
So the overlapping is between the onAddBuildingClicked() and distributePower(). Now imagine the case where you have 50 of these kind of overlappings between various parts of the game model.
This sounds like it could benefit from a client/server approach:
The player is a client - interactivity and rendering happen on that end. So the player presses a button, the request goes to the server. The reply from the server comes back, and the player's state is updated. At any point between these things happening, the screen can be re-painted, and it reflects the state of the game as the client currently knows it.
The AI is likewise a client - it's the equivalent of a bot.
The simulation is the server. It gets updates from its clients at various times and updates the state of the world, then sends out these updates to everyone as appropriate. Here's where it ties in with your situation: The simulation/AI requires a static world, and many things are happening at once. The server can simply queue up change requests and apply them before sending the updates back to the client(s). So as far as the server's concerned, the game world isn't actually changing in real time, it's changing whenever the server darn well decides it is.
Finally, on the client side, you can prevent the delay between pressing the button and seeing a result by doing some quick approximate calculations and displaying a result (so the immediate need is met) and then displaying the more correct result when the server gets around to talking to you.
Note that this does not actually have to be implemented in a TCP/IP over-the-internet sort of way, just that it helps to think of it in those terms.
Alternately, you can place the responsibility for keeping the data coherent during the simulation on a database, as they're already built with locking and coherency in mind. Something like sqlite could work as part of a non-networked solution.
Not sure I fully understand the behavior you are looking for, but it sounds like you need something like a state change thread/queue so all state changes are handled by a single thread.
Create an api, maybe like SwingUtilities.invokeLater() and/or SwingUtilities.invokeAndWait() for your state change queue to handle your state change requests.
How that is reflected in the gui I think depends on the behavior you are looking for. i.e. Can't withdraw money because current state is $0, or pop back to the user that the account was empty when the withdraw request was processed. (probably not with that terminology ;-) )
The easiest approach is to make the simulation fast enough to run in the EDT. Prefer programs that work!
For the two-thread model, what I suggest is synchronise the domain model with a rendering model. The render model should keep data on what came from the domain model.
For an update: In the simulation thread lock the render model. Traverse the render model updating where things are different from what is expected update the render model. When finished traversing, unlock the render model and schedule a repaint. Note that in this approach you don't need a bazillion listeners.
The render model can have different depths. At one extreme it might be an image and the update operation is just to replace a single reference with the new image object (this wont handle, for instance, resizing or other superficial interaction very well). You might not bother checking whether an item has change and just update eveything.
If changing the game state is fast (once you know what to change it to) you can treat the game state like other Swing models and only change or view the state in the EDT. If changing the game state is not fast, then you can either synchronize state change and do it in swing worker/timer (but not the EDT) or you can do it in separate thread that you treat similarly to the EDT (at which point you look at using a BlockingQueue to handle change requests). The last is more useful if the UI never has to retrieve information from the game state but instead has the rendering changes sent via listeners or observers.
Is it possible to incrementally update the game state and still have a model that is consistent? For example recalculate for a subset of planet/player/fleet objects in between renders/user updates.
If so, you could run incremental updates in the EDT that only calculate a small part of the state before allowing the EDT to process user inputs and render.
Following each incremental update in the EDT you would need to remember how much of the model remains to be updated and schedule a new SwingWorker on the EDT to continue this processing after any pending user inputs and rendering has been performed.
This should allow you to avoid copying or locking the game model while still keeping the user interactions responsive.
I think you shouldn't have World store any data or make changes to any objects itself, it should only be used to maintain a reference to an object and when that object needs to be changed, have the Player making the change change it directly. In this event, the only thing you need to do is synchronize each object in the game world so that when a Player is making a change, no other Player can do so. Here's an example of what I'm thinking:
Player A needs to know about a Planet, so it asks World for that Planet (how is dependent upon your implementation). World returns a reference to the Planet object Player A asked for. Player A decides to make a change, so it does so. Let's say it adds a building. The method to add a building to the Planet is synchronized so only one player can do so at a time. The building will keep track of its own construction time (if any) so the Planet's add building method would be freed up almost immediately. This way multiple players can ask for information on the same planet at the same time without affecting each other and players can add buildings almost simultaneously without much appearance of lag. If two players are looking for a place to put the building (if that is part of your game), then checking the suitability of a location will be a query not a change.
I'm sorry if this doesn't answer you're question, I'm not sure if I understood it correctly.
How about implementing a pipes and filters architecture. Pipes connect filters together and queue requests if the filter is not fast enough. Processing happens inside filters. The first filter is the AI engine while the rendering engine is implemented by a set of subsequent filters.
On every timer tick, the new dynamic world state is computed based on all the inputs (Time is also an input) and a copy inserted into the first pipe.
In the simplest case your rendering engine is implemented as a single filter. It just takes the state snapshots from the input pipe and renders it together with the static state. In a live game, the rendering engine may want to skip states if there are more than one in the pipe while if you're doing a benchmark or outputting a video you'll want to render every one.
The more filters you can decompose your rendering engine into, the better the parallelism will be. Maybe it is even possible to decompose the AI engine, e.g. you may want to separate dynamic state into fast changing and slow changing state.
This architecture gives you good parallelism without a lot of synchronization.
A problem with this architecture is that garbage collection is going to run frequently freezing all the threads every time, possible killing any advantage gained from multi-threading.
It looks like you need a priorityqueue to put the updates to the model on, in which updates frmo the user have priority over the updates from the simulation and other inputs. What I hear you saying is that the user always needs immediate feedback over his actions wheras the other inputs (simulation, otherwise) could have workers that may take longer than one simulation step.
Then synchronize on the priorityqueue.

Categories