I'm developing a Java desktop flight simulation. I need to record all the pilot actions as they occur in the cockpit, such as throttle controls, steering, weapon deployment, etc. so that I can view these events at a later time (or stream them live).
I'd like to add a visual replay feature on the playback of the events so I can visually see the cockpit as I move forward and backward in time. There's no problem with the replay as long as I play back the event in chronological order, but the rewind is a little trickier.
How would you implement the rewind feature?
I would use a modified Memento pattern.
The difference would be that I would have the Memento object store a list of all of the pilot actions.
The Memento pattern is typically used for rolling back (undo), however in your case I could see it applying as well. You would need to have the pilot actions be store-able states as well.
You could use a variant of the Command Pattern and have each one of your pilot actions implement an undo operation.
For example if your pilot made the action steer left (simple, i know) the inverse of it would be steer right.
public interface IPilotAction {
void doAction(CockpitState state);
void undoAction(CockpitState state);
}
public class ThrottleControl implement IPilotAction {
private boolean increase;
private int speedAmount;
public ThrottleControl(boolean increase, int speedAmount) {
this.increase = increase;
this.speedAmount = speedAmount;
}
public void doAction(CockpitState state) {
if (increase) {
state.speed += speedAmount;
} else {
state.speed -= speedAmount;
}
}
public void undoAction(CockpitState state) {
if (increase {
state.speed -= speedAmount;
} else {
state.speed += speedAmount;
}
}
What you're looking for is actually a blend of the Command and Memento patterns. Every pilot action should be a command that you can log. Every logged command has, if req'd, a memento recording any additional state that (A) is not in the command, and (B) cannot reliably be reconstructed. The "B" is important, there's some of this state in pretty much any non-trivial domain. It needs to be stored to recover an accurate reconstruction.
If you merge these concepts, essentially attaching a memento to each command, you'll have a fully logged series of deterministic events.
I discussed this at more length in a different answer. Don't be afraid to substantially adapt the design patterns to your specific needs. :)
RE Performance Concerns:
If you expect jumping a number of minutes to be a frequent case, and after implementation you show that it's an unworkable performance bottleneck, I would suggest implementing an occasional "snapshot" along with the logging mechanism. Essentially save the entire application state once every few minutes to minimize the amount of log-rolling that you need to perform. You can then access the desired timeframe from the nearest saved state. This is analogous to key frames in animation and media.
Not a direct answer, but check out discussion of implementing undo. Mostly they will be about text editors, but the same principles should apply.
It helps if you prefer immutability. Undoing complex changes is difficult. Even automated systems have performance problems (Software Transaction Memory, STM).
Make sure that you've implemented the simulation in such a way that the simulation's "state" is a function. That is, a function of time.
Given an initial state at time T0, you should be able to construct the simulation frame at time Tn for any n. For example, an initial stationary state and no events (yet) might equal the identity function, so Tn == Tn+1.
Given some pilot action event at time Ta, you should be able to construct a frame Ta+n for any n. So you think of events as modifying a function that takes a time value as argument and returns the frame of the simulation for that time.
I would implement the history of events as a Zipper of (time, function) pairs representing the control state of the simulation. The "current" state would be in focus, with a list of future states on the right, and past states on the left. Like so:
([past], present, [future])
Every time the simulation state changes, record a new state function in the future. Running the simulation then becomes a matter of taking functions out of the future list and passing the current time into them. Running it backwards is exactly the same except that you take events out of the past list instead.
So if you're at time Tn and you want to rewind to time Tn-1, look into the past list for the latest state whose time attribute is less than n-1. Pass n-1 into its function attribute, and you have the state of simulation at time Tn-1.
I've implemented a Zipper datastructure in Java, here.
you can just store the state at every instance. 1kb for state (wind speed, object speeds + orientation / control input states, x 30fps x 20 min ~ 36megs. 1kb of state would let you record about 16 objects (pos / speed / angular speed / orientation / and 5 axis of control / effect)
that may be too much for you, but it will be easiest to implement. there will have to be no work done at all to recreate state (instant acecss), and you can interpolate between states pretty easy (for faster / slower playback). for disk space you can just zip it, and that can be done while recording, so while playing that memory is not being hogged.
a quick way to save space would be to paginate the recording file, and compress each bin separately. ie one zip stream for each minute. that way you would only have to decompress the current bin, saving a bunch on memory, but that depends how well your state data zips.
recording commands and having your class files implement multiple directions of playback would require a lot of debugging work. slowing / speeding up playback would also be more computationally intensive. and the only thing you save on is space.
if thats a premium, there are other ways to save on that too.
Related
with a basic understanding of Akka classic, I moved to Typed and noticed, that the typed version of my code is significantly slower than the classic one.
The task is to aggregate "ticks" (containing an instrument name, a timestamp and a price) per instrument.
In the classic code, I dynamically create one actor for each instrument and kep a Map<Instrument, ActorRef> outside the actor system to delegate the incoming ticks to.
In the typed code, a "parent" was required, thus I moved the routing logic with the Map into this parent actor, so I ended up with two Actors classes here (the actual tick actor and the routing parent actor).
Otherwise, the code is pretty much the same, just once implemented via the classic api and once typed.
When testing both logics (primitively) I found that the version using the classic logic took a bit less than 1.5 seconds to process 1,000,000 ticks, while the typed one required a bit more than 3.5 seconds.
The obvious first reason was to move the guardian parent (which is also the router) to its own PinnedDispatcher, so it could run on its own thread, with all the other actors using the default threadpool. This increased performance a good bit, leading to around 2.1 seconds to process 1,000,000 ticks.
My question is: Does anyone have an idea where the remaining performance (0.6 seconds) might be lost?
Typed runs on top of classic (a typed Behavior<T> is effectively wrapped in a function which casts messages to T; once wrapped, it can then be treated as basically a classic Receive), so it introduces some overhead per-message.
I'm guessing from the improvement in putting the routing parent on a pinned dispatcher that the typed implementation sent every tick through the parent, so note that you're incurring that overhead twice. Depending on how many Instruments you have relative to the number of ticks, the typed code can be made much more like the classic code by using something like the SpawnProtocol for the parent, so the code outside the ActorSystem would, at a high-level:
check a local Map<Instrument, ActorRef<Tick>> (or whatever)
if there's an ActorRef for the instrument in question send the tick to that ActorRef
otherwise, ask the parent actor for an ActorRef<Tick> corresponding to the instrument in question; then save the resulting ActorRef in the local Map and send the tick to that ActorRef
This is more like the situation in classic: the number of messages (ignoring internal system messages) is now 1 million plus 2x the number of Instruments, vs. 2 million.
My application contains a number of objects which contain getters and setters. These correspond to changing the state of physical objects (for example, a stepper motor).
Other threads may call methods on this object in order to do things to the stepper motor - this provides an interface between the stepper motor and the underlying hardware. So, for example, we may have a function that causes the motor to rotate by 15 degrees, or we may have a function that causes it to return to a neutral position.
Now, these objects care threadsafe, but that's not good enough. Consider the situation where one thread tries to rotate the motor by 90 degrees (by firing six calls to rotate by 15 degrees) and half way through, another resets the motor, meaning that it's only moved 45 degrees.
My design solution is to allow the controlling objects to take out locks on the controller, but I'm unsure how to manage this. It seems that most of the Java locking methods are designed to be atomic over a single method call, where I wish to have the objects locked for an indeterminate amount of time.
Would a simple Java lock be sufficient for this purpose, or does anyone know of something better? I'm worried by the fact that the standard ReentrantLock would seem to almost require the try-finally paradigm, meaning that I'd be likely bastardising it to a certain extent.
You could provide a method to submit several commands atomically. Assuming all your methods are synchronized, it could simply be:
public synchronized void submitAtomically(List<Command> commands) {
for (Command c : commands) {
submit(c);
}
}
public synchronized void submit(Command c) {
//rotate or reset or ...
}
If you don't want the methods to block other threads for too long, the simplest would be to use a typical producer/copnsumer pattern:
private final BlockingQueue<Command> queue = new LinkedBlockingQueue<> ();
public synchronized void submit(Command c) {
queue.put(c);
}
//somewhere else:
new Thread(new Runnable() {
public void run() {
while(true) {
Command c = queue.take();
c.execute();
}
}
}).start();
If a client submits 6 rotations via the submitAtomically, it prevents other threads from inserting other commands in the middle of the 6 rotations. However the submit operation is very fast (it does not actually execute the command) so it will not block the other threads for long.
In the database world, this is done by having transactions, which is a way of grouping small low-level operations into big high-level operations that are atomic. Going down that road would be quite painful.
I think you need to go back and decide what the fundamental atomic operations are to be.
Consider the situation where one thread tries to rotate the motor by 90 degrees (by firing six calls to rotate by 15 degrees) and half way through, another resets the motor, meaning that it's only moved 45 degrees.
It seems that you have decided that "rotate 15 degrees" is the only atomic operation, but that is evidently a poor fit for your application.
Do you also need "rotate 45 degrees" and "rotate 90 degrees" as atomic operations? Perhaps you need "rotate X degrees" as an atomic operation?
What is the purpose of rotating the motor to a particular position? If thread A rotates the motor to position X, and then thread B immediately rotates it to a different position, what has been achieved? Is some operation to be done (by thread A) once the motor is at position X? If so, you want the rotation and that operation together to be one atomic opeartion.
And why rotate the motor by a given amount before performing an operation? Do you in fact want the motor to be in a specific position (absolute, not relative to its previous position) when the operation is performed? In that case you do not want your operations to be given the amount to rotate by, but rather the required position. The atomic operation would be responsible for deciding by how much to rotate the motor by.
I'm developing a clock class for my discrete event simulation. I already have events being held in a PriorityQueue and thus sorted according to which event has the nearest event time. However there's one thing I can't get my head around. In the papers about Discrete Event Simulation that I've read, it's clearly stated that the clock jumps from events to events and therefore it is not necessary to have a clock which "ticks".
But how would this work, I have an EventScheduler class which holds the events in the PriorityQueue. So after it figures out when this next event is, could I just invoke a "setTime" method in the Clock which the EventScheduler invokes with the given time of the next event? But then It would never really run as a clock it would just keep jumping to the next event ?
I was thinking that the clock runs (ticks) and then it knows when an event will occur from the EventScheduler and when the clock reaches that time, it processes the events , updates the system state and perhaps generates an output event.
Sorry for being a bit unclear but I'm just interested in any tips on how the clock works, does it tick and then only "do" stuff when an event occurs or does it just jump from events to events?
Also is there any built in functionality in java that you suggest I could use for this? E.g. Timer class
The idea is that nothing happens without going into your event queue. Think about it: what is you clock doing during a time when it "ticks", but there are no events? Nothing. So why process those times at all?
So yes, you just go from event to event in the queue. Really, the "clock" in a discrete event is pretty much exactly what you've built: a priority queue sorted in "chronological" order and some sense of "now" that is the position in the queue.
If you pop off the head queue, then "now" could just be the head of the queue, and you're done. Often times more sophisticated models may have further features, such as the ability to detect when events are attempted to be scheduled before "now" - this is, for instance, indicative of a model that is responding too slowly: in the real world, it would always be "late" and catching up to what's going on in the simulation as a whole.
If you have e.g. a model that requires updating every second, then you have to put those events in the queue, or they don't happen. Frequently, for problems that fit the discrete event simulation model well (in my career, this has been physics-based modeling), this is not a problem: your models usually "idle" when there are no events, and can have their state calculated at any particular time in the future when no events change their state.
If this is not true of your models, then perhaps discrete event modeling is not really a good fit for your problem domain.
java.util.concurrent package ( available since Java 5) helps in building concurrent applications that can benefit from multicore systems and in DES applications.
here is a list of items designed for such applications.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
I'm writing a Java Application that will side scroll sheet music across the screen and then when it crosses a middle line, it will play the note(s).
It will have a variable speed based on the beats per minute.
Every quarter of a beat I need to have a "tick" function that will get the next note (if any) and start its animation. To calculate this tick I have a function 60000ms/bpm/4. This will be separate from the animation timer, because the repaint should probably be called at some constant rate.
So I'm thinking I need Util Timer for the "ticks" and a swing timer for the JPanel and drawing in the paintComponent() method.
My question is: What would be the best practice for accomplishing this? I've done a fair amount of Java programming, but no Swing or animations so I would like to learn the best way to do this.
Thanks
Nate
There is no reason to use Timer or TimerTask to solve this problem.
In this case, you have a series of notes, and when you start playing, you can calculate ahead of time, the exact time that each and every note should play. I am assuming that you already have some sort of loop that is updating the display at a steady rate. (e.g. 30 refreshes per second, or something like that). Given such a loop, all you need is an event oriented class that can tell you whether it is time to play a note.
long noteTime[] = new long[numberOfNotes];
long startTime = System.currentTimeMillis();
Declare the above array. Then walk through all the notes in the song, and calculate the time that each note is expected to play. Say you have qurter notes, the first note will play at startTime, the second one beat after startTime, the third two beats after start time, etc. This is where you calculate the time for a beat and use it. Just calculate the actual time values for each note to play.
Then, in the middle of your event loop that is refreshing the display, include the following code:
int nextNote = 0;
while (event_loop_condition) {
.
.
.
if (System.currentTimeMillis()>noteTime[nextNote]) {
playNote(nextNote++);
}
.
.
.
}
The point is that you already have an event loop, all you need to know is whether it it time yet to play the note, and this will do that for you.
On the other hand, if you are not handling the refresh, and you really do want to do this on a thread, the follow method can be called on a thread, and it will play all the notes at the correct times:
playAllNotes() {
for (int i=0; i<numberOfNotes; i++) {
Thread.sleep(noteTime[i]-System.currentTimeMillis());
playNote(i);
}
}
The sleep statement will delay until the time that the note should be played, and will play it at that time. Then it will sleep until the time for the next note to be played.
The important thing to notice about both methods, is that any delay in playing a note is NOT compounded for the next note. Say some system utility kicks in and delays one note by 50ms. The next note will not be delayed by this, because you calculated all the times for all the notes to be played up front. Given that threads are competing for CPU time, you will have thread/process contention, and there will be small variances in the time that notes are played, but they will never compound!
A lot of programmers inappropriately use timers (See discussion of Timers) on my website if you want to know more.
Ok, I have a game server running in Java/Hibernate/Spring/Quartz. The game clock ticks with a Quartz timer, and that works just fine.
However, I have many other things that need to happen at specific, tweakable intervals (in game time, not real time).
For instance, every 24 hours game time (~ 47 minutes real time, depending on the servers clock multiplier) a bunch of different once-a-day game actions happen, like resupply, or what have you.
Now, the current system is pretty rough, but works - I have a table in the database that's essentially a cron - a string key, the execution time of the next event and then hours, minutes, seconds and days until the next one after that. The time ticker checks that and then fires off a message with that code (the events string key) in it to a queue, adding the days, minutes, seconds to the current time and setting that as the next execution time.
The message listener is the grody part - it switches on the key and hits one of its methods.
Now I understand that this can work just fine, but it really doesn't sit well with me. What would your solution be to this, to have each piece of code in its own little class? What design pattern covers this? (I'm sure there is one). I have a few ideas, but I'd like to hear some opinions.
Rather than a switching on a set of codes, you could use the code as a key into a map, where the values are objects that implement a handler interface. This allows you to be much more flexible in adding new event types.
The pattern looks something like this:
private final Map<String, Handler> handlers = new TreeMap<String, Handler>();
public void register(String event, Handler handler) {
handlers.put(event, handler);
}
public void handle(String event) {
Handler handler = handler.get(event);
if (handler == null) {
/* Log or throw an exception for unknown event type. */
}
else {
handler.execute();
}
}
Rather than explicitly registering handlers, you could use something like Java 6's ServiceLoader to add new behaviors just by dropping JARs into the class path.
I would use a variant of the Command Pattern. I would extend the Command pattern to make a IIntervalCommand class. It would have a interval property, and a readonly CanExecute property in addition to the Execute method.
Then you create a CommandList Class that holds a list of IIntervalCommands. It would have a method called CheckToExecute that you pass it the current game time. The CheckToExecute method would traverse the list calling CanExecute for each command. CanExecute will return true if the elapsed time has occurred. If CanExecute return true then CheckToExecute will call the Execute Method of the object implementing IIntervalCommand.
Then adding additional game events is a matter of creating a new class implementing IIntervalClass. Instantiating the Object and adding it to the IntervalCommandList.
If the processing of the event is time consuming then the command could spawn the processing as a separate thread. It will return false to it's CanExecute property until the thread returns even if the interval has passed again. Or you have it spawn off another thread if the interval passed again.
You avoid the giant case statement. You could eliminate the database and setup the parameters when you instantiate the objects. Or keep it and use it as part of a factory that creates all your IIntervalCommands.
Instead of switching on the key you can use a hashtable to dispatch these events. This way your timer events don't need to know about each other.
It should be possible do have something like:
timerQueue.registerHandler("key",new TimerHandler(){
// do something timer related
});
This way you can restart java code handling events without losing your persisted queue of events.
http://en.wikipedia.org/wiki/Priority_queue'>Priority queues are worth looking at if you have not already.
I personally wouldn't put this in the database but rather keep a separate service running in the background. Then my webservice or web application would communicate with this service through interprocess communication. Don't know how this translates into java world though.
Conceptually I think you're doing two things;
Firstly you have a scaled version of time. As long as the relationship between this time and wall-clock time remains constant I'm fairly sure I'd just delegate this scaling behavior to a single class, that would have signatures like
DateTime getFutureTime( VirtualTimeSpan timespan)
I'd be using this to map virtual time spans to instances of real-time. Thereafter you can operate in real-time, which probably simplifies things a little since you can the use standard scheduling features.
The second part regards scheduling work for a future worker process. There's a number of core technologies working with this; Conceptually I think JMS is the java-grand-dad of a lot of these, it defines concepts much like the ones you're using and what you need. I think taking a look at JMS is fine for seeing concepts you may find interesting, it uses selectors to send tasks to specific workers, much like the ones you decribe.
Alas, JMS never seemed to fit the bill for most people. A lot of people found it was too heavyweight or the implementations too buggy. So usually people ended up with home made queue technologies. But the concepts are all there. Can't you just use quartz ?