pcossenb@rodan.acs.syr.edu (Paul C. Ossenbruggen) (06/06/89)
I have a question about heaps. It seems that during the execution of my program a lot of little handles are created (13 bytes, to be exact) and then deleted. So what I get on the heap is hundreds of these thirteen byte chunks of free space. It does not seem to create any problems but I am wondering if it is symptomatic of a bug. I have used TMON's heap scramble and purge and have had no crashes (this also gets rid of them). So if it does not matter, I will forget about it but if you know what might be the cause and if it is a problem please let me know. Also does anyone have any experience writing routines to handle undo? If you have, could you give me an overview of the procedures involved for implementing it in a graphics environment? I'd mainly like to know how you store the info that has been deleted and then restore it without creating anomolies. It would be really helpful if you had some example code I could look at or if you know of some that is available. Thanks. - Paul ------------------------------------------------------------------------------- | Paul C. Ossenbruggen pcossenb@rodan.acs.syr.edu | | Syracuse University rspco@suvm.bitnet | | pcossenb@sunrise.acs.syr.edu |
lsr@Apple.COM (Larry Rosenstein) (06/07/89)
In article <1634@cmx.npac.syr.edu> pcossenb@rodan.acs.syr.edu (Paul C. Ossenbruggen) writes: > So what I get on the heap is hundreds of these thirteen byte chunks of free > space. It does not seem to create any problems but I am wondering if it is > symptomatic of a bug. I have used TMON's heap scramble and purge Not necessarily. If the stuff is being freed, then everything should be cool. You can try breaking on NewHandle and/or DisposHandle and see who is creating/freeing these things, which might point out an inefficiency in your program. > Also does anyone have any experience writing routines to handle undo? If you > have, could you give me an overview of the procedures involved for implementing > it in a graphics environment? I'd mainly like to know how you store the info > that has been deleted and then restore it without creating anomolies. It would > be really helpful if you had some example code I could look at or if you know There are 2 implementation techniques you can use for Undo. I will use a drawing program as the example, since that seems to be what you are asking about. The straightforward technique is to save enough information so that the command can be reversed. For example, if you move a bunch of shapes, you can save the distance they were moved and then to Undo this you simply move the same shapes in the opposite direction. This assumes that you know what shapes were involved in the command, which means you also have to remember the selection at the time the command was done. The easiest way to represent selections in a graphics document is to add an isSelected bit to each shape. To remember the current selection, therefore, you can add a wasSelected bit. (This breaks down if you wanted to implement multiple levels of undo, however.) So when you do the command you copy the isSelected bits into the wasSelected bits, and do the command. To undo it, you copy the bits back, and then reverse the command. This means that after the Undo the selection will be the same as when the command was originally done, which I think is the right thing to do. This technique breaks down when the amount of information you have to remember becomes large or difficult to deal with. For example, consider the Bring to Front command. In this case you would need to remember the exact position of each shape in the list, so that you can put it back in the right spot. This would either require an index field in each object, or that you make a copy of the list of shapes, etc. Any of these approaches uses a lot of memory. Many commands in a graphics editor are like this (e.g., changing the fill pattern in the selected shapes). The solution, therefore, is to pretend the command has been done. You don't change your internal data structures to bring the shapes to the front, but you display them on the screen as if the data structures had been changed. You can think of this as a filter that you place between the data structure and the display code. With the filter in place, it looks as if the command has been done, but to undo the command you can simply remove the filter. Assume that the shapes are normally drawn from back to front. The Bring to Front filter changes this order by drawing all the unaffected shapes first, and then running through the list a second time drawing the affected shapes. Similarly, implementing change fill pattern involves a filter that draws each affected shape with a new pattern, rather than the one stored with the shape. Using filters adds a complication. When the command can no longer be undone, then the filter must be committed against the data structures. In the case of Bring to Front, for example, this means that when the user does the next command you first have to adjust the list of shapes to (finally) execute the Bring to Front command. Note that you don't do this if the user has undone the Bring to Front command; in that case, the filter is not being used. In MacApp, we use command objects to represent undoable commands. The TCommand class has a Commit method (in addition to DoIt, UndoIt, and RedoIt), just so that you can implement filtering. MacApp will call the Commit method just before it calls the DoIt method of the next command object (assuming that the old command hasn't been undone). I don't have any example code that shows the use of filtering, so I can't help out there. Larry Rosenstein, Apple Computer, Inc. Object Specialist Internet: lsr@Apple.com UUCP: {nsc, sun}!apple!lsr AppleLink: Rosenstein1