Mama Tate
Mama Tate

Reputation: 283

Passing a Method with return value type in a for loop

Ok, guys i am a little confused about this thing. I will show you the code i have issues with.

So i have a CellMap class which has this method:

public Vector3 GetFreeCell()
{
    Vector3 result = new Vector3();

    if (mOccupiedPoint != null)
    {
        result = (Vector3)mOccupiedPoint[0];

        mOccupiedPoint.RemoveAt(0);
    }

    return result;
}

Next i have my WorldMap class which has this method:

private void AddObject(GameObjectBase obj, int times, Vector3 position)
{
    for (int i = 0; i < times; i++)
    {
        Vector3 tempPos = position;

        AddObject(obj, tempPos);
    }
}

So now when i pass for a Vector3 parameter GetFreeCell() in my AddObject method like this:

private CellMap mCellMap;

public WorldMap()
{
    CreateCellMap(100, 1, 100);

    AddObject(new DarkForestTreeA(), 1000, mCellMap.GetFreeCell());

}

i get the same old Vector3 value from the mCellMap.GetFreeCell().I can change the AddObject() method like:

private void AddObject(GameObjectBase obj, int times)
{
    for (int i = 0; i < times; i++)
    {

        AddObject(obj, mCellMap.GetFreeCell());
    }
}

but i want to keep the Vector3 parameter. Can somebody help me out and give me a hint how can make the GetFreeCell() method execute in the for loop, but to pass it only as a parameter?

Upvotes: 0

Views: 826

Answers (3)

Guffa
Guffa

Reputation: 700562

You can't pass in an object and have it just update itself for each use.

You can pass a function into the method, and use that to get a position for each iteration:

private void AddObject(GameObjectBase obj, int times, Func<Vector3> getPosition)
{
    for (int i = 0; i < times; i++)
    {
        Vector3 tempPos = getPosition();

        AddObject(obj, tempPos);
    }
}

You Can call it using a lambda expression for the function:

AddObject(new DarkForestTreeA(), 1000, () => mCellMap.GetFreeCell());

A solution that is a bit more tricky, is to send in a "magic" object, that will convert itself to a Vector3 when used, and return a new value each time:

public class MagicVector3 {

  private Func<Vector3> _getVector;

  public MagicVector3(Func<Vector3> getVector) {
    _getVector = getVector;
  }

  public static implicit operator Vector3(MagicVector3 magic) {
    return magic._getVector();
  }

}

Now you can just change the Vector3 parameter to MagicVector3, and call it using:

AddObject(new DarkForestTreeA(), 1000, new MagicVector3(() => mCellMap.GetFreeCell()));

This code has a bit of a code smell, though. Normally you wouldn't use a value like that, as it kind of hides what's actually happening.

Upvotes: 0

p.s.w.g
p.s.w.g

Reputation: 149040

Your question is a bit confusing, but if I understand what you're asking, you want to pass a function (in this case GetFreeCell) to AddObject which will be invoked times many times. In that case, use a delegate:

public WorldMap()
{
    CreateCellMap(100, 1, 100);

    AddObject(new DarkForestTreeA(), 1000, mCellMap.GetFreeCell); // note no () after method name
}

private void AddObject(GameObjectBase obj, int times, Func<Vector3> vectorFunc)
{
    for (int i = 0; i < times; i++)
    {
        AddObject(obj, vectorFunc());
    }
}

Upvotes: 3

user27414
user27414

Reputation:

Is this what you're looking for?

private void AddObject(GameObjectBase obj, int times, Vector3 position)
{
    for (int i = 0; i < times; i++)
    {
        Vector3 tempPos = mCellMap.GetFreeCell();

        AddObject(obj, tempPos);
    }
}

Upvotes: 0

Related Questions