Using a delegate method as object parameter

Hello everyone, i’m struggling currently with the delegates and the event. I know in the past i managed to get a simple one working (just firing an event from the back to my view), but here i have a specific, yet simple, situation :

I have a location, let’s say a village (object LocationVillage, inheriting Location).The location have buildings (object Building). The village location is responsible for initializing the buildings the first time it is created (game creation), so it create, for example, the Building SimpleHouse with name, construction timer, if it is available at startup or not, etc.

My view of the village use a BuildingController for every building. When the controller get clicked on, construction start. And when construction end, i want the Building linked to the BuildingController to ResolveConstruction (adding a new family, updating resources, etc.).

Obviously, every building has different things to do at resolution. So it is my LocationVillage that hold theses methods (SimpleHouseBuilt(), for example).

So, what i want is to pass as argument, in the constructor, the link to the SimpleHouseBuilt method to my SimpleHouse Building object, so that when i will call the Resolve method of the Building object, it will trigger the SimpleHouseBuilt method.

Obviously, i have other options… I could just use a routing method with the building type as parameter, in a switch. I could also (that’s what i’m doing currently) just invoke the method based on its name from the Building class (as long as i have the location reference). But that doesn’t seem as clean to me as just doing a simple

public class Building 
{

public string Name {get; set;}
public delegate void ResolveMethod();

public Building(string name, methodRef ref)
{
    Name = name;
    ResolveMethod = ref;
}
public void Resolve()
{
   ResolveMethod.execute();
}

}

public class LocationVillage : Location 
{

public Building SimpleHouse {get; set;}

public LocationVillage()
{
SimpleHouse = new Building("Simple House", SimpleHouseBuilt);
}

public void SimpleHouseBuilt()
{

// do stuff

}

}

Obviously this code don’t work, I look for the real syntax.

P.S : I know you can also do it with delegate + event, by subscribing the delegate to the event to call with +=, but i didn’t manage to get it right either.

Any tips ? Thank you guys.

Use the generic Action delegate from the System namespace.

using System; // don't forget this

// some stuff removed for clarity on how to add it to your own code

class Building
{
   private Action OnCompleteCallback;

   public Building(string name, Action callback)
   {
      OnCompleteCallback = callback;
      // other stuff
   }

   public void Resolve()
   {
       if(OnCompleteCallback != null)
             OnCompleteCallback();
    }
}

public class LocationVillage : Location
{
    public LocationVillage()
    {
        SimpleHouse = new Building("Simple House", SimpleHouseBuilt);
    }

    public void SimpleHouseBuilt() { }
}
2 Likes

Annnd it was that simple. Damn, i didn’t know about the Action callback, and google searches didn’t even suggest it (or i completely missed it).

Thanks a lot GroZZleR, i tried it, it works just fine :slight_smile:

1 Like

There’s parameterized versions too, if you need to pass data. It might make things easier depending on your overall structure.

I use them a lot for UI callbacks, so I know what widgets were clicked and whatnot.

private Action<UiWidget> clicked;

private void OnClick()
{
   if(clicked != null)
       clicked(this);
}