- Home /
Choosing Events/Delegates to Register for by Parameters Passed
I'm trying to determine the best model for dynamically choosing events to register for. Here's my situation: I have a UserData class that keeps track of overall play stats, and a Challenge class that keeps track of challenges for the user to complete (~3 will be active at a time) and contains fields for text, a delegate that gets passed a lambda expression for testing completion, and a CheckComplete method.
Currently, I'm looking to have UserData fire an event whenever something is updated (with a different event for each stat). Then, upon instantiation, Challenges hook up their CheckComplete method (which uses the lambda expression to check for completion) to the relevant event(s) in UserData.
As far as I'm aware at this point, events can't be passed as arguments, so I'm probably going to need to use multicast delegates.
My ultimate goal here is to only check to see if a Challenge is completed when a relevant stat changes, as opposed to, say, checking all the active challenges for completion whenever any stat changes.
I'm sure this will make some of you weep, but here's a small (non-working) example of what I'm trying to do:
public static class UserData
{
public event Action ClubbedSealsUpdated;
public event Action LifetimeScoreUpdated;
...
}
public class Challenge
{
public event Action ChallengeCompleted;
public string text;
private Func<bool> condition;
public Challenge ( string displayText, Func<bool> completionCondition,
event[] eventsToRegisterFor )
{
text = displayText;
condition = completionCondition;
foreach ( event e in eventsToRegisterFor )
{
e += this.CheckComplete();
}
}
public void CheckComplete ()
{
if ( condition )
{
UserData.ChallengePoints += 10;
ChallengeCompleted(this);
...
}
}
}
public static class Challenges
{
public static List<Challenge> activeChallenges;
public static List<Challenge> allChallenges = new List<Challenge>() {
new Challenge( "Club 10 baby seals",
() => UserData.ClubbedSeals >= 10,
UserData.ClubbedSealsUpdated ),
new Challenge( "Accumulate 10,000 total points",
() => UserData.LifetimeScore >= 10000,
UserData.LifetimeScoreUpdated )
}
}
Does this seem like a reasonable way to accomplish my task? If it is, how do pass which events to register for as parameters in the Challenge constructor? Or is there something better I haven't considered?