How to implement Undo Redo operation in flex 4 for maintain history?
I'm working with flex UIComponent and DisplayObjects for creating and editing diagrams,but
in flex there is no way to handle user operation history directly.
there is any idea to achieve this?
You could implement the Command Pattern for all actions with execute and undo methods, and queue them up.
so when the user wants to do some thing - lets say create an AddFiveToTotal class and executes:
public method execute():void{
totalModel.add( 5 );
}
This class would then be stored on a FIFO queue.
if the user needs to undo the command would be popped and the undo function called:
public method undo():void{
totalModel.subtract( 5 );
}
for redoability, don't pop, just iterate the queue
also take a look at the Memento Pattern
If you are using any of the currently popular MVC(S) frameworks you will undoubtably find a util that some one has already created
You can acheive with help of memento pattern. It hard to track all properties better you can what are property need to use for undo/redo operation.
Memento Design pattern
Memento pattern
Demo sample with source code http://www.flairpy.com/mementoPattern/MementoSample.html
There are several ways you can address to this problem. First is to keep the states of your whole canvas in a Vector (I mean have a listener for all the things user can do on the stage and saving the state after a change) and then have an index of current state saved, so that you could move through your Vector and put the needed state on the stage. This is the easiest way to approach undo/redo functionality, but beware that you'll have to make clones of objects a lot and this will become a memory hog if you're going to deal with a lot of objects or a lot of undo/redos.
The second approach is to only keep what changed in that vector, so that you won't have to create and clone a lot of objects, but only save one object in your Vector which will contain all the properties that have changed and their last values. This will get you something like this:
private var mHistory:Vector.<Object> = new Vector.<Object>();
private var mCurrentIndex:int = -1;
public function storeState(state:Object)
{
mHistory.push(state);
mCurrentIndex++;
}
public function undo():void
{
if(mCurrentIndex < 1)
return;
mCurrentIndex--;
//here you could test for values that could have changed
var item:DisplayObject = this.getChildByName(mHistory[mCurrentIndex].name);
if(mHistory[mCurrentIndex].x != undefined)
item.x = mHistory[mCurrentIndex].x;
// etc. you get the point. Note that this is only comfortable if only several things can change
}
And the call for storeState function would be like this:
var state:Object = { name:DisplayObjectName, x:120, y:20 };
storeState(state);
Again, you will have to listen to all movement and changes if you want to record them.
Related
I was actually looking for a way to pass by reference in AS3 but then it seemed that adobe and lots of people's understanding of pass by reference is different from what I have been taught at the university. I was taught java was pass by value and C++ allowed pass by reference.
I'm not trying to argue what pass by value and reference are. I just want to explain why I'm using pass by object in the question...
Back to the question, I would like to do something like:
public function swapCard(cardA:Cards, cardB:Cards) {
var temp:Cards = cardA;
cardA = cardB;
cardB = temp;
}
...
swapCard(c1, c2);
EDIT: adding two examples on how I'm using the swapCard function
1) in the process of swaping a card between player1 and player2's hand
swapCard(player1.hand[s], player2.hand[t]);
2) in the process of swaping a card between player1's hand and deck
swapCard(player1.hand[s], player1.deck[rand]);
In C++, we only need to add a symbol before the parameters to make it work (and we call THIS pass by reference). But in AS3, cardA and cardB are just pointers to the formal parameters. Here in the function, changing the pointers does not do anything to the formal parameters :(
I have been searching for hours but I couldn't find a way to without knowing all the properties of the Cards.
If I have to change the properties of the cards one by one then maybe I should change swapCard to a static function in class Cards? (because I don't want to expose everything to another class) I'm not sure if this is a good practice either. This is like adding a swap_cars function into class Cars. If I let this happen, what will be next? Wash car, lend car, rent car... I really want to keep the Cards class clean and holds only the details of the card. Is there a possible way to do this properly in AS3?
The kind of swap function that you're trying to implement is not possible in AS3. The input parameters are references to the input objects but the references themselves are passed by value. This means that inside the function you can change the cardA and cardB but those changes will not be visible outside the function.
Edit: I added this portion after you edited your question with sample usage.
It seems like you're trying to swap two objects in 2 different arrays at given array positions in each - you can create a function for this in AS3 but not the way you attempted.
One possible implementation is to pass the arrays themselves and the positions that you're trying to exchange; something like this:
// Assumes arrays and indices are correct.
public function SwapCards(playerHand:Array, playerCardIndex:int,
playerDeck:Array, playerDeckIndex:int):void
{
var tempCard:Card = playerHand[playerHandIndex];
playerHand[playerHandIndex] = playerDeck[playerDeckIndex];
playerDeck[playerDeckIndex] = tempCard;
}
Note that you still exchange references and the arrays themselves are still passed by reference (and the array references are passed by value - you could, if you wanted, change the arrays to new arrays inside this function but you wouldn't see new arrays outside). However, because the array parameters refer to the same arrays inside and outside the function, you can make changes to the contents of the array (or other array properties) and those changes will be visible outside.
This solution is faster than cloning the card because that involves allocating memory for a new Card instance (which is expensive) and that temporary instance will also have to be freed by the garbage collector (which is also expensive).
You mentioned in a comment that you pass cards down to lower levels of code - if you don't have a back reference to the arrays (and the positions of the cards), you will not be able to easily swap cards - in AS3, all input parameters are copies (either the copy of the value for primitive types or the copy of the reference for complex objects - changes to the input parameters in a function will not be visible outside).
EDIT: renaming the function from clone to copyFrom as pointed out by aaron. Seems like clone is supposed to be used as objA = objB.clone()
At this point, I'm adding a copyFrom() function in the Cards class such that
var temp:Cards = new Cards(...);
var a:Cards = new Cards(...);
...
temp.copyFrom(a);
...
temp will be copying everything from a.
public function swapCard(cardA:Cards, cardB:Cards) {
var temp:Cards = new Cards();
temp.copyFrom(cardA);
cardA.copyFrom(cardB);
cardB.copyFrom(temp);
}
I will wait for a week or so to see if there are any other options
You have some good answers already, but based on the comments back-and-forth with me, here's my suggestion (I use "left" and "right" naming because it helps me visualize, but it doesn't matter):
function swapCard(leftCards:Array, leftCard:Card, rightCards:Array, rightCard:Card):void {
var leftIndex:int = leftCards.indexOf(leftCard);
var rightIndex:int = rightCards.indexOf(rightCard);
leftCards[leftIndex] = rightCard;
rightCards[rightIndex] = leftCard;
}
Now you can swap the cards in the two examples you posted like this:
swapCard(player1.hand, player1.hand[s], player2.hand, player2.hand[t]);
swapCard(player1.hand, player1.hand[s], player1.deck, player1.deck[rand]);
However, note that while this swaps the cards in the arrays, it does not swap direct references to the cards in those arrays. In other words:
var a:Card = player1.hand[0];
var b:Card = player2.hand[0];
swapCard(player1.hand, a, player2.hand, b);
// does not change the references a and b, they still refer to the same card
a == player2.hand[0];
a != player1.hand[0];
b == player1.hand[0];
b != player2.hand[0];
Typically, this sort of thing is handled by dispatching a "changed" event so that any code that cares about the state of a player's hand array will know to re-evaluate the state of the hand.
There's a deep misunderstanding going on here. The question is about object reference but the PO is not trying to swap any Object reference at all.
The problem comes from the fact that the PO does not understand the difference between variable and objects. He's trying to swap variable/object reference which is not dynamically possible of course. He wants with a function to make the variable holding a reference to Object A, swap its object reference with another variable. Since Objects can be passed around but not variables (since they are just holders (not pointers)) the task is not possible without a direct use of the given variable.
To resume:
variables are not Objects!
variables hold a reference to an object.
variables cannot be passed in function or referenced in functions because THEY ARE NOT OBJECTS.
I'm currently trying to find a "definitive" solution (meaning : finding a solution that seems efficient a complying with OOP precepts) to a recurring problem I've been experiencing for some time : the problem of shared data in different parts of my code.
Take note that I'm not using any MVC framework anywhere here. I'm just refering to my data class as a Model and to the display class as a View (because its the proper names and have nothing to do with the MVC pattern, people made views & models way before the MVC pattern was "created").
Here's my problem :
Whenever I make an application that uses some quite expanded data (for example a game), I try to separate logic (movements, collisions, etc...) and display in two classes. But then, I stumble upon the problem : how to "bind" the data stored in my logic class with the corresponding display objects in my view class, without duplicating data, references, or other things between the different classes ?
Lets take a basic example :
I have a MyLogicClass, holding a Vector of "EntityData" objects (each with position, sizes, various states, everything to handle the logic of my items)
And I have a MyViewClass, creating and displaying Sprites for each EntityData that are in the MyLogicClass, and make them move after them being updated in the game loop.
The first thing that would come to my mind would be to store inside each data element its corresponding view, thus allowing me to loop throught my Vector to update the items logic then update the views accordingly. But that forces me to hold a MyLogicClass reference inside the MyViewClass, to be sure that I can target the entities data, forcing me to couple the two classes (things that I would prefer not to do).
On the other hand, there's the solution of each Entity having an ID, both in my data model (MyLogicClass's EntityData objects having an ID parameter) and in my View class (Sprites holding a reference to its original entity data ID). But when I want to target a specific entity that forces me to loop for it in my data model, then loop for it again to find the related Sprite in my View. This solution allows me to have loose coupling between my data and my view, but looping through hundreds of elements twice every frame (can happen !) really sounds not performance optimized for me.
I may be giving the whole problem a lot more importance that it should deserve, but I've been stumbling upon that more than one time, and I'd love to have some other views than mine about that.
Do you guys have any advice / solution for such an issue ?
Are there some other data formats / hierarchy that I may not be aware of for such case ?
What I've done is 'link' them together using events and event listeners. I have my "model parts" throw specific events that the "display parts" catch and render/update.
I've found this does let me structure some of my tests by writing testing code that would listener for certain events and error checks it that way. My code is still separated and testable on it's own: I can test my "model" by triggering and making sure the right events with the right values are being thrown. Like-wise, I can write some testing code to throw preset events that can be caught by the "display" to see if it has any issues.
Then once it is all working, I just reuse those same event listeners and link to 'each other'.
Later my "controller" (user input) would manipulate the "model" parts, which would cause events to be thrown to the "display" thus be rendered/updated.
I don't know if this is "correct" or not in terms of following the mvc pattern nor do I really have any formal knowledge on these sorts of things. I'd be interested in someone else's more knowledgeable opinion as well.
I think maybe you have over thought the problem. I do this sometimes.
Your view class has to have some type of link to the model obviously and an event is a great way to do it. Something bare bones here to give you an idea.
// Model class
package
{
class MyModel extends EventDispatcher
{
// you can make them public but that would
// be against some oop practices. so private it is
private var m_position:Vector2D;
MyModel(){}
// one way of doing getters/getters
// example: theModel.SetPosition(something);
public function GetPosition():Vector2D { return m_position; }
public function SetPosition(value:Vector2D):void
{
m_position = value;
ModelChanged();
}
// the other way
// sample: theModel.position = something;
public function get position():Vector2D {return m_position; }
public function set position(value:Vector2D):void
{
m_position = value;
ModelChanged();
}
private function ModelChanged():void
{
dispatchEvent(new Event(Event.CHANGE));
}
}
}
// now for our view.
package
{
class MyView extends Sprite // or whatever
{
private var model:MyModel;
MyView(model:MyModel)
{
this.model = model;
model.addEventListener(Event.CHANGE, handleModelChanged);
// fire off an event to set the initial position.
handleModelChanged(NULL);
}
private function handleModelChanged(evt:Event):void
{
x = model.position.x;
y = model.position.y;
// etc etc etc.
}
}
}
Anyhow you don't need the setters if your going to have the logic in the model file also obviously if nothing outside of the model needs to change it no reason for setters. But you do need the getters.
This decouples the model from the view and you can write any view any way you want and all you have to provide is a handler for when the model has changed. Just expose whatever data your views will need with getters.
You now only have to loop through the models and if one changes it will fire off an event and the views that are listening in will update.
hope I didn't miss anything and that explains what you were wanting.
Edit: I forgot to add, you don't have to have "ModelChanged()" all over the place if your using something like an update function. Just update and when your finished fire off the event.
Riddle me this: I have my MouseEvent.MOUSE_DOWN which calls mouseHandler. The latter looks something like this:
public function mouseHandler(evt:MouseEvent):void
{
var p:Point = new Point(mouseX, mouseY);
var objs:Array = new Array(getObjectsUnderPoint(p));
}
Now what I want to know is thusly: will the objs array and p point be overwritten every time, simply causing the previous objs array and p point to be wiped and a new one generated, or...does it just create a new array and point over and over and over? Of course if I trace(objs) it gives me the expected results, but am I chocking up the system in the background without realising? Your expertise would be appreciated.
EDIT: well after learning a fair bit from the answerers -thanks btw- that made me think of something else and, a quick search later, found a way to theoretically reliably remove the references:
var a = null;
Now I appreciate that this is probably not needed as they'll be GCed at the end of the function, but considering it takes two ticks to write, better safe than sorry, no?
It works like this from what I understand - references for these variables will be lost after function will end. The values will be GC'ed then eventually.
If you will call the function second time, the new references will be created, and filled with new data, the values of previous references hovewer, may still exist in memory, and wait for Garbage Collector, but that may not necessarily happen! If they have attached listeners, the Flash Player will think that they are still useful, so they will exist in the memory to the end of the application run and listen, and even react to events - even if you theoretically cannot access them anymore.
Edit:
In your case whats happening is that you are creating two references that will disappear at the end of the function. They are not related to event listener, the listener creates them, but is not attached to them so it won't stop GC from collecting them after function will end. You creates an array of references, but that are just references to other objects that values are referred in other places (like the display list), if the array alone is not referred anywhere outside of this function, it should be GCted.
Since p is an object, not a primitive, the memory allocation for it will come from the Heap (and therefore need to be garbage collected) instead of the stack like local primitives (and are wiped once the function ends.
So new memory will be allocated every time this function is called, which will temporarily increase memory usage until they get GC'd, but the amount is probably insignificant (assuming that array isn't massive!).
When I make the same query twice, the second time it does not return new rows form the database (I guess it just uses the cache).
This is a Windows Form application, where I create the dataContext when the application starts.
How can I force Linq to SQL not to use the cache?
Here is a sample function where I have the problem:
public IEnumerable<Orders> NewOrders()
{
return from order in dataContext.Orders
where order.Status == 1
select order;
}
The simplest way would be to use a new DataContext - given that most of what the context gives you is caching and identity management, it really sounds like you just want a new context. Why did you want to create just the one and then hold onto it?
By the way, for simple queries like yours it's more readable (IMO) to use "normal" C# with extension methods rather than query expressions:
public IEnumerable<Orders> NewOrders()
{
return dataContext.Orders.Where(order => order.Status == 1);
}
EDIT: If you never want it to track changes, then set ObjectTrackingEnabled to false before you do anything. However, this will severely limit it's usefulness. You can't just flip the switch back and forward (having made queries between). Changing your design to avoid the singleton context would be much better, IMO.
It can matter HOW you add an object to the DataContext as to whether or not it will be included in future queries.
Will NOT add the new InventoryTransaction to future in memory queries
In this example I'm adding an object with an ID and then adding it to the context.
var transaction = new InventoryTransaction()
{
AdjustmentDate = currentTime,
QtyAdjustment = 5,
InventoryProductId = inventoryProductId
};
dbContext.InventoryTransactions.Add(transaction);
dbContext.SubmitChanges();
Linq-to-SQL isn't clever enough to see this as needing to be added to the previously cached list of in memory items in InventoryTransactions.
WILL add the new InventoryTransaction to future in memory queries
var transaction = new InventoryTransaction()
{
AdjustmentDate = currentTime,
QtyAdjustment = 5
};
inventoryProduct.InventoryTransactions.Add(transaction);
dbContext.SubmitChanges();
Wherever possible use the collections in Linq-to-SQL when creating relationships and not the IDs.
In addition as Jon says, try to minimize the scope of a DataContext as much as possible.
I'm currently working on a class that calculates the difference between two objects. I'm trying to decide what the best design for this class would be. I see two options:
1) Single-use class instance. Takes the objects to diff in the constructor and calculates the diff for that.
public class MyObjDiffer {
public MyObjDiffer(MyObj o1, MyObj o2) {
// Calculate diff here and store results in member variables
}
public boolean areObjectsDifferent() {
// ...
}
public Vector getOnlyInObj1() {
// ...
}
public Vector getOnlyInObj2() {
// ...
}
// ...
}
2) Re-usable class instance. Constructor takes no arguments. Has a "calculateDiff()" method that takes the objects to diff, and returns the results.
public class MyObjDiffer {
public MyObjDiffer() { }
public DiffResults getResults(MyObj o1, MyObj o2) {
// calculate and return the results. Nothing is stored in this class's members.
}
}
public class DiffResults {
public boolean areObjectsDifferent() {
// ...
}
public Vector getOnlyInObj1() {
// ...
}
public Vector getOnlyInObj2() {
// ...
}
}
The diffing will be fairly complex (details don't matter for the question), so there will need to be a number of helper functions. If I take solution 1 then I can store the data in member variables and don't have to pass everything around. It's slightly more compact, as everything is handled within a single class.
However, conceptually, it seems weird that a "Differ" would be specific to a certain set of results. Option 2 splits the results from the logic that actually calculates them.
EDIT: Option 2 also provides the ability to make the "MyObjDiffer" class static. Thanks kitsune, I forgot to mention that.
I'm having trouble seeing any significant pro or con to either option. I figure this kind of thing (a class that just handles some one-shot calculation) has to come up fairly often, and maybe I'm missing something. So, I figured I'd pose the question to the cloud. Are there significant pros or cons to one or the other option here? Is one inherently better? Does it matter?
I am doing this in Java, so there might be some restrictions on the possibilities, but the overall question of design is probably language-agnostic.
Use Object-Oriented Programming
Use option 2, but do not make it static.
The Strategy Pattern
This way, an instance MyObjDiffer can be passed to anyone that needs a Strategy for computing the difference between objects.
If, down the road, you find that different rules are used for computation in different contexts, you can create a new strategy to suit. With your code as it stands, you'd extend MyObjDiffer and override its methods, which is certainly workable. A better approach would be to define an interface, and have MyObjDiffer as one implementation.
Any decent refactoring tool will be able to "extract an interface" from MyObjDiffer and replace references to that type with the interface type at some later time if you want to delay the decision. Using "Option 2" with instance methods, rather than class procedures, gives you that flexibility.
Configure an Instance
Even if you never need to write a new comparison method, you might find that specifying options to tailor the behavior of your basic method is useful. If you think about using the "diff" command to compare text files, you'll remember how many different options there are: whitespace- and case-sensitivity, output options, etc. The best analog to this in OO programming is to consider each diff process as an object, with options set as properties on that object.
You want solution #2 for a number of reasons. And you don't want it to be static.
While static seems like fun, it's a maintenance nightmare when you come up with either (a) a new algorithm with the same requirements, or (b) new requirements.
A first-class object (without much internal state) allows you to evolve into a class hierarchy of different differs -- some slower, some faster, some with more memory, some with less memory, some for old requirements, some for new requirements.
Some of your differs may wind up with complicated internal state or memory, or incremental diffing or hash-code-based diffing. All kinds of possibilities might exist.
A reusable object allows you to pick your differ at application start-up time using a properties file.
In the long run, you want to minimize the number of new operations that are scattered throughout your application. You'd like to have your new operations focused in places where you can find and control them. To change from old differ algorithm to new differ algorithm, you'd like to do the following.
Write the new subclass.
Update a properties file to start using the new subclass.
And be completely confident that there wasn't some hidden d= new MyObjDiffer( x, y ) tucked away that you didn't know about.
You want to use d= theDiffer.getResults( x, y ) everywhere.
What the Java libraries do is they have a DifferFactory that's static. The factor checks the properties and emits the correct Differ.
DifferFactory df= new DifferFactory();
MyObjDiffer mod= df.getDiffer();
mod.getResults( x, y );
The Factory typically caches the single copy -- it doesn't have to physically read the properties every time getDiffer is called.
This design gives you ultimate flexibility in the future. At it looks like other parts of the Java libraries.
I can't really say I have firm reasons why it's the 'best' approach, but I usually write classes for objects that you can have a 'conversation' with. So it would be like your 'single use' option 1, except that by calling a setter, you would 'reset' it for another use.
Rather than supplying the implementation (which is pretty obvious), here's a sample invocation:
MyComparer cmp = new MyComparer(obj1, obj2);
boolean match = cmp.isMatch();
cmp.setSubjects(obj3,obj4);
List uniques1 = cmp.getOnlyIn(MyComparer.FIRST);
cmd.setSubject(MyComparer.SECOND,obj5);
List uniques = cmp.getOnlyIn(MyComparer.SECOND);
... and so on.
This way, the caller gets to decide whether they want to instantiate lots of objects, or keep reusing the one.
It's particularly useful if the object needs a lot of setup. Lets say your comparer takes options. There could be many. Set it up once, then use it many times.
// set up cmp with options and the master object
MyComparer cmp = new MyComparer();
cmp.setIgnoreCase(true);
cmp.setIgnoreTrailingWhitespace(false);
cmp.setSubject(MyComparer.FIRST,canonicalSubject);
// find items that are in the testSubjects objects,
// but not in the master.
List extraItems = new ArrayList();
for (Iterator it=testSubjects.iterator(); it.hasNext(); ) {
cmp.setSubject(MyComparer.SECOND,it.next());
extraItems.append(cmp.getOnlyIn(MyComparer.SECOND);
}
Edit: BTW I called it MyComparer rather than MyDiffer because it seemed more natural to have an isMatch() method than an isDifferent() method.
I'd take numero 2 and reflect on whether I should make this static.
Why are you writing a class whose only purpose is to calculate the difference between two objects? That sounds like a task either for a static function or a member function of the class.
I would go for a static constructor method, something like.
Diffs diffs = Diffs.calculateDifferences(foo, bar);
In this way, it's clear when you're calculating the differences, and there is no way to misuse the object's interface.
I like the idea of explicitly starting the work rather than having it occur on instantiation. Also, I think the results are substantial enough to warrant their own class. Your first design isn't as clean to me. Someone using this class would have to understand that after performing the calculation some other class members are now holding the results. Option 2 is more clear about what is happening.
It depends on how you're going to use diffs. In my mind, it makes sense to treat diffs as a logical entity because it needs to support some operations like 'getDiffString()', or 'numHunks()', or 'apply()'. I might take your first one and do it more like this:
public class Diff
{
public Diff(String path1, String path2)
{
// get diff
if (same)
throw new EmptyDiffException();
}
public String getDiffString()
{
}
public int numHunks()
{
}
public bool apply(String path1)
{
// try to apply diff as patch to file at path1. Return
// whether the patch applied successfully or not.
}
public bool merge(Diff diff)
{
// similar to apply(), but do merge yourself with another diff
}
}
Using a diff object like this also might lend itself to things like keeping a stack of patches, or serializing to a compressed archive, maybe an "undo" queue, and so on.