Changing the value of a custom DynamicEnum from an input pin seems to have no effect

Hey there,

I’m using 5.3-0080.

I’m trying to create a C# dynamic enum that would give me a list of available video outputs (stuff like \\.\DISPLAY1 and so on).

I have created a C# VideoOut dynamic enum, the GetEntries method looks like this :

    protected override IReadOnlyDictionary<string, object> GetEntries()
    {
        var entries = new Dictionary<string, object>(Screen.AllScreens.Length);
        foreach(var screen in Screen.AllScreens)
        {
            var name = screen.DeviceName;
            if(!entries.ContainsKey(name))
            {
                entries.Add(name, screen);
            }
        }
        return entries;
    }

Note I had to edit the csproj a bit in to use Forms, which you need to retrieve Screens… :

[...]
<TargetFramework>net6.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
[...]

Now, in a Process Node I can create an input of type VideoOut, which correctly lists my connected monitors. But it looks like the value of the enum does not update :

screenenum

Now if we disconnect the IOBox and go inside Foo, changing the Input’s default value does indeed update :

screenenuminside

Then, as suggested in the Gray Book, I tried creating an Definition [Primitive.DynamicEnum] to check if I could see the Entries of my Enum. Creating the Definition node and creating an IOBox on its input throws this error :

Error
MissingMethodException: "Constructor on type 'VL.Lib.Collections.IDynamicEnum' not found."
    StackTrace:
        System.RuntimeType { internal object CreateInstanceImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture) { ... } } 
        VL.AppServices.Serialization.DynamicEnumSerializer { public virtual VL.Lib.Collections.IDynamicEnum Deserialize(VL.Core.SerializationContext context, object content, System.Type type) { ... } } 
        VL.AppServices.Serialization.UngenericDelegatingSerializer`1 { public virtual object Deserialize(VL.Core.SerializationContext context, object content, System.Type type) { ... } } 
        VL.AppServices.Serialization.SerializationContextInternal { public virtual object Deserialize(object content, string name, System.Type staticType) { ... } } 
        VL.AppServices.Serialization.SerializationServiceImpl { protected virtual object Deserialize(VL.Core.NodeContext nodeContext, object content, System.Type type, bool throwOnError, bool pathsAreRelativeToDocument, System.Collections.Generic.IReadOnlyList<>& errorMessages) { ... } } 
        VL.Model.CompileTimeValue+<>c__DisplayClass9_0 { internal object <GetClrValue>g__Compute|1(System.Type type, bool unwrap, object serializedValue) { ... } } 
        System.Collections.Concurrent.ConcurrentDictionary`2 { public TValue GetOrAdd(TKey key, System.Func<, > valueFactory) { ... } } 
        VL.Model.CompileTimeValue { public object GetClrValue(System.Type type, bool unwrap) { ... } } 
        VL.Model.VLSession { private void UpdateRuntimeValuesFromModel(VL.Model.Internal.Compound current, VL.Model.Internal.Compound previous, VL.Model.Internal.Document document) { ... } } 
        VL.Model.VLSession { private void UpdateRuntimeValuesFromModel(VL.Model.Internal.Compound current, VL.Model.Internal.Compound previous, VL.Model.Internal.Document document) { ... } } 
        VL.Model.VLSession { private void UpdateRuntimeValuesFromModel(VL.Model.Internal.Compound current, VL.Model.Internal.Compound previous, VL.Model.Internal.Document document) { ... } } 
        VL.Model.VLSession { private void UpdateRuntimeValuesFromModel(VL.Model.Internal.Compound current, VL.Model.Internal.Compound previous, VL.Model.Internal.Document document) { ... } } 
        VL.Model.VLSession { private void UpdateRuntimeValuesFromModel(VL.Model.Internal.Compound current, VL.Model.Internal.Compound previous, VL.Model.Internal.Document document) { ... } } 
        VL.Model.VLSession { private void UpdateRuntimeValuesFromModel(VL.Model.Internal.Compound current, VL.Model.Internal.Compound previous, VL.Model.Internal.Document document) { ... } } 
        VL.Model.VLSession+<OnSolutionUpdatingAsync>d__208 { private virtual void MoveNext() { ... } } 
        System.Runtime.ExceptionServices.ExceptionDispatchInfo { public void Throw() { ... } } 
        System.Runtime.CompilerServices.TaskAwaiter { private static void ThrowForNonSuccess(System.Threading.Tasks.Task task) { ... } } 
        System.Runtime.CompilerServices.TaskAwaiter { private static void HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task task) { ... } } 
        VL.Model.VLSession+<UpdateAsync>d__187 { private virtual void MoveNext() { ... } } 

Ignored that and tried to type it to VideoOut anyway, but the same error is thrown and the Enum IOBox does not update.

The fact that it seems to work when changing the default of my Process Node’s input made me think it was buggy. But please let me know if I’m not doing this thing correctly :)

I have attached a zip with the patch and the C# solution so you can repro, if needed.

Cheers!

PS Not sure if it’s related, but before uploading the patch I wanted to annotate it a bit, and realized that I could not edit a comment IOBox : it would revert to the state in which it was created :

commentnotupdating

I saw this as well in my project when I was playing with this DynamicEnum thing, and this did not happen in a fresh patch, so I assume this is related.

PPS The behavior that makes the comment revert to its creation state disappears when I remove the Definition (DynamicEnum) node from my patch :

commentnotupdatingsolved

screenDynamicEnum.zip (143.9 KB)

Thanks in advance!

seb

1 Like

Most probably you need to add the type forward and mark it as immutable. But in general, unacceptable all of those issues. Expect fixes in upcoming.

All fixed. Also the PS & PPS parts shouldn’t lead to that behavior. Thanks a lot for the report!

Thanks for the fix, will have a look :)