Mr. Fist said:
Maybe an Empty Map feature?
Just click on it from a menu and the map turns into a black space devoid of entities or solid ground.
No, just add a Delete All Entities function. If you want to erase all the tiles, you can use the existing Fill function (at least, I
think it already exists?).
dooey100 said:
An undo stack would be awesome, although I understand they are rather hard to implement, and would need a fairly significant rewrite for a lot of the map editing functions.
I'm not sure I agree with it being a stack, though. I've thought a little about a way to implement an undo list. The idea was to have an UndoList class (which would probably have only a single instance) containing an std::list (a doubly-linked list, in case you're unfamiliar with the STL) and an iterator pointing to the current element (an iterator is a pointer or a class that behaves like one; if you didn't use the STL you'd probably just use a pointer). If you haven't undone anything since your last action, the iterator would point at a null entry indicating the end of the list.
The list elements would be pointers to an abstract UndoAction class. The UndoAction class would need two pure virtual method, undoAction() and redoAction(). When you choose "Undo" from the menu, the list pointer would be decremented, and then the undoAction() method would be called on the pointee. When you choose "Redo" from the menu, the redoAction() method would be called on the pointee, and then the pointer would be incremented. And when you do an action that can be undone, everything on the list from the current pointer to the end is deleted, the new action is inserted at the end, and the pointer is incremented.
Then all you would have to do is create classes that inherit from UndoAction for every type of action that you want to be able to undo.
dooey100 said:
I was assuming each major area of the editor would have its own stack. EG the map editor would have a stack, the entity editor would have a stack, and the script editor would have a stack (although having a stack seems less necessary for scripting)
Uh... I don't think I like this idea. I could accept the potential usefulness of a separate undo list for the script editor, but I think there should be a single list for anything else.
dooey100 said:
Also you wouldn't need new functions for undos, as its always just the opposite of whatever was done. Deleted an entity here? Undo = create an entity. Create an entity? Undo = delete the entity. Change a map tile? Undo = change a map tile
Creating an entity is not necessarily the action to take when undoing a delete entity action. If the structure storing an entity is complex enough, it would probably be better to not delete it at all, but simply store a pointer to it in the undo action.
However, if it's very simple (like a POD type with only a few elements) it wouldn't make much of a difference. In that case, copy the entity, then delete it. Undoing would still be a different action from creating a new entity, though.
dooey100 said:
To limit the memory usage, limit the stack size. Yeah, that means you can only undo so far, but almost every program I've seen can only undo so far. (The sole exception being Paint.net)
That's not the sole exception. There are plenty of programs that support an unlimited undo list. Some of them allow you to choose the limit.
S. P. Gardebiter said:
It's way easier.
Why don't you use classes for a undo function?
As you can see, I quite agree. I'll even post the code I wrote for this (for a different program, but it work just as well here). Note that this code is still incomplete and untested.
Code:
[color=#7F7F7F]// undo.h[/COLOR]
[color=#7F7F7F]#include[/COLOR] <list>
[color=#7F7F7F]class[/COLOR] cAction {
[color=#7F7F7F]public[/COLOR]:
[color=#7F7F7F]virtual void[/COLOR] undo() = 0; [color=#7F7F7F]// undoes this action if it has not already been undone[/COLOR]
[color=#7F7F7F]virtual void[/COLOR] redo() = 0; [color=#7F7F7F]// redoes this action if it has been undone[/COLOR]
[color=#7F7F7F]virtual bool[/COLOR] isDone() = 0; [color=#7F7F7F]// checks to see whether the action has been undone; returns false if it has[/COLOR]
[color=#7F7F7F]virtual[/COLOR] [color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]string[/COLOR] getActionName() = 0; [color=#7F7F7F]// returns the name of this action for display in the Edit menu[/COLOR]
[color=#7F7F7F]virtual[/COLOR] ~cAction();
};
[color=#7F7F7F]class[/COLOR] cUndoList {
[color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]list[/COLOR]<cAction*> theList;
[color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]list[/COLOR]<cAction*>::[color=#7F7F7F]iterator[/COLOR] cur, lastSave;
[color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]size_t[/COLOR] num_actions;
[color=#7F7F7F]public[/COLOR]:
cUndoList();
[color=#7F7F7F]void[/COLOR] undo(); [color=#7F7F7F]// undoes the current action and decrements the cur pointer[/COLOR]
[color=#7F7F7F]void[/COLOR] redo(); [color=#7F7F7F]// increments the cur pointer and redoes the current action[/COLOR]
[color=#7F7F7F]void[/COLOR] save(); [color=#7F7F7F]// sets the last saved action to the current action[/COLOR]
[color=#7F7F7F]void[/COLOR] revert(); [color=#7F7F7F]// undoes all actions back to (but excluding) the last saved action[/COLOR]
[color=#7F7F7F]void[/COLOR] add(cAction* what);
[color=#7F7F7F]static[/COLOR] [color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]size_t[/COLOR] maxUndoSize;
};
[color=#7F7F7F]// undo.cpp[/COLOR]
[color=#7F7F7F]#include[/COLOR] "undo.h"
cUndoList::cUndoList(){
lastSave = cur = theList.[color=#7F7F7F]begin[/COLOR]();
}
[color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]size_t[/COLOR] cUndoList::maxUndoSize = 0;
[color=#7F7F7F]// TODO: These functions should have error checking to ensure they do not access an out of bounds action; basically, if cur == theList.[color=#7F7F7F]end[/COLOR](), then there are no more actions to redo[/COLOR]
[color=#7F7F7F]void[/COLOR] cUndoList::undo(){
cur--;
(*cur)->undo();
}
[color=#7F7F7F]void[/COLOR] cUndoList::redo(){
(*cur)->redo();
cur++;
}
[color=#7F7F7F]void[/COLOR] cUndoList::save(){
lastSave = cur;
}
[color=#7F7F7F]void[/COLOR] cUndoList::revert(){
[color=#7F7F7F]while[/COLOR](cur != lastSave) undo();
}
[color=#7F7F7F]void[/COLOR] cUndoList::add(cAction* what){
theList.[color=#7F7F7F]push_back[/COLOR](what);
num_actions++;
[color=#7F7F7F]while[/COLOR](num_actions > maxUndoSize)
theList.[color=#7F7F7F]pop_front[/COLOR](), num_actions--;
}
Schokobecher said:
I meant it like:
Normal (warnings, not all editing tools visible (like ASM and stuff))
Advanced (Everything visible, less warning, more powerful)
If you're going to do that, why not allow the user to pick and choose which warnings are suppressed and which editing tools are available?