NodeCanvas Forums › Support › Generic Events with null values
Hey everyone,
I just stumbled upon a problem with generic Events in NodeCanvas. The issue is that I am able to send null as a parameter via SendEvent<T>, but CheckEvent<T>- and CheckEventValue<T> ignore such events and only fire when the incoming event is not null.
Looking at the sourcecode, it looks like this is intentional behaviour at least for CheckEventValue, but I wonder why. Are there any downsides to allowing null values in event parameters? Anyway, due to the design of some components in our current project I need events to work with null parameters, so I patched both Conditions to explicitly allow null values.
Maybe this is useful to others or maybe this is just a bug.
[EDIT] Forum Software doesn’t allow upload of ZIP files, so heres the diffs inline:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.../ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEvent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEvent.cs b/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEvent.cs index 18086cb..ebd8053 100644 --- a/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEvent.cs +++ b/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEvent.cs @@ -56,7 +56,7 @@ namespace NodeCanvas.Tasks.Conditions{ protected override bool OnCheck(){ return false; } public void OnCustomEvent(EventData receivedEvent){ if (isActive && receivedEvent.name.ToUpper() == eventName.value.ToUpper()){ - if (receivedEvent.value is T){ + if (receivedEvent.value == null || receivedEvent.value is T){ saveEventValue.value = (T)receivedEvent.value; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.../NodeCanvas/Tasks/Conditions/Utility/CheckEventValue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEventValue.cs b/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEventValue.cs index 594d13f..9621703 100644 --- a/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEventValue.cs +++ b/Assets/Packages/ParadoxNotion/NodeCanvas/Tasks/Conditions/Utility/CheckEventValue.cs @@ -22,7 +22,7 @@ namespace NodeCanvas.Tasks.Conditions{ public void OnCustomEvent(EventData receivedEvent){ if (receivedEvent is EventData<T> && isActive && receivedEvent.name.ToUpper() == eventName.value.ToUpper()){ var receivedValue = ((EventData<T>)receivedEvent).value; - if (receivedValue != null && receivedValue.Equals(value.value)){ + if (receivedValue == null || receivedValue.Equals(value.value)){ #if UNITY_EDITOR if (NodeCanvas.Editor.NCPrefs.logEvents){ |
Hello,
Thanks for bringing this to my attention. Null should definitely been possible to send (and compare with CheckEventValue).
Here are the final changes I’ve just made:
CheckEvent.cs
I’ve used reflection here so that assignable types work as well. It can be a bit slower, but also more flexible and convenient.
1 2 3 4 5 6 7 8 9 10 11 |
if (isActive && receivedEvent.name.ToUpper() == eventName.value.ToUpper()){ var eventType = receivedEvent.GetType(); if (eventType.RTIsGenericType()){ var valueType = eventType.RTGetGenericArguments().FirstOrDefault(); if (typeof(T).RTIsAssignableFrom(valueType)){ saveEventValue.value = (T)receivedEvent.value; } } |
CheckEventValue.cs
I don’t know what I was thinking in my previous code. It doesn’t make a lot of sense the way I did it before 🙂
I think I was trying to only catch events of the exact specified T type, but was not really convenient. This now handles assignable types as well as nulls of course.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public void OnCustomEvent(EventData receivedEvent){ if (isActive && receivedEvent.name.ToUpper() == eventName.value.ToUpper()){ var receivedValue = receivedEvent.value; if (object.Equals(receivedValue, value.value)){ #if UNITY_EDITOR if (NodeCanvas.Editor.NCPrefs.logEvents){ Logger.Log(string.Format("Event Received from ({0}): '{1}'", agent.gameObject.name, receivedEvent.name), "Event", this); } #endif YieldReturn(true); } } } |
Thank you!
Join us on Discord: https://discord.gg/97q2Rjh
Null should definitely been possible to send (and compare with CheckEventValue)
Thats good to hear. Thanks for the quick response and the patches!
CheckEvent.cs did error out on FirstOrDefault because System.Linq wasn’t imported. No biggie though and the patches seem to work fine as far as i can tell. 🙂
Cheers
You are very welcome and thanks for letting me know it works for you as well.
Indeed, you need to be “using System.Linq” 🙂
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh