[GREENFOOT-49] Save the state of the world
Add functionality to save the state of the world.
A discussion of some of the different possible solutions follows below. Headings marked with a * indicates that it is currently a the most likely solution.
h1. How to get the state of the world h2. Serializing Breaks if the class implementation is changed. h2. * Recording Record object creation and method invocation like it is done in JUnit for BlueJ. This is the better solution
h1. How to store the state h2. A separate setup file We could have the interactions stored in a separate file somewhere. This would make it difficult for the suer to modify it though, and would seem a bit like "magic". h2. * In source code We could create a setup() method in the world class that was last instantiated and put the source code in there. Would work well with the previous decision of using recording to capture the state since that can easily be translated into source code. Also, this allows the user to modify the generated code easily if desired.
After saving the state of the world, the world class that was set up could look something like this:
{noformat} public class MyWorld extends World { public MyWorld() { super(20,20,20); ... setup(); //added by greenfoot. What if it is already here? Maybe we should not add it automatically? }
/**
* Sets up the world with objects. This method has been generated by Greenfoot
* and modifying might result in strange behaviour. If custom setup is needed, put
* it in a separate method that you call from the constructor.
*/
private void setup()
{
Car car1 = new Car();
addObject(car1, 23, 43);
car1.setRotation(45);
}
} {noformat}
h1. How to handle previously created state h2. Wipe everything We could just ignore everything that was previously saved. This is not desirable though, since the user would not be able to edit an existing save. h2. Replay We ask the user if he wants to reuse his existing setup and then rerun the setup method of the world and track what invocation are made (or just construct a new world which should also call the setup method?) Would overwrite users modifcations. For instance if the user introduced randomness, if-statements or loops, only the outcome of these would be recorded, which would result in different behaviour (for the randomness, it would no longer be random) or ugly code (loops would be expanded into individual lines). We could argue that the user should not modify this code, and add his "random" or looped object creation somewhere else \- however, how would we avoid tracking these custom additions? I guess we would have to make sure that we only track things done in the setup() method. It would allow for method invocations. And only break setups that has been modified by the user.
h2. Reuse source Again, we ask the user if he wants to reuse his existing setup. If so, we make reuse the source code in the setup() method and just add the new interactions after this code. h3. Variable names Selecting names for variables will be difficult though. We could count number of instances of given class and start numbering from there. This will work if not edited, but could potentially break if the user renamed variables (but that should be rare enough that we don't care). To do this, we would have to track objects that are deleted and remove their instantiation so they don't count towards the numbering.
h3. Changing objects from previous recording session Since we are just reusing the source code, we don't actually know the variable names of the previous objects, so we don't know how to reference them (could be out of scope too, if user modified).
Prohibit changing objects from previous states:: bq. We could prohibit modifications of these object. Then we should somehow indicate this by greying out those objects and make method invocation/move/delete inaccessible.
Allow changing:: bq. Try to figure out a way to reference them (getOneObjectAt?).
h1. When to record h2. Record everything h2. Record until act It was suggested that it should only be allowed to save the state in the time between a compile and until act() is called the first time. That probably makes sense... or maybe it should just only record in that period and allow saving at any later time (until compile)
h2. * Explicitly start recording Have a special recording mode which is activated by the user. When starting this mode, the world should be re-instantiated after the user has accepted to do so. We have to choose this if we need to prohibit modifying objects that was added in a previous state (see above).
h1. What is recorded?
- Interactive construction of objects and addition to the world.
- Interactive method calling
- Interactive moving of objects
- Interactive deletion of objects
Issue metadata
- Issue type: Task
- Priority: Medium
- Fix versions: 2.0