- Home /
[C#] Am I using events right?
Hello. I've been trying to get into the practice of using events, but I'm not sure I'm using them exactly right.
Let's say I have an event that should be called whenever the player loses health. What I have been doing is subscribing to the event with the function for losing health, and whenever I want the player to lose health I call the event. Should I be calling the event whenever the lose health function is called instead? Here are a couple examples with the two workflows to show what I mean:
Example 1:
Function1 subscribes to event
Function2 needs function1 to be called, so they call the event rather then calling the function itself.
Example 2:
Function1 calls event inside of it's code.
Function2 needs function1 to be called, but since function1 has a call to the event in it's code, it simply calls function1, calling the event at the same time.
So, with all that said, which way is the "right" way? Are they both okay? If one of them is more efficient, which one?
Don't exactly understand the examples, next time provide some example code. $$anonymous$$akes it easier than trying to understand "function that needs function that calls function with function".
Let me give you another using the same premise of being interested on player health loss..
You subscribe/register callbacks of interested classes/entities/whatever to an event. Basically an event is like a list of functions to call when something happens. Functions that can be from any script. Also the event raising(the term for calling the event and notifying the interested) happens where the event happens in reality. So in the case of damage being applied, you will raise the event right after you subtract the damage to the remaining health.
class Player{
public delegate void HealthLostDelegate(float);
public event HealthLostDelegate HealthLost;
private float remainingHealth;
public void ApplyDamage(float damage){
remainingHealth -= damage;
if(HealthLost != null){
HealthLost(remainingHealth);
}
}
}
class HealthHUD{
void Start(){
FindObjectByType<Player>().HealthLost += UpdateHealth;
}
private void UpdateHealth(float newHealth){
someTextComponent.text = newHealth.ToString();
}
}
This is very hastily written so there might be mistakes here and there but this is more to show you the logic.
Answer by SUpersindit2 · Feb 04, 2016 at 10:26 AM
Lets say we have a function Called A subscribed to the event function Called E, all we need to do is call E() and it will execute all the subscribed functions which is A.
However you must be mindful that in the case of no subscribers in the event and you call it, it might cause memory leakage, so you must check that the event E != null before calling it.
Answer by cjdev · Feb 04, 2016 at 10:45 AM
The first example is the idea of events. Another way to think of it is not as if one method is calling another but as if methods are saying they want to do something when some conditions occur. When an event is called it's called by some unrelated and unknown method to those waiting for it, which is the idea: to decouple the links between objects and make them easier to work with. This way you don't need to change all your classes if you change one of them just because they all reference a method in it.
Not only that, it relieves you from having to check for boolean flags inside Update functions as well, what we call Polling. Booleans tend to increase if you don't use events and they also tend to create massive State diagrams where you need to check what happens when one is true and another is false for an array of booleans.
But, there are drawbacks as well. If you connect , by chance or otherwise, a long list of listeners that adds to many layers in depth, you WILL see spikes here and there in the game. You have to do some polling as well. Use event queues and a dispatcher in order to decouple the call stack from the actual point of the event raising to release the script that raises the event from the big call stack that will be created from the event being raised.