Object Tag issue

Sonny

Member
Licensed User
Longtime User
Greetings.

I'm having a problem; storing a data type in an object tag returns unusual values.

When I click on either tile object, the click event will have the "SwapType" variable values as:

tileSwap.xSource = 2
tileSwap.ySource = 2
tileSwap.xTarget = 2
tileSwap.yTarget = 2

When the intention is to retrieve the first set of values from the first Tile click and the second set of values from the second Tile click.

Am I doing something wrong here?

Thanks in advance.

Here's the code:


------- Main Body -------

Sub Process Globals

Type SwapType(xSource As Int, ySource As Int, xTarget As Int, yTarget As Int)

End Sub


Sub Activity_Create(FirstTime As Boolean)

Dim tileSwap As SwapType
Dim xTiles(2) as Tiles

Activity.Initialize("")

tileSwap.xSource = 1
tileSwap.ySource = 1
tileSwap.xTarget = 1
tileSwap.yTarget = 1

xLoc = 100 : yLoc = 100
xDim = 150 : yDim = 150

xTiles(0).Initialize
xTiles(0).setObj(Activity, xLoc, yLoc, xDim, yDim)
xTiles(0).setTag(tileSwap)

tileSwap.xSource = 2
tileSwap.ySource = 2
tileSwap.xTarget = 2
tileSwap.yTarget = 2

xLoc = 300 : yLoc = 300
xDim = 150 : yDim = 150

xTiles(1).Initialize
xTiles(1).setObj(Activity, xLoc, yLoc, xDim, yDim)
xTiles(1).setTag(tileSwap)

End Sub

------- Class Tiles -------

Public Sub setObj(ActivityView As Activity, xLoc As Int, yLoc As Int, xDim As Int, yDim As Int)

Dim TileObj As Label

TileObj.Initialize("Tile")
ActivityView.AddView(TileObj, xLoc, yLoc, xDim, yDim)

End Sub


Public Sub setTag(sType As SwapType)

TileObj.Tag = sType

End Sub


Private Sub Tile_Click()

Dim TileSwap As SwapType
Dim xtSource, ytSource as Int
Dim xtTarget, ytTarget as Int

TileSwap = TileObj.Tag

xtSource = TileSwap.xSource
ytSource = TileSwap.ySource

xtTarget = TileSwap.xTarget
ytTarget = TileSwap.yTarget

End Sub
 

Informatix

Expert
Licensed User
Longtime User
You always use the same instance, so you always get the last values set.
You should write:
B4X:
Dim tileSwap(2) As SwapType
tileSwap(0).xSource = 1
tileSwap(0).ySource = 1
tileSwap(0).xTarget = 1
tileSwap(0).yTarget = 1

tileSwap(1).xSource = 2 'These values are now stored in a different place in memory
tileSwap(1).ySource = 2
tileSwap(1).xTarget = 2
tileSwap(1).yTarget = 2
 
Upvote 0

Sonny

Member
Licensed User
Longtime User
Thanks for the Response.

Yes, I'm using the same "instance" of what I thought was a primitive - but I'm updating it with new values, so shouldn't that work? I mean, I created the data type as a seperate entity from the xTiles() object, so wouldn't that mean that I can manipulate it independent of xTiles? I'm storing xSource in the object xTiles(x).Tag, then I'm updating xSource and storing that in object xTiles(x+1).Tag.

Isn't this instance of my Data Type (xSource) merely a collection of primitives, and as such, passed by value, so I'm not breaking any rules here? I assumed that anything that does not need to be Initialized, ie; no "tileSwap.Initilize" needed here, can be treated as a primitive or am I mistaken?

Thanks.
 
Upvote 0

Sonny

Member
Licensed User
Longtime User
The thing that's really confusing me here is that if I add a "getTag" method to the class, then call it in my main body - after each assignment, so as to "recover" my Data Type from each instance of xTiles, then the correct values for each object are returned. It's just when I try to do this from the "Click" event within the Class itself that's giving me the last set values exclusively.

