Jump to content

C# Reflection and Extension methods?


Recommended Posts

I'm banging my head into the wall trying to figure out how to build a reflection wrapper for mechjeb.   I've got static methods working...  but now am trying to get the dynamic ones to work...  which I understand means getting the Master mechjeb core of the active vessel.     But... as far as getting that to work... I'm failing miserably.  

I THINK in the initialize method I'm finding the types for both the core and the vessel extensions, and then the GetCore function looks in the extensions for the GetMasterMechJeb method and invokes it, passing it the active vessel as an argument.     But it's throwing "Object reference not set to an instance of an object" exceptions when invoked.    I read somewhere that extension methods were actually static methods that take the object they extend as the first parameter...  but.. I think I'm doing it wrong?

I necro'ed an ancient post of mine trying to get help getting started... but... am now trying to dig in again and could use more specific help with this bit of it?  


What I've got at the moment (obviously cut down to just what I'm working on for your convenience) -
 

  public class MJWrapper
    {
        public static System.Type CoreType;
        public static System.Object core;
        public static Vessel vessel { get { return FlightGlobals.ActiveVessel; } }
        public static System.Type mjVesExtensions;

 public static bool Initialize()
        {
            if (Initialized)
                return true;
            AssemblyLoader.loadedAssemblies.TypeOperation(t => { if (t.FullName == "MuMech.MechJebCore") { CoreType = t; } });
            AssemblyLoader.loadedAssemblies.TypeOperation(t => { if (t.FullName == "MuMech.VesselExtensions") { mjVesExtensions = t; } });
            if (CoreType == null) {return false;}
            if (!GetCore()){ return false;}
            Initialized = true;
            return true;
        }

        public static bool GetCore()
        {
            MethodInfo GetMastr = mjVesExtensions.GetMethod("GetMasterMechJeb", BindingFlags.Public | BindingFlags.Static);
            core= GetMastr.Invoke(null, new object[] { vessel });
            return (core != null);
        }

}

       

Edited by artwhaley
Link to comment
Share on other sites

I'm totally at a loss on this and near giving up.  I've wasted DAYS reading everything I can find on reflection and I still can't make it work. 

I found an elegant looking wrapper for mechjeb reflection in the persistent rotation source code...  I copied it...  that didn't work at all. In the gravity turn source code I found a method that let me get the static methods...  but the method he used to get a dynamic property...  didn't work for me either.   

And I know I'm not providing enough information in this post to get any help.  "It didn't work" is a rough place to start... but at this point...  I don't even know what question to ask.  

I have an entire statically linked interface to Mechjeb working...  but it's really important to me to get it changed over to use reflection so it doesn't cause loading errors if mechjeb isn't installed.

Edited by artwhaley
Link to comment
Share on other sites

Hum, your code seems to be working. Are you sure you are not calling it before the MJCore is actually on the vessel ?

Here is my full test plugin that toggles the Ascent AP (you need the last MJ to have the call I use)

https://gist.github.com/sarbian/829efb072f71691527ad4a95057b7884

 

Edited by sarbian
Link to comment
Share on other sites

2 hours ago, artwhaley said:

@sarbian  I can't say thank you enough for looking at it.   And no hurry!   The whole first effort was here on gist....   in case I was closer before...  https://gist.github.com/artwhaley/f5bb453b8ed18fa89b53e47ffde46407

You might take a look at the code I use for RasterPropMonitor or Avionics Systems.

https://github.com/MOARdV/AvionicsSystems/blob/master/Source/MASIMechJeb.cs

Link to comment
Share on other sites

Well, @sarbian, I totally got your code to work!  This is a big step in the right direction.  I can't say enough how much I appreciate you of all people making time to help me.   In the interest of maybe saving you the next IM you might get on the same subject, I'm going to post the next step as I got it working; the following code demonstrates how to get one of the mechjeb computer modules and invoke a method in it. 

            MethodInfo getmodule = CoreType.GetMethod("GetComputerModule", BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, new[] { typeof(string) },null);   //Note GetComputerModule is overloaded so Type.DefaultBinder and the parameters after it grab the method that takes a string.
            System.Object node = getmodule.Invoke(core, new object[] {"MechJebModuleNodeExecutor" });  //Instance of the Node Execetor in the core object
            MethodInfo ExecOne = NodeExecutor.GetMethod("ExecuteOneNode", BindingFlags.Instance | BindingFlags.Public);  
            ExecOne.Invoke(node, new object[] { core });  //method belongs to NodeExecutor but gets passed the vessel master mechjeb as parameter!

I am certain I'm not done asking dumb questions on this project, and I most certainly WILL dig into the example that you've posted @MOARdV .  I don't know why I thought the RasterPropMonitor/Mechjeb link required statically linking at compile time.   If I'd remembered that you used reflection there I might have found my own answer sooner. 

Sarbian, would you like me to flesh this out and contribute it back to the Mechjeb repository as an example wrapper so others can see how to do it?    And if so... would you rather have the large finished wrapper that I'm going to be using for my project - something that gives access to most of Mechjeb and is ready for people to just add to their project and use...   or a slightly fleshed out and well commented version of essentially what you provided me here?  

 

Thank you both for the help!

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...