mcneel / rhino.inside

Sample Projects for Rhino.Inside
MIT License
384 stars 168 forks source link

RhinoCore.Dispose() #14

Closed tarabishy2020 closed 5 years ago

tarabishy2020 commented 5 years ago

Hello,

Could someone provide more explanation on what is happening when this method is called?

I want to clear somethings up, based on the behaviour I am getting.

1> Initialize a new instance of RhinoCore 2> Rhino's interface opens up (If the WindowStyle chosen is Normal)
3> RhinoCommon code could be run here 4> Call Dispose on the class instance 5> Rhino's interface is closed 6> RhinoCommon code could still be run

Questions

A. Is there a way to start Rhino's interface again, without initializing a new instance of RhinoCore? When I do that Rhino opens on the Licensing window asking for a license, then when I deal with that, it starts loading but throws errors in couple of plugins " Error occurred loading plug-in. Details: Exception has been thrown by the target of an invocation ---- mscorlib" " Unable to load rdk_ui.rhp plug-in: application initialization failed" " Unable to load Displacement.rhp plug-in: could not open plugin file or plug-in failed to start" Then the program I am trying to run Rhino inside crashes.

B. Could you explain why after step number 4, step number 6 is still possible?

kike-garbo commented 5 years ago

Hi,

A. Right now is not possible. Let me work on this and make a new sample that shows how to do it. B. Is possible because some .NET assemblies are still loaded. Is not a supported way of calling it and can stop working on any new update.

tarabishy2020 commented 5 years ago

thank you @kike-garbo

kike-garbo commented 5 years ago

I recently committed some changes that show how to close and open the Rhino editor window. In summary I'm hiding and showing it again when the user request it, using this Property from Eto. Eto is distributed with Rhino since V6.

var RhinoMainWindow = Rhino.UI.RhinoEtoApp.MainWindow;
RhinoMainWindow.Visible = !RhinoMainWindow.Visible;

You can see this more in detail in the RhinoInside.Revit.UI.RhinoCommand.Execute method here in the source code.

tarabishy2020 commented 5 years ago

@kike-garbo , thank you for that. But my problem persists, and i believe its different from what this part might address.

var RhinoMainWindow = Rhino.UI.RhinoEtoApp.MainWindow;
RhinoMainWindow.Visible = !RhinoMainWindow.Visible;

To provide more context, I am working on using this for Unity, I had it running in Editor and runtime perfectly. The only problem is, during development, whenever you edit anything unity has to recompile, once that happens the running instance of rhino.inside is forced shutdown. Rhino.UI.RhinoEtoApp.MainWindow returns a null reference. And instantiating a new instance of rhinocore causes the errors I mentioned before to occur. The only solution for now is to relaunch unity, which is tedious during development.

kike-garbo commented 5 years ago

Could you please provide me a Unity sample project where you are using RhinoInside? Even if it is an empty project that just creates a RhinoCore instance, will be helpful. I just need a place to start that is similar to your case.

Thanks in advance.

kike-garbo commented 5 years ago

Hi @tarabishy2020, I added a sample for Unity in the unity/wip branch Could you please take a look to it and tell me if it helps?

tarabishy2020 commented 5 years ago

Hi @kike-garbo ,

I just saw this, sorry about that. So, I had setup my project in a way to use the RhinoCommon and Grasshopper NuGet packages. But using your branch, I get this error once I open the unity project "System.DllNotFoundException: RhinoLibrary"

So had to edit your Unity.cs file so that the Startup class looks like this

static class Startup
  {
    static string RhinoSystemDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Rhino WIP", "System");
    static string PATH = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process);
    static bool isLoaded = PATH.Contains(RhinoSystemDir);
    static Startup()
    {
      if (!isLoaded)
      {
        Environment.SetEnvironmentVariable("PATH", PATH + ";" + RhinoSystemDir + ";", EnvironmentVariableTarget.Process);
        GC.SuppressFinalize(new RhinoCore(new string[] { "/scheme=Unity", "/nosplash" }, WindowStyle.Minimized));
        isLoaded = true;
      }
    }
  }

I think the way you launch it by using GC.SupressFinalize is what solved the rhino instance being closed everytime unity recompiles the project

kike-garbo commented 5 years ago

Thanks for pointing out the way you update the PATH var. I fixed it in the repo.

Yes, SupressFinalize is there to “fix” the fact that Unity destroy everything on each run.