Sign in to follow this  
Spa8nky

[C#] [XNA] Get and set with extensions?

Recommended Posts

If I wish to access the X and Y value of a Vector2 class as an Index in XNA, then I currently use the following extension:
        public static float Index(this Vector2 v, int index)
        {
            switch (index)
            {
                case 0: { return v.X; }
                case 1: { return v.Y; }

                default:
                    {
                        // This is unsafe code BUT it is useful for debugging
                        throw new ArgumentOutOfRangeException(
                            "Vector component index out of range"
                        );
                    }
            }
        }

This works fine for accessing the X and Y value, but how can I set the X and Y value using this method?
            for (int i = 0; i < 2; ++i)
            {
                // Accessing Index value works fine
                v = point.Index(i);
                v = Math.Max(v, min.Index(i));
                v = Math.Min(v, max.Index(i));

                // Setting Index value is not possible
                q.Index(i) = v;
            }

If this isn't possible, is there another method I can use? Thank you.

Share this post


Link to post
Share on other sites
Would this work?


public static void SetIndex(this Vector2 v, int index, float value)
{
switch (index)
{
case 0: { v.X = value; }
case 1: { v.Y = value; }

default:
{
// This is unsafe code BUT it is useful for debugging
throw new ArgumentOutOfRangeException(
"Vector component index out of range"
);
}
}
}




A bit different to what you wanted it to look like, but I think it serves the purpose. I don't know why you're getting/setting the coordinates like this, though. :p

Share this post


Link to post
Share on other sites
That will work if the break keyword is used:


public static void SetIndex(this Vector2 v, int index, float value)
{
switch (index)
{
case 0:
{
v.X = value;
break;
}
case 1:
{
v.Y = value;
break;
}

default:
{
// This is unsafe code BUT it is useful for debugging
throw new ArgumentOutOfRangeException(
"Vector component index out of range"
);
}
}
}



Quote:

I don't know why you're getting/setting the coordinates like this, though. :p


So I can set the values in one loop as opposed to repeating the same lines of code for x and y or x,y and z.

Thanks for the help, Barguast.

If anyone can think of any other methods to tackle this then please share.

Share this post


Link to post
Share on other sites
Just done some testing and found that the method you posted doesn't work:


Vector2 v = new Vector2();
v.SetIndex(1, 100f);
Console.WriteLine(v);


v is still (0,0) and not (0,100).

Share this post


Link to post
Share on other sites
You need to brush up on the differences between reference types and value types. Vector2 is a value type, so it is copied by value when passed to a function as an argument. When you assign the value to one of its members, you are only modifying a copy, and the original variable isn't changed.

Share this post


Link to post
Share on other sites
I assume extension methods do not allow you to overload operators (if you can overload subscript operators at all in C#)?

Share this post


Link to post
Share on other sites
Quote:

You need to brush up on the differences between reference types and value types.


As far as I know, extension methods don't allow the "ref" keyword to be used with the "this" keyword, so it seems it just isn't possible to do it this way.

Is this correct?

Share this post


Link to post
Share on other sites
Quote:
Original post by Spa8nky
Quote:

You need to brush up on the differences between reference types and value types.


As far as I know, extension methods don't allow the "ref" keyword to be used with the "this" keyword, so it seems it just isn't possible to do it this way.

Is this correct?


Yes.

Share this post


Link to post
Share on other sites
Quote:
Original post by Spa8nky
So I can set the values in one loop as opposed to repeating the same lines of code for x and y or x,y and z.


Can you provide an example?

Share this post


Link to post
Share on other sites
Quote:

Can you provide an example?


Repeating the following for x, y (and z in 3D) would seem unecessary:


for (int i = 0; i < 2; ++i)
{
// Find distance intervals for current two slabs
// Distance is between slab min/max values
float d_S0 = a.MinPoint.Index(i) - b.MaxPoint.Index(i);
float d_S1 = b.MinPoint.Index(i) - a.MaxPoint.Index(i);

// The distance is positive if the intervals do not overlap
// Must be >= to 0 and not > 0, otherwise MTV can equal Vector2.Zero and cause NaN
if (d_S0 >= 0f || d_S1 >= 0f)
{
return false;
}

// Current distance interval for slabs
float d = (d_S0 > d_S1) ? -d_S0 : d_S1;

// If d is the smallest distance so far
if (Math.Abs(d) < Math.Abs(mtv_Distance))
{
// Store the distance and the current axis
mtv_Distance = d;
mtv_Axis = i;
}
}

Share this post


Link to post
Share on other sites

for( int componentIndex = 0; componentIndex < 3; ++componentIndex ) {
vec.SetByIndex( componentIndex, valueGoesHere );
}

Obviously, contrived, but you can scale the operation. I personally do not consider it worthwhile (or indeed, good practice) to build an extension method for this sort of thing though. For complex examples like Spa8nky's, I'd either refactor the complexity to a function (if it's actually that complicated) or pull it outside the loop. The latter can always be done if the computation has no dependence on the component index.

Share this post


Link to post
Share on other sites
Would this be a sensible way of doing it then:


public static void SetIndex(ref Vector2 v, int index, float value)
{
switch (index)
{
case 0:
{
v.X = value;
break;
}
case 1:
{
v.Y = value;
break;
}

default:
{
// This is unsafe code BUT it is useful for debugging
throw new ArgumentOutOfRangeException(
"Vector component index out of range"
);
}
}
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this