Why would there be a difference based upon "how" I work with a class, when a class is just a class and it should completely wrap all of it's properties and methods, etc., such that the encapsulation should be complete and implementation agnostic? I would gather that there should be no difference whether I'm accesing the Tag value either externally via a "get" method, or internally via a simple property (result = Class.Tag).

My "get" method, by the way, is:

Public Sub getTag()

Return TileObj.Tag

End Sub

And I've confirmed that the Click event is returning the correct instance of the Class because other instance properties contain the proper values. It's only the Tag property for each instance, that is returning the final copy of my Daty Type within the Click event invocation, irrespective of invoking instance.

Thanks.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
The thing that's really confusing me here is that if I add a "getTag" method to the class, then call it in my main body - after each assignment, so as to "recover" my Data Type from each instance of xTiles, then the correct values for each object are returned.

It's normal.
I simplify how it works:
You set tileSwap to 1 -> 1 is in memory
You get tileSwap -> you get 1
You set tileSwap to 2 -> 1 is replaced by 2 in memory
You get tileSwap -> you get 2

A custom type needs to be instantiated like a class with a Dim and an Initialize (the Initialize is not mandatory if your type declares only primitive values). If you want different values, you have to create different instances. One instance for one set of values.

when a class is just a class and it should completely wrap all of it's properties and methods,

There's no property in the class implementation of B4A. Only global or local variables. But that does not change the reasoning:
If you set the global variable GV of the class C to tileswap, GV stores a pointer to tileswap.
Now, you instantiate a second class C2. You set GV to tileswap (with different values). This GV is different from the GV of C (you have two GVs in memory) BUT both store the same pointer and get exactly the same data.
A custom type is not a primitive type. So the class variables do not store the values, only the references.
 
Upvote 0

Sonny

Member
Licensed User
Longtime User
Okay,

So in my last response, where I'm using my own getter, the Dalvic VM is taking an "optimized" approach - seeing that the values that I'm requesting are still in memory, so it retrieves them from memory - instead of actually invoking my getter method to retrieve the values from the copy stored in the class object. And when I'm retrieving the tag, while within my class' click event code, I'm in a different namespace - one that does not already have my requested data in memory, so that's when an actual fetch is done containing the "real" values that are stored - references to the same Data Type in each objects' Tag "property". Correct?
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Okay,

So in my last response, where I'm using my own getter, the Dalvic VM is taking an "optimized" approach - seeing that the values that I'm requesting are still in memory, so it retrieves them from memory - instead of actually invoking my getter method to retrieve the values from the copy stored in the class object. And when I'm retrieving the tag, while within my class' click event code, I'm in a different namespace - one that does not already have my requested data in memory, so that's when an actual fetch is done containing the "real" values that are stored - references to the same Data Type in each objects' Tag "property". Correct?

You have a particular skill to complicate simple things. ;-)
In my answer, the words "namespace" or "Dalvik" are not used because they are not necessary to understand what's going on. I don't know how I can explain this more clearer than I did.
Here's a second solution to your problem:
B4X:
Dim tileSwap As SwapType
tileSwap.xSource = 1
tileSwap.ySource = 1
tileSwap.xTarget = 1
tileSwap.yTarget = 1

Dim tileSwap As SwapType 'Creates a new instance, the previous one is no longer accessible by its name but still exists in memory, in a different location
tileSwap.xSource = 2
tileSwap.ySource = 2
tileSwap.xTarget = 2
tileSwap.yTarget = 2
 
Upvote 0

Sonny

Member
Licensed User
Longtime User
LMAO.

Please forgive me. I've worked as a Vignette V6 CMS Developer for a long time - translation: I've worked with "Technical" Project Managers for way too long - they have a tendency to rub off on to you. I understand what you mean now. I implemented your first solution and it's working perfectly. Thanks for the assist. :)

>> Sonny <<
 
Upvote 0
Top