Pointers with XNA

Started by
15 comments, last by Starnick 13 years, 3 months ago
I want to use pointers using XNA in C# but apparently I can't unless I write unsafe code. What's a way to work around this? I want to have a simple bool pointer that gets dynamically updated throughout my game. Doesn't C# have some way to use dynamic variables?
Advertisement
A good read http://msdn.microsof...3c3bfhx(v=vs.80).aspx
Well C# has a mechanism for changing the values of variables.

One is the "out" method, it is used when the function is always going to create a new value (and you're already returning another value). It assumes you aren't using the value that is being passed in. Variables don't have to be initialised before use.



class X
{
private void FunctionChangeValue(out int x)
{
x = 2;
}

public void UseX()
{
int x;
FuncitonChangeValue(out x);
}
}




The other is ref, the parameter can have an existing value.


class X
{
private void FunctionChangeValue(ref int x)
{
x = 2 * x;
}

public void UseX()
{
int x = 2;
FuncitonChangeValue(ref x);
}
}



At compile time they are compiled into the same code.

Another note is you can't pass Properties via ref or out, you have to put them into temporary variables. This is because Properties are actually get/set functions and your actually passing the "pointer" behind the scenes to the variable.
Also consider that in C# objects are passed by reference by default. This is for the same reason you always pass variables in C++ by reference or pointers for speed efficiency. http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx

So if you change a property on a object that is passed to a function, it WILL change the value of that property even when it returns to the calling function.

If you do the following:


int newX(A x)
{
x.Value = 233;
x = new A();
x.Value = 222;
}


The calling function will NOT have the new X, since that just changes the reference. The calling function will retain the other class instance that was passed which had its Value property changed to 233.

If you want to get the new reference you need the ref or out keyword.
If you want to "reference" value types you could help yourself with a wrapper (very bare):


public class BoolWrapper
{
public bool Value;
}

And then just pass around such a BoolWrapper instance and read/change Value. If you got more than just bools, go for a generic:


public class Wrapper<T>
{
public T Value;
}

If you want to "reference" value types you could help yourself with a wrapper (very bare):


public class BoolWrapper
{
public bool Value;
}

And then just pass around such a BoolWrapper instance and read/change Value. If you got more than just bools, go for a generic:


public class Wrapper<T>
{
public T Value;
}



Why use this very "Java" type wrapper system when C# has the ref keyword for doing the same thing? The ref keyword and the out keyword above work with value types just fine.


Tell us more about this boolean value. I suspect there are only one or two places it really needs to be accessed, and some forward thinking design can remove the need to pass a naked "pointer" or even passing it by reference.
So basically the boolean is representing the last direction the character moved. It's pacman movement (ex. the character is moving up in a corridor, and the user pushes left, the character will keep moving up until an intersection is met, and then the last direction would have been up, which I switch to false). There's probably a much easier way to do this type of movement, and I'm open to suggestions. The whole pointer thing just got me really curious.
The solution is to package the useful information about the player into a class or structure, and pass that to the areas of the code that need it. Only the input subsystem needs to change the value, a delegate can be a nice way of decoupling the dependency here. All other areas need read only access, so you can just make it a read only property of the class/struct.

So basically the boolean is representing the last direction the character moved. It's pacman movement (ex. the character is moving up in a corridor, and the user pushes left, the character will keep moving up until an intersection is met, and then the last direction would have been up, which I switch to false). There's probably a much easier way to do this type of movement, and I'm open to suggestions. The whole pointer thing just got me really curious.


I got a suggestion, since I don't quote understand how you cover the movements with a boolean (only?): Pac-Man style movement has four directions, and if you need to cover the "not moving" part, only then an additional boolean comes in (e.g. isMoving flag). Or you could encode it into the moving with an enum, e.g.

public enum Movement { Up, Right, Down, Left, None};


But I don't understand why you need pointers here.
Edit Ninja-ed by rip-off. Yes, pack your Pac-Man states into a class and pass that around.

@deepdene : It was meant as an alternative to your suggestions, since out/ref don't work always (e.g. properties, return values).
As ubird pointed out, I think using enums and bit flags to represent the state is not only easier but less error prone. You can define more information (e.g. in a single parameter have several bit flags set, rather than several parameters of booleans). Plus, I could see some debugging nightmares if you're passing state information that can be changed without its owner being aware of the change. This goes in hand with wanting that state information to be read-only, and all changes to it have to go through the owner/entity first.

A usual case where you'd want to pass a structure by reference are when they're large structures to avoid having to copy the data - e.g. XNA's Matrix struct. In fact that's the rationale behind all the ref/out functions in XNA's math structures. But for a boolean, I think it's a bit overkill, aside from the reasons above.

This topic is closed to new replies.

Advertisement