Getting gui control from callback function

fabio

Well-known member
Messages
70
Reactions
263
Points
53
Hi. I'm finishing some plugin but I need help with an issue. I have an indeterminate number of people on a scene (any scene) and I need to setup an UIDynamicPopup for each one. So from the code below, is there any way to get 'i' inside the callback functions? I can resolve this by creating a separate callback function for each posible person, but it must be a way to get from which popup the call is coming from.

Code:
    for(int i = 0; i < NUMBER_OF_PLEOPLE; i++)
    {
        JSONStorableStringChooser[] person[i] = new JSONStorableStringChooser("person" + i.ToString(), null, "", "", SyncAtom);
        RegisterStringChooser(person[i]);
        UIDynamicPopup dp = CreateFilterablePopup(person[i]);
        dp.popupPanelHeight = 1000f;
        dp.label = "Person #" + i.ToString();
        dp.popup.onOpenPopupHandlers += SyncAtomChocies;
    }

Code:
    // before opening the popup
    private void SyncAtomChoices()
    {
        // populate with person[i] string posibilities         (HOW DO I GET i INSIDE HERE)
    }

Code:
    // after choosing a string from the popup
    private void SyncAtom(string atomUID)
    {
        // set person[i] = atomUID                (HOW DO I GET i INSIDE HERE)
    }
 
I was hoping for some command for this but I couldn't find it. I solved it by putting the callbacks inside a helper class and passing on the index (i) on the class constructor.

Code:
        for(int i = 1; i <= NUMBER_OF_PLAYERS; i++)
        {
            DynPopupCallBack pop = new DynPopupCallBack(i);
            person[i] = new JSONStorableStringChooser("person" + i.ToString(), null, "", "", pop.SyncAtom);
            RegisterStringChooser(person[i] );
            UIDynamicPopup dp = CreateFilterablePopup(person[i]);
            dp.popupPanelHeight = 1000f;
            dp.label = "Person #" + i.ToString();
            dp.popup.onOpenPopupHandlers += pop.SyncAtomChoices;
        }

    public class DynPopupCallBack
    {
        public int i;
        
        public DynPopupCallBack(int _i)
        {
            i = _i;
        }
        
        // before opening the popup
        public void SyncAtomChoices()
        {
            // populate with person[i] string posibilities
            SuperController.LogMessage( "Before popup: " + i.ToString("#.00") );
        }
        
        // after choosing a string from the popup
        public void SyncAtom(string atomUID)
        {
            // set person[i] = atomUID
            SuperController.LogMessage( "String selected for: " + i.ToString("#.00") );
        }
    }
 
What you had been looking for is called Lambda functions.

If you define such a Lambda inside your for loop and use i, it would be automatically captured at the time the loop executes. Internally the following essentially creates that wrapper class for you and wraps the regular function call into a the lambda, so the function signature matches the callback.
C#:
    for(int i = 0; i < NUMBER_OF_PLEOPLE; i++)
    {
        JSONStorableStringChooser[] person[i] = new JSONStorableStringChooser(
                "person" + i.ToString(), null, "", "", (string atomUID) => SyncAtom(atomUID, i));
        RegisterStringChooser(person[i]);
        UIDynamicPopup dp = CreateFilterablePopup(person[i]);
        dp.popupPanelHeight = 1000f;
        dp.label = "Person #" + i.ToString();
        dp.popup.onOpenPopupHandlers += () => SyncAtomChocies(i);
    }



    // before opening the popup
    private void SyncAtomChoices(int i)
    {
        // populate with person[i] string posibilities
    }

    // after choosing a string from the popup
    private void SyncAtom(string atomUID, int i)
    {
        // set person[i] = atomUID           
    }
 
I knew it! I knew I was missing something, it was knowledge :LOL:

Thanks for the link but thank you very much for the code that makes it very easy to understand the concept. I see tons of uses for this.
 
Back
Top Bottom