Array cascades its changed to secondary temp array in as3 - actionscript-3

I came across a unique (to me), and quite puzzling situation.
I have an array of three values.
focal[x,y,z]
these values change based on user input.
however when the change occurs, they are logged into a new array to test for valid changed
A simplified psuedo version of my code:
var temp:Array = focal; //I have even changed this to a const at times but to no avail
//changes to array are made like thus:
focal[1]++;
focal[0]--;
if(valid){
doStuff();
} else {
focal = temp;
}
However, when the focal[1]++; focal[0]--; ect, ect, code takes place. It also changed the temp array.
and since it changes my temp, it never resets me original code back to its previous nature.
I have never seen this behavior and its kinda throwin' me off. Suggestions?

when you are doing like this:
var temp:Array = focal; // Both array variables refer to the same array.
if you want to make a backup or temporary array you need to copy all the componetns from one to another:
var baseArray : Array = [0, 0, 0];
var tempArray : Array = baseArray.slice();
baseArray[0]++;
baseArray[1] += 2;
baseArray[2] += 3;
trace ( baseArray ); // output: 1,2,3
trace ( tempArray ); // output: 0,0,0

I add the deep copy method to the (very good) post by Jevgenij:
import flash.utils.ByteArray;
function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
More informations here: http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7ee7.html

Related

Errors when loading random movie clips from an array as3

I am getting closer to finding a solution for the errors being generated when running the code below.
I have three boxes on the stage. The goal is to load one random item from the array without any one item being duplicated in more than one of the three boxes.
Yasuyuki Uno has been very helpful. We are currently trying to solve the following:
Code:
var animalArray: Array = [animal1, animal2, animal3, animal4, animal5, animal6, animal7, animal8, animal9, animal10];
var randArr: Array = [];
var rand: int;
// Get random value for 3 times.
for(var i:int=0,len:int=animalArray.length;i<3;i++,len--){
rand = Math.floor( Math.random() * len); // Generate random integer between 0 and len-1.
randArr.push(animalArray.splice(rand,1)); // Delete a value from original array and add that value to new array.
}
box1.addChild(randArr[0]);
box2.addChild(randArr[1]);
box3.addChild(randArr[2]);
Error Message: Incorrect number of arguments. Expected no more than 0
Any help would be greatly appreciated. Thnx!
Assuming that animal1, animal2, etc are linkage IDs in your library, they are class references so they need to be instantiated using the new operator.
There are a few other non-critical issues with your code that made it hard to understand from my point of view:
Using animal1 instead of Animal1 and so on for class names. Uncapitalized names look like properties or functions, not classes.
Using Array instead of Vector. Vectors give you better errors; had you been using Vectors from the start your problem would be obvious.
Example:
var animalTypes:Vector.<Class> = new <Class>[Animal1, Animal2, Animal3, Animal4, Animal5, Animal6, Animal7, Animal8, Animal9, Animal10];
var randomAnimals:Vector.<DisplayObject> = new <DisplayObject>[];
// Get random value for 3 times.
for (var i:int = 0; i < 3; i++){
// Generate random integer between 0 and length-1.
var randomIndex:int = Math.random() * animalTypes.length;
// Remove a class from original vector.
var randomAnimalType:Class = animalTypes.splice(randomIndex, 1)[0];
// Create an instance of the animal class.
var randomAnimal:DisplayObject = new randomAnimalType();
// Add the instance to the random vector.
randomAnimals.push(randomAnimal);
}
box1.addChild(randomAnimals[0]);
box2.addChild(randomAnimals[1]);
box3.addChild(randomAnimals[2]);
As you check length of animalArray in for expression, it's no need to change variable len.
Also if you want to fill with 3 random items new array, you need to use this code:
const arr: Array = [animal1, animal2, animal3, animal4, animal5, animal6, animal7];
const genArr: Array = [];
var len: int = arr.length;
var n: int = 3;
while(n--) {
const randIndex: int = Math.floor(Math.random()*len); // get random index
genArr.push(arr.splice(randIndex, 1)[0]); // splice returns array, so we need first and exist item
len--; // decrement length as optimized solution of no-read length of array each cycle
}
trace(genArr);

Using 'File' to save scene object locations to rebuild later in AS3

I am attempting to use the 'File' function in ActionScript 3 to save the following information:
I have varying draggable display objects in the scene, the amount and type can vary. I want to save the amount and their position and then load them back in a future session.
I am struggling to use File to save anything, I have searched the Adobe documentation and cannot get my head round how to use it.
I have not yet developed any code using it.
Any help would be appreciated.
Thank you.
You are trying to write a DisplayObject into the file directly, this is prevented by Flash engine due to the way Flash handles default serialization of any object. In order to save a DisplayObject into the external resource, you need to employ IExternalizable on that object's class and any class of objects you will plan to store as well. The implementation of writeExternal should save all data required to rebuild the said object from scratch, and readExternal should also employ methods to restore the integrity of said DisplayObject by performing addChild() on nested display objects, or adding them into other internal structures that object might contain.
Note, other answers contain valid points for doing a custom serialization with XML or JSON, and also contain links to requires import, in particular, flash.utils.registerClassAlias and flash.utils.getDefinitionByName are gravely needed to recreate the structure from a serialized data chunk.
An example: Let's say you have a drawing board in a Board class, and a set of rectangles that you can drag by using mouse, that differ by size and color. Rectangles are custom made MovieClips and don't have a class of their own, but each MovieClip is also assigned a color property to simplify their distinction. This means you need to implement IExternalizable on Board class only. Let's also assume Board class has a pieces array that contains all links to nested rectangles, and a method to create a new properly sized rectangle based on width, height and color supplied as parameters. (There might be more requirements to the data structure of Board to meet in your case, so watch closely) So, the process of serializing Board will be to collect all the data from nested MCs and stuff it in order into IDataOutput supplied, and the process of restoring an instance of Board should retrieve stored data, parse it to find what is where, create the nested MCs to be the same like they've been stored, position them properly, addChild() to self and rebuild thepieces` array.
public class Board extends Sprite implements IExternalizable {
private var pieces:Array;
public function createRectangle(_width:Number,_height:Number,color:uint):MovieClip {
var mc:MovieClip=new MovieClip();
mc.graphics.beginFill(color);
mc.graphics.drawRect(0,0,_width,_height);
mc.graphics.endFill();
mc.color=color;
pieces.push(mc);
return mc;
}
A refinement to data structure is already visible - you need to store the passed _width and _height in the MC somewhere, because the actual width of that MC will differ from what's passed by the default line thickness (1, 0.5 on either side). x and y are properly retrieved from MC's properties, though. So, adding both lines into createRectangle is necessary.
mc._width=_width;
mc._height=_height;
With this, serializing the Board becomes more easy.
public function writeExternal(output:IDataOutput):void {
var pl:int=pieces.length; // cache
output.writeInt(pl); // assuming we keep this array in integral state
for (var i:int=0;i<pl;i++) {
var _mc:MovieClip=pieces[i];
output.writeDouble(_mc.x); // this is usually not rounded when dragging, so saving as double
output.writeDouble(_mc.y);
output.writeDouble(_mc._width);
output.writeDouble(_mc._height);
output.writeInt(_mc._color);
}
// if anything is left about the "Board" itself, write it here
// I'm assuming nothing is required to save
}
To restore, you need to read the data out of IDataInput in the very same order as it was written in writeExternal and then process to rebuilding the display list we've stored.
public function readExternal(input:IDataInput):void {
// by the time this is called, the constructor has been processed
// so "pieces" should already be an instantiated variable (empty array)
var l:int;
var _x:Number;
var _y:Number;
var _width:Number;
var _height:Number;
var _color:uint;
// ^ these are buffers to read data to. We don't yet have objects to read these into
input.readInt(l); // get pieces length
for (var i:int=0;i<l;i++) {
input.readDouble(_x);
input.readDouble(_y);
input.readDouble(_width);
input.readDouble(_height);
input.readInt(_color);
// okay we got all the data representing the rectangle, now make one
var mc:MovieClip=createRectangle(_width,_height,_color);
mc.x=_x;
mc.y=_y;
addChild(mc); // createRectangle does NOT have addchild call
// probably because there are layers for the parts to be added to
// I'm assuming there are no layers here, but you might have some!
// pieces array is populated inside createRectangle, so we leave it alone
}
// read all the data you have stored after storing pieces
}
In case your nested MCs have a class that also implements IExternalizable, you can save the entire array in a single instruction, writeObject(pieces), this will make Flash walk through the array, find all data it contains and call writeObject on any nested object, essentially calling that class's writeExternal function for each of the instance in the array. Restoring such an array should include rebuilding the display list by walking the array and calling addChild() on each of the restored instances.
And last but not the least, registerClassAlias() should be called prior to doing any serialization or deserialization of custom objects. Best place to call these is probably your main object's constructor, as this will surely be called before any other code your application contains.
Assuming all your objects to save belong to the same parent, you could dosomething along these lines:
First, create a class file (let's call is SaveData.as and put it in the root of your project directory). This will describe the data you want to save:
package
{
import flash.geom.Rectangle;
public class SaveData
{
public var bounds:Rectangle; //to save where an object is on the stage
public var classType:Class; //to save what kind of object it is
//you could add in more proterties, like rotation etc
public function SaveData() {
}
}
}
Next, on your save function, do something like this:
//this will hold all your data
//a vector is the same as an array only all members must be of the specified type
var itemList:Vector.<SaveData> = new Vector.<SaveData>();
//populate the array/vector with all the children of itemContainer
var tmpItem:SaveData;
//loop through all children of item container
for (var i:int = 0; i < itemContainer.numChildren; i++) {
tmpItem = new SaveData(); //create a new save record for this object
tmpItem.bounds = itemContainer.getChildAt(i).getBounds(itemContainer); //save it's bounds
tmpItem.classType = getDefinitionByName(itemContainer.getChildAt(i)) as Class; //save it's type
itemList.push(tmpItem); //add it to the array
}
//Now you have an array describing all the item on screen
//to automatically serialize/unserialize, you need this line (and you need to register every class nested in SaveData that isn't a primitive type - which would just be Rectangle in this case
registerClassAlias("SaveData", SaveData);
registerClassAlias("flash.geom.Rectangle", Rectangle);
//create a new File to work with
var file:File = File.applicationStorageDirectory; //or whatever directory you want
file.resolvePath("saveData.data"); //or whatever you want to call it
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeObject(itemList); //write the array to this file
fileStream.close();
Now, to load it back in:
var itemContainer:Sprite = new Sprite(); //however you initialize this
addChild(itemContainer);
var file:File = File.applicationStorageDirectory;
file.resolvePath("saveData.data");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var itemList:Vector.<SaveData> = fileStream.readObject() as Vector.<SaveData>;
fileStream.close();
//now that you've read in the array of all items from before, you need to recreate them:
var tmpItem:DisplayObject;
var tmpClass:Class;
//loop through all items in the array, and create a object
for (var i:int = 0; i < itemList.length; i++) {
tmpClass = itemList[i].classType; //The type of item
tmpItem = new tmpClass() as DisplayObject; //create the item
//now move the item to it's former position and scale
tmpItem.x = itemList[i].x;
tmpItem.y = itemList[i].y;
tmpItem.width = itemList[i].width;
tmpItem.height = itemList[i].height;
//add the item back to the parent
itemContainer.addChild(tmpItem);
}
If you're not sure of the imports, here they are:
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.registerClassAlias;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
var bytes:ByteStream;
var filename:String = "mySaveFile.sav";
//[...] //initialize byte stream with your data
//get a reference to where you want to save the file
//(in this example, in the application storage directory,
//which is fine if you don't need to move the save file between computers
var outFile:File = File.applicationStorageDirectory;
outFile = outFile.resolvePath(fileName);
//create a file output stream, which writes the byte stream to the file
var outStream:FileStream = new FileStream();
outStream.open(outFile, FileMode.WRITE);
outStream.writeBytes(bytes, 0, bytes.length);
outStream.close();
//to load the file:
var inFile:File = File.applicationStorageDirectory;
inFile = inFile.resolvePath(fileName);
bytes = new ByteArray();
var inStream:FileStream = new FileStream();
inStream.open(inFile, FileMode.READ);
inStream.readBytes(bytes);
inStream.close();
I usually use SharedObject, by saving the number of objects with their locations ,scale ,rotation , .. etc. as an array (usually multidimensional array).
this example is tested :
first make a movie clip giving it "mc" as a name in the ActionScript Linkage
add any graphics you like
(this MovieClip will be the objects to be saved later )
then add the following script
////////// get random values for each object
var speed:Number ;
var yPosition:Number ;
var size:Number ;
this.width = size;
this.height = size;
this.y = yPosition ;
//// Moving the MovieClip from Left to right
function moving(e:Event):void
{
this.x += speed ;
if(this.x > 550)
{
this.removeEventListener(Event.ENTER_FRAME,moving);
MovieClip(parent).removeChild(this);
}
}
this.addEventListener(Event.ENTER_FRAME,moving);
in the root stage of the project add :
import flash.events.MouseEvent;
import flash.display.MovieClip;
var num:int = 0 ;
var mmc:MovieClip ;
var mySharedObj:SharedObject = SharedObject.getLocal("SavingStatus"); //// SharedObject to save info
function init()
{
if (!mySharedObj.data.savedArray)
{
///// first run No datat saved
this.addEventListener(Event.ENTER_FRAME,addingmcs)
}else {
///// Laoding previusly saved data
loading();
}
}
init() ;
/////////////// adding MovieClips to stage /////
function addingmcs(e:Event):void
{
num +=1 ;
if(num > 20){
num = 0 ;
mmc = new mc ;
mmc.speed = 2 + (5 * Math.random()) ;
mmc.yPosition = 500 * Math.random() ;
mmc.size = 50 + 10 * Math.random() ;
this.addChild(mmc);
}
}
///////////////////////////////////////////
///////////////////////////////////////////////
var obj:* ; //// to hold children MovieClips of the stage
var savingArr:Array = new Array ; //// the array to be saved , Contains all info of the children
////////////// Save all MovieClips with their parameters ////////////
function saving(e:MouseEvent):void
{
this.removeEventListener(Event.ENTER_FRAME,addingmcs)
for (var i:int=0;i<this.numChildren;i++)
{
if (this.getChildAt(i)is MovieClip) { ///// add all MovieClips of the stage to the array with their info (position - size - speed ... etc)
obj = this.getChildAt(i);
savingArr.push([obj , obj.x , obj.y , obj.speed , obj.size]); //// add the info in 3 dimentional array
obj.speed = 0 ;
}
}
////////////////saving array externally
mySharedObj.data.savedArray = savingArr ;
mySharedObj.flush ();
}
save_btn.addEventListener(MouseEvent.CLICK,saving)
////////////// Load all saved parameters ////////////
load_btn.addEventListener(MouseEvent.CLICK,loading)
function loading(e:MouseEvent =null):void
{
savingArr = mySharedObj.data.savedArray ;
for (var i:int=0;i<savingArr.length ; i++)
{
mmc = new mc ;
mmc.x = savingArr[i][1] ; ///// Get saved x
mmc.yPosition = savingArr[i][2] ; ///// Get saved y
mmc.speed = savingArr[i][3] ; ///// Get saved speed
mmc.size = savingArr[i][4] ; ///// Get saved size
addChild(mmc);
}
this.addEventListener(Event.ENTER_FRAME,addingmcs) ;
}
You already have some answers here but from your question, maybe you are missing the larger context.
So the File class represents a path to a file on disk and the FileStream class enables reading and writing data to that file. These are easy to use and there are many examples on the web. Here is one tutorial from Adobe: Reading and writing files
But what data to write and what is the format and data type? Those are the more important and more interesting questions.
The simplest approach is to use a text based format like XML or JSON where you read and write whatever properties of Sprites (or other objects) you want. One advantage of this is that the resulting file is a human readable/editable text file. A minor disadvantage is that you need to specify which properties to save and restore and deal with simple data type conversions (string to int, etc).
A more robust approach is to use what is called Serialization where the state of an entire object is saved and restored. This is more complicated and while not hard, is probably overkill for your project needs. There are good examples and discussion here , here and here.
For your current project and skill level, I'd suggest using XML orJSON Here's a tutorial using XML: Loading and Processing External XML Files

AS3 - Using a For Loop to Update Multiple Points and Their Values in an Array

I'm a bit new with AS3 (but not really with coding) so please forgive my ignorance. I'm creating a small function that will be called by a Main Function to update the position of 52 Pointers that have the x and y position of multiple point objects (empty movie clips). It will also then update two global arrays with those values (one array for the x and one for the y).
The problem is, as there are 52 of them, and they will probably grow in quantity, I'd like to be able to use a FOR function to do it, but I can't seem to be able to figure it out.
I get this error: Access of undefined property _point.
Here is a piece of the code that dream about:
function happyFunc():void
{
var avpointers:int = 52;
var vpointx:Array = new Array();
var vpointy:Array = new Array();
for (aa=0; aa<vpointers; aa++)
{
vpointx[aa] = _point[aa].x;
vpointy[aa] = _point[aa].y;
}
}
And this is the code that I'm stuck with...
function reallySadFunc():void
{
_point1 = localToGlobal(new Point(point1.x,point1.y));
//...
_point52 = localToGlobal(new Point(point52.x,point1.y));
vpointx[0] = _point1.x;
vpointx[1] = _point2.x;
//...
//oh god there are 104 lines of this why do I have to suffer
}
Thank you!
If I read your question correctly, I think this is what you need:
public static const CLIP_COUNT:int = 52;
// ...
private function happyFunc(parentClip:DisplayObjectContainer):void
{
var vpointx:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var vpointy:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var clipPoint:Point = new Point ();
var globalPoint:Point;
for (var i:int = 0; i < CLIP_COUNT; i++)
{
var childClip:DisplayObject = parentClip.getChildByName("point" +
(i + 1).toString());
clipPoint.x = childClip.x;
clipPoint.y = childClip.y;
globalPoint = parentClip.localToGlobal(clipPoint);
vpointx[i] = globalPoint.x;
vpointy[i] = globalPoint.y;
}
// do something with vpointx and vpointy - they're local variables
// and will go out of scope unless you declare them as class members
// or somehow return them from this function.
}
This function works by taking the parent display object (the one that contains the 52 movie clips - this could be the Stage) and iterates through them by getting each movie clip by name. The code assumes that your movie clips are called point1, point2, ..., point52.
To speed up the local-to-global coordinate conversion, two Point objects are created and then reused during the for loop to avoid creating many temporary Point instances.
Instead of using Array, use Vector.<Number> - this class has better performance than Array does.

Two dimensional array of objects in as3

Is it possible to make array in as3 like this :
countdowns[bodyID][powerupName] = { time: powerup.getTime(), onRemove: onRemove };
I have been trying for hours but no luck..
Thanks
Sure, but you have to declare each object separately and you have to call index number instead of variable name
Say I have an array of colors with a sub array of types of that color filled with objects describing RGB
var colors:Array = [];
var red:Array = [];
var darkRed:Object = { r : 256, g : 100, b : 100 }
red.push( darkRed ); //darkRed is now part of red
colors.push( red ); //red is now part of colors
To access darkRed, you would do this:
colors[0][0]; //that is darkRed
I believe this is what you are trying to accomplish :
var countdowns:Array = new Array;
countdowns[bodyID] = new Array;
countdowns[bodyID][powerupName] = { time: powerup.getTime(), onRemove: onRemove };
The second dimension of the countdowns Array is achieved by inserting an array into each element of the first dimension.
While this certainly can be done, but it's possible you're overcomplicating things. Perhaps a single-dimensional Array ob tailored Objects will suit better.
var ob:Object=new Object();
ob.bodyId=bodyId;
ob.powerup=powerup; // direct link to powerup might serve you better!
ob.onRemove=onRemove;
countdowns.push(ob);

How can I copy an ArrayCollection of transfer objects in actionscript?

public function create():ArrayCollection{
var index:int = 0;
var data:ArrayCollection = new ArrayCollection();
var length:int = originalData.length;
for(index; index < length; index++){
data.addItem(originalData[index]);
}
return data;
}
originalData is the original state of my data from database.
data is a copy of originalData used to be manipulated as the provider for my List component.
There's a button I use to call the create() function above, that
would mean, I want to revert all changes in data, and go back to
everything I have in originalData.
But when I debug my function, originalData has all the changes made in data.
When I use
list.selectedItem.thing = "new string";
is supposed to modify data[index].thing, because data is my List.dataprovider. but it changes originalData[index].thing also and this collection wasn't used for anything, except for creating a copy of itself!
I don't know why this happens. I didn't know how to phrase this behaviour as a google query.
Please, if you don't understand the question, comment it so I can try and make it clearer. This has consumed more time than its functionality is worth.
EDIT:
I've also tried this, but it doesn't work:
public function create():ArrayCollection{
var index:int = 0;
var data:ArrayCollection = new ArrayCollection();
var length:int = originalData.length;
for(index; index < length; index++){
// initializing a Item object.
var dataItem:Item = new Item();
dataItem = originalData[index] as Item;
data.addItem(dataItem);
}
return data;
}
EDIT 2:
Based on your answers and some research I came up with this generic function to copy arrayCollections made of custom objects.
public static function copy(objectClassName:String, objectClass:Class, arrayCollection:ArrayCollection):ArrayCollection{
var index:int = 0;
var length:int = arrayCollection.length;
var copy:ArrayCollection = new ArrayCollection();
for(index; index < length; index++){
registerClassAlias(objectClassName,objectClass);
copy.addItemAt(ObjectUtil.copy(arrayCollection.getItemAt(index)) as objectClass,index);
}
return copy;
}
As Tom says, this is because AS3 passes by reference. If you don't want to modify the original values then you should, again as Tom says, create copies of them.
Fortunately, AS3 has a utility to do this -- ObjectUtils.copy. Try this code instead of your original:
public function create():ArrayCollection{
var index:int = 0;
var data:ArrayCollection = new ArrayCollection();
var length:int = originalData.length;
for(index; index < length; index++){
data.addItem(mx.utils.ObjectUtil.copy(originalData[index]));
}
return data;
}
Do take note that copy() returns a generic Object. If you want to access any of its properties in a type-safe manner you'll have to cast it to its type.
A bit more about the pass-by-reference deal. Let's say we have items a, b, and c floating around in memory. You put them into an array(originalData). originalData now contains references to a, b, and c. You then create an ArrayCollection and insert (again) references to a, b, c. Objects a, b, and c aren't what's being stored in either the array or the ArrayCollection. So when you update originalData[0] you're getting a reference to an object (a), and updating it.
Likewise when you update ArrayCollection.getItemAt(0) you're getting the same reference and updating the underlying object which is why you're getting the behavior you're getting. Making a copy and inserting it means you're referencing an entirely new object.
I am not used to actionscript, but it looks to me like you are putting references to objects from one arrayCollection to another arrayCollection. So if you change those objects, this will be reflected in both arrayCollections since they refer to the same objects.
To avoid this you should make copies from the original objects to put in the new arrayCollection.
To create a deep copy of an array and keep the type, use the following method:
public static function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
This is the way proposed by Adobe.
Update: idea for a type safe copy function
public static function copyTypeSafe( ac:ArrayCollection ):ArrayCollection
{
var cloneAc:ArrayCollection = new ArrayCollection();
if( ac.length == 0 ) {
return cloneAc;
}
var className:String = getQualifiedClassName( ac.getItemAt(0) );
registerClassAlias( className, (getDefinitionByName( className ) as Class ) );
for each (var obj:Object in ac)
{
cloneAc.addItem( ObjectUtil.copy( obj ) );
}
return cloneAc;
}
You need to do a registerClassAlias call for each of the classes inside of your collection, then just use the function clone with the ByteArray suggested above and it will work fine. The key is to do a registerClassAlias call for each type inside of the ArrayCollection which you want to maintain. In my case:
var productGroupClassName:String = getQualifiedClassName(ProductGroup);
registerClassAlias( productGroupClassName, ProductGroup );
var productClassName:String = getQualifiedClassName(Product);
registerClassAlias( productClassName, Product );
//Need to create a copy so the original values will not be altered
dataProvider = copyTypeSafe(EnalityData.productsInfo);