Jump to content

Delegate help


jmbon

Recommended Posts

Hello, I am trying to create a new GUI window in KSP but when I call my delegate callback(onDraw()), VS errors on me. I've looked at the API pages, Unity tutorials and C# pages for help but have been unable to fix the issues. I'd greatly appreciate any help. Below is my code along with the VS errors. 

 

namespace KSP_Wind_Display
{
//    public delegate CallBack(int que, int onDraw);

    public class Wind_GUI_Display : PartModule
    {
        delegate void CallBack();
        CallBack callback;


        private Rect window_pos = new Rect(); // New blank window
        private GUIStyle window_style, label_style;
        private bool has_init_styles = false;

        public override void OnStart(PartModule.StartState state)
        {
            base.OnStart(state);

            if (!has_init_styles)
                init_styles();

            callback += onDraw;

            if (state != StartState.Editor)
                RenderingManager.AddToPostDrawQueue(0, callback());               
<-------- Error 11 The best overloaded method match for 'RenderingManager.AddToPostDrawQueue(int, Callback)' has some invalid arguments
<-------- Error 12 Argument 2: cannot convert from 'void' to 'Callback'	
        }

        private void onDraw() // Start up the window
        {
            if (this.vessel == FlightGlobals.ActiveVessel)
                window_pos = GUILayout.Window(10, window_pos, onWindow, "Wind Direction", window_style);
        }

        private void onWindow(int window_id)
        {
            GUILayout.BeginHorizontal();
            GUILayout.EndHorizontal();

            GUI.DragWindow(); // Makes the window draggable
        }

        private void init_styles()
        {
            window_style = new GUIStyle(HighLogic.Skin.window);
            window_style.fixedWidth = 250.0f;

            label_style = new GUIStyle(HighLogic.Skin.label);
            label_style.stretchWidth = true; // stretches the label width to that of the window

            has_init_styles = true;
        }
	}
}

For Error 11, shouldn't that result in onDraw() being called. AddToPostDrawQueue needs an int and Callback as it's arguments and that's what I am passing it. 

For Error 12, I suspect the problem is where I first declare Callback to be void type of delegate. However, I don't want Callback to return anything so it has to be a void. 

I've worked at this problem for about 2 hours now and online forums, tutorials and man pages haven't help. Can someone here spot the issue and at least give me a hint on how to resolve it? Thanks in advance.

Link to comment
Share on other sites

Here's the problem.

  • What you're doing:  "AddToPostDrawQueue(0, callback())"
  • What you should be doing:  "AddToPostDrawQueue(0, callback)"

By adding those parentheses, what that means is that you're not passing the callback itself to the method.  Instead, what you're doing is calling the callback (which returns void), and then passing that return value to AddToPostDrawQueue.  So of course VS is complaining, because you're giving it a void when it wanted a callback.

Just get rid of the parentheses so that you're passing the callback itself.

Link to comment
Share on other sites

Ok. I understand that. When I make the changes, VS gives me;

Error    11    The best overloaded method match for 'RenderingManager.AddToPostDrawQueue(int, Callback)' has some invalid arguments
Error    12    Argument 2: cannot convert from 'CallBack' to 'Callback'
 

I believe Error 11 is being caused by Error 12 but unless there is a reserved keyword type called Callback, Error 12 doesn't make much sense to me. All I can think of is that Callback in 

.RenderingManager.AddToPostDrawQueue(int, Callback)

is not a delegate at all. However, I can find no other reference in Unity nor C# man pages to callbacks except in delegates. Any ideas or wisdom? Thanks again. 

Link to comment
Share on other sites

1 hour ago, jmbon said:

Ok. I understand that. When I make the changes, VS gives me;

Error    11    The best overloaded method match for 'RenderingManager.AddToPostDrawQueue(int, Callback)' has some invalid arguments
Error    12    Argument 2: cannot convert from 'CallBack' to 'Callback'
 

I believe Error 11 is being caused by Error 12 but unless there is a reserved keyword type called Callback, Error 12 doesn't make much sense to me. All I can think of is that Callback in 


.RenderingManager.AddToPostDrawQueue(int, Callback)

is not a delegate at all. However, I can find no other reference in Unity nor C# man pages to callbacks except in delegates. Any ideas or wisdom? Thanks again. 

So, I'll answer your question in two ways.  First, I'll tell you how you can answer this sort of question yourself.  :)  Then I'll describe your specific issue.

So, the thing to do in Visual Studio:  Mouse over "RenderingManager" and hit F12.  This will take you to the definition of the RenderingManager class.  You'll see the AddToPostDrawQueue method there, and you can see that it takes a Callback.  Hmm, what's a Callback, you wonder.  So you just mouseover that and hit F12 again and it takes you to the definition.  There!  Your question is answered.  :)

In this case, it shows you that it's defined in the KSPUtil assembly, and that it's a delegate which is just a void function that takes no arguments.

Since you declared your own delegate as being void and taking no arguments, I'm not sure why it doesn't like it, I would have thought they'd be equivalent.  Have you tried declaring your own callback as "Callback" (from KSPUtil) rather than declaring your own CallBack-with-a-capital-B?  What happens then?

Link to comment
Share on other sites

I didn't know about the F12 functionality but it's the same as right clicking the variable, class, etc., and selecting 'Peek Definition'. See, I thought they were equivalent as well, hence me coming here after the forums, man pages, and online tutorials/examples didn't help. 

Anywho, when changing the B to lowercase, I got conflicting types from my program and KSPUtils.dll . I commented out my 

public delegate CallBack(int que, int onDraw);

and it seems to have solved the current issue but now my UI window doesn't show up in KSP. 

using UnityEngine;

//This module will create a new GUI window and button, on button press the part will explode, close the GUI, and be removed.

namespace KSP_Wind_Display
{
    public class Wind_GUI_Display : PartModule
    {
        Callback callback;

        private Rect window_pos = new Rect(); // New blank window
        private GUIStyle window_style, label_style;
        private bool has_init_styles = false;

        public override void OnStart(PartModule.StartState state)
        {
            base.OnStart(state);

            if (!has_init_styles)
                init_styles();

            callback += onDraw;

            if (state == StartState.Flying || state == StartState.Landed || state == StartState.PreLaunch || state == StartState.Splashed)
            {
                RenderingManager.AddToPostDrawQueue(0, callback);
                Debug.Log("\n\n\n\nIt should have drawn the UI\n\n\n\n");
            }
        }

        private void onDraw() // Start up the window
        {
            if (this.vessel == FlightGlobals.ActiveVessel)
                window_pos = GUILayout.Window(1, window_pos, onWindow, "Wind Direction", GUILayout.MinWidth(100));
        }

        private void onWindow(int window_id)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Label("Width");
            GUILayout.EndHorizontal();

            GUI.DragWindow(); // Makes the window draggable
        }

        private void init_styles()
        {
            window_style = new GUIStyle(HighLogic.Skin.window);
            window_style.fixedWidth = 250.0f;

            label_style = new GUIStyle(HighLogic.Skin.label);
            label_style.stretchWidth = true; // stretches the label width to that of the window

            has_init_styles = true;
        }
    }
}

I suspect the problem is because 'callback' was a delegate where I casted onDraw to. Now that it's not really a delegate, I suspect that 'RenderingManager.AddToPostDrawQueue(0, callback);' isn't being called correctly now. Any thoughts? I appreciate the help. 

Edited by jmbon
code change
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